zydx-plus 1.33.449 → 1.34.451

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zydx-plus",
3
- "version": "1.33.449",
3
+ "version": "1.34.451",
4
4
  "description": "Vue.js",
5
5
  "main": "src/index.js",
6
6
  "files": [
@@ -0,0 +1,6 @@
1
+ import main from './src/chat';
2
+
3
+ main.install = function(Vue) {
4
+ Vue.component(main.name, main);
5
+ };
6
+ export default main;
Binary file
@@ -0,0 +1,575 @@
1
+ <template>
2
+ <div class="chat-content"
3
+ :style="{
4
+ top: `${y !== '' ? `${y}px` : '50%'}`,
5
+ left: `${x !== '' ? `${x}px` : '50%'}`,
6
+ marginTop: `${y === ''? '-325px' : '0'}`,
7
+ marginLeft: `${x === ''? '-300px' : '0'}`,
8
+ }">
9
+ <div class="chat-header">
10
+ <span class="chat-header-title"
11
+ @mousedown.stop="chatMousedown"
12
+ @mouseup.stop="chatMouseup">
13
+ AI助手
14
+ </span>
15
+ <i class="iconfont zydx-guanbi" @click.stop="aiClose"></i>
16
+ </div>
17
+ <div class="chat-in" ref="content">
18
+ <div class="chat-in-cont" ref="contentLi">
19
+ <div class="chat-in-li" :class="{'left': item.role === 'assistant', 'right': item.role === 'user'}" v-for="(item,index) in messages">
20
+ <div class="ai-avatar" v-if="item.role === 'assistant'">
21
+ <img src="./ai.png" alt="" />
22
+ </div>
23
+ <div class="text-cont">{{ item.content }}</div>
24
+ </div>
25
+ </div>
26
+ </div>
27
+ <div class="chat-input">
28
+ <div class="chat-text">
29
+ <textarea :disabled="disabled" @keydown="handleKeydown" v-model="userText" placeholder="请输入问题..."></textarea>
30
+ </div>
31
+ <div class="chat-send">
32
+ <i @click="speak" :class="{'speak': microphone}" class="iconfont zydx-luyinhuatongmai"></i>
33
+ <button @click="send" :disabled="disabled" :class="{'disabled': disabled}">{{ disabled? '发送中...': '发送' }}</button>
34
+ </div>
35
+ </div>
36
+ <div class="microphone" v-if="microphone">
37
+ <div class="microphone-cont mic-anim">
38
+ <div class="microphone1">
39
+ <div class="microphone2">
40
+ <div class="microphone3" @click="stopRecording">
41
+ <div>
42
+ <svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 38 68" width="26" height="48">
43
+ <path id="并集_轮廓_" data-name="并集 (轮廓)" fill="#ccc"
44
+ d="M10,44a3,3,0,0,1-3-3V3a3,3,0,0,1,3-3H28a3,3,0,0,1,3,3V41a3,3,0,0,1-3,3Zm17-4V4H11V40ZM0,47V24a2,2,0,0,1,4,0V45a2,2,0,0,0,2,2H32a2,2,0,0,0,2-2V24a2,2,0,0,1,4,0V47a4,4,0,0,1-4,4H21v9c7.34.26,13,1.93,13,4,0,2.21-6.72,4-15,4S4,66.21,4,64c0-2,5.66-3.7,13-4V51H4A4,4,0,0,1,0,47ZM19,64h.79L19,64l-.79,0Z"/>
45
+ <rect fill="#fff" x="11" y="4" width="16" height="36"/>
46
+ <rect class="volume" :height="volume(vol)" width="12" :y="volume2(vol)" x="13" fill="#43cf7c"/>
47
+ </svg>
48
+ </div>
49
+ <p>{{ voiceLoading? '语音转换中...': `正在说话:${countdown}s` }}</p>
50
+ </div>
51
+ </div>
52
+ </div>
53
+ </div>
54
+ </div>
55
+ </div>
56
+ </template>
57
+
58
+ <script>
59
+ import Recorder from 'js-audio-recorder'
60
+ import axios from 'axios'
61
+ export default {
62
+ name: 'zydx-chat',
63
+ data() {
64
+ return {
65
+ token: '',
66
+ messages: [],
67
+ userText: '',
68
+ disabled: false,
69
+ x: '',
70
+ y: '',
71
+ left: 0,
72
+ top: 0,
73
+ isMove: false,
74
+ microphone: false,
75
+ recorder: null,
76
+ countdown: 59,
77
+ fileSize: 0,
78
+ vol: 0,
79
+ base64: '',
80
+ voiceLoading: false
81
+ }
82
+ },
83
+ beforeUnmount() {
84
+ this.recorder.destroy()
85
+ },
86
+ mounted() {
87
+ const _this = this
88
+ this.init()
89
+ this.recorder.onprogress = function (params) {
90
+ if(_this.countdown <= 0) {
91
+ _this.stopRecording()
92
+ }else {
93
+ _this.countdown = 59 - parseInt(params.duration)
94
+ _this.vol = params.vol
95
+ }
96
+ }
97
+ document.addEventListener('mousemove', (e) => {
98
+ if (!this.isMove) return
99
+ this.x = e.clientX - this.left;
100
+ this.y = e.clientY - this.top;
101
+ // 超出边界
102
+ const w = document.documentElement.clientWidth;
103
+ const h = document.documentElement.clientHeight;
104
+ if (this.x < 0) {
105
+ this.x = 0;
106
+ }
107
+ if (this.y < 0) {
108
+ this.y = 0;
109
+ }
110
+ if (this.x > (w - 600)) {
111
+ this.x = w - 600;
112
+ }
113
+ if (this.y > (h - 650)) {
114
+ this.y = h - 650;
115
+ }
116
+ this.$emit('move', {x: this.x, y: this.y})
117
+ })
118
+ document.addEventListener('mouseup', (event) => {
119
+ this.isMove = false
120
+ })
121
+ },
122
+ watch: {
123
+ messages: {
124
+ handler: function (e, oldVal) {
125
+ sessionStorage.setItem('messages', JSON.stringify(e)) // 保存聊天记录
126
+ },
127
+ deep: true
128
+ },
129
+ },
130
+ methods: {
131
+ speak() {
132
+ if(this.disabled) return
133
+ this.microphone = !this.microphone
134
+ if(this.microphone) {
135
+ this.recorder.start().then(() => { // 开始录音
136
+ this.countdown = 59
137
+ this.fileSize = 0
138
+ this.vol = 0
139
+ this.base64 = ''
140
+ }, (error) => {
141
+ this.microphone = false
142
+ this.$message({
143
+ type: 'text',
144
+ cancelShow: false,
145
+ promptContent: '录音失败,请检查麦克风是否可用'
146
+ })
147
+ });
148
+ }else {
149
+ this.microphone = true
150
+ this.stopRecording()
151
+ }
152
+ },
153
+ stopRecording() {
154
+ this.recorder.stop() // 停止录音
155
+ // 获取录音文件
156
+ const pcm = this.recorder.getPCMBlob()
157
+ const file = new File([pcm], 'audio.pcm', {type: 'audio/pcm'})
158
+ let reader = new FileReader();
159
+ reader.readAsDataURL(file)
160
+ reader.onload = async () => {
161
+ this.base64 = reader.result.split('base64,')[1]
162
+ await this.getSpeech()
163
+ }
164
+ },
165
+ async getSpeech() {
166
+ const _this = this
167
+ const token = await this.getAccessToken('voice')
168
+ const data = {
169
+ format: "pcm",
170
+ rate: 16000,
171
+ channel: 1,
172
+ cuid: "Ukvpuzv27RdJhltQBlpITVLNTcxs5ctM",
173
+ token: token.data.data,
174
+ speech: this.base64,
175
+ len: this.recorder.fileSize,
176
+ };
177
+ _this.voiceLoading = true
178
+ axios.post('/server_api', data)
179
+ .then(function(data){
180
+ _this.voiceLoading = false
181
+ _this.microphone = false
182
+ for(let i=0; i< data.data.result.length; i++) {
183
+ _this.userText += data.data.result[i]
184
+ }
185
+ _this.recorder.destroy()
186
+ })
187
+ .catch(function(err){
188
+ _this.recorder.destroy()
189
+ });
190
+ },
191
+ volume(v) {
192
+ if(v === 0) {
193
+ return 32
194
+ }else {
195
+ return v/3 > 32 ? 32 : v/5
196
+ }
197
+ },
198
+ volume2(v) {
199
+ if(v === 0) {
200
+ return 6
201
+ }else {
202
+ return 6 + 32 - this.volume(v)
203
+ }
204
+ },
205
+ chatMousedown(event) {
206
+ event.preventDefault()
207
+ //鼠标按下事件
208
+ this.left = event.offsetX;
209
+ this.top = event.offsetY;
210
+ this.isMove = true
211
+ },
212
+ chatMouseup() {
213
+ this.isMove = false
214
+ },
215
+ // 监听键盘事件
216
+ handleKeydown(e) {
217
+ if(e.keyCode === 32){
218
+ e.preventDefault();
219
+ return;
220
+ }
221
+ if(e.keyCode === 13){
222
+ e.preventDefault();
223
+ this.send()
224
+ }
225
+ },
226
+ // 滚动到底部
227
+ scrollToBottom() {
228
+ this.$nextTick(() => {
229
+ this.$refs.content.scrollTo(0,this.$refs.contentLi.scrollHeight)
230
+ })
231
+ },
232
+ // 发送消息
233
+ send() {
234
+ const _this = this
235
+ // 去掉换行和空格
236
+ let text = _this.userText.replace(/[\r\n]/g, '').replace(/\s*/g, '')
237
+ if(!text) return
238
+ _this.messages.push({
239
+ role: 'user',
240
+ content: text
241
+ })
242
+ _this.userText = ''
243
+ _this.disabled = true
244
+ _this.messages.push({
245
+ role: 'assistant',
246
+ content: '努力思考中...'
247
+ })
248
+ _this.scrollToBottom()
249
+ let mess = JSON.parse(JSON.stringify(_this.messages)) // 拷贝一份记录
250
+ mess.pop()
251
+ axios.post(`/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions?access_token=${_this.token}`,{
252
+ messages: mess
253
+ }).then(function(data){
254
+ _this.messages.pop()
255
+ if(data.data.error_code){
256
+ _this.messages.push({
257
+ role: 'assistant',
258
+ content: '这个问题太难了!'
259
+ })
260
+ _this.disabled = false
261
+ _this.scrollToBottom()
262
+ return
263
+ }
264
+ _this.messages.push({
265
+ role: 'assistant',
266
+ content: data.data.result
267
+ })
268
+ _this.scrollToBottom()
269
+ _this.disabled = false
270
+ }).catch(function(err){
271
+ _this.disabled = false
272
+ this.$message({promptContent: err, cancelShow: false})
273
+ });
274
+ },
275
+ // 初始化
276
+ async init() {
277
+ this.messages = JSON.parse(sessionStorage.getItem('messages')) || []
278
+ this.scrollToBottom()
279
+ // 初始化录音
280
+ this.recorder = new Recorder({
281
+ sampleBits: 16, // 采样位数,支持 8 或 16,默认是16
282
+ sampleRate: 16000, // 采样率,支持 11025、16000、22050、24000、44100、48000,根据浏览器默认值,我的chrome是48000
283
+ numChannels: 1, // 声道,支持 1 或 2, 默认是1
284
+ })
285
+ const token = await this.getAccessToken('ai')
286
+ this.token = token.data.data
287
+ },
288
+ async getAccessToken(v) {
289
+ return axios({
290
+ url: '/zydx/voice/getBaiduToken',
291
+ method: 'post',
292
+ headers: {
293
+ 'Authorization': localStorage.getItem('sessionId'),
294
+ 'Content-Type': 'application/x-www-form-urlencoded'
295
+ },
296
+ params: {
297
+ type: v,
298
+ }
299
+ }).then(function(data){
300
+ return data
301
+ })
302
+ .catch(function(err){
303
+ console.log(err)
304
+ });
305
+ // return await getBaiduToken({type: v})
306
+ },
307
+ // 关闭
308
+ aiClose() {
309
+ this.$emit('close')
310
+ }
311
+ }
312
+ }
313
+ </script>
314
+
315
+ <style scoped>
316
+ .disabled{
317
+ background: #ccc !important;
318
+ }
319
+ .chat-content {
320
+ width: 600px;
321
+ height: 650px;
322
+ background: #fff;
323
+ box-shadow: 0 0 10px rgba(0, 0, 0, .2);
324
+ position: fixed;
325
+ z-index: 10;
326
+ }
327
+
328
+ .chat-header {
329
+ height: 30px;
330
+ background: rgba(67, 207, 124, 1);
331
+ display: flex;
332
+ line-height: 30px;
333
+ padding: 0 10px;
334
+ box-sizing: border-box;
335
+ color: #fff;
336
+ font-size: 14px;
337
+ position: relative;
338
+ }
339
+ .chat-header-title{
340
+ cursor: move;
341
+ display: inline-block;
342
+ width: calc(100% - 30px);
343
+ margin-right: 30px;
344
+ }
345
+
346
+ .chat-header i {
347
+ cursor: pointer;
348
+ font-size: 18px;
349
+ position: absolute;
350
+ top: 0;
351
+ right: 10px;
352
+ z-index: 1;
353
+ }
354
+
355
+ .chat-in {
356
+ height: calc(100% - 112px);
357
+ overflow-y: auto;
358
+ transition: all 0.5s;
359
+ }
360
+
361
+ .chat-input {
362
+ height: 82px;
363
+ background: rgba(242, 242, 242, 1);
364
+ }
365
+
366
+ .chat-text {
367
+ width: 100%;
368
+ height: 55px;
369
+ padding: 5px;
370
+ box-sizing: border-box;
371
+ }
372
+
373
+ .chat-text textarea {
374
+ width: 100%;
375
+ height: 100%;
376
+ font-family: Helvetica, sans-serif;
377
+ border: none;
378
+ outline: none;
379
+ resize: none;
380
+ background: transparent;
381
+ font-size: 14px;
382
+ }
383
+
384
+ .chat-send {
385
+ padding: 0 5px 5px 5px;
386
+ height: 24px;
387
+ display: flex;
388
+ justify-content: space-between;
389
+ }
390
+
391
+ .chat-send i {
392
+ width: 24px;
393
+ display: inline-block;
394
+ height: 24px;
395
+ box-sizing: border-box;
396
+ border-radius: 50%;
397
+ border: 1px solid #ccc;
398
+ text-align: center;
399
+ line-height: 23px;
400
+ font-size: 14px;
401
+ background: #fff;
402
+ cursor: pointer;
403
+ }
404
+
405
+ .chat-send button {
406
+ background: rgba(67, 207, 124, 1);
407
+ border: none;
408
+ outline: none;
409
+ width: 70px;
410
+ height: 24px;
411
+ color: #fff;
412
+ font-size: 12px;
413
+ cursor: pointer;
414
+ border-radius: 3px;
415
+ text-align-last: justify;
416
+ word-break: break-all;
417
+ text-justify: distribute;
418
+ padding: 0 10px;
419
+ box-sizing: border-box;
420
+ }
421
+ .chat-in-cont{
422
+ padding: 5px 15px;
423
+ }
424
+ .chat-in-li{
425
+ padding: 10px 0;
426
+ }
427
+ .left{
428
+ position: relative;
429
+ min-height: 50px;
430
+ }
431
+ .left .text-cont{
432
+ box-shadow: 0 0 10px rgba(0,0,0,.2);
433
+ background: #fff;
434
+ margin-left: 60px;
435
+ }
436
+ .right{
437
+ text-align: right;
438
+ }
439
+ .right .text-cont{
440
+ background: #fff;
441
+ background: rgba(149, 236, 105, 1);
442
+ }
443
+ .text-cont{
444
+ padding: 10px;
445
+ border-radius: 5px;
446
+ display: inline-block;
447
+ text-align: justify !important;
448
+ max-width: 60%;
449
+ font-size: 14px;
450
+ line-height: 24px;
451
+ white-space: pre-line;
452
+ }
453
+ .ai-avatar{
454
+ position: absolute;
455
+ left: 0;
456
+ top: 10px;
457
+ width: 50px;
458
+ height: 50px;
459
+ border-radius: 50%;
460
+ overflow: hidden;
461
+ box-shadow: 0 0 10px rgba(0,0,0,.2);
462
+ background: #fff;
463
+ padding: 5px;
464
+ box-sizing: border-box;
465
+ }
466
+ .ai-avatar img{
467
+ width: 100%;
468
+ height: 100%;
469
+ }
470
+ .speak{
471
+ background: #43cf7c !important;
472
+ color: #fff !important;
473
+ border: 1px solid #43cf7c !important;
474
+ }
475
+ .microphone{
476
+ position: absolute;
477
+ left: 50%;
478
+ top: 50%;
479
+ z-index: 50;
480
+ width: 150px;
481
+ height: 150px;
482
+ transform: translate(-50%,-50%);
483
+ }
484
+ .microphone-cont{
485
+ width: 100%;
486
+ height: 100%;
487
+ border-radius: 50%;
488
+ position: relative;
489
+ }
490
+ .microphone1{
491
+ width: 100%;
492
+ height: 100%;
493
+ border-radius: 50%;
494
+ background: rgba(67, 207, 124, 0.3);
495
+ }
496
+ .microphone2{
497
+ width: calc(100% - 30px);
498
+ height: calc(100% - 30px);
499
+ border-radius: 50%;
500
+ background: rgba(67, 207, 124, 0.5);
501
+ position: absolute;
502
+ top: 50%;
503
+ left: 50%;
504
+ z-index: 1;
505
+ transform: translate(-50%,-50%);
506
+ }
507
+ .microphone3{
508
+ width: calc(100% - 30px);
509
+ height: calc(100% - 30px);
510
+ border-radius: 50%;
511
+ background: rgba(67, 207, 124, 0.8);
512
+ position: absolute;
513
+ top: 50%;
514
+ left: 50%;
515
+ z-index: 1;
516
+ transform: translate(-50%,-50%);
517
+ text-align: center;
518
+ padding-top: 10px;
519
+ box-sizing: border-box;
520
+ cursor: pointer;
521
+ }
522
+ .microphone3 p{
523
+ font-size: 12px;
524
+ color: #fff;
525
+ line-height: 18px;
526
+ }
527
+ .mic-anim .microphone1{
528
+ animation: mic-anim 1.5s infinite;
529
+ }
530
+ @keyframes mic-anim{
531
+ 0%{
532
+ background: rgba(67, 207, 124, 0.2);
533
+ }
534
+ 80%{
535
+ background: rgba(67, 207, 124, 0.4);
536
+ }
537
+ 100%{
538
+ background: rgba(67, 207, 124, 0.2);
539
+ }
540
+ }
541
+ .mic-anim .microphone2{
542
+ animation: mic-anim2 1.5s infinite;
543
+ }
544
+ @keyframes mic-anim2{
545
+ 0%{
546
+ background: rgba(67, 207, 124, 0.4);
547
+ }
548
+ 40%{
549
+ background: rgba(67, 207, 124, 0.6);
550
+ }
551
+ 80%{
552
+ background: rgba(67, 207, 124, 0.4);
553
+ }
554
+ 100%{
555
+ background: rgba(67, 207, 124, 0.4);
556
+ }
557
+ }
558
+ .mic-anim .microphone3{
559
+ animation: mic-anim3 1.5s infinite;
560
+ }
561
+ @keyframes mic-anim3{
562
+ 0%{
563
+ background: rgba(67, 207, 124, 0.8);
564
+ }
565
+ 20%{
566
+ background: rgba(67, 207, 124, 1);
567
+ }
568
+ 40%{
569
+ background: rgba(67, 207, 124, 0.8);
570
+ }
571
+ 100%{
572
+ background: rgba(67, 207, 124, 0.8);
573
+ }
574
+ }
575
+ </style>
@@ -58,6 +58,11 @@
58
58
  <span :class="{'but-name-color':voiceOpen}" v-html="voiceOpen?'关闭语音':'语音输入'"></span>
59
59
  </div>
60
60
  </div>
61
+ <div v-if='isShowAiTool' class="editor-but">
62
+ <div class="editor-but-name" @click="showAi">
63
+ <span>AI助手</span>
64
+ </div>
65
+ </div>
61
66
  <!-- <div class="editor-but">
62
67
  <div class="editor-but-name">
63
68
  <label>
@@ -67,6 +72,7 @@
67
72
  </div>
68
73
  </div>-->
69
74
  </div>
75
+ <zydx-chat v-if="isShowAi" @close='isShowAi = false'></zydx-chat>
70
76
  <div :class="{'editor-content-show': !editableShow}" class="editor-content">
71
77
  <div class="editing">
72
78
  <div v-if="signMenuShow" class="editing-header">
@@ -615,6 +621,7 @@ import MarginStandard from "../src/margin-standard.vue";
615
621
  import MarginWide from "../src/margin-wide.vue";
616
622
  import isSelect from "../src/isSelect.vue";
617
623
  import Paint from '../../paint/src/paint'
624
+ import zydxChat from '../../chat/src/chat.vue'
618
625
 
619
626
  const img = require('./image/annotation.png')
620
627
  export default {
@@ -632,6 +639,7 @@ export default {
632
639
  zydxColoring,
633
640
  zydxDragPopup,
634
641
  zydxSelect,
642
+ zydxChat,
635
643
  delSvg, editSvg, viewSvg,Paint
636
644
  },
637
645
  beforeUnmount() {
@@ -794,6 +802,7 @@ export default {
794
802
  timeOut: null,
795
803
  isShowPageMargin: false,
796
804
  isShowHorizontalLine: false,
805
+ isShowAi: false,
797
806
  isShowSwitchingFormat: false,
798
807
  templateType: 'freeTypesetting',
799
808
  switchingFormat: [
@@ -870,6 +879,10 @@ export default {
870
879
  }
871
880
  },
872
881
  props: {
882
+ isShowAiTool: {
883
+ type: Boolean,
884
+ default: true
885
+ },
873
886
  html: {
874
887
  type: Array,
875
888
  default: () => []
@@ -1346,6 +1359,9 @@ export default {
1346
1359
  },
1347
1360
  emits: ['confirm', 'enclosure', 'enlDownload', 'enlSee'],
1348
1361
  methods: {
1362
+ showAi() {
1363
+ this.isShowAi = !this.isShowAi
1364
+ },
1349
1365
  // 插入白板数据
1350
1366
  exportImg(e) {
1351
1367
  this.uploadFile(e, this.uploadImage).then(r => {
@@ -3723,8 +3739,8 @@ export default {
3723
3739
  },
3724
3740
 
3725
3741
  close() {
3726
- if (this.ws === null) return
3727
3742
  this.voiceOpen = false
3743
+ if (this.ws === null) return
3728
3744
  this.ws?.send(JSON.stringify({"type": "CANCEL"}))
3729
3745
  this.ws?.close()
3730
3746
  this.ws = null
@@ -19,8 +19,10 @@
19
19
  <button v-if="voiceShow" class="buts" @mousedown.stop="speechDown" @click="voice()"
20
20
  :style="{color: (voiceStatus)? '#4B0C77' :'#000'}">{{ voiceStatus ? '关闭语音' : '语音输入' }}
21
21
  </button>
22
+ <button v-if='isShowAiTool' class="buts" @click="showAi">AI助手</button>
22
23
  </div>
23
24
  </div>
25
+ <zydx-chat v-if="isShowAi" @close='isShowAi = false'></zydx-chat>
24
26
  <div class="ed-cont" :style="heightStyleCont">
25
27
  <div :style="{'border': (borderShow)? '1px solid #ccc': '0'}" v-if="editorShow">
26
28
  <editor-content @paste.native.capture.prevent="preventPaste" ref="editorRef" class="editor" :editor="editor"
@@ -162,13 +164,16 @@ import alignmentModeCenter from './img/center.png'
162
164
  import alignmentModeLeft from './img/left.png'
163
165
  import alignmentModeRight from './img/right.png'
164
166
 
167
+ import zydxChat from '../../chat/src/chat.vue'
168
+
165
169
  export default {
166
170
  name: 'zydx-xiao-editor',
167
171
  components: {
168
172
  EditorContent,
169
173
  BubbleMenu,
170
174
  svgs,
171
- Paint
175
+ Paint,
176
+ zydxChat
172
177
  },
173
178
  data() {
174
179
  return {
@@ -202,7 +207,8 @@ export default {
202
207
  editorRef: null,
203
208
  imgSizeVal: '',
204
209
  currentImgDom: {},
205
- paintShow: false
210
+ paintShow: false,
211
+ isShowAi: false,
206
212
  }
207
213
  },
208
214
  beforeUnmount() {
@@ -213,6 +219,10 @@ export default {
213
219
  this.ws = null
214
220
  },
215
221
  props: {
222
+ isShowAiTool: {
223
+ type: Boolean,
224
+ default: true
225
+ },
216
226
  titleVertical: {
217
227
  type: Boolean,
218
228
  default: false
@@ -419,6 +429,9 @@ export default {
419
429
  })
420
430
  },
421
431
  methods: {
432
+ showAi() {
433
+ this.isShowAi = !this.isShowAi
434
+ },
422
435
  exportImg(e) {
423
436
  this.uploadFile(e, this.uploadImage).then(r => {
424
437
  this.paintShow = false
@@ -236,6 +236,7 @@ export default {
236
236
  },
237
237
  emits: ['cancel','exportImg'],
238
238
  created() {
239
+ stayTime = 0
239
240
  this.ids = this.randomId()
240
241
  },
241
242
  mounted() {
@@ -551,8 +552,11 @@ export default {
551
552
  this.top = e.clientY - this.topOffset;
552
553
  },
553
554
  mouseup(e) {
554
- console.log(stayTime)
555
555
  clearInterval(timer)
556
+ if (!this.pressDown) {
557
+ stayTime = 0
558
+ return
559
+ }
556
560
  if (stayTime <= 100 && this.pressDown) { // 如果小于100就是点击事件
557
561
  if (!this.toolArr[this.toolIndex]) {
558
562
  stayTime = 0
@@ -583,6 +587,7 @@ export default {
583
587
  return id.replace(/[0-9]/g, '')
584
588
  },
585
589
  cancel() {
590
+ stayTime = 0
586
591
  document.body.style.overflow = 'visible'
587
592
  this.$emit('cancel')
588
593
  }
@@ -2,7 +2,7 @@
2
2
  <div class="read">
3
3
  <vue-office-docx v-if="fileType === 'docx'" :src="url" style="height: 100%;" @rendered="renderedHandler" @error="errorHandler" />
4
4
  <vue-office-excel v-if="fileType === 'xlsx' && xlsx" :src="url" style="height: 100%;" @rendered="renderedHandler" @error="errorHandler" />
5
- <div class="view-pdf" v-if="fileType === 'pdf'">
5
+ <div class="view-pdf" @scroll="scroll" v-if="fileType === 'pdf'">
6
6
  <div class="pageContainer" v-for="(item,index) in idArr">
7
7
  <canvas :id="item"></canvas>
8
8
  <div class="pdfPage">{{ index + 1 }}/{{ pdfPages }}</div>
@@ -35,7 +35,7 @@ import '@vue-office/docx/lib/index.css'
35
35
  import '@vue-office/excel/lib/index.css'
36
36
 
37
37
  import Mess from '../../tipBox/index'
38
-
38
+ let pdfs = null
39
39
  export default {
40
40
  name: "zydx-read",
41
41
  components: {VueOfficeDocx,VueOfficeExcel},
@@ -54,7 +54,8 @@ export default {
54
54
  pdf: null,
55
55
  page: 0,
56
56
  xlsx: true,
57
- canvasArr: []
57
+ canvasArr: [],
58
+ pageIndex: 0
58
59
  }
59
60
  },
60
61
  props: {
@@ -148,10 +149,11 @@ export default {
148
149
  cMapPacked: true
149
150
  })
150
151
  loadingTask.promise.then((pdf) => {
151
- that.pdf = pdf
152
+ pdfs = pdf
152
153
  that.pdfPages = pdf.numPages // 获取pdf文件的总页数
153
154
  that.page = pdf.numPages
154
- that.getPDF(pdf,that.page)
155
+ that.pageIndex = that.page > 1? 2:1
156
+ that.getPDF(pdf,that.pageIndex)
155
157
  }).catch(() => {
156
158
  that.loading = false
157
159
  Mess({
@@ -160,12 +162,29 @@ export default {
160
162
  })
161
163
  })
162
164
  },
165
+ scroll(e) {
166
+ const dom = e.target
167
+ var scrollTop = dom.scrollTop; //滑入屏幕上方的高度
168
+ var windowHeitht = dom.clientHeight; //能看到的页面的高度
169
+ var scrollHeight = dom.scrollHeight; //监控的整个div的高度(包括现在看到的和上下隐藏起来看不到的)
170
+ let total = scrollTop + windowHeitht
171
+ if(total === scrollHeight){
172
+ if(this.pageIndex >= this.page) return
173
+ if((this.page - this.pageIndex) > 2) {
174
+ this.pageIndex += 2
175
+ this.getPDF(pdfs,2)
176
+ }else {
177
+ this.pageIndex += 1
178
+ this.getPDF(pdfs,1)
179
+ }
180
+ }
181
+ },
163
182
  getPDF(pdf,page) {
164
183
  let that = this
165
184
  for (let i = 0; i < page; i++) {
166
185
  const id = 'canvas' + Math.random().toString(36).substr(2)
167
186
  that.idArr.push(id)
168
- pdf.getPage(that.idArr.length).then(function (page) {
187
+ pdf.getPage(this.pageIndex === 1? 1:this.pageIndex + i - 1).then(function (page) {
169
188
  let canvas = document.getElementById(id)
170
189
  that.canvasArr.push(canvas)
171
190
  let ctx = canvas.getContext('2d');
package/src/index.js CHANGED
@@ -35,6 +35,7 @@ import question from './components/question/index';
35
35
  import tagging from './components/tagging/index';
36
36
  import seek from './components/seek/index';
37
37
  import sketchpad from './components/sketchpad/index';
38
+ import chat from './components/chat/index';
38
39
 
39
40
  const components = [
40
41
  Calendar,
@@ -70,7 +71,8 @@ const components = [
70
71
  question,
71
72
  tagging,
72
73
  seek,
73
- sketchpad
74
+ sketchpad,
75
+ chat
74
76
  ];
75
77
 
76
78
  function install(app) {
@@ -83,7 +85,7 @@ function install(app) {
83
85
  }
84
86
 
85
87
  export default {
86
- version: '1.33.449',
88
+ version: '1.34.451',
87
89
  install,
88
90
  Calendar,
89
91
  Message,
@@ -121,6 +123,7 @@ export default {
121
123
  question,
122
124
  tagging,
123
125
  seek,
124
- sketchpad
126
+ sketchpad,
127
+ chat
125
128
  };
126
129