zydx-plus 1.20.111 → 1.20.113

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.20.111",
3
+ "version": "1.20.113",
4
4
  "description": "Vue.js",
5
5
  "main": "src/index.js",
6
6
  "files": [
@@ -1,171 +1,191 @@
1
1
  <template>
2
- <we-toolbar v-show="!readOnly && toolbar.length > 0" class="toolbar" :handle="handle" />
3
- <we-editable class="editable" :style="{'min-height': height + 'px'}" :handle="handle" v-model:json="formData.html" />
4
- <div class="but" v-if="!readOnly && toolbar.length > 0">
5
- <button class="def-but" v-if="butShow" @click="confirm">完成</button>
6
- </div>
2
+ <we-toolbar v-show="!readOnly && toolbar.length > 0" class="toolbar" :handle="handle"/>
3
+ <we-editable class="editable" :style="{'min-height': height + 'px'}" :handle="handle" v-model:json="formData.html"/>
4
+ <div class="but" v-if="!readOnly && toolbar.length > 0">
5
+ <button class="def-but" v-if="butShow" @click="confirm">完成</button>
6
+ </div>
7
7
  </template>
8
8
  <script>
9
9
  import '@wangeditor/editor/dist/css/style.css'
10
- import { defineComponent, shallowReactive } from 'vue'
11
- import { Boot } from '@wangeditor/editor'
10
+ import {defineComponent, shallowReactive} from 'vue'
11
+ import {Boot} from '@wangeditor/editor'
12
12
  import attachmentModule from '@wangeditor/plugin-upload-attachment'
13
13
  import formulaModule from '@wangeditor/plugin-formula'
14
- import { menuModule } from './menu'
15
- import { nodeModule } from './node'
16
- import { useWangEditor,WeEditable, WeToolbar } from './wangeditor5-for-vue3/index'
14
+ import {menuModule} from './menu'
15
+ import {nodeModule} from './node'
16
+ import {useWangEditor, WeEditable, WeToolbar} from './wangeditor5-for-vue3/index'
17
+
17
18
  Boot.registerModule(attachmentModule)
18
19
  Boot.registerModule(formulaModule)
19
20
  Boot.registerModule(nodeModule)
20
21
  Boot.registerModule(menuModule)
21
22
 
22
23
  export default defineComponent({
23
- name: 'zydx-editor',
24
- components: { WeEditable, WeToolbar },
25
- props: {
26
- height: {
27
- type: String,
28
- default: '800'
29
- },
30
- placeholder: {
31
- type: String,
32
- default: '请开始你的表演'
33
- },
34
- html: {
35
- type: String,
36
- default: ''
37
- },
38
- readOnly: {
39
- type: Boolean,
40
- default: false
41
- },
42
- butShow: {
43
- type: Boolean,
44
- default: true
45
- },
46
- toolbar: {
47
- type: Array,
48
- default: []
49
- },
50
- menusText: {
51
- type: Array,
52
- default: []
53
- },
54
- uploadImage: {
55
- type: Object,
56
- default: {}
24
+ name: 'zydx-editor',
25
+ components: {WeEditable, WeToolbar},
26
+ props: {
27
+ height: {
28
+ type: String,
29
+ default: '800'
30
+ },
31
+ placeholder: {
32
+ type: String,
33
+ default: '请开始你的表演'
34
+ },
35
+ html: {
36
+ type: Array,
37
+ default: []
38
+ },
39
+ readOnly: {
40
+ type: Boolean,
41
+ default: false
42
+ },
43
+ butShow: {
44
+ type: Boolean,
45
+ default: true
46
+ },
47
+ toolbar: {
48
+ type: Array,
49
+ default: []
50
+ },
51
+ menusText: {
52
+ type: Array,
53
+ default: []
54
+ },
55
+ uploadImage: {
56
+ type: Object,
57
+ default: {}
58
+ },
59
+ uploadAttachment: {
60
+ type: Object,
61
+ default: {}
62
+ }
57
63
  },
58
- uploadAttachment: {
59
- type: Object,
60
- default: {}
61
- }
62
- },
63
- emits: ['confirm'],
64
- watch: {
65
- html() {
66
- this.formData.html = this.html
64
+ emits: ['confirm'],
65
+ watch: {
66
+ html: {
67
+ handler: function (e, oldVal) {
68
+ this.formData.html = e
69
+ },
70
+ deep: true
71
+ },
72
+ readOnly: {
73
+ handler: function (e, oldVal) {
74
+ this.opts.editable.config.readOnly = e
75
+ },
76
+ deep: true
77
+ },
67
78
  },
68
- readOnly(e) {
69
- this.opts.editable.config.readOnly = e
70
- }
71
- },
72
- methods: {
73
- confirm() {
74
- this.syncContent() //强制同步数据
75
- this.$emit('confirm', this.formData.html)
76
- },
77
- getContent() {
78
- this.syncContent() //强制同步数据
79
- return this.formData.html
80
- }
81
- },
82
- mounted() {
83
- this.formData.html = this.html
84
- setTimeout(() => {
85
- if(this.readOnly) this.opts.editable.config.readOnly = this.readOnly
86
- },0)
87
- },
88
- setup(props) {
89
- const { opts, handle, instance, clearContent, syncContent, reloadEditor } = useWangEditor({
90
- // 防抖时长。当会触发重载的配置项发生变化 365ms 后,编辑器会重载
91
- reloadDelary: 365,
92
- // 菜单栏配置
93
- toolbar: {
94
- mode: 'simple', // 指定简介模式
95
- config:{
96
- toolbarKeys: props.toolbar
97
- }
98
- },
99
- // 编辑器配置
100
- editable: {
101
- config: {
102
- placeholder: props.placeholder,
103
- readOnly: false,
104
- autoFocus: (props.html !== ''),
105
- MENU_CONF: {
106
- // 上传图片
107
- uploadImage: props.uploadImage,
108
- uploadAttachment: props.uploadAttachment
109
- }
110
- // hoverbarKeys: {
111
- // attachment: {
112
- // menuKeys: ['menu4'],
113
- // },
114
- // },
79
+ methods: {
80
+ confirm() {
81
+ this.syncContent() //强制同步数据
82
+ this.$emit('confirm', this.formData.html)
83
+ },
84
+ getContent() {
85
+ this.syncContent() //强制同步数据
86
+ return this.formData.html
115
87
  }
116
- }
117
- })
118
- // 不要使用 reactive/ref,应该使用 shallowReactive/shallowRef 来接收 json array 数据
119
- const formData = shallowReactive({html: ''})
120
- setTimeout(() => {
121
- for (let i = 0; i < props.menusText.length; i++) {
122
- let indexs = findIndexByKey(menuModule.menus,props.menusText[i]['key'])
123
- menuModule.menus[indexs].factory(props.menusText[i])
124
- }
125
- },0)
126
- // 根据key值查询数组索引
127
- function findIndexByKey(arr, value) {
128
- for (let i = 0; i < arr.length; i++) {
129
- if (arr[i]['key'] === value) {
130
- return i
88
+ },
89
+ setup(props) {
90
+ const {opts, handle, instance, clearContent, syncContent, reloadEditor} = useWangEditor({
91
+ // 防抖时长。当会触发重载的配置项发生变化 365ms 后,编辑器会重载
92
+ reloadDelary: 365,
93
+ // 菜单栏配置
94
+ toolbar: {
95
+ mode: 'simple', // 指定简介模式
96
+ config: {
97
+ toolbarKeys: props.toolbar
98
+ }
99
+ },
100
+ // 编辑器配置
101
+ editable: {
102
+ config: {
103
+ placeholder: props.placeholder,
104
+ readOnly: props.readOnly,
105
+ // autoFocus: (props.html !== ''),
106
+ autoFocus: true, // 自动聚焦
107
+ MENU_CONF: {
108
+ // 上传图片
109
+ uploadImage: props.uploadImage,
110
+ uploadAttachment: props.uploadAttachment
111
+ }
112
+ // hoverbarKeys: {
113
+ // attachment: {
114
+ // menuKeys: ['menu4'],
115
+ // },
116
+ // },
117
+ }
118
+ }
119
+ })
120
+ // 不要使用 reactive/ref,应该使用 shallowReactive/shallowRef 来接收 json array 数据
121
+ const formData = shallowReactive({html: props.html})
122
+ setTimeout(() => {
123
+ for (let i = 0; i < props.menusText.length; i++) {
124
+ let indexs = findIndexByKey(menuModule.menus, props.menusText[i]['key'])
125
+ menuModule.menus[indexs].factory(props.menusText[i])
126
+ }
127
+ }, 0)
128
+
129
+ // 根据key值查询数组索引
130
+ function findIndexByKey(arr, value) {
131
+ for (let i = 0; i < arr.length; i++) {
132
+ if (arr[i]['key'] === value) {
133
+ return i
134
+ }
135
+ }
136
+ return -1
131
137
  }
132
- }
133
- return -1
138
+
139
+ return {opts, handle, formData, syncContent}
134
140
  }
135
- return { opts, handle, formData, syncContent }
136
- }
137
141
  })
138
142
  </script>
139
143
 
140
144
  <style scoped>
141
- .but{
142
- text-align: right;
145
+ .but {
146
+ text-align: right;
143
147
  }
148
+
144
149
  /*工具栏样式*/
145
- .toolbar{
146
- border: 1px solid #d9d9d9;
147
- margin-bottom: 20px;
150
+ .toolbar {
151
+ border: 1px solid #d9d9d9;
152
+ margin-bottom: 20px;
148
153
  }
154
+
149
155
  /*工具栏剧中显示*/
150
156
  .w-e-toolbar {
151
- justify-content: center !important;
157
+ justify-content: center !important;
152
158
  }
159
+
153
160
  /*编辑器样式*/
154
- .editable{
155
- width: 100%;
156
- background-color: #fff;
157
- border: 1px solid #e8e8e8;
158
- margin-bottom: 20px;
159
- position: relative;
161
+ .editable {
162
+ width: 100%;
163
+ background-color: #fff;
164
+ border: 1px solid #e8e8e8;
165
+ margin-bottom: 20px;
166
+ position: relative;
160
167
  }
161
- .def-but{
162
- margin-left: 5px;
163
- font-size: 12px;
164
- background-color: transparent;
165
- border: 1px solid #000;
166
- border-radius: 3px;
167
- padding: 2px 5px;
168
- cursor: pointer;
169
- min-width: 60px;
168
+
169
+ .def-but {
170
+ margin-left: 5px;
171
+ font-size: 12px;
172
+ background-color: transparent;
173
+ border: 1px solid #000;
174
+ border-radius: 3px;
175
+ padding: 2px 5px;
176
+ cursor: pointer;
177
+ min-width: 60px;
178
+ }
179
+
180
+ :deep(.w-e-textarea-divider) {
181
+ padding: 0;
182
+ }
183
+
184
+ :deep(.w-e-text-container p) {
185
+ margin: 5px 0;
186
+ }
187
+
188
+ :deep(.w-e-text-placeholder) {
189
+ top: 6px;
170
190
  }
171
191
  </style>
@@ -1,6 +1,7 @@
1
1
  let signData = null
2
2
  let titleData = null
3
3
 
4
+ const num = {1: '①', 2: '②', 3: '③', 4: '④', 5: '⑤', 6: '⑥', 7: '⑦', 8: '⑧', 9: '⑨', 10: '⑩', 11: '⑪', 12: '⑫', 13: '⑬', 14: '⑭', 15: '⑮', 16: '⑯', 17: '⑰', 18: '⑱', 19: '⑲', 20: '⑳',}
4
5
 
5
6
  function typeCode(node,value) {
6
7
  let hasAttachment = false
@@ -15,6 +16,25 @@ function typeCode(node,value) {
15
16
  return hasAttachment
16
17
  }
17
18
 
19
+ function addNode(editor,nodes) {
20
+ editor.clear()
21
+ nodes.forEach(node => {
22
+ editor.insertNode(node)
23
+ })
24
+ }
25
+
26
+ // 查询数组中有没有某个值
27
+ function hasValue(arr, value) {
28
+ let num = 0
29
+ arr.some(item => {
30
+ item.children.some(items => {
31
+ if(items.sup) num++
32
+ })
33
+ })
34
+ return num
35
+ }
36
+
37
+ //添加标志
18
38
  class signButtonMenu {
19
39
  constructor(v) {
20
40
  signData = v
@@ -37,7 +57,6 @@ class signButtonMenu {
37
57
  // 点击菜单时触发的函数
38
58
  exec(editor, value) {
39
59
  if (this.isDisabled(editor)) return
40
- // console.log(editor.getEditableContainer())
41
60
  let node = editor.children
42
61
  let nodes = JSON.parse(JSON.stringify(node)) //拷贝一份
43
62
  if(typeCode(node,'attachment')) return
@@ -48,14 +67,10 @@ class signButtonMenu {
48
67
  children: [{text:''}]
49
68
  }
50
69
  nodes.unshift(resume)
51
- editor.clear()
52
- console.log(nodes)
53
- for(let i = 0; i < nodes.length; i++){
54
- editor.insertNode(nodes[i])
55
- }
70
+ addNode(editor,nodes)
56
71
  }
57
72
  }
58
-
73
+ //添加红头
59
74
  class redButtonMenu {
60
75
  constructor() {
61
76
  this.title = '添加红头' // 自定义菜单标题
@@ -123,13 +138,10 @@ class redButtonMenu {
123
138
  nodes.splice(1,0,resume1)
124
139
  nodes.splice(2,0,resume2)
125
140
  }
126
- editor.clear()
127
- for(let i = 0; i < nodes.length; i++){
128
- editor.insertNode(nodes[i])
129
- }
141
+ addNode(editor,nodes)
130
142
  }
131
143
  }
132
-
144
+ // 添加标题
133
145
  class titleButtonMenu {
134
146
  constructor(v) {
135
147
  titleData = v
@@ -154,16 +166,22 @@ class titleButtonMenu {
154
166
  const resume = {
155
167
  type: 'paragraph',
156
168
  children: [{
157
- text: titleData.text,
158
- color: '#000000',
159
- fontSize: '48px',
169
+ type: 'titleAttachment',
170
+ fileName: titleData.text,
171
+ children: [{text:''}]
160
172
  }],
161
173
  textAlign: 'center'
162
174
  }
175
+ const resume2 = {
176
+ type: 'paragraph',
177
+ children: [{text:''}],
178
+ textAlign: 'left'
179
+ }
163
180
  editor.insertNode(resume)
181
+ editor.insertNode(resume2)
164
182
  }
165
183
  }
166
-
184
+ // 添加参考文献
167
185
  class literatureButtonMenu {
168
186
  constructor(v) {
169
187
  titleData = v
@@ -197,7 +215,8 @@ class literatureButtonMenu {
197
215
  text: '[2]作者.学位论文名称[D1.毕业院校所在城市:毕业院校,论文提交年份:页码',
198
216
  color: '#000000',
199
217
  fontSize: '14px',
200
- }]
218
+ }],
219
+ textAlign: 'left'
201
220
  }
202
221
  const resume3 = {
203
222
  type: 'paragraph',
@@ -205,7 +224,8 @@ class literatureButtonMenu {
205
224
  text: '[3]作者.著作名称[M.出版社所在城市:出版社名称,出版年份:页码.',
206
225
  color: '#000000',
207
226
  fontSize: '14px',
208
- }]
227
+ }],
228
+ textAlign: 'left'
209
229
  }
210
230
  const resume4 = {
211
231
  type: 'paragraph',
@@ -213,7 +233,8 @@ class literatureButtonMenu {
213
233
  text: '[4]作者.文章名称[N].报纸名称,发行日期(版面)',
214
234
  color: '#000000',
215
235
  fontSize: '14px',
216
- }]
236
+ }],
237
+ textAlign: 'left'
217
238
  }
218
239
  editor.insertNode(resume)
219
240
  editor.insertNode(resume2)
@@ -221,6 +242,53 @@ class literatureButtonMenu {
221
242
  editor.insertNode(resume4)
222
243
  }
223
244
  }
245
+ // 添加标注
246
+ class taggingButtonMenu {
247
+ constructor(v) {
248
+ titleData = v
249
+ this.title = '添加标注' // 自定义菜单标题
250
+ this.tag = 'button'
251
+ }
252
+ getValue(editor) {
253
+ return false
254
+ }
255
+ isActive(editor) {
256
+ return false
257
+ }
258
+ isDisabled(editor) {
259
+ return false
260
+ }
261
+ exec(editor, value) {
262
+ if (this.isDisabled(editor)) return
263
+ const anchor = editor.selection.anchor
264
+ if(anchor.offset === 0) return
265
+ let node = editor.children
266
+ let nodes = JSON.parse(JSON.stringify(node)) //拷贝一份
267
+ const numSub = hasValue(nodes,'sup')
268
+ let one = nodes[0]
269
+ nodes.splice(0,1)
270
+ nodes.unshift({
271
+ type: 'attachment',
272
+ text: one.children[0].text
273
+ })
274
+ nodes[anchor.path[0]].children.push({
275
+ text: num[numSub+1],
276
+ sup: true
277
+ },{text: ' '})
278
+ nodes.push({
279
+ type: 'divider',
280
+ children: [{text:''}]
281
+ })
282
+ nodes.push({
283
+ type: 'paragraph',
284
+ children: [{
285
+ text: `${num[numSub+1]}填写标注内容`,
286
+ }],
287
+ textAlign: 'left'
288
+ })
289
+ addNode(editor,nodes)
290
+ }
291
+ }
224
292
 
225
293
  const signMenuConf = {
226
294
  key: 'signMenu',
@@ -248,7 +316,13 @@ const literatureMenuConf = {
248
316
  return new literatureButtonMenu(v)
249
317
  },
250
318
  }
319
+ const taggingMenuConf = {
320
+ key: 'taggingMenu',
321
+ factory(v) {
322
+ return new taggingButtonMenu(v)
323
+ },
324
+ }
251
325
 
252
326
  export const menuModule = {
253
- menus: [signMenuConf,redMenuConf,titleMenuConf,literatureMenuConf]
327
+ menus: [signMenuConf,redMenuConf,titleMenuConf,literatureMenuConf,taggingMenuConf]
254
328
  }
@@ -28,12 +28,37 @@ function renderAttachment(elem, children, editor) {
28
28
  return attachVnode
29
29
  }
30
30
 
31
+ function titleAttachment(elem, children, editor) {
32
+ const iconText = h(
33
+ 'span',
34
+ {
35
+ props: { contentEditable: false },
36
+ style: {display: 'inline-block',fontSize: '24px',fontWeight: 400}
37
+ },
38
+ [ elem.fileName ]
39
+ )
40
+ const attachVnode = h(
41
+ 'span',
42
+ {
43
+ props: { contentEditable: false },
44
+ style: { display: 'inline-block'},
45
+ // on: { click() { console.log('clicked', link) } }
46
+ },
47
+ [ iconText]
48
+ )
49
+ return attachVnode
50
+ }
51
+
31
52
 
32
53
  const renderElemConf = {
33
54
  type: 'attachment',
34
55
  renderElem: renderAttachment,
35
56
  }
57
+ const titleElemConf = {
58
+ type: 'titleAttachment',
59
+ renderElem: titleAttachment,
60
+ }
36
61
 
37
62
  export const nodeModule = {
38
- renderElems: [renderElemConf]
63
+ renderElems: [renderElemConf,titleElemConf]
39
64
  }
@@ -274,22 +274,7 @@ export default {
274
274
  this.uploadAttData.push(file)
275
275
  }else {
276
276
  this.uploadFile(file,this.uploadImage).then(r => {
277
- const url = this.uploadImage.url + r.data
278
- const html = [
279
- {
280
- node: "element",
281
- tag: "p",
282
- child: [{
283
- attr: {
284
- src: url,
285
- width:"100%"
286
- },
287
- tag: 'img',
288
- node: "element",
289
- }],
290
- }
291
- ]
292
- this.insertContent(html)
277
+ this.imgHtml(r.data)
293
278
  })
294
279
  }
295
280
  }else {
@@ -299,27 +284,30 @@ export default {
299
284
  this.uploadAttData.push(r.data.annex)
300
285
  this.$emit('enclosureSuccess', r.data.annex)
301
286
  }else {
302
- const url = this.uploadImage.url + r.data
303
- const html = [
304
- {
305
- node: "element",
306
- tag: "p",
307
- child: [{
308
- attr: {
309
- src: url,
310
- width:"100%"
311
- },
312
- tag: 'img',
313
- node: "element",
314
- }]
315
- }
316
- ]
317
- this.insertContent(html)
287
+ this.imgHtml(r.data)
318
288
  }
319
289
  })
320
290
  }
321
291
  e.target.value = ''
322
292
  },
293
+ imgHtml(data) {
294
+ const url = this.uploadImage.url + data
295
+ const html = [
296
+ {
297
+ node: "element",
298
+ tag: "p",
299
+ child: [{
300
+ attr: {
301
+ src: url,
302
+ width:"100%"
303
+ },
304
+ tag: 'img',
305
+ node: "element",
306
+ }],
307
+ }
308
+ ]
309
+ this.insertContent(html)
310
+ },
323
311
  insertContent(v) {
324
312
  for(let i=0; i< v.length; i++) {
325
313
  let html = json2html(v[i])
@@ -78,11 +78,17 @@ export default {
78
78
  this.pageIndex = val
79
79
  },
80
80
  immediate: true
81
+ },
82
+ source: {
83
+ handler: function (val, oldVal) {
84
+ this.readPdf()
85
+ },
86
+ immediate: true
81
87
  }
82
88
  },
83
89
  emits: ['flip'],
84
90
  mounted() {
85
- this.readPdf()
91
+ // this.readPdf()
86
92
  this.id = 'canvas-wrap' + Math.random().toString(36).substr(2)
87
93
  },
88
94
  methods: {
package/src/index.js CHANGED
@@ -63,7 +63,7 @@ function install(app) {
63
63
  }
64
64
 
65
65
  export default {
66
- version: '1.20.111',
66
+ version: '1.20.113',
67
67
  install,
68
68
  Calendar,
69
69
  Message,