askbot-dragon 1.4.1 → 1.4.2

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 (85) 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 +58 -58
  5. package/public/index.html +59 -59
  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 +92 -92
  11. package/src/assets/js/Base64Util.js +22 -22
  12. package/src/assets/js/common.js +11 -11
  13. package/src/assets/js/hammer.js +71 -71
  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 +191 -191
  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 +211 -211
  20. package/src/components/ActionAlertIframe.vue +112 -112
  21. package/src/components/AiGuide.vue +467 -467
  22. package/src/components/AnswerDocknowledge.vue +446 -446
  23. package/src/components/AnswerVoice.vue +280 -285
  24. package/src/components/AskIFrame.vue +15 -15
  25. package/src/components/ConversationContainer.vue +4028 -4028
  26. package/src/components/FileType.vue +86 -86
  27. package/src/components/Message.vue +27 -27
  28. package/src/components/actionSatisfaction.vue +107 -107
  29. package/src/components/actionSendToBot.vue +62 -62
  30. package/src/components/answerDissatisfaction.vue +62 -62
  31. package/src/components/answerRadio.vue +108 -108
  32. package/src/components/ask-components/DissatisfactionOptions.vue +57 -57
  33. package/src/components/ask-components/Msgloading.vue +37 -37
  34. package/src/components/ask-components/SatisfactionV2.vue +15 -15
  35. package/src/components/askVideo.vue +138 -138
  36. package/src/components/assetDetails.vue +370 -370
  37. package/src/components/assetMessage.vue +228 -228
  38. package/src/components/associationIntention.vue +331 -331
  39. package/src/components/attachmentPreview.vue +90 -90
  40. package/src/components/botActionSatisfactor.vue +68 -68
  41. package/src/components/chatContent.vue +513 -513
  42. package/src/components/feedBack.vue +136 -136
  43. package/src/components/fielListView.vue +349 -349
  44. package/src/components/file/AliyunOssComponents.vue +108 -108
  45. package/src/components/formTemplate.vue +3362 -3362
  46. package/src/components/loadingProcess.vue +164 -164
  47. package/src/components/message/ActionAlertIframe.vue +112 -112
  48. package/src/components/message/ShopMessage.vue +164 -164
  49. package/src/components/message/TextMessage.vue +924 -924
  50. package/src/components/message/TicketMessage.vue +177 -177
  51. package/src/components/message/swiper/index.js +4 -4
  52. package/src/components/message/swiper/ticketSwiper.vue +503 -503
  53. package/src/components/message/swiper/ticketSwiperItem.vue +61 -61
  54. package/src/components/msgLoading.vue +231 -231
  55. package/src/components/myPopup.vue +70 -70
  56. package/src/components/pdfPosition.vue +829 -829
  57. package/src/components/popup.vue +227 -227
  58. package/src/components/previewDoc.vue +228 -228
  59. package/src/components/previewPdf.vue +257 -257
  60. package/src/components/receiverMessagePlatform.vue +65 -65
  61. package/src/components/recommend.vue +89 -89
  62. package/src/components/selector/hOption.vue +20 -20
  63. package/src/components/selector/hSelector.vue +199 -199
  64. package/src/components/selector/hWrapper.vue +216 -216
  65. package/src/components/senderMessagePlatform.vue +50 -50
  66. package/src/components/source/BotMessage.vue +24 -24
  67. package/src/components/source/CustomMessage.vue +24 -24
  68. package/src/components/test.vue +260 -260
  69. package/src/components/tree.vue +294 -294
  70. package/src/components/utils/AliyunIssUtil.js +72 -72
  71. package/src/components/utils/ckeditor.js +155 -155
  72. package/src/components/utils/ckeditorImageUpload/command.js +109 -109
  73. package/src/components/utils/ckeditorImageUpload/editing.js +11 -11
  74. package/src/components/utils/ckeditorImageUpload/plugin-image.js +11 -11
  75. package/src/components/utils/ckeditorImageUpload/toolbar-ui.js +40 -40
  76. package/src/components/utils/ckeditorfileUpload/common.js +133 -133
  77. package/src/components/utils/ckeditorfileUpload/editing.js +11 -11
  78. package/src/components/utils/ckeditorfileUpload/plugin_file.js +11 -11
  79. package/src/components/utils/ckeditorfileUpload/toolbar_ui.js +34 -34
  80. package/src/components/utils/format_date.js +25 -25
  81. package/src/components/utils/index.js +6 -6
  82. package/src/components/utils/math_utils.js +29 -29
  83. package/src/components/voiceComponent.vue +119 -119
  84. package/src/main.js +60 -60
  85. package/vue.config.js +55 -55
@@ -1,830 +1,830 @@
1
- <template>
2
- <div class="pdf_view" ref="pdfView" @scroll="pdfScroll">
3
- <div class="btn_footer" v-if="tagIds.length > 1">
4
- <div class="prev" @click="prev">上一段</div>
5
- <div class="next" @click="next">下一段</div>
6
- </div>
7
- </div>
8
- </template>
9
-
10
- <script>
11
- import _ from 'lodash'
12
- // import * as pdfjsLib from 'pdfjs-dist'
13
- // pdfjsLib.GlobalWorkerOptions.workerSrc = 'pdfjs-dist/build/pdf.worker';
14
- // import { TextLayerBuilder } from "pdfjs-dist/web/pdf_viewer";
15
- // EventBus pdf_viewer 支持绑定自定义事件,一版不做
16
- // import 'pdfjs-dist/web/pdf_viewer.css'
17
- /* eslint-disable */
18
- const pdfjsLib = window['pdfjsLib']
19
- if(pdfjsLib) {
20
- pdfjsLib.GlobalWorkerOptions.workerSrc = window['pdfjs-dist/build/pdf.worker']
21
- // 'pdfjs-dist/build/pdf.worker';
22
- }
23
- const { TextLayerBuilder } = window['pdfjs-dist/web/pdf_viewer']
24
- // import { zoomElement } from '../assets/js/hammer'
25
- export default {
26
- name: 'pdfView',
27
- props:['tagIds','isMessageRecord'],
28
- data() {
29
- return {
30
- url: '',
31
- // pdfjsLib: window['pdfjs-dist/build/pdf'],
32
- // pdfjsLib: pdfjsLib,
33
- pages: [],
34
- pageLoadStatus: {
35
- WAIT: 0,
36
- LOADED: 1,
37
- },
38
- scale: 1,
39
- rotation: 0,
40
- pageSize: {},
41
- PAGE_INTVERVAL: 15,
42
- SLICE_COUNT: 5,
43
- contentView: null,
44
- fisrtLoad: true,
45
- TextLayerBuilder: null,
46
- totalPageCount: 0,
47
- identifyTextPostion: {
48
- top: 0,
49
- left: 0,
50
- width: 100,
51
- height: 0,
52
- page: 1,
53
- pageHeight: 0,
54
- pageWidth: 0,
55
- extractInfo: {},
56
- currentPageAllLine: []
57
- },
58
- currentPageAllLine: [],
59
- pdfUrl: '',
60
- cachePdf: [],
61
- newViewer: null,
62
- currentPage: 0,
63
- changetoolbar: false,
64
- allTr:[],
65
- preViewType: 'pdf',
66
- displacement:{
67
- pageX:0,
68
- pageY:0,
69
- moveable:false,
70
- pageX2:0,
71
- pageY2:0,
72
- originScale:1,
73
- },
74
- isTouchMoved: false,
75
- transformSalce: null,
76
- }
77
- },
78
- methods: {
79
- getpdfResloutePage (pdfResloute) {
80
- // 根据当前页面宽度设置缩放比例
81
- // this.scale = Math.round(this.$refs.pdfView.clientWidth / pdfResloute.pageWidth * 100) / 100
82
- // console.log(this.scale,'this.scale');
83
- if(this.isMessageRecord) {
84
- this.scale = Math.round(this.$refs.pdfView.clientWidth / pdfResloute.pageWidth * 100) / 100
85
- } else {
86
- this.scale = 1
87
- }
88
- // 从后端获取到当前分片后所有的pdf页码,初始化数组,数组下{} 对应每页pdf文件
89
- this.pdfUrl = pdfResloute.publicPageFileUrl.substring(0, pdfResloute.publicPageFileUrl.lastIndexOf('/') + 1)
90
- this.initPages(pdfResloute.total)
91
- // 定位功能,加载对应页码位置
92
- this.loadPdfData(pdfResloute.page)
93
- },
94
- async loadPdfData (loadPage) {
95
- if(this.pages[loadPage - 1] && this.pages[loadPage - 1].dom && this.pages[loadPage - 1].dom.children.length > 0) {
96
- return
97
- }
98
- // pdfjsLib.GlobalWorkerOptions.workerSrc = require("pdfjs-dist/legacy/build/pdf.worker.entry.js");
99
- // 拿到第一个分片
100
- const { startPage, url } = await this.fetchPdfFragment(loadPage);
101
- let loadingTask = pdfjsLib.getDocument(url)
102
- loadingTask.promise.then((pdfDoc) => {
103
- // 将已经下载的分片保存到 pages 数组中
104
- for (let i = 0; i < pdfDoc.numPages; i += 1) {
105
- const pageIndex = startPage + i;
106
- const page = this.pages[pageIndex - 1];
107
- // 不在缓存列表内,重新获取本页pdf
108
- if (page.loadStatus !== this.pageLoadStatus.LOADED) {
109
- pdfDoc.getPage(i + 1).then((pdfPage) => {
110
- page.pdfPage = pdfPage;
111
- page.loadStatus = this.pageLoadStatus.LOADED;
112
- // 通知可以进行渲染了
113
- this.startRenderPages(pdfPage, page, pageIndex)
114
- });
115
- } else {
116
- if (this.changetoolbar) {
117
- this.$nextTick(() => {
118
- this.renderHighlights()
119
- })
120
- this.changetoolbar = false
121
- }
122
- }
123
- }
124
- });
125
- },
126
- initPages (totalPage) {
127
- // const pages = [];
128
- this.totalPageCount = totalPage
129
- for (let i = 0; i < totalPage; i += 1) {
130
- this.pages.push({
131
- pageNo: i + 1,
132
- loadStatus: this.pageLoadStatus.WAIT,
133
- pdfPage: null,
134
- dom: null
135
- });
136
- }
137
- },
138
- async fetchPdfFragment (pageIndex) {
139
- // 置换加签后的文件地址。
140
- let obj = {}
141
- await this.$http.post(
142
- '/knowledge-api/temporary-certificate/or-origin?expired=30',
143
- this.pdfUrl + pageIndex + '.pdf',
144
- {
145
- headers: {
146
- "Content-Type": "application/json",
147
- },
148
- }).then(async res => {
149
- if(res.bodyText) {
150
- // 最后返回一个 包含这4个参数的对象
151
- obj = await {
152
- "startPage": pageIndex, // 分片的开始页码
153
- "endPage": pageIndex + 5, // 分片结束页码
154
- "totalPage": this.totalPageCount, // pdf 总页数
155
- "url": res.bodyText // 分片内容下载地址
156
- }
157
- }
158
- if (res.data) {
159
- // 最后返回一个 包含这4个参数的对象
160
- obj = await {
161
- "startPage": pageIndex, // 分片的开始页码
162
- "endPage": pageIndex + 5, // 分片结束页码
163
- "totalPage": this.totalPageCount, // pdf 总页数
164
- "url": res.data // 分片内容下载地址
165
- }
166
- }
167
- })
168
- return obj
169
- },
170
- startRenderPages (pdfPage, page, pageIndex) {
171
- const viewport = pdfPage.getViewport({
172
- scale: this.scale, // 缩放的比例
173
- rotation: this.rotation, // 旋转的角度
174
- });
175
- // 记录pdf页面高度
176
- const pageSize = {
177
- width: viewport.width,
178
- height: viewport.height,
179
- }
180
- this.pageSize = pageSize
181
- // 创建内容绘制区,并设置大小
182
- if(this.$refs.pdfView.clientWidth / this.pageSize.width >= 1 || this.isMessageRecord) {
183
- this.contentView.style.width = `${pageSize.width }px`;
184
- this.contentView.style.height = `${(this.totalPageCount * (pageSize.height + this.PAGE_INTVERVAL)) + this.PAGE_INTVERVAL}px`;
185
- } else {
186
- this.transformSalce = this.$refs.pdfView.clientWidth / this.pageSize.width
187
- this.contentView.style.width = `${pageSize.width * this.transformSalce}px`;
188
- this.contentView.style.height = `${(this.totalPageCount * (pageSize.height * (this.transformSalce) + this.PAGE_INTVERVAL)) + this.PAGE_INTVERVAL}px`;
189
- }
190
- this.contentView.style.margin = '0 auto 0'
191
- console.log(this.transformSalce);
192
- this.contentView.style.position = 'relative'
193
- this.contentView.style.paddingBottom = '60px'
194
- // contentView.style.overflowY = 'auto'
195
- this.$refs.pdfView.appendChild(this.contentView);
196
- this.renderPages(pageIndex)
197
- },
198
- renderPageContent (page, pageIndex) {
199
- const { pdfPage, pageNo, dom } = page;
200
- // dom 元素已存在,无须重新渲染,直接返回
201
- console.log(dom, 'dom');
202
- if (dom && dom.children.length != 0) {
203
- return;
204
- }
205
- const viewport = pdfPage.getViewport({
206
- scale: this.scale,
207
- rotation: this.rotation,
208
- });
209
- // 创建新的canvas
210
- const canvas = document.createElement('canvas');
211
- const context = canvas.getContext('2d');
212
- // canvas.getContext('2d');
213
- canvas.height = this.pageSize.height;
214
- canvas.width = this.pageSize.width;
215
- // 创建渲染的dom
216
- const pageDom = document.createElement('div');
217
- pageDom.style.position = 'absolute';
218
- pageDom.style.top = `${((pageNo - 1) * (this.pageSize.height + this.PAGE_INTVERVAL)) + this.PAGE_INTVERVAL}px`;
219
- pageDom.style.width = `${this.pageSize.width}px`;
220
- pageDom.style.height = `${this.pageSize.height}px`;
221
- pageDom.appendChild(canvas);
222
- // 渲染内容
223
- let renderContext = {
224
- canvasContext: context,
225
- viewport: viewport,
226
- }
227
- pdfPage.render(renderContext).promise.then(() => {
228
- console.log(pdfPage.getTextContent(), 'getTextContent');
229
- return pdfPage.getTextContent()
230
- }).then((textContent) => {
231
- const textLayerDiv = document.createElement('div');
232
- textLayerDiv.setAttribute('class', 'textLayer');
233
- // 将文本图层div添加至每页pdf的div中
234
- // 创建新的TextLayerBuilder实例
235
- let textLayer = new TextLayerBuilder({
236
- textLayerDiv: textLayerDiv,
237
- pageIndex: pdfPage._pageIndex,
238
- viewport: viewport,
239
- });
240
- let findPage = this.currentPageAllLine.find(l => { return l.page == pageIndex })
241
- if (findPage) {
242
- let AllLines = findPage.allLines
243
- // setTimeout(() => {
244
- if (AllLines.length > 0) {
245
- for (let j = 0; j < AllLines.length; j++) {
246
- let lines = AllLines[j].lines
247
- let rectdom = document.createElement('div')
248
- rectdom.setAttribute('react-count', AllLines[j].pageCount);
249
- rectdom.style.position = 'absolute';
250
- rectdom.style.top = 0
251
- rectdom.style.left = 0
252
- rectdom.classList.add('rectdom')
253
- for (let index = 0; index < lines.length; index++) {
254
- if (!/^\s+$/g.test(lines[index].content)) {
255
- let postionArr = lines[index].location
256
- let div = document.createElement('div')
257
- div.style.position = 'absolute';
258
- div.style.left = postionArr[0] * this.scale + 'px',
259
- // 后端返回的坐标有基线对齐的问题,top 值是后端算好(基线top - 文字高度),在此加上文字高度的 1/9 (大致比例)为实际展示出文字的top值
260
- div.style.top = (postionArr[1] + postionArr[3] / 9) * this.scale + 'px'
261
- div.style.height = postionArr[3] * this.scale + 'px';
262
- div.style.width = postionArr[2] * this.scale + 'px'
263
- div.style.backgroundColor = 'rgba(54, 106, 255, 0.3)'
264
- div.classList.add('lineHeight')
265
- rectdom.appendChild(div)
266
- }
267
- }
268
- if (rectdom.children.length > 0) {
269
- pageDom.appendChild(rectdom)
270
- }
271
- }
272
- }
273
- }
274
- textLayer.setTextContent(textContent);
275
- textLayer.render()
276
- pageDom.appendChild(textLayer.textLayerDiv);
277
- page.dom = pageDom;
278
- this.contentView.appendChild(pageDom);
279
- if(this.transformSalce !== null) {
280
- this.contentView.style.transform = `scale(${this.transformSalce}, ${this.transformSalce})`
281
- }
282
- if (this.changetoolbar) {
283
- setTimeout(() => {
284
- this.renderHighlights()
285
- this.changetoolbar = false
286
- }, 100)
287
- }
288
- if (this.fisrtLoad) {
289
- setTimeout(() => {
290
- // (this.pageSize.height + this.PAGE_INTVERVAL)
291
- if (this.$refs.pdfView.clientHeight - (this.pageSize.height + this.PAGE_INTVERVAL) > 0 ) {
292
- let loadNum = Math.ceil(this.$refs.pdfView.clientHeight / (this.pageSize.height + this.PAGE_INTVERVAL))
293
- for (let n = 0; n < loadNum; n++) {
294
- this.loadPdfData(pageNo + n)
295
- }
296
- } else {
297
- this.renderHighlights()
298
- }
299
- if(this.transformSalce !== null) {
300
- if (this.$refs.pdfView.scrollTop == Math.floor((pageNo - 1) * (this.pageSize.height + this.PAGE_INTVERVAL)) * this.transformSalce ) {
301
- this.fisrtLoad = false
302
- } else {
303
- this.$refs.pdfView.scrollTop = `${((pageNo - 1) * (this.pageSize.height + this.PAGE_INTVERVAL) * this.transformSalce)}`
304
- this.renderHighlights()
305
- }
306
- } else {
307
- if (this.$refs.pdfView.scrollTop == Math.floor((pageNo - 1) * (this.pageSize.height + this.PAGE_INTVERVAL))) {
308
- this.fisrtLoad = false
309
- } else {
310
- this.$refs.pdfView.scrollTop = `${((pageNo - 1) * (this.pageSize.height + this.PAGE_INTVERVAL))}`
311
- this.renderHighlights()
312
-
313
- }
314
- }
315
- // zoomElement(this.contentView)
316
- }, 100)
317
- }
318
- })
319
- },
320
- // 监听容器的滚动事件,触发 scrollPdf 方法
321
- // 这里加了防抖保证不会一次产生过多请求
322
- debounceScrollPdf: _.debounce(function (e, that) {
323
- if (this.fisrtLoad) {
324
- this.fisrtLoad = false
325
- return
326
- }
327
- const scrollTop = e.target.scrollTop;
328
- const height = e.target.clientHeight;
329
- // 根据内容可视区域中心点计算页码, 没有滚动时,指向第一页
330
- const pageIndex = scrollTop > 0 ?
331
- Math.ceil((scrollTop + (height / 2)) / (that.pageSize.height + that.PAGE_INTVERVAL)) :
332
- 1;
333
-
334
- pageIndex - 1 != 0 && that.loadPdfData(pageIndex - 1)
335
- that.loadPdfData(pageIndex)
336
- pageIndex + 1 <= that.totalPageCount && that.loadPdfData(pageIndex + 1)
337
- }, 200),
338
- directScrolling (e, that) {
339
- if (this.fisrtLoad) {
340
- this.fisrtLoad = false
341
- return
342
- }
343
- const scrollTop = e.target.scrollTop;
344
- const height = e.target.clientHeight;
345
- // 根据内容可视区域中心点计算页码, 没有滚动时,指向第一页
346
- const pageIndex = scrollTop > 0 ?
347
- Math.ceil((scrollTop + (height / 2)) / (that.pageSize.height + that.PAGE_INTVERVAL)) :
348
- 1;
349
- this.loadPdfData(pageIndex)
350
- },
351
- pdfScroll (e) {
352
- if(this.preViewType !== 'pdf' || this.isTouchMoved) {
353
- return
354
- }
355
- this.debounceScrollPdf(e, this)
356
- },
357
- // 分片每次只做一次处理,所以不考虑多片情况
358
- loadBefore (pageIndex) {
359
- this.loadPdfData(pageIndex)
360
- // const start = (Math.floor(pageIndex / this.SLICE_COUNT) * this.SLICE_COUNT) - (this.SLICE_COUNT - 1);
361
- // if (start > 0) {
362
- // // const prevPage = this.pages[start - 1] || {};
363
- // this.loadPdfData(start)
364
- // // prevPage.loadStatus === this.pageLoadStatus.WAIT && this.loadPdfData(start);
365
- // }
366
- },
367
- loadAfter (pageIndex) {
368
- this.loadPdfData(pageIndex)
369
- // const start = (Math.floor(pageIndex / this.SLICE_COUNT) * this.SLICE_COUNT) + 1;
370
- // if (start <= this.pages.length) {
371
- // // const nextPage = this.pages[start - 1] || {};
372
- // this.loadPdfData(start)
373
- // // nextPage.loadStatus === this.pageLoadStatus.WAIT && this.loadPdfData(start);
374
- // }
375
- },
376
- // 首先我们获取到需要渲染的范围
377
- // 根据当前的可视范围内的页码,我们前后只保留 8 页
378
- getRenderScope (pageIndex) {
379
- const pagesToRender = [];
380
- let i = pageIndex - 1;
381
- let j = pageIndex + 1;
382
- // pageIndex - 1 表示当前页码数 对应的下标位置
383
- pagesToRender.push(this.pages[pageIndex - 1]);
384
- while (pagesToRender.length < 10 && pagesToRender.length < this.pages.length) {
385
- if (i > 0) {
386
- pagesToRender.push(this.pages[i - 1]);
387
- i -= 1;
388
- }
389
- if (pagesToRender.length >= 10) {
390
- break;
391
- }
392
- if (j <= this.pages.length) {
393
- pagesToRender.push(this.pages[j - 1]);
394
- j += 1;
395
- }
396
- }
397
- return pagesToRender;
398
- },
399
- // 渲染需要展示的页面,不需展示的页码将其清除
400
- renderPages (pageIndex) {
401
- const pagesToRender = this.getRenderScope(pageIndex);
402
- for (const i of this.pages) {
403
- if (pagesToRender.includes(i)) {
404
- i.loadStatus === this.pageLoadStatus.LOADED ?
405
- this.renderPageContent(i, pageIndex) :
406
- this.renderPageLoading(i);
407
- } else {
408
- this.clearPage(i);
409
- }
410
- }
411
- },
412
- // 清除页面 dom
413
- clearPage (page) {
414
- if (page.dom) {
415
- this.contentView.removeChild(page.dom);
416
- page.loadStatus = 0
417
- page.dom = undefined;
418
- }
419
- },
420
- // 页面正在下载时渲染loading视图
421
- renderPageLoading (page) {
422
- const { pageNo, dom } = page;
423
- if (dom && dom.children.length != 0) {
424
- return;
425
- }
426
- const pageDom = document.createElement('div');
427
- pageDom.style.width = `${this.pageSize.width}px`;
428
- pageDom.style.height = `${this.pageSize.height}px`;
429
- pageDom.style.position = 'absolute';
430
- pageDom.style.top = `${((pageNo - 1) * (this.pageSize.height + this.PAGE_INTVERVAL)) + this.PAGE_INTVERVAL
431
- }px`;
432
- pageDom.style.backgroundImage = `url('https://guoranopen-zjk.oss-cn-zhangjiakou.aliyuncs.com/cdn-common/images/loading.gif')`
433
- pageDom.style.backgroundPosition = 'center'
434
- pageDom.style.backgroundRepeat = 'no-repeat'
435
- pageDom.style.backgroundColor = '#FFF'
436
- page.dom = pageDom;
437
- this.contentView.appendChild(pageDom);
438
- },
439
- prev () {
440
- this.currentPage--
441
- if (this.currentPage < 0) {
442
- // this.currentPage = this.tagIds.length - 1
443
- this.currentPage = 0
444
- }
445
- if(this.preViewType == 'pdf') {
446
- this.scrollToUplaodePage(this.currentPage)
447
- } else {
448
- this.scrollToExcalTop(this.currentPage)
449
- }
450
- // this.getpdfResloutePage(this.cachePdf[this.currentPage - 1])
451
- },
452
- next () {
453
- this.currentPage++
454
- if (this.currentPage >= this.tagIds.length) {
455
- this.currentPage = this.tagIds.length - 1
456
- }
457
- if(this.preViewType == 'pdf') {
458
- this.scrollToUplaodePage(this.currentPage)
459
- } else {
460
- this.scrollToExcalTop(this.currentPage)
461
- }
462
- },
463
- currentChange (value) {
464
- this.currentPage = value - 1
465
- if(this.preViewType == 'pdf') {
466
- this.scrollToUplaodePage(this.currentPage)
467
- } else {
468
- this.scrollToExcalTop(this.currentPage)
469
- }
470
- },
471
- scrollToUplaodePage (currentPage) {
472
- this.changetoolbar = true
473
- if(this.preViewType !== 'pdf') {
474
- return
475
- }
476
- let pdfResloute = this.cachePdf[currentPage]
477
- this.identifyTextPostion.extractInfo = pdfResloute.extractInfo
478
- this.identifyTextPostion.left = pdfResloute.extractInfo.location[0]
479
- this.identifyTextPostion.top = pdfResloute.extractInfo.location[1]
480
- this.identifyTextPostion.width = pdfResloute.extractInfo.location[2]
481
- this.identifyTextPostion.height = pdfResloute.extractInfo.location[3]
482
- this.identifyTextPostion.page = pdfResloute.page
483
- this.identifyTextPostion.pageHeight = pdfResloute.pageHeight
484
- this.identifyTextPostion.pageWidth = pdfResloute.pageWidth
485
- // 在当前段落在最后一页pdf时,根据计算的高度并不能触发滚动,在此执行重新渲染方法,非次情况会执行两次,待优化
486
- this.$nextTick(() => {
487
- this.renderHighlights()
488
- })
489
- if(this.transformSalce !== null) {
490
- this.$refs.pdfView.scrollTop = `${((pdfResloute.page - 1) * (this.pageSize.height + this.PAGE_INTVERVAL) * this.transformSalce)}`
491
- } else {
492
- this.$refs.pdfView.scrollTop = `${((pdfResloute.page - 1) * (this.pageSize.height + this.PAGE_INTVERVAL))}`
493
- }
494
- },
495
- scrollToExcalTop(currentPage) {
496
- for (let index = 0; index < this.allTr.length; index++) {
497
- if(index == currentPage) {
498
- Array.from(this.allTr[index].children).forEach(item =>{
499
- item.style.background = 'rgba(255, 136, 0, 0.6)'
500
- })
501
- // this.$refs.pdfView.scrollTop = this.allTr[index].offsetTop
502
- this.$refs.pdfView.scrollTop = this.allTr[index].getBoundingClientRect().top
503
-
504
- } else {
505
- Array.from(this.allTr[index].children).forEach(item =>{
506
- item.style.background = 'rgba(54, 106, 255, 0.6)'
507
- })
508
- }
509
- }
510
- },
511
- // pdf是否需要重新渲染高亮位置
512
- renderHighlights () {
513
- let lineHeightDom = Array.from(document.getElementsByClassName('rectdom'))
514
- console.log(lineHeightDom, this.currentPage, 'this.currentPage');
515
- if (lineHeightDom) {
516
- lineHeightDom.forEach((d) => {
517
- for (let i = 0; i < d.children.length; i++) {
518
- if (d.getAttribute('react-count') == this.currentPage) {
519
- d.children[i].style.backgroundColor = 'rgba(255, 136, 0, 0.3)'
520
- } else {
521
- d.children[i].style.backgroundColor = 'rgba(54, 106, 255, 0.3)'
522
- }
523
- }
524
- })
525
- }
526
- },
527
- displayHiglight (pageIndex) {
528
- let lineHeightDom = Array.from(document.getElementsByClassName('rectdom'))
529
- if (lineHeightDom) {
530
- lineHeightDom.forEach((d) => {
531
- if (d.getAttribute('page-index') == pageIndex) {
532
- d.style.display = 'none'
533
- }
534
- })
535
- }
536
- },
537
- // 前端暂时缓存多页
538
- autoLoadMore (pageIndex) {
539
- let pdfResloute = this.cachePdf.find(cache => {
540
- return cache.page == pageIndex
541
- })
542
- if (pdfResloute) {
543
- this.getpdfResloutePage(pdfResloute)
544
- } else {
545
- this.loadPdfData(pageIndex)
546
- }
547
- },
548
- setPageAllLine (arr) {
549
- this.currentPageAllLine = []
550
- arr.forEach((item, index) => {
551
- let i = this.currentPageAllLine.findIndex(l => { return l.page && l.page == item.page })
552
- if (i != -1) {
553
- // this.currentPageAllLine[i].allLines.lines.push(item.extractInfo.lines)
554
- this.currentPageAllLine[i].allLines.push({
555
- pageCount: index,
556
- lines: item.extractInfo.lines
557
- })
558
- } else {
559
- this.currentPageAllLine.push({
560
- page: item.page,
561
- allLines: [{
562
- pageCount: index,
563
- lines: item.extractInfo.lines
564
- }],
565
- })
566
- }
567
- })
568
- },
569
- openTouch() {
570
- // this.$nextTick()将回调延迟到下次 DOM 更新循环之后执行
571
- let that = this;
572
- this.$nextTick(() => {
573
- // setInterval(() => {
574
- // this.scale = this.scale + 0.1
575
- // that.pages.forEach((item, index) =>{
576
- // if(item.dom) {
577
- // item.dom.children.forEach( childDom =>{
578
- // if(childDom.getAttribute('react-count')) {
579
- // childDom.style.transform = "scale(" + this.scale + ")";
580
- // childDom.style.transformOrigin = "0px 0px 0px";
581
- // } else {
582
- // item.dom = null
583
- // this.startRenderPages(item.pdfPage, null, index)
584
- // }
585
- // } )
586
- // }
587
- // })
588
- // }, 100);
589
- // 获取放大或缩小的区域DOM
590
- let matrix_box = this.contentView
591
- matrix_box.addEventListener("touchstart", function (event) {
592
- this.isTouchMoved = true
593
- let touches = event.touches;
594
- let events = touches[0];
595
- let events2 = touches[1];
596
-
597
- // event.preventDefault();
598
-
599
- // 第一个触摸点的坐标
600
- that.displacement.pageX = events.pageX;
601
- that.displacement.pageY = events.pageY;
602
-
603
- that.displacement.moveable = true;
604
-
605
- if (events2) {
606
- that.displacement.pageX2 = events2.pageX;
607
- that.displacement.pageY2 = events2.pageY;
608
- }
609
-
610
- that.displacement.originScale = this.scale || 1;
611
- // console.log(that.displacement);
612
- });
613
- document.addEventListener("touchmove", function (event) {
614
- if (!that.displacement.moveable) {
615
- return;
616
- }
617
- // event.preventDefault();
618
- let touches = event.touches;
619
- let events = touches[0];
620
- let events2 = touches[1];
621
- // 双指移动
622
- if (events2) {
623
- // 第2个指头坐标在touchmove时候获取
624
- if (!that.displacement.pageX2) {
625
- that.displacement.pageX2 = events2.pageX;
626
- }
627
- if (!that.displacement.pageY2) {
628
- that.displacement.pageY2 = events2.pageY;
629
- }
630
- // 双指缩放比例计算
631
- let zoom = that.getDistance({
632
- x: events.pageX,
633
- y: events.pageY
634
- },
635
- {
636
- x: events2.pageX,
637
- y: events2.pageY
638
- }
639
- ) / that.getDistance(
640
- {
641
- x: that.displacement.pageX,
642
- y: that.displacement.pageY
643
- },
644
- {
645
- x: that.displacement.pageX2,
646
- y: that.displacement.pageY2
647
- }
648
- );
649
- // 应用在元素上的缩放比例
650
- let newScale = that.displacement.originScale * zoom;
651
- console.log(zoom, newScale , this.scale, 'newScale');
652
- // 最大缩放比例限制
653
- if (newScale > 2) {
654
- newScale = 2;
655
- }
656
- // 最大缩放比例限制
657
- if(newScale < 1) {
658
- newScale = 1;
659
- }
660
- // 记住使用的缩放值
661
- that.displacement.scale = newScale;
662
- // console.log(newScale);
663
- matrix_box.style.transform = "scale(" + newScale + ")";
664
- // 设置旋转元素的基点位置
665
- matrix_box.style.transformOrigin = "0px 0px 0px";
666
- }
667
- },{ passive: false });
668
- document.addEventListener('touchend',function() {
669
- that.isTouchMoved = false
670
- },{ passive: false })
671
- });
672
- },
673
- getDistance(start, stop) {
674
- // Math.hypot()计算参数的平方根
675
- return Math.hypot(stop.x - start.x, stop.y - start.y);
676
- },
677
- setupCanvas(canvas, width, height) {
678
- const dpr = 1;
679
- // const rect = canvas.getBoundingClientRect();
680
- canvas.width = width
681
- canvas.height = height
682
- const ctx = canvas.getContext('2d');
683
- console.log(canvas.width, canvas.height, dpr, this.scale);
684
- ctx?.scale(dpr, dpr );
685
- return ctx;
686
- },
687
- },
688
- computed:{
689
- perviewUrl() {
690
- return '/web/viewer.html?file=' + '/pdflist/pdf4split-1.pdf'
691
- }
692
- },
693
- watch:{
694
- tagIds: {
695
- handler(value) {
696
- if(value && value.length) {
697
- // 在 pdf_view 下创建 所有canvs的容器
698
- this.contentView = document.createElement('div')
699
- this.contentView.style.transformOrigin = '0px 0px 0px'
700
- this.$http.get('/knowledge-api/knowledge/knowledge-part-location-info/list?ids=' + value.join(',')).then(res =>{
701
- 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}
702
- if (res.data.code == 0) {
703
- // tagIds 会按照gpt识别的生成有序的数组,前端直接按照下标的顺序取就可以了
704
- // 缓存拿到的所有数据
705
- this.cachePdf = res.data.data
706
- let publicPageFileUrl = res.data.data[0].publicPageFileUrl
707
- this.currentPage = 0
708
- // console.log(publicPageFileUrl.substring(publicPageFileUrl.lastIndexOf('.')));
709
- if (publicPageFileUrl.substring(publicPageFileUrl.lastIndexOf('.')) === '.pdf') {
710
- this.preViewType = 'pdf'
711
- this.setPageAllLine(this.cachePdf)
712
- this.getpdfResloutePage(res.data.data[0])
713
- } else {
714
- this.preViewType = 'excal'
715
- this.$http.post(
716
- '/knowledge-api/temporary-certificate/or-origin?expired=30',
717
- publicPageFileUrl,
718
- {
719
- headers: {
720
- "Content-Type": "application/json",
721
- },
722
- }).then(res => {
723
- // 使用原声请求方式 axios会带有不需要的请求头
724
- let xhr = new XMLHttpRequest();
725
- xhr.open('GET', res.data || res.bodyText , true);
726
- // 定义请求完成的处理函数,请求前也可以增加加载框/禁用下载按钮逻辑
727
- xhr.onload = ({ currentTarget }) => {
728
- // 请求完成
729
- if (currentTarget.status === 200) { // 返回200
730
- this.contentView.innerHTML = currentTarget.response
731
- this.contentView.style.padding = '10px'
732
- // this.contentView.style.position = 'relative'
733
- this.$refs.pdfView.style.backgroundColor = '#FFFFFF'
734
- this.$refs.pdfView.appendChild(this.contentView)
735
- let allTr = Array.from(this.$refs.pdfView.getElementsByTagName('tr'))
736
- this.allTr = []
737
- for (let index = 0; index < allTr.length; index++) {
738
- if(value.includes(allTr[index].getAttribute('tag-id'))) {
739
- this.allTr.push(allTr[index])
740
- }
741
- }
742
- this.currentChange(1)
743
-
744
- }
745
- }
746
- xhr.send();
747
- })
748
- }
749
-
750
- } else {
751
- let div = document.createElement('div')
752
- div.innerText = '文件加载异常'
753
- this.contentView.appendChild(div)
754
- this.$refs.pdfView.appendChild(this.contentView)
755
- }
756
- })
757
- }
758
- },
759
- deep:true,
760
- immediate:true
761
- }
762
- },
763
- mounted () {
764
- }
765
- }
766
- </script>
767
-
768
- <style lang="less" scoped>
769
- .pdf_view {
770
- width: 100%;
771
- height: calc(100% - 51px);
772
- overflow: auto;
773
- background-color: #f5f7fb;
774
- padding-bottom: 60px;
775
- box-sizing: border-box;
776
- // position: relative;
777
- // > div {
778
- // width: 100%;
779
- // height: 100%;
780
- // overflow: hidden;
781
- // overflow-y: auto;
782
- // position: relative;
783
- // }
784
- > iframe {
785
- width: 100%;
786
- height: 100%;
787
- }
788
- a:link {
789
- color: none;
790
- }
791
- a:visited {
792
- color: none;
793
- }
794
- a:hover {
795
- color: none;
796
- }
797
- a:active {
798
- color: none;
799
- }
800
- .btn_footer {
801
- width: 100%;
802
- height: 60px;
803
- display: flex;
804
- align-items: center;
805
- justify-content: space-around;
806
- position: absolute;
807
- bottom: 0px;
808
- left: 0;
809
- z-index: 999;
810
- background: #ffffff;
811
- .prev, .next {
812
- width: 35%;
813
- height: 40px;
814
- display: flex;
815
- align-items: center;
816
- justify-content: center;
817
- border-radius: 50px;
818
- cursor: pointer;
819
- }
820
- .prev {
821
- background: #F2F5FA;
822
- color: #000;
823
- }
824
- .next {
825
- background: #366aff;
826
- color: #ffffff;
827
- }
828
- }
829
- }
1
+ <template>
2
+ <div class="pdf_view" ref="pdfView" @scroll="pdfScroll">
3
+ <div class="btn_footer" v-if="tagIds.length > 1">
4
+ <div class="prev" @click="prev">上一段</div>
5
+ <div class="next" @click="next">下一段</div>
6
+ </div>
7
+ </div>
8
+ </template>
9
+
10
+ <script>
11
+ import _ from 'lodash'
12
+ // import * as pdfjsLib from 'pdfjs-dist'
13
+ // pdfjsLib.GlobalWorkerOptions.workerSrc = 'pdfjs-dist/build/pdf.worker';
14
+ // import { TextLayerBuilder } from "pdfjs-dist/web/pdf_viewer";
15
+ // EventBus pdf_viewer 支持绑定自定义事件,一版不做
16
+ // import 'pdfjs-dist/web/pdf_viewer.css'
17
+ /* eslint-disable */
18
+ const pdfjsLib = window['pdfjsLib']
19
+ if(pdfjsLib) {
20
+ pdfjsLib.GlobalWorkerOptions.workerSrc = window['pdfjs-dist/build/pdf.worker']
21
+ // 'pdfjs-dist/build/pdf.worker';
22
+ }
23
+ const { TextLayerBuilder } = window['pdfjs-dist/web/pdf_viewer']
24
+ // import { zoomElement } from '../assets/js/hammer'
25
+ export default {
26
+ name: 'pdfView',
27
+ props:['tagIds','isMessageRecord'],
28
+ data() {
29
+ return {
30
+ url: '',
31
+ // pdfjsLib: window['pdfjs-dist/build/pdf'],
32
+ // pdfjsLib: pdfjsLib,
33
+ pages: [],
34
+ pageLoadStatus: {
35
+ WAIT: 0,
36
+ LOADED: 1,
37
+ },
38
+ scale: 1,
39
+ rotation: 0,
40
+ pageSize: {},
41
+ PAGE_INTVERVAL: 15,
42
+ SLICE_COUNT: 5,
43
+ contentView: null,
44
+ fisrtLoad: true,
45
+ TextLayerBuilder: null,
46
+ totalPageCount: 0,
47
+ identifyTextPostion: {
48
+ top: 0,
49
+ left: 0,
50
+ width: 100,
51
+ height: 0,
52
+ page: 1,
53
+ pageHeight: 0,
54
+ pageWidth: 0,
55
+ extractInfo: {},
56
+ currentPageAllLine: []
57
+ },
58
+ currentPageAllLine: [],
59
+ pdfUrl: '',
60
+ cachePdf: [],
61
+ newViewer: null,
62
+ currentPage: 0,
63
+ changetoolbar: false,
64
+ allTr:[],
65
+ preViewType: 'pdf',
66
+ displacement:{
67
+ pageX:0,
68
+ pageY:0,
69
+ moveable:false,
70
+ pageX2:0,
71
+ pageY2:0,
72
+ originScale:1,
73
+ },
74
+ isTouchMoved: false,
75
+ transformSalce: null,
76
+ }
77
+ },
78
+ methods: {
79
+ getpdfResloutePage (pdfResloute) {
80
+ // 根据当前页面宽度设置缩放比例
81
+ // this.scale = Math.round(this.$refs.pdfView.clientWidth / pdfResloute.pageWidth * 100) / 100
82
+ // console.log(this.scale,'this.scale');
83
+ if(this.isMessageRecord) {
84
+ this.scale = Math.round(this.$refs.pdfView.clientWidth / pdfResloute.pageWidth * 100) / 100
85
+ } else {
86
+ this.scale = 1
87
+ }
88
+ // 从后端获取到当前分片后所有的pdf页码,初始化数组,数组下{} 对应每页pdf文件
89
+ this.pdfUrl = pdfResloute.publicPageFileUrl.substring(0, pdfResloute.publicPageFileUrl.lastIndexOf('/') + 1)
90
+ this.initPages(pdfResloute.total)
91
+ // 定位功能,加载对应页码位置
92
+ this.loadPdfData(pdfResloute.page)
93
+ },
94
+ async loadPdfData (loadPage) {
95
+ if(this.pages[loadPage - 1] && this.pages[loadPage - 1].dom && this.pages[loadPage - 1].dom.children.length > 0) {
96
+ return
97
+ }
98
+ // pdfjsLib.GlobalWorkerOptions.workerSrc = require("pdfjs-dist/legacy/build/pdf.worker.entry.js");
99
+ // 拿到第一个分片
100
+ const { startPage, url } = await this.fetchPdfFragment(loadPage);
101
+ let loadingTask = pdfjsLib.getDocument(url)
102
+ loadingTask.promise.then((pdfDoc) => {
103
+ // 将已经下载的分片保存到 pages 数组中
104
+ for (let i = 0; i < pdfDoc.numPages; i += 1) {
105
+ const pageIndex = startPage + i;
106
+ const page = this.pages[pageIndex - 1];
107
+ // 不在缓存列表内,重新获取本页pdf
108
+ if (page.loadStatus !== this.pageLoadStatus.LOADED) {
109
+ pdfDoc.getPage(i + 1).then((pdfPage) => {
110
+ page.pdfPage = pdfPage;
111
+ page.loadStatus = this.pageLoadStatus.LOADED;
112
+ // 通知可以进行渲染了
113
+ this.startRenderPages(pdfPage, page, pageIndex)
114
+ });
115
+ } else {
116
+ if (this.changetoolbar) {
117
+ this.$nextTick(() => {
118
+ this.renderHighlights()
119
+ })
120
+ this.changetoolbar = false
121
+ }
122
+ }
123
+ }
124
+ });
125
+ },
126
+ initPages (totalPage) {
127
+ // const pages = [];
128
+ this.totalPageCount = totalPage
129
+ for (let i = 0; i < totalPage; i += 1) {
130
+ this.pages.push({
131
+ pageNo: i + 1,
132
+ loadStatus: this.pageLoadStatus.WAIT,
133
+ pdfPage: null,
134
+ dom: null
135
+ });
136
+ }
137
+ },
138
+ async fetchPdfFragment (pageIndex) {
139
+ // 置换加签后的文件地址。
140
+ let obj = {}
141
+ await this.$http.post(
142
+ '/knowledge-api/temporary-certificate/or-origin?expired=30',
143
+ this.pdfUrl + pageIndex + '.pdf',
144
+ {
145
+ headers: {
146
+ "Content-Type": "application/json",
147
+ },
148
+ }).then(async res => {
149
+ if(res.bodyText) {
150
+ // 最后返回一个 包含这4个参数的对象
151
+ obj = await {
152
+ "startPage": pageIndex, // 分片的开始页码
153
+ "endPage": pageIndex + 5, // 分片结束页码
154
+ "totalPage": this.totalPageCount, // pdf 总页数
155
+ "url": res.bodyText // 分片内容下载地址
156
+ }
157
+ }
158
+ if (res.data) {
159
+ // 最后返回一个 包含这4个参数的对象
160
+ obj = await {
161
+ "startPage": pageIndex, // 分片的开始页码
162
+ "endPage": pageIndex + 5, // 分片结束页码
163
+ "totalPage": this.totalPageCount, // pdf 总页数
164
+ "url": res.data // 分片内容下载地址
165
+ }
166
+ }
167
+ })
168
+ return obj
169
+ },
170
+ startRenderPages (pdfPage, page, pageIndex) {
171
+ const viewport = pdfPage.getViewport({
172
+ scale: this.scale, // 缩放的比例
173
+ rotation: this.rotation, // 旋转的角度
174
+ });
175
+ // 记录pdf页面高度
176
+ const pageSize = {
177
+ width: viewport.width,
178
+ height: viewport.height,
179
+ }
180
+ this.pageSize = pageSize
181
+ // 创建内容绘制区,并设置大小
182
+ if(this.$refs.pdfView.clientWidth / this.pageSize.width >= 1 || this.isMessageRecord) {
183
+ this.contentView.style.width = `${pageSize.width }px`;
184
+ this.contentView.style.height = `${(this.totalPageCount * (pageSize.height + this.PAGE_INTVERVAL)) + this.PAGE_INTVERVAL}px`;
185
+ } else {
186
+ this.transformSalce = this.$refs.pdfView.clientWidth / this.pageSize.width
187
+ this.contentView.style.width = `${pageSize.width * this.transformSalce}px`;
188
+ this.contentView.style.height = `${(this.totalPageCount * (pageSize.height * (this.transformSalce) + this.PAGE_INTVERVAL)) + this.PAGE_INTVERVAL}px`;
189
+ }
190
+ this.contentView.style.margin = '0 auto 0'
191
+ console.log(this.transformSalce);
192
+ this.contentView.style.position = 'relative'
193
+ this.contentView.style.paddingBottom = '60px'
194
+ // contentView.style.overflowY = 'auto'
195
+ this.$refs.pdfView.appendChild(this.contentView);
196
+ this.renderPages(pageIndex)
197
+ },
198
+ renderPageContent (page, pageIndex) {
199
+ const { pdfPage, pageNo, dom } = page;
200
+ // dom 元素已存在,无须重新渲染,直接返回
201
+ console.log(dom, 'dom');
202
+ if (dom && dom.children.length != 0) {
203
+ return;
204
+ }
205
+ const viewport = pdfPage.getViewport({
206
+ scale: this.scale,
207
+ rotation: this.rotation,
208
+ });
209
+ // 创建新的canvas
210
+ const canvas = document.createElement('canvas');
211
+ const context = canvas.getContext('2d');
212
+ // canvas.getContext('2d');
213
+ canvas.height = this.pageSize.height;
214
+ canvas.width = this.pageSize.width;
215
+ // 创建渲染的dom
216
+ const pageDom = document.createElement('div');
217
+ pageDom.style.position = 'absolute';
218
+ pageDom.style.top = `${((pageNo - 1) * (this.pageSize.height + this.PAGE_INTVERVAL)) + this.PAGE_INTVERVAL}px`;
219
+ pageDom.style.width = `${this.pageSize.width}px`;
220
+ pageDom.style.height = `${this.pageSize.height}px`;
221
+ pageDom.appendChild(canvas);
222
+ // 渲染内容
223
+ let renderContext = {
224
+ canvasContext: context,
225
+ viewport: viewport,
226
+ }
227
+ pdfPage.render(renderContext).promise.then(() => {
228
+ console.log(pdfPage.getTextContent(), 'getTextContent');
229
+ return pdfPage.getTextContent()
230
+ }).then((textContent) => {
231
+ const textLayerDiv = document.createElement('div');
232
+ textLayerDiv.setAttribute('class', 'textLayer');
233
+ // 将文本图层div添加至每页pdf的div中
234
+ // 创建新的TextLayerBuilder实例
235
+ let textLayer = new TextLayerBuilder({
236
+ textLayerDiv: textLayerDiv,
237
+ pageIndex: pdfPage._pageIndex,
238
+ viewport: viewport,
239
+ });
240
+ let findPage = this.currentPageAllLine.find(l => { return l.page == pageIndex })
241
+ if (findPage) {
242
+ let AllLines = findPage.allLines
243
+ // setTimeout(() => {
244
+ if (AllLines.length > 0) {
245
+ for (let j = 0; j < AllLines.length; j++) {
246
+ let lines = AllLines[j].lines
247
+ let rectdom = document.createElement('div')
248
+ rectdom.setAttribute('react-count', AllLines[j].pageCount);
249
+ rectdom.style.position = 'absolute';
250
+ rectdom.style.top = 0
251
+ rectdom.style.left = 0
252
+ rectdom.classList.add('rectdom')
253
+ for (let index = 0; index < lines.length; index++) {
254
+ if (!/^\s+$/g.test(lines[index].content)) {
255
+ let postionArr = lines[index].location
256
+ let div = document.createElement('div')
257
+ div.style.position = 'absolute';
258
+ div.style.left = postionArr[0] * this.scale + 'px',
259
+ // 后端返回的坐标有基线对齐的问题,top 值是后端算好(基线top - 文字高度),在此加上文字高度的 1/9 (大致比例)为实际展示出文字的top值
260
+ div.style.top = (postionArr[1] + postionArr[3] / 9) * this.scale + 'px'
261
+ div.style.height = postionArr[3] * this.scale + 'px';
262
+ div.style.width = postionArr[2] * this.scale + 'px'
263
+ div.style.backgroundColor = 'rgba(54, 106, 255, 0.3)'
264
+ div.classList.add('lineHeight')
265
+ rectdom.appendChild(div)
266
+ }
267
+ }
268
+ if (rectdom.children.length > 0) {
269
+ pageDom.appendChild(rectdom)
270
+ }
271
+ }
272
+ }
273
+ }
274
+ textLayer.setTextContent(textContent);
275
+ textLayer.render()
276
+ pageDom.appendChild(textLayer.textLayerDiv);
277
+ page.dom = pageDom;
278
+ this.contentView.appendChild(pageDom);
279
+ if(this.transformSalce !== null) {
280
+ this.contentView.style.transform = `scale(${this.transformSalce}, ${this.transformSalce})`
281
+ }
282
+ if (this.changetoolbar) {
283
+ setTimeout(() => {
284
+ this.renderHighlights()
285
+ this.changetoolbar = false
286
+ }, 100)
287
+ }
288
+ if (this.fisrtLoad) {
289
+ setTimeout(() => {
290
+ // (this.pageSize.height + this.PAGE_INTVERVAL)
291
+ if (this.$refs.pdfView.clientHeight - (this.pageSize.height + this.PAGE_INTVERVAL) > 0 ) {
292
+ let loadNum = Math.ceil(this.$refs.pdfView.clientHeight / (this.pageSize.height + this.PAGE_INTVERVAL))
293
+ for (let n = 0; n < loadNum; n++) {
294
+ this.loadPdfData(pageNo + n)
295
+ }
296
+ } else {
297
+ this.renderHighlights()
298
+ }
299
+ if(this.transformSalce !== null) {
300
+ if (this.$refs.pdfView.scrollTop == Math.floor((pageNo - 1) * (this.pageSize.height + this.PAGE_INTVERVAL)) * this.transformSalce ) {
301
+ this.fisrtLoad = false
302
+ } else {
303
+ this.$refs.pdfView.scrollTop = `${((pageNo - 1) * (this.pageSize.height + this.PAGE_INTVERVAL) * this.transformSalce)}`
304
+ this.renderHighlights()
305
+ }
306
+ } else {
307
+ if (this.$refs.pdfView.scrollTop == Math.floor((pageNo - 1) * (this.pageSize.height + this.PAGE_INTVERVAL))) {
308
+ this.fisrtLoad = false
309
+ } else {
310
+ this.$refs.pdfView.scrollTop = `${((pageNo - 1) * (this.pageSize.height + this.PAGE_INTVERVAL))}`
311
+ this.renderHighlights()
312
+
313
+ }
314
+ }
315
+ // zoomElement(this.contentView)
316
+ }, 100)
317
+ }
318
+ })
319
+ },
320
+ // 监听容器的滚动事件,触发 scrollPdf 方法
321
+ // 这里加了防抖保证不会一次产生过多请求
322
+ debounceScrollPdf: _.debounce(function (e, that) {
323
+ if (this.fisrtLoad) {
324
+ this.fisrtLoad = false
325
+ return
326
+ }
327
+ const scrollTop = e.target.scrollTop;
328
+ const height = e.target.clientHeight;
329
+ // 根据内容可视区域中心点计算页码, 没有滚动时,指向第一页
330
+ const pageIndex = scrollTop > 0 ?
331
+ Math.ceil((scrollTop + (height / 2)) / (that.pageSize.height + that.PAGE_INTVERVAL)) :
332
+ 1;
333
+
334
+ pageIndex - 1 != 0 && that.loadPdfData(pageIndex - 1)
335
+ that.loadPdfData(pageIndex)
336
+ pageIndex + 1 <= that.totalPageCount && that.loadPdfData(pageIndex + 1)
337
+ }, 200),
338
+ directScrolling (e, that) {
339
+ if (this.fisrtLoad) {
340
+ this.fisrtLoad = false
341
+ return
342
+ }
343
+ const scrollTop = e.target.scrollTop;
344
+ const height = e.target.clientHeight;
345
+ // 根据内容可视区域中心点计算页码, 没有滚动时,指向第一页
346
+ const pageIndex = scrollTop > 0 ?
347
+ Math.ceil((scrollTop + (height / 2)) / (that.pageSize.height + that.PAGE_INTVERVAL)) :
348
+ 1;
349
+ this.loadPdfData(pageIndex)
350
+ },
351
+ pdfScroll (e) {
352
+ if(this.preViewType !== 'pdf' || this.isTouchMoved) {
353
+ return
354
+ }
355
+ this.debounceScrollPdf(e, this)
356
+ },
357
+ // 分片每次只做一次处理,所以不考虑多片情况
358
+ loadBefore (pageIndex) {
359
+ this.loadPdfData(pageIndex)
360
+ // const start = (Math.floor(pageIndex / this.SLICE_COUNT) * this.SLICE_COUNT) - (this.SLICE_COUNT - 1);
361
+ // if (start > 0) {
362
+ // // const prevPage = this.pages[start - 1] || {};
363
+ // this.loadPdfData(start)
364
+ // // prevPage.loadStatus === this.pageLoadStatus.WAIT && this.loadPdfData(start);
365
+ // }
366
+ },
367
+ loadAfter (pageIndex) {
368
+ this.loadPdfData(pageIndex)
369
+ // const start = (Math.floor(pageIndex / this.SLICE_COUNT) * this.SLICE_COUNT) + 1;
370
+ // if (start <= this.pages.length) {
371
+ // // const nextPage = this.pages[start - 1] || {};
372
+ // this.loadPdfData(start)
373
+ // // nextPage.loadStatus === this.pageLoadStatus.WAIT && this.loadPdfData(start);
374
+ // }
375
+ },
376
+ // 首先我们获取到需要渲染的范围
377
+ // 根据当前的可视范围内的页码,我们前后只保留 8 页
378
+ getRenderScope (pageIndex) {
379
+ const pagesToRender = [];
380
+ let i = pageIndex - 1;
381
+ let j = pageIndex + 1;
382
+ // pageIndex - 1 表示当前页码数 对应的下标位置
383
+ pagesToRender.push(this.pages[pageIndex - 1]);
384
+ while (pagesToRender.length < 10 && pagesToRender.length < this.pages.length) {
385
+ if (i > 0) {
386
+ pagesToRender.push(this.pages[i - 1]);
387
+ i -= 1;
388
+ }
389
+ if (pagesToRender.length >= 10) {
390
+ break;
391
+ }
392
+ if (j <= this.pages.length) {
393
+ pagesToRender.push(this.pages[j - 1]);
394
+ j += 1;
395
+ }
396
+ }
397
+ return pagesToRender;
398
+ },
399
+ // 渲染需要展示的页面,不需展示的页码将其清除
400
+ renderPages (pageIndex) {
401
+ const pagesToRender = this.getRenderScope(pageIndex);
402
+ for (const i of this.pages) {
403
+ if (pagesToRender.includes(i)) {
404
+ i.loadStatus === this.pageLoadStatus.LOADED ?
405
+ this.renderPageContent(i, pageIndex) :
406
+ this.renderPageLoading(i);
407
+ } else {
408
+ this.clearPage(i);
409
+ }
410
+ }
411
+ },
412
+ // 清除页面 dom
413
+ clearPage (page) {
414
+ if (page.dom) {
415
+ this.contentView.removeChild(page.dom);
416
+ page.loadStatus = 0
417
+ page.dom = undefined;
418
+ }
419
+ },
420
+ // 页面正在下载时渲染loading视图
421
+ renderPageLoading (page) {
422
+ const { pageNo, dom } = page;
423
+ if (dom && dom.children.length != 0) {
424
+ return;
425
+ }
426
+ const pageDom = document.createElement('div');
427
+ pageDom.style.width = `${this.pageSize.width}px`;
428
+ pageDom.style.height = `${this.pageSize.height}px`;
429
+ pageDom.style.position = 'absolute';
430
+ pageDom.style.top = `${((pageNo - 1) * (this.pageSize.height + this.PAGE_INTVERVAL)) + this.PAGE_INTVERVAL
431
+ }px`;
432
+ pageDom.style.backgroundImage = `url('https://guoranopen-zjk.oss-cn-zhangjiakou.aliyuncs.com/cdn-common/images/loading.gif')`
433
+ pageDom.style.backgroundPosition = 'center'
434
+ pageDom.style.backgroundRepeat = 'no-repeat'
435
+ pageDom.style.backgroundColor = '#FFF'
436
+ page.dom = pageDom;
437
+ this.contentView.appendChild(pageDom);
438
+ },
439
+ prev () {
440
+ this.currentPage--
441
+ if (this.currentPage < 0) {
442
+ // this.currentPage = this.tagIds.length - 1
443
+ this.currentPage = 0
444
+ }
445
+ if(this.preViewType == 'pdf') {
446
+ this.scrollToUplaodePage(this.currentPage)
447
+ } else {
448
+ this.scrollToExcalTop(this.currentPage)
449
+ }
450
+ // this.getpdfResloutePage(this.cachePdf[this.currentPage - 1])
451
+ },
452
+ next () {
453
+ this.currentPage++
454
+ if (this.currentPage >= this.tagIds.length) {
455
+ this.currentPage = this.tagIds.length - 1
456
+ }
457
+ if(this.preViewType == 'pdf') {
458
+ this.scrollToUplaodePage(this.currentPage)
459
+ } else {
460
+ this.scrollToExcalTop(this.currentPage)
461
+ }
462
+ },
463
+ currentChange (value) {
464
+ this.currentPage = value - 1
465
+ if(this.preViewType == 'pdf') {
466
+ this.scrollToUplaodePage(this.currentPage)
467
+ } else {
468
+ this.scrollToExcalTop(this.currentPage)
469
+ }
470
+ },
471
+ scrollToUplaodePage (currentPage) {
472
+ this.changetoolbar = true
473
+ if(this.preViewType !== 'pdf') {
474
+ return
475
+ }
476
+ let pdfResloute = this.cachePdf[currentPage]
477
+ this.identifyTextPostion.extractInfo = pdfResloute.extractInfo
478
+ this.identifyTextPostion.left = pdfResloute.extractInfo.location[0]
479
+ this.identifyTextPostion.top = pdfResloute.extractInfo.location[1]
480
+ this.identifyTextPostion.width = pdfResloute.extractInfo.location[2]
481
+ this.identifyTextPostion.height = pdfResloute.extractInfo.location[3]
482
+ this.identifyTextPostion.page = pdfResloute.page
483
+ this.identifyTextPostion.pageHeight = pdfResloute.pageHeight
484
+ this.identifyTextPostion.pageWidth = pdfResloute.pageWidth
485
+ // 在当前段落在最后一页pdf时,根据计算的高度并不能触发滚动,在此执行重新渲染方法,非次情况会执行两次,待优化
486
+ this.$nextTick(() => {
487
+ this.renderHighlights()
488
+ })
489
+ if(this.transformSalce !== null) {
490
+ this.$refs.pdfView.scrollTop = `${((pdfResloute.page - 1) * (this.pageSize.height + this.PAGE_INTVERVAL) * this.transformSalce)}`
491
+ } else {
492
+ this.$refs.pdfView.scrollTop = `${((pdfResloute.page - 1) * (this.pageSize.height + this.PAGE_INTVERVAL))}`
493
+ }
494
+ },
495
+ scrollToExcalTop(currentPage) {
496
+ for (let index = 0; index < this.allTr.length; index++) {
497
+ if(index == currentPage) {
498
+ Array.from(this.allTr[index].children).forEach(item =>{
499
+ item.style.background = 'rgba(255, 136, 0, 0.6)'
500
+ })
501
+ // this.$refs.pdfView.scrollTop = this.allTr[index].offsetTop
502
+ this.$refs.pdfView.scrollTop = this.allTr[index].getBoundingClientRect().top
503
+
504
+ } else {
505
+ Array.from(this.allTr[index].children).forEach(item =>{
506
+ item.style.background = 'rgba(54, 106, 255, 0.6)'
507
+ })
508
+ }
509
+ }
510
+ },
511
+ // pdf是否需要重新渲染高亮位置
512
+ renderHighlights () {
513
+ let lineHeightDom = Array.from(document.getElementsByClassName('rectdom'))
514
+ console.log(lineHeightDom, this.currentPage, 'this.currentPage');
515
+ if (lineHeightDom) {
516
+ lineHeightDom.forEach((d) => {
517
+ for (let i = 0; i < d.children.length; i++) {
518
+ if (d.getAttribute('react-count') == this.currentPage) {
519
+ d.children[i].style.backgroundColor = 'rgba(255, 136, 0, 0.3)'
520
+ } else {
521
+ d.children[i].style.backgroundColor = 'rgba(54, 106, 255, 0.3)'
522
+ }
523
+ }
524
+ })
525
+ }
526
+ },
527
+ displayHiglight (pageIndex) {
528
+ let lineHeightDom = Array.from(document.getElementsByClassName('rectdom'))
529
+ if (lineHeightDom) {
530
+ lineHeightDom.forEach((d) => {
531
+ if (d.getAttribute('page-index') == pageIndex) {
532
+ d.style.display = 'none'
533
+ }
534
+ })
535
+ }
536
+ },
537
+ // 前端暂时缓存多页
538
+ autoLoadMore (pageIndex) {
539
+ let pdfResloute = this.cachePdf.find(cache => {
540
+ return cache.page == pageIndex
541
+ })
542
+ if (pdfResloute) {
543
+ this.getpdfResloutePage(pdfResloute)
544
+ } else {
545
+ this.loadPdfData(pageIndex)
546
+ }
547
+ },
548
+ setPageAllLine (arr) {
549
+ this.currentPageAllLine = []
550
+ arr.forEach((item, index) => {
551
+ let i = this.currentPageAllLine.findIndex(l => { return l.page && l.page == item.page })
552
+ if (i != -1) {
553
+ // this.currentPageAllLine[i].allLines.lines.push(item.extractInfo.lines)
554
+ this.currentPageAllLine[i].allLines.push({
555
+ pageCount: index,
556
+ lines: item.extractInfo.lines
557
+ })
558
+ } else {
559
+ this.currentPageAllLine.push({
560
+ page: item.page,
561
+ allLines: [{
562
+ pageCount: index,
563
+ lines: item.extractInfo.lines
564
+ }],
565
+ })
566
+ }
567
+ })
568
+ },
569
+ openTouch() {
570
+ // this.$nextTick()将回调延迟到下次 DOM 更新循环之后执行
571
+ let that = this;
572
+ this.$nextTick(() => {
573
+ // setInterval(() => {
574
+ // this.scale = this.scale + 0.1
575
+ // that.pages.forEach((item, index) =>{
576
+ // if(item.dom) {
577
+ // item.dom.children.forEach( childDom =>{
578
+ // if(childDom.getAttribute('react-count')) {
579
+ // childDom.style.transform = "scale(" + this.scale + ")";
580
+ // childDom.style.transformOrigin = "0px 0px 0px";
581
+ // } else {
582
+ // item.dom = null
583
+ // this.startRenderPages(item.pdfPage, null, index)
584
+ // }
585
+ // } )
586
+ // }
587
+ // })
588
+ // }, 100);
589
+ // 获取放大或缩小的区域DOM
590
+ let matrix_box = this.contentView
591
+ matrix_box.addEventListener("touchstart", function (event) {
592
+ this.isTouchMoved = true
593
+ let touches = event.touches;
594
+ let events = touches[0];
595
+ let events2 = touches[1];
596
+
597
+ // event.preventDefault();
598
+
599
+ // 第一个触摸点的坐标
600
+ that.displacement.pageX = events.pageX;
601
+ that.displacement.pageY = events.pageY;
602
+
603
+ that.displacement.moveable = true;
604
+
605
+ if (events2) {
606
+ that.displacement.pageX2 = events2.pageX;
607
+ that.displacement.pageY2 = events2.pageY;
608
+ }
609
+
610
+ that.displacement.originScale = this.scale || 1;
611
+ // console.log(that.displacement);
612
+ });
613
+ document.addEventListener("touchmove", function (event) {
614
+ if (!that.displacement.moveable) {
615
+ return;
616
+ }
617
+ // event.preventDefault();
618
+ let touches = event.touches;
619
+ let events = touches[0];
620
+ let events2 = touches[1];
621
+ // 双指移动
622
+ if (events2) {
623
+ // 第2个指头坐标在touchmove时候获取
624
+ if (!that.displacement.pageX2) {
625
+ that.displacement.pageX2 = events2.pageX;
626
+ }
627
+ if (!that.displacement.pageY2) {
628
+ that.displacement.pageY2 = events2.pageY;
629
+ }
630
+ // 双指缩放比例计算
631
+ let zoom = that.getDistance({
632
+ x: events.pageX,
633
+ y: events.pageY
634
+ },
635
+ {
636
+ x: events2.pageX,
637
+ y: events2.pageY
638
+ }
639
+ ) / that.getDistance(
640
+ {
641
+ x: that.displacement.pageX,
642
+ y: that.displacement.pageY
643
+ },
644
+ {
645
+ x: that.displacement.pageX2,
646
+ y: that.displacement.pageY2
647
+ }
648
+ );
649
+ // 应用在元素上的缩放比例
650
+ let newScale = that.displacement.originScale * zoom;
651
+ console.log(zoom, newScale , this.scale, 'newScale');
652
+ // 最大缩放比例限制
653
+ if (newScale > 2) {
654
+ newScale = 2;
655
+ }
656
+ // 最大缩放比例限制
657
+ if(newScale < 1) {
658
+ newScale = 1;
659
+ }
660
+ // 记住使用的缩放值
661
+ that.displacement.scale = newScale;
662
+ // console.log(newScale);
663
+ matrix_box.style.transform = "scale(" + newScale + ")";
664
+ // 设置旋转元素的基点位置
665
+ matrix_box.style.transformOrigin = "0px 0px 0px";
666
+ }
667
+ },{ passive: false });
668
+ document.addEventListener('touchend',function() {
669
+ that.isTouchMoved = false
670
+ },{ passive: false })
671
+ });
672
+ },
673
+ getDistance(start, stop) {
674
+ // Math.hypot()计算参数的平方根
675
+ return Math.hypot(stop.x - start.x, stop.y - start.y);
676
+ },
677
+ setupCanvas(canvas, width, height) {
678
+ const dpr = 1;
679
+ // const rect = canvas.getBoundingClientRect();
680
+ canvas.width = width
681
+ canvas.height = height
682
+ const ctx = canvas.getContext('2d');
683
+ console.log(canvas.width, canvas.height, dpr, this.scale);
684
+ ctx?.scale(dpr, dpr );
685
+ return ctx;
686
+ },
687
+ },
688
+ computed:{
689
+ perviewUrl() {
690
+ return '/web/viewer.html?file=' + '/pdflist/pdf4split-1.pdf'
691
+ }
692
+ },
693
+ watch:{
694
+ tagIds: {
695
+ handler(value) {
696
+ if(value && value.length) {
697
+ // 在 pdf_view 下创建 所有canvs的容器
698
+ this.contentView = document.createElement('div')
699
+ this.contentView.style.transformOrigin = '0px 0px 0px'
700
+ this.$http.get('/knowledge-api/knowledge/knowledge-part-location-info/list?ids=' + value.join(',')).then(res =>{
701
+ 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}
702
+ if (res.data.code == 0) {
703
+ // tagIds 会按照gpt识别的生成有序的数组,前端直接按照下标的顺序取就可以了
704
+ // 缓存拿到的所有数据
705
+ this.cachePdf = res.data.data
706
+ let publicPageFileUrl = res.data.data[0].publicPageFileUrl
707
+ this.currentPage = 0
708
+ // console.log(publicPageFileUrl.substring(publicPageFileUrl.lastIndexOf('.')));
709
+ if (publicPageFileUrl.substring(publicPageFileUrl.lastIndexOf('.')) === '.pdf') {
710
+ this.preViewType = 'pdf'
711
+ this.setPageAllLine(this.cachePdf)
712
+ this.getpdfResloutePage(res.data.data[0])
713
+ } else {
714
+ this.preViewType = 'excal'
715
+ this.$http.post(
716
+ '/knowledge-api/temporary-certificate/or-origin?expired=30',
717
+ publicPageFileUrl,
718
+ {
719
+ headers: {
720
+ "Content-Type": "application/json",
721
+ },
722
+ }).then(res => {
723
+ // 使用原声请求方式 axios会带有不需要的请求头
724
+ let xhr = new XMLHttpRequest();
725
+ xhr.open('GET', res.data || res.bodyText , true);
726
+ // 定义请求完成的处理函数,请求前也可以增加加载框/禁用下载按钮逻辑
727
+ xhr.onload = ({ currentTarget }) => {
728
+ // 请求完成
729
+ if (currentTarget.status === 200) { // 返回200
730
+ this.contentView.innerHTML = currentTarget.response
731
+ this.contentView.style.padding = '10px'
732
+ // this.contentView.style.position = 'relative'
733
+ this.$refs.pdfView.style.backgroundColor = '#FFFFFF'
734
+ this.$refs.pdfView.appendChild(this.contentView)
735
+ let allTr = Array.from(this.$refs.pdfView.getElementsByTagName('tr'))
736
+ this.allTr = []
737
+ for (let index = 0; index < allTr.length; index++) {
738
+ if(value.includes(allTr[index].getAttribute('tag-id'))) {
739
+ this.allTr.push(allTr[index])
740
+ }
741
+ }
742
+ this.currentChange(1)
743
+
744
+ }
745
+ }
746
+ xhr.send();
747
+ })
748
+ }
749
+
750
+ } else {
751
+ let div = document.createElement('div')
752
+ div.innerText = '文件加载异常'
753
+ this.contentView.appendChild(div)
754
+ this.$refs.pdfView.appendChild(this.contentView)
755
+ }
756
+ })
757
+ }
758
+ },
759
+ deep:true,
760
+ immediate:true
761
+ }
762
+ },
763
+ mounted () {
764
+ }
765
+ }
766
+ </script>
767
+
768
+ <style lang="less" scoped>
769
+ .pdf_view {
770
+ width: 100%;
771
+ height: calc(100% - 51px);
772
+ overflow: auto;
773
+ background-color: #f5f7fb;
774
+ padding-bottom: 60px;
775
+ box-sizing: border-box;
776
+ // position: relative;
777
+ // > div {
778
+ // width: 100%;
779
+ // height: 100%;
780
+ // overflow: hidden;
781
+ // overflow-y: auto;
782
+ // position: relative;
783
+ // }
784
+ > iframe {
785
+ width: 100%;
786
+ height: 100%;
787
+ }
788
+ a:link {
789
+ color: none;
790
+ }
791
+ a:visited {
792
+ color: none;
793
+ }
794
+ a:hover {
795
+ color: none;
796
+ }
797
+ a:active {
798
+ color: none;
799
+ }
800
+ .btn_footer {
801
+ width: 100%;
802
+ height: 60px;
803
+ display: flex;
804
+ align-items: center;
805
+ justify-content: space-around;
806
+ position: absolute;
807
+ bottom: 0px;
808
+ left: 0;
809
+ z-index: 999;
810
+ background: #ffffff;
811
+ .prev, .next {
812
+ width: 35%;
813
+ height: 40px;
814
+ display: flex;
815
+ align-items: center;
816
+ justify-content: center;
817
+ border-radius: 50px;
818
+ cursor: pointer;
819
+ }
820
+ .prev {
821
+ background: #F2F5FA;
822
+ color: #000;
823
+ }
824
+ .next {
825
+ background: #366aff;
826
+ color: #ffffff;
827
+ }
828
+ }
829
+ }
830
830
  </style>