zydx-plus 1.32.257 → 1.32.258
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 +1 -1
- package/src/components/editor/src/butJson.js +7 -7
- package/src/components/editor/src/editor.vue +19 -56
- package/src/components/editor2/src/editor.vue +181 -269
- package/src/components/editor2/src/level.vue +64 -0
- package/src/components/flip/src/flip.vue +1 -1
- package/src/components/read/src/read.vue +1 -1
- package/src/index.js +1 -1
- package/src/components/editor2/src/microphone.vue +0 -47
package/package.json
CHANGED
|
@@ -46,13 +46,13 @@ export function butJson (editor,data) {
|
|
|
46
46
|
name: '添加作者',
|
|
47
47
|
key: 'authorMenu',
|
|
48
48
|
menuKeys: [],
|
|
49
|
-
html: `<p class="author" data-signId="author" style="text-align: center;"><span style="color: rgb(0, 0, 0);font-size:
|
|
49
|
+
html: `<p class="author" data-signId="author" style="text-align: center;"><span style="color: rgb(0, 0, 0);font-size: 16px;font-family: KaiT;">${menusData(data,'authorMenu').text}</span></p>`
|
|
50
50
|
},
|
|
51
51
|
subjectMenu: {
|
|
52
52
|
name: '添加题目',
|
|
53
53
|
key: 'subjectMenu',
|
|
54
54
|
menuKeys: [],
|
|
55
|
-
html: `<p data-signId="subject" style="text-align: center;"><span style="color: rgb(0, 0, 0);font-size: 24px;">${menusData(data,'subjectMenu').text}</span></p>`
|
|
55
|
+
html: `<p data-signId="subject" style="text-align: center;padding-bottom: 30px;"><span style="color: rgb(0, 0, 0);font-size: 24px;font-family: SimHei;font-weight: 700;">${menusData(data,'subjectMenu').text}</span></p>`
|
|
56
56
|
},
|
|
57
57
|
paragraphMenu: {
|
|
58
58
|
name: '添加落款',
|
|
@@ -73,19 +73,19 @@ export function butJson (editor,data) {
|
|
|
73
73
|
name: '关键词',
|
|
74
74
|
key: 'keywordMenu',
|
|
75
75
|
menuKeys: [],
|
|
76
|
-
html: `<p class="keyword"><span style="color: rgb(0, 0, 0);font-size:
|
|
76
|
+
html: `<p class="keyword" data-signId="keyword"><span style="color: rgb(0, 0, 0);font-size: 12px;font-weight: 700;font-family: SimSun;">关键词:</span><span style="color: rgb(0, 0, 0);font-size: 12px;font-family: KaiTi">关键词内容...</span></p>`
|
|
77
77
|
},
|
|
78
78
|
abstractMenu: {
|
|
79
79
|
name: '添加摘要',
|
|
80
80
|
key: 'abstractMenu',
|
|
81
81
|
menuKeys: [],
|
|
82
|
-
html: `<p class="abstract"><span style="color: rgb(0, 0, 0);font-size:
|
|
82
|
+
html: `<p class="abstract" data-signId="abstract"><span style="color: rgb(0, 0, 0);font-size: 12px;font-weight: 700;font-family: SimSun;">摘要:</span><span style="color: rgb(0, 0, 0);font-size: 12px;font-family: KaiTi">摘要内容...</span></p>`
|
|
83
83
|
},
|
|
84
84
|
literatureMenu: {
|
|
85
85
|
name: '添加文献',
|
|
86
86
|
key: 'literatureMenu',
|
|
87
87
|
menuKeys: [],
|
|
88
|
-
html: `<p><span style="color: rgb(0, 0, 0);font-size:
|
|
88
|
+
html: `<p><span style="color: rgb(0, 0, 0);font-size: 12px;font-family: SimSun">[1]作者.期刊论文名称IJ1.期刊名称,发表年份(第几期):页码</span></p><p><span style="color: rgb(0, 0, 0);font-size: 14px;font-family: SimSun">[2]作者.学位论文名称[D1.毕业院校所在城市:毕业院校,论文提交年份:页码</span></p><p><span style="color: rgb(0, 0, 0);font-size: 14px;font-family: SimSun">[3]作者.著作名称[M.出版社所在城市:出版社名称,出版年份:页码.</span></p><p data-signId="literature"><span style="color: rgb(0, 0, 0);font-size: 14px;font-family: SimSun">[4]作者.文章名称[N].报纸名称,发行日期(版面)</span></p>`
|
|
89
89
|
},
|
|
90
90
|
taggingMenu: {
|
|
91
91
|
name: '添加标注',
|
|
@@ -104,8 +104,8 @@ export function butJson (editor,data) {
|
|
|
104
104
|
key: 'ackMenu',
|
|
105
105
|
menuKeys: [],
|
|
106
106
|
html: [
|
|
107
|
-
`<p data-signId="ack" contenteditable="false" style="text-align: center;"><span style="color: rgb(0, 0, 0);font-size:
|
|
108
|
-
`<p><span style="color: rgb(0, 0, 0);font-size: 14px;">致谢内容...</span></p>`
|
|
107
|
+
`<p data-signId="ack" contenteditable="false" style="text-align: center;"><span style="color: rgb(0, 0, 0);font-size: 16px;font-weight: bold;">致谢</span></p>`,
|
|
108
|
+
`<p><span style="color: rgb(0, 0, 0);font-size: 14px;font-family: KaiTi;">致谢内容...</span></p>`
|
|
109
109
|
]
|
|
110
110
|
},
|
|
111
111
|
'group-image': {
|
|
@@ -69,11 +69,6 @@
|
|
|
69
69
|
<button class="but" @click="imgCancel">取消</button>
|
|
70
70
|
</div>
|
|
71
71
|
</div>
|
|
72
|
-
<!-- <div v-if="loading" class="loading-back">-->
|
|
73
|
-
<!-- <div class="loading-cont">-->
|
|
74
|
-
<!-- <div class="loadings">Loading</div>-->
|
|
75
|
-
<!-- </div>-->
|
|
76
|
-
<!-- </div>-->
|
|
77
72
|
<div class="down-html" id="test" v-html="htmlArr2"></div>
|
|
78
73
|
</div>
|
|
79
74
|
</template>
|
|
@@ -796,12 +791,14 @@ export default {
|
|
|
796
791
|
// 关键词
|
|
797
792
|
if (data.key === 'keywordMenu') {
|
|
798
793
|
const html = butJson(this.editor, this.menusText)[data.key].html
|
|
799
|
-
this.
|
|
794
|
+
const r = await this.signIdData('keyword')
|
|
795
|
+
if (r === -1) this.editor.chain().focus().insertContentAt(this.selection(), html).run()
|
|
800
796
|
}
|
|
801
797
|
// 摘要
|
|
802
798
|
if (data.key === 'abstractMenu') {
|
|
803
799
|
const html = butJson(this.editor, this.menusText)[data.key].html
|
|
804
|
-
this.
|
|
800
|
+
const r = await this.signIdData('abstract')
|
|
801
|
+
if (r === -1) this.editor.chain().focus().insertContentAt(this.selection(), html).run()
|
|
805
802
|
}
|
|
806
803
|
// 致谢
|
|
807
804
|
if (data.key === 'ackMenu') {
|
|
@@ -918,6 +915,12 @@ export default {
|
|
|
918
915
|
.down-html :deep(img){
|
|
919
916
|
padding: 5px 0;
|
|
920
917
|
}
|
|
918
|
+
:deep(.keyword) {
|
|
919
|
+
text-indent: 2em;
|
|
920
|
+
}
|
|
921
|
+
:deep(.abstract) {
|
|
922
|
+
text-indent: 2em;
|
|
923
|
+
}
|
|
921
924
|
.read-only {
|
|
922
925
|
position: relative;
|
|
923
926
|
margin: 0 auto;
|
|
@@ -925,7 +928,7 @@ export default {
|
|
|
925
928
|
|
|
926
929
|
.read-only-page {
|
|
927
930
|
width: 100%;
|
|
928
|
-
padding: 100px;
|
|
931
|
+
padding: 120px 100px 66px 100px;
|
|
929
932
|
background-color: #fff;
|
|
930
933
|
box-sizing: border-box;
|
|
931
934
|
position: relative;
|
|
@@ -944,13 +947,19 @@ export default {
|
|
|
944
947
|
line-height: 24px;
|
|
945
948
|
text-align: justify;
|
|
946
949
|
}
|
|
950
|
+
:deep(p[data-signid="subject"]) {
|
|
951
|
+
padding-bottom: 30px;
|
|
952
|
+
}
|
|
953
|
+
:deep(.author){
|
|
954
|
+
padding-bottom: 40px;
|
|
955
|
+
}
|
|
947
956
|
:deep(.text){
|
|
948
957
|
text-indent: 2em;
|
|
949
958
|
}
|
|
950
959
|
|
|
951
960
|
.read-only-a {
|
|
952
961
|
position: absolute;
|
|
953
|
-
bottom:
|
|
962
|
+
bottom: 36px;
|
|
954
963
|
left: 50%;
|
|
955
964
|
z-index: 1;
|
|
956
965
|
font-size: 14px;
|
|
@@ -1169,57 +1178,11 @@ li {
|
|
|
1169
1178
|
}
|
|
1170
1179
|
|
|
1171
1180
|
.editing-cont {
|
|
1172
|
-
padding: 100px;
|
|
1181
|
+
padding: 120px 100px 66px 100px;
|
|
1173
1182
|
box-sizing: border-box;
|
|
1174
1183
|
width: 794px;
|
|
1175
1184
|
min-height: 700px;
|
|
1176
1185
|
}
|
|
1177
|
-
.loading-back{
|
|
1178
|
-
position: absolute;
|
|
1179
|
-
top: 0;
|
|
1180
|
-
left: 0;
|
|
1181
|
-
right: 0;
|
|
1182
|
-
bottom: 0;
|
|
1183
|
-
z-index: 100;
|
|
1184
|
-
display: flex;
|
|
1185
|
-
align-items: center;
|
|
1186
|
-
}
|
|
1187
|
-
.loading-cont{
|
|
1188
|
-
display: inline-block;
|
|
1189
|
-
margin: 0 auto;
|
|
1190
|
-
}
|
|
1191
|
-
.loadings {
|
|
1192
|
-
display: inline-block;
|
|
1193
|
-
font-size: 28px;
|
|
1194
|
-
font-family: Arial, Helvetica, sans-serif;
|
|
1195
|
-
font-weight: bold;
|
|
1196
|
-
color: #fff;
|
|
1197
|
-
text-shadow: 0 0 2px #ff3d00, 0 0 1px #ff3d00, 0 0 1px #ff3d00;
|
|
1198
|
-
letter-spacing: 2px;
|
|
1199
|
-
position: relative;
|
|
1200
|
-
}
|
|
1201
|
-
|
|
1202
|
-
.loadings::after {
|
|
1203
|
-
content: "Loading";
|
|
1204
|
-
position: absolute;
|
|
1205
|
-
left: 0;
|
|
1206
|
-
top: 0;
|
|
1207
|
-
color: #ff3d00;
|
|
1208
|
-
width: 0%;
|
|
1209
|
-
height: 100%;
|
|
1210
|
-
overflow: hidden;
|
|
1211
|
-
animation: loading-animation 6s linear infinite;
|
|
1212
|
-
}
|
|
1213
|
-
|
|
1214
|
-
@keyframes loading-animation {
|
|
1215
|
-
0% {
|
|
1216
|
-
width: 0;
|
|
1217
|
-
}
|
|
1218
|
-
|
|
1219
|
-
100% {
|
|
1220
|
-
width: 100%;
|
|
1221
|
-
}
|
|
1222
|
-
}
|
|
1223
1186
|
.menu{
|
|
1224
1187
|
background-color: #fff;
|
|
1225
1188
|
padding: 5px;
|
|
@@ -23,7 +23,16 @@
|
|
|
23
23
|
</div>
|
|
24
24
|
<div class="ed-cont" :style="heightStyleCont">
|
|
25
25
|
<div :style="{'border': (borderShow)? '1px solid #ccc': '0'}" v-if="editorShow">
|
|
26
|
-
<editor-content ref="editorRef" class="editor" :editor="editor"
|
|
26
|
+
<editor-content @paste.native.capture.prevent="preventPaste" ref="editorRef" class="editor" :editor="editor"
|
|
27
|
+
:style="heightStyleCont"/>
|
|
28
|
+
</div>
|
|
29
|
+
<div v-if="voiceStatus" class="speak">
|
|
30
|
+
<div class="speak-cont">
|
|
31
|
+
<svg t="1698630789078" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4553" width="15" height="15"><path d="M533.84533333 930.88426667c-13.65333333 0-24.576-10.92266667-24.576-24.576v-122.33386667c0-13.65333333 10.92266667-24.576 24.576-24.576s24.576 10.92266667 24.576 24.576v122.33386667c-0.54613333 13.65333333-11.4688 24.576-24.576 24.576zM533.84533333 686.21653333c-101.03466667 0-183.5008-82.46613333-183.5008-183.5008V258.048c0-101.03466667 82.46613333-183.5008 183.5008-183.5008s183.5008 82.46613333 183.5008 183.5008v244.66773333c0 101.03466667-82.46613333 183.5008-183.5008 183.5008z m0-563.06346666c-74.27413333 0-134.89493333 60.6208-134.89493333 134.89493333v244.66773333c0 74.27413333 60.6208 134.89493333 134.89493333 134.89493334s134.89493333-60.6208 134.89493334-134.89493334V258.048c-0.54613333-74.27413333-60.6208-134.89493333-134.89493334-134.89493333z" fill="#fff" p-id="4554"></path><path d="M533.84533333 808.5504c-168.7552 0-305.83466667-137.07946667-305.83466666-305.83466667 0-13.65333333 10.92266667-24.576 24.576-24.576s24.576 10.92266667 24.576 24.576c0 141.99466667 115.23413333 257.2288 257.2288 257.2288S790.528 644.7104 790.528 502.71573333c0-13.65333333 10.92266667-24.576 24.576-24.576s24.576 10.92266667 24.576 24.576c0 168.7552-137.07946667 305.83466667-305.83466667 305.83466667zM729.36106667 955.46026667H337.78346667c-13.65333333 0-24.576-10.92266667-24.576-24.576s10.92266667-24.576 24.576-24.576h391.5776c13.65333333 0 24.576 10.92266667 24.576 24.576s-10.92266667 24.576-24.576 24.576z" fill="#FFF" p-id="4555"></path></svg>
|
|
32
|
+
<svgs :vol="vol"></svgs>
|
|
33
|
+
<span>{{ error? '开启语音失败' : '正在说话...' }}</span>
|
|
34
|
+
<svg style="cursor: pointer" @click="close" t="1698630749910" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4415" width="20" height="20"><path d="M726.976 274.432a16 16 0 0 0-22.656 0L512 466.752l-192.32-192.32a16 16 0 0 0-22.624 0l-22.656 22.624a16 16 0 0 0 0 22.624l192.32 192.32-192.32 192.32a16 16 0 0 0 0 22.656l22.656 22.624a16 16 0 0 0 22.624 0l192.32-192.32 192.32 192.32a16 16 0 0 0 22.656 0l22.624-22.624a16 16 0 0 0 0-22.624L557.28 512l192.32-192.352a16 16 0 0 0 0-22.624l-22.624-22.624z" fill="#fff" p-id="4416"></path></svg>
|
|
35
|
+
</div>
|
|
27
36
|
</div>
|
|
28
37
|
<div class="editor-but" v-if="butText !== '' && readOnly">
|
|
29
38
|
<button class="buts" @click="complete">{{ butText }}</button>
|
|
@@ -80,34 +89,10 @@
|
|
|
80
89
|
</div>
|
|
81
90
|
</div>
|
|
82
91
|
</div>
|
|
83
|
-
<div class="microphone" v-if="voiceStatus">
|
|
84
|
-
<div class="microphone-cont" :class="{'mic-anim': recordingStatus}">
|
|
85
|
-
<div class="microphone1">
|
|
86
|
-
<div class="microphone2">
|
|
87
|
-
<div class="microphone3" @click.stop="startVoice">
|
|
88
|
-
<svgs :vol="vol"></svgs>
|
|
89
|
-
<p v-if="recordingStatus">{{ voiceLoading? '语音转换中...': `正在说话:${countdown}s` }}</p>
|
|
90
|
-
</div>
|
|
91
|
-
</div>
|
|
92
|
-
</div>
|
|
93
|
-
</div>
|
|
94
|
-
<div class="microphone-text">{{ recordingStatus?'按下停止说话':'按下开始说话' }}</div>
|
|
95
|
-
</div>
|
|
96
|
-
<div class="text-editing" v-if="textEditing">
|
|
97
|
-
<div class="text-editing-cont">
|
|
98
|
-
<p>语音转换结果:</p>
|
|
99
|
-
<zydx-textarea ref="textarea" :height="130" :value="voiceContent"></zydx-textarea>
|
|
100
|
-
<div class="text-editing-but">
|
|
101
|
-
<button class="buts" @click="editingConfirm">确认</button>
|
|
102
|
-
<button class="buts" @click="editingCancel">取消</button>
|
|
103
|
-
</div>
|
|
104
|
-
</div>
|
|
105
|
-
</div>
|
|
106
92
|
</div>
|
|
107
93
|
</template>
|
|
108
94
|
<script>
|
|
109
95
|
import Recorder from 'js-audio-recorder'
|
|
110
|
-
import axios from 'axios'
|
|
111
96
|
import zydxTextarea from '../../textarea/src/textarea'
|
|
112
97
|
import {html2json, json2html} from 'html2json'
|
|
113
98
|
import {Editor, EditorContent} from '@tiptap/vue-3'
|
|
@@ -120,7 +105,7 @@ import textStyle from '@tiptap/extension-text-style'
|
|
|
120
105
|
import {sid} from "./sign-id";
|
|
121
106
|
import {FontSize} from "./font-size";
|
|
122
107
|
import {titleId} from "./title-id";
|
|
123
|
-
import svgs from "./
|
|
108
|
+
import svgs from "./level";
|
|
124
109
|
|
|
125
110
|
export default {
|
|
126
111
|
name: 'zydx-xiao-editor',
|
|
@@ -137,20 +122,20 @@ export default {
|
|
|
137
122
|
heightStyleCont: {},
|
|
138
123
|
voiceStatus: false,
|
|
139
124
|
recorder: null,
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
fileSize: 0,
|
|
125
|
+
ws: null,
|
|
126
|
+
audioContext: null,
|
|
127
|
+
audioData: [],
|
|
144
128
|
vol: 0,
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
textEditing: false
|
|
129
|
+
appData: {},
|
|
130
|
+
error: false,
|
|
131
|
+
time: {}
|
|
149
132
|
}
|
|
150
133
|
},
|
|
151
134
|
beforeUnmount() {
|
|
152
|
-
this.editor
|
|
153
|
-
this.recorder
|
|
135
|
+
this.editor?.destroy()
|
|
136
|
+
this.recorder?.destroy()
|
|
137
|
+
this.ws?.send(JSON.stringify({"type":"CANCEL"}))
|
|
138
|
+
this.ws?.close()
|
|
154
139
|
},
|
|
155
140
|
props: {
|
|
156
141
|
data: {
|
|
@@ -271,6 +256,7 @@ export default {
|
|
|
271
256
|
this.editor = new Editor({
|
|
272
257
|
content: json2html({node: "root", child: (this.data.html === undefined || null) ? [] : this.data.html}),
|
|
273
258
|
editable: this.readOnly,
|
|
259
|
+
enablePasteRules: true,
|
|
274
260
|
extensions: [
|
|
275
261
|
sid,
|
|
276
262
|
StarterKit,
|
|
@@ -311,16 +297,7 @@ export default {
|
|
|
311
297
|
}
|
|
312
298
|
}
|
|
313
299
|
})
|
|
314
|
-
|
|
315
|
-
this.$refs.editorRef.$el.addEventListener('paste', (event) => {
|
|
316
|
-
event.preventDefault();
|
|
317
|
-
const text = event.clipboardData.getData('text/plain');
|
|
318
|
-
const index = this.editor.state.selection.$anchor.path[1]
|
|
319
|
-
this.editor.chain().focus().insertContentAt(this.selection(), `<p>${text}</p>`).run()
|
|
320
|
-
const json = this.editor.getJSON()
|
|
321
|
-
json.content.splice(index, 1)
|
|
322
|
-
this.editor?.commands.setContent(json)
|
|
323
|
-
})
|
|
300
|
+
_this.appID()
|
|
324
301
|
// 初始化录音
|
|
325
302
|
this.recorder = new Recorder({
|
|
326
303
|
sampleBits: 16, // 采样位数,支持 8 或 16,默认是16
|
|
@@ -328,121 +305,152 @@ export default {
|
|
|
328
305
|
numChannels: 1, // 声道,支持 1 或 2, 默认是1
|
|
329
306
|
})
|
|
330
307
|
this.recorder.onprogress = function (params) {
|
|
331
|
-
|
|
332
|
-
_this.stopRecording()
|
|
333
|
-
}else {
|
|
334
|
-
_this.countdown = 59 - parseInt(params.duration)
|
|
335
|
-
_this.fileSize = params.fileSize
|
|
336
|
-
_this.vol = params.vol
|
|
337
|
-
}
|
|
308
|
+
_this.vol = params.vol
|
|
338
309
|
}
|
|
339
310
|
},
|
|
340
311
|
methods: {
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
const
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
312
|
+
// 粘贴文本处理
|
|
313
|
+
preventPaste(event) {
|
|
314
|
+
const text = event.clipboardData.getData('text/plain');
|
|
315
|
+
const text2 = text.replace(/[\r\n]/g, '').replace(/\s*/g, '')
|
|
316
|
+
this.editor.chain().focus().insertContentAt(this.selection(), text2).run()
|
|
317
|
+
},
|
|
318
|
+
to16kHz(audioData, sampleRate = 44100) {
|
|
319
|
+
const data = new Float32Array(audioData);
|
|
320
|
+
const fitCount = Math.round(data.length * (16000 / sampleRate));
|
|
321
|
+
const newData = new Float32Array(fitCount);
|
|
322
|
+
const springFactor = (data.length - 1) / (fitCount - 1);
|
|
323
|
+
newData[0] = data[0];
|
|
324
|
+
for (let i = 1; i < fitCount - 1; i++) {
|
|
325
|
+
const tmp = i * springFactor;
|
|
326
|
+
const before = Math.floor(tmp).toFixed();
|
|
327
|
+
const after = Math.ceil(tmp).toFixed();
|
|
328
|
+
const atPoint = tmp - before;
|
|
329
|
+
newData[i] = data[before] + (data[after] - data[before]) * atPoint;
|
|
347
330
|
}
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
331
|
+
newData[fitCount - 1] = data[data.length - 1];
|
|
332
|
+
return newData;
|
|
333
|
+
},
|
|
334
|
+
to16BitPCM(input) {
|
|
335
|
+
const dataLength = input.length * (16 / 8);
|
|
336
|
+
const dataBuffer = new ArrayBuffer(dataLength);
|
|
337
|
+
const dataView = new DataView(dataBuffer);
|
|
338
|
+
let offset = 0;
|
|
339
|
+
for (let i = 0; i < input.length; i++, offset += 2) {
|
|
340
|
+
const s = Math.max(-1, Math.min(1, input[i]));
|
|
341
|
+
dataView.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7fff, true);
|
|
342
|
+
}
|
|
343
|
+
return dataView;
|
|
344
|
+
},
|
|
345
|
+
getAudioSuccess() {
|
|
346
|
+
let that = this
|
|
347
|
+
const mediaStreamSource = that.recorder.audioInput
|
|
348
|
+
// 创建一个音频分析对象,采样的缓冲区大小为0(自动适配),输入和输出都是单声道
|
|
349
|
+
const scriptProcessor = that.recorder.context.createScriptProcessor(1024, 1, 1);
|
|
350
|
+
scriptProcessor.onaudioprocess = (e) => {
|
|
351
|
+
// 去处理音频数据
|
|
352
|
+
const inputData = e.inputBuffer.getChannelData(0)
|
|
353
|
+
const output = that.to16kHz(inputData, that.recorder.context.sampleRate);
|
|
354
|
+
const audioData = that.to16BitPCM(output);
|
|
355
|
+
that.audioData.push(...new Int8Array(audioData.buffer));
|
|
356
|
+
if (that.audioData.length > 10240) {
|
|
357
|
+
const audioDataArray = new Int8Array(that.audioData);
|
|
358
|
+
that.ws.send(audioDataArray)
|
|
359
|
+
that.audioData = [];
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
mediaStreamSource.connect(scriptProcessor);
|
|
363
|
+
scriptProcessor.connect(that.recorder.context.destination);
|
|
352
364
|
},
|
|
353
|
-
// 语音输入
|
|
354
365
|
voice() {
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
},
|
|
359
|
-
startVoice() {
|
|
360
|
-
if (!this.recordingStatus) {
|
|
366
|
+
let that = this
|
|
367
|
+
that.voiceStatus = !this.voiceStatus
|
|
368
|
+
if(that.voiceStatus) {
|
|
361
369
|
this.recorder.start().then(() => { // 开始录音
|
|
362
|
-
this.
|
|
363
|
-
this.
|
|
370
|
+
this.audioData = []
|
|
371
|
+
this.webSocketInit()
|
|
364
372
|
}, (error) => {
|
|
365
|
-
this.recordingStatus = false
|
|
366
373
|
this.$message({
|
|
367
374
|
type: 'text',
|
|
368
375
|
cancelShow: false,
|
|
369
376
|
promptContent: '录音失败,请检查麦克风是否可用'
|
|
370
377
|
})
|
|
371
378
|
});
|
|
372
|
-
}
|
|
373
|
-
|
|
379
|
+
}else {
|
|
380
|
+
that.close()
|
|
374
381
|
}
|
|
375
382
|
},
|
|
376
|
-
|
|
383
|
+
close() {
|
|
384
|
+
this.voiceStatus = false
|
|
385
|
+
this.ws.send(JSON.stringify({"type":"CANCEL"}))
|
|
386
|
+
this.ws.close()
|
|
377
387
|
this.recorder.stop() // 停止录音
|
|
378
|
-
this.
|
|
379
|
-
this.vol = 0
|
|
380
|
-
// 获取录音文件
|
|
381
|
-
const pcm = this.recorder.getPCMBlob()
|
|
382
|
-
const file = new File([pcm], 'audio.pcm', {type: 'audio/pcm'})
|
|
383
|
-
let reader = new FileReader();
|
|
384
|
-
reader.readAsDataURL(file)
|
|
385
|
-
reader.onload = async () => {
|
|
386
|
-
this.base64 = reader.result.split('base64,')[1]
|
|
387
|
-
await this.getSpeech()
|
|
388
|
-
}
|
|
388
|
+
this.recorder.destroy()
|
|
389
389
|
},
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
390
|
+
webSocketInit() {
|
|
391
|
+
const _this = this
|
|
392
|
+
_this.ws = new WebSocket(`wss://vop.baidu.com/realtime_asr?sn=${this.getRandomCode(15)}`)
|
|
393
|
+
_this.ws.binaryType = 'arraybuffer'
|
|
394
|
+
_this.ws.onopen = function () {
|
|
395
|
+
_this.error = false
|
|
396
|
+
const json = {
|
|
397
|
+
type: 'START',
|
|
398
|
+
data: {
|
|
399
|
+
appid: Number(_this.appData.qfClientId),
|
|
400
|
+
appkey: _this.appData.qfClientSecret,
|
|
401
|
+
dev_pid: 15372,
|
|
402
|
+
cuid: 'HpURryNC91ddJmAPq7iwu26OvMDW4jMS',
|
|
403
|
+
format: 'pcm',
|
|
404
|
+
sample: 16000,
|
|
405
|
+
}
|
|
398
406
|
}
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
if
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
407
|
+
_this.ws.send(JSON.stringify(json))
|
|
408
|
+
_this.getAudioSuccess()
|
|
409
|
+
}
|
|
410
|
+
_this.ws.onmessage = function (e) {
|
|
411
|
+
const data = JSON.parse(e.data)
|
|
412
|
+
if(data.err_no === 0){
|
|
413
|
+
const json = _this.editor.getJSON()
|
|
414
|
+
const index = _this.editor.state.selection.$anchor.path[1]
|
|
415
|
+
if(data.start_time === _this.time.start_time) {
|
|
416
|
+
const text = json.content[index].content[0].text
|
|
417
|
+
json.content[index].content[0].text = text.slice(0, text.length - _this.time.result.length) + data.result
|
|
418
|
+
_this.editor.commands.setContent(json)
|
|
419
|
+
}else {
|
|
420
|
+
_this.editor.chain().focus().insertContentAt(_this.selection(), data.result).run()
|
|
411
421
|
}
|
|
422
|
+
_this.time = data
|
|
412
423
|
}
|
|
413
|
-
|
|
414
|
-
|
|
424
|
+
}
|
|
425
|
+
_this.ws.onerror = function () {
|
|
426
|
+
// 连接失败重连
|
|
427
|
+
setTimeout(() => {
|
|
428
|
+
_this.error = true
|
|
429
|
+
_this.webSocketInit()
|
|
430
|
+
}, 5000)
|
|
431
|
+
}
|
|
415
432
|
},
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
_this.voiceContent += data.data.result[i]
|
|
438
|
-
}else {
|
|
439
|
-
_this.voiceContent += `${data.data.result[i]}<bt>`
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
})
|
|
443
|
-
.catch(function(err){
|
|
444
|
-
console.log(err)
|
|
445
|
-
});
|
|
433
|
+
appID() {
|
|
434
|
+
let token = null
|
|
435
|
+
let remember = localStorage.getItem('remember')
|
|
436
|
+
if(remember === '1') {
|
|
437
|
+
token = localStorage.getItem('sessionId')
|
|
438
|
+
}else {
|
|
439
|
+
token = sessionStorage.getItem('sessionId')
|
|
440
|
+
}
|
|
441
|
+
const xhr = new XMLHttpRequest()
|
|
442
|
+
// xhr.open('GET', 'http://192.168.15.126:8888/zydx/voice/getDesKeyId')
|
|
443
|
+
// xhr.setRequestHeader('Authorization', 'e891f5a9-4cf0-4f9f-b969-c91d44e6648c')
|
|
444
|
+
xhr.open('GET', '/zydx/voice/getDesKeyId')
|
|
445
|
+
xhr.setRequestHeader('Authorization', token)
|
|
446
|
+
xhr.onreadystatechange = () => {
|
|
447
|
+
if (xhr.readyState === 4) {
|
|
448
|
+
if (xhr.status === 200) {
|
|
449
|
+
this.appData = JSON.parse(xhr.responseText).data
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
xhr.send()
|
|
446
454
|
},
|
|
447
455
|
enclosureAction(v) {
|
|
448
456
|
return v.map(x => {
|
|
@@ -628,6 +636,19 @@ export default {
|
|
|
628
636
|
if (v === 'centerH2') this.editor.chain().focus().setFontSize('16px').setBold().setTextAlign('center').run()
|
|
629
637
|
if (v === 'leftH2') this.editor.chain().focus().setFontSize('16px').setBold().setTextAlign('left').run()
|
|
630
638
|
if (v === 'rightH2') this.editor.chain().focus().setFontSize('16px').setBold().setTextAlign('right').run()
|
|
639
|
+
},
|
|
640
|
+
getRandomCode(length) {
|
|
641
|
+
if (length > 0) {
|
|
642
|
+
let data = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"];
|
|
643
|
+
let nums = "";
|
|
644
|
+
for (let i = 0; i < length; i++) {
|
|
645
|
+
let r = parseInt(Math.random() * 61);
|
|
646
|
+
nums += data[r];
|
|
647
|
+
}
|
|
648
|
+
return nums.replace(/(.{4})/g, "$1-");
|
|
649
|
+
} else {
|
|
650
|
+
return false;
|
|
651
|
+
}
|
|
631
652
|
}
|
|
632
653
|
}
|
|
633
654
|
}
|
|
@@ -635,143 +656,33 @@ export default {
|
|
|
635
656
|
</script>
|
|
636
657
|
|
|
637
658
|
<style scoped>
|
|
638
|
-
.
|
|
639
|
-
text-align:
|
|
640
|
-
|
|
641
|
-
}
|
|
642
|
-
.text-editing{
|
|
643
|
-
position: fixed;
|
|
644
|
-
left: 0;
|
|
645
|
-
right: 0;
|
|
646
|
-
top: 0;
|
|
647
|
-
bottom: 0;
|
|
648
|
-
z-index: 50;
|
|
649
|
-
display: flex;
|
|
650
|
-
align-items: center;
|
|
651
|
-
padding-left: 320px;
|
|
659
|
+
.speak{
|
|
660
|
+
text-align: right;
|
|
661
|
+
padding: 5px 0;
|
|
652
662
|
}
|
|
653
|
-
.
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
margin: 0 auto;
|
|
663
|
+
.speak-cont{
|
|
664
|
+
background: rgba(67, 207, 124, 1);
|
|
665
|
+
color: #fff;
|
|
666
|
+
padding: 0 10px;
|
|
667
|
+
height: 30px;
|
|
668
|
+
line-height: 30px;
|
|
660
669
|
display: inline-block;
|
|
670
|
+
border-radius: 20px;
|
|
661
671
|
}
|
|
662
|
-
.
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
font-weight: 700;
|
|
666
|
-
}
|
|
667
|
-
.mic-anim .microphone1{
|
|
668
|
-
animation: mic-anim 1.5s infinite;
|
|
669
|
-
}
|
|
670
|
-
@keyframes mic-anim{
|
|
671
|
-
0%{
|
|
672
|
-
background: rgba(67, 207, 124, 0.2);
|
|
673
|
-
}
|
|
674
|
-
80%{
|
|
675
|
-
background: rgba(67, 207, 124, 0.4);
|
|
676
|
-
}
|
|
677
|
-
100%{
|
|
678
|
-
background: rgba(67, 207, 124, 0.2);
|
|
679
|
-
}
|
|
680
|
-
}
|
|
681
|
-
.mic-anim .microphone2{
|
|
682
|
-
animation: mic-anim2 1.5s infinite;
|
|
683
|
-
}
|
|
684
|
-
@keyframes mic-anim2{
|
|
685
|
-
0%{
|
|
686
|
-
background: rgba(67, 207, 124, 0.4);
|
|
687
|
-
}
|
|
688
|
-
40%{
|
|
689
|
-
background: rgba(67, 207, 124, 0.6);
|
|
690
|
-
}
|
|
691
|
-
80%{
|
|
692
|
-
background: rgba(67, 207, 124, 0.4);
|
|
693
|
-
}
|
|
694
|
-
100%{
|
|
695
|
-
background: rgba(67, 207, 124, 0.4);
|
|
696
|
-
}
|
|
697
|
-
}
|
|
698
|
-
.mic-anim .microphone3{
|
|
699
|
-
animation: mic-anim3 1.5s infinite;
|
|
672
|
+
.speak-cont svg{
|
|
673
|
+
vertical-align: middle;
|
|
674
|
+
margin-top: -3px;
|
|
700
675
|
}
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
}
|
|
705
|
-
20%{
|
|
706
|
-
background: rgba(67, 207, 124, 1);
|
|
707
|
-
}
|
|
708
|
-
40%{
|
|
709
|
-
background: rgba(67, 207, 124, 0.8);
|
|
710
|
-
}
|
|
711
|
-
100%{
|
|
712
|
-
background: rgba(67, 207, 124, 0.8);
|
|
713
|
-
}
|
|
714
|
-
}
|
|
715
|
-
.microphone{
|
|
716
|
-
position: fixed;
|
|
717
|
-
left: 50%;
|
|
718
|
-
top: 50%;
|
|
719
|
-
z-index: 50;
|
|
720
|
-
width: 200px;
|
|
721
|
-
margin-left: 60px;
|
|
722
|
-
margin-top: -120px;
|
|
723
|
-
}
|
|
724
|
-
.microphone-cont{
|
|
725
|
-
width: 200px;
|
|
726
|
-
height: 200px;
|
|
727
|
-
border-radius: 50%;
|
|
728
|
-
position: relative;
|
|
729
|
-
}
|
|
730
|
-
.microphone1{
|
|
731
|
-
width: 200px;
|
|
732
|
-
height: 200px;
|
|
733
|
-
border-radius: 50%;
|
|
734
|
-
background: rgba(67, 207, 124, 0.3);
|
|
735
|
-
}
|
|
736
|
-
.microphone2{
|
|
737
|
-
width: 160px;
|
|
738
|
-
height: 160px;
|
|
739
|
-
border-radius: 50%;
|
|
740
|
-
background: rgba(67, 207, 124, 0.5);
|
|
741
|
-
position: absolute;
|
|
742
|
-
top: 50%;
|
|
743
|
-
left: 50%;
|
|
744
|
-
z-index: 1;
|
|
745
|
-
transform: translate(-50%,-50%);
|
|
746
|
-
}
|
|
747
|
-
.microphone3{
|
|
748
|
-
width: 120px;
|
|
749
|
-
height: 120px;
|
|
750
|
-
border-radius: 50%;
|
|
751
|
-
background: rgba(67, 207, 124, 0.8);
|
|
752
|
-
position: absolute;
|
|
753
|
-
top: 50%;
|
|
754
|
-
left: 50%;
|
|
755
|
-
z-index: 1;
|
|
756
|
-
transform: translate(-50%,-50%);
|
|
757
|
-
text-align: center;
|
|
758
|
-
padding-top: 18px;
|
|
759
|
-
box-sizing: border-box;
|
|
760
|
-
cursor: pointer;
|
|
761
|
-
}
|
|
762
|
-
.microphone3 p{
|
|
763
|
-
font-size: 12px;
|
|
764
|
-
color: #fff;
|
|
765
|
-
line-height: 18px;
|
|
676
|
+
.speak-cont span{
|
|
677
|
+
font-size: 14px;
|
|
678
|
+
padding: 0 5px;
|
|
766
679
|
}
|
|
767
|
-
.
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
font-size: 18px;
|
|
771
|
-
line-height: 26px;
|
|
680
|
+
.text-editing-cont p {
|
|
681
|
+
font-size: 16px;
|
|
682
|
+
line-height: 24px;
|
|
772
683
|
font-weight: 700;
|
|
773
|
-
background: rgba(255,255,255,0.8);
|
|
774
684
|
}
|
|
685
|
+
|
|
775
686
|
:deep(.imgCont) {
|
|
776
687
|
line-height: 0 !important;
|
|
777
688
|
}
|
|
@@ -940,6 +851,7 @@ export default {
|
|
|
940
851
|
display: inline-block;
|
|
941
852
|
position: relative;
|
|
942
853
|
}
|
|
854
|
+
|
|
943
855
|
.schedule span {
|
|
944
856
|
font-size: 12px;
|
|
945
857
|
position: absolute;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="14" height="14"
|
|
3
|
+
viewBox="0 0 16 16" fill="none">
|
|
4
|
+
<g opacity="1" transform="translate(0 0) rotate(0)">
|
|
5
|
+
<mask id="bg-mask-0" fill="white">
|
|
6
|
+
<use transform="translate(0 0) rotate(0)" xlink:href="#path_0"></use>
|
|
7
|
+
</mask>
|
|
8
|
+
<g mask="url(#bg-mask-0)">
|
|
9
|
+
<rect :fill="volFill(vol,1)" x="1" y="12" width="2" height="5"/>
|
|
10
|
+
<rect :fill="volFill(vol,2)" x="5" y="8" width="2" height="9"/>
|
|
11
|
+
<rect :fill="volFill(vol,3)" x="9" y="4" width="2" height="13"/>
|
|
12
|
+
<rect :fill="volFill(vol,4)" x="13" y="0" width="2" height="17"/>
|
|
13
|
+
</g>
|
|
14
|
+
</g>
|
|
15
|
+
<defs>
|
|
16
|
+
<rect id="path_0" x="0" y="0" width="16" height="16"/>
|
|
17
|
+
</defs>
|
|
18
|
+
</svg>
|
|
19
|
+
</template>
|
|
20
|
+
|
|
21
|
+
<script>
|
|
22
|
+
export default {
|
|
23
|
+
props: {
|
|
24
|
+
vol: {
|
|
25
|
+
type: Number,
|
|
26
|
+
default: 0
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
methods: {
|
|
30
|
+
volFill(v,n) {
|
|
31
|
+
v = Math.floor(v)
|
|
32
|
+
if(n === 1) {
|
|
33
|
+
if(v >= 10) {
|
|
34
|
+
return '#fff'
|
|
35
|
+
} else {
|
|
36
|
+
return '#12A64D'
|
|
37
|
+
}
|
|
38
|
+
} else if(n === 2) {
|
|
39
|
+
if(v >= 25) {
|
|
40
|
+
return '#fff'
|
|
41
|
+
} else {
|
|
42
|
+
return '#12A64D'
|
|
43
|
+
}
|
|
44
|
+
} else if(n === 3) {
|
|
45
|
+
if(v >= 35) {
|
|
46
|
+
return '#fff'
|
|
47
|
+
} else {
|
|
48
|
+
return '#12A64D'
|
|
49
|
+
}
|
|
50
|
+
} else if(n === 4) {
|
|
51
|
+
if(v >= 45) {
|
|
52
|
+
return '#fff'
|
|
53
|
+
} else {
|
|
54
|
+
return '#12A64D'
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
</script>
|
|
61
|
+
|
|
62
|
+
<style scoped>
|
|
63
|
+
|
|
64
|
+
</style>
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
<script>
|
|
32
32
|
import * as PdfJs from 'pdfjs-dist/legacy/build/pdf.js' // 注意导入的写法d
|
|
33
33
|
PdfJs.GlobalWorkerOptions.workerSrc = require('pdfjs-dist/build/pdf.worker.entry')
|
|
34
|
-
const jsdelivr = '
|
|
34
|
+
const jsdelivr = '/zydx/static/cmaps/'
|
|
35
35
|
export default {
|
|
36
36
|
name: "zydx-flip",
|
|
37
37
|
data() {
|
|
@@ -95,7 +95,7 @@ export default {
|
|
|
95
95
|
let that = this
|
|
96
96
|
const loadingTask = PdfJs.getDocument({
|
|
97
97
|
url: this.url,
|
|
98
|
-
cMapUrl: "
|
|
98
|
+
cMapUrl: "/zydx/static/cmaps/",
|
|
99
99
|
cMapPacked: true
|
|
100
100
|
})
|
|
101
101
|
loadingTask.promise.then((pdf) => {
|
package/src/index.js
CHANGED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div>
|
|
3
|
-
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 38 68" width="36" height="68">
|
|
4
|
-
<path id="并集_轮廓_" data-name="并集 (轮廓)" fill="#ccc"
|
|
5
|
-
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"/>
|
|
6
|
-
<rect fill="#fff" x="11" y="4" width="16" height="36"/>
|
|
7
|
-
<rect class="volume" :height="volume(vol)" width="12" :y="volume2(vol)" x="13" fill="#43cf7c"/>
|
|
8
|
-
</svg>
|
|
9
|
-
</div>
|
|
10
|
-
</template>
|
|
11
|
-
|
|
12
|
-
<script>
|
|
13
|
-
export default {
|
|
14
|
-
name: "microphone",
|
|
15
|
-
props: {
|
|
16
|
-
vol: {
|
|
17
|
-
type: Number,
|
|
18
|
-
default: 0
|
|
19
|
-
}
|
|
20
|
-
},
|
|
21
|
-
data() {
|
|
22
|
-
return {}
|
|
23
|
-
},
|
|
24
|
-
methods: {
|
|
25
|
-
volume(v) {
|
|
26
|
-
if(v === 0) {
|
|
27
|
-
return 32
|
|
28
|
-
}else {
|
|
29
|
-
return v/3 > 32 ? 32 : v/5
|
|
30
|
-
}
|
|
31
|
-
},
|
|
32
|
-
volume2(v) {
|
|
33
|
-
if(v === 0) {
|
|
34
|
-
return 6
|
|
35
|
-
}else {
|
|
36
|
-
return 6 + 32 - this.volume(v)
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
</script>
|
|
42
|
-
|
|
43
|
-
<style scoped>
|
|
44
|
-
.volume {
|
|
45
|
-
transition: all 0.2s;
|
|
46
|
-
}
|
|
47
|
-
</style>
|