@longhongguo/form-create-ant-design-vue 3.2.43 → 3.2.44
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/dist/form-create.esm.js +2 -2
- package/dist/form-create.esm.js.map +1 -1
- package/dist/form-create.js +2 -2
- package/dist/form-create.js.map +1 -1
- package/package.json +1 -1
- package/src/components/FcEditorWrapper.vue +178 -0
- package/src/core/api.js +0 -1
- package/src/core/manager.js +442 -442
package/src/core/manager.js
CHANGED
|
@@ -1,442 +1,442 @@
|
|
|
1
|
-
import getConfig from './config'
|
|
2
|
-
import mergeProps from '@form-create/utils/lib/mergeprops'
|
|
3
|
-
import is, { hasProperty } from '@form-create/utils/lib/type'
|
|
4
|
-
import extend from '@form-create/utils/lib/extend'
|
|
5
|
-
|
|
6
|
-
function isTooltip(info) {
|
|
7
|
-
return info.type === 'tooltip'
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
function tidy(props, name) {
|
|
11
|
-
if (!hasProperty(props, name)) return
|
|
12
|
-
if (is.String(props[name])) {
|
|
13
|
-
props[name] = { [name]: props[name], show: true }
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
function isFalse(val) {
|
|
18
|
-
return val === false
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function tidyBool(opt, name) {
|
|
22
|
-
if (hasProperty(opt, name) && !is.Object(opt[name])) {
|
|
23
|
-
opt[name] = { show: !!opt[name] }
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function tidyRule(rule) {
|
|
28
|
-
const _rule = { ...rule }
|
|
29
|
-
delete _rule.children
|
|
30
|
-
return _rule
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export default {
|
|
34
|
-
validate() {
|
|
35
|
-
const form = this.form()
|
|
36
|
-
if (form) {
|
|
37
|
-
return form.validate()
|
|
38
|
-
} else {
|
|
39
|
-
return new Promise((v) => v())
|
|
40
|
-
}
|
|
41
|
-
},
|
|
42
|
-
validateField(field) {
|
|
43
|
-
const form = this.form()
|
|
44
|
-
if (form) {
|
|
45
|
-
return form.validateFields(field)
|
|
46
|
-
} else {
|
|
47
|
-
return new Promise((v) => v())
|
|
48
|
-
}
|
|
49
|
-
},
|
|
50
|
-
clearValidateState(ctx) {
|
|
51
|
-
const fItem = this.vm.refs[ctx.wrapRef]
|
|
52
|
-
if (fItem) {
|
|
53
|
-
fItem.clearValidate()
|
|
54
|
-
}
|
|
55
|
-
},
|
|
56
|
-
tidyOptions(options) {
|
|
57
|
-
;['submitBtn', 'resetBtn', 'row', 'info', 'wrap', 'col', 'title'].forEach(
|
|
58
|
-
(name) => {
|
|
59
|
-
tidyBool(options, name)
|
|
60
|
-
}
|
|
61
|
-
)
|
|
62
|
-
return options
|
|
63
|
-
},
|
|
64
|
-
tidyRule({ prop }) {
|
|
65
|
-
tidy(prop, 'title')
|
|
66
|
-
tidy(prop, 'info')
|
|
67
|
-
return prop
|
|
68
|
-
},
|
|
69
|
-
mergeProp(ctx) {
|
|
70
|
-
const def = {
|
|
71
|
-
info: {
|
|
72
|
-
type: 'popover',
|
|
73
|
-
placement: 'topLeft',
|
|
74
|
-
icon: 'QuestionCircleOutlined'
|
|
75
|
-
},
|
|
76
|
-
title: {},
|
|
77
|
-
col: { span: 24 },
|
|
78
|
-
wrap: {}
|
|
79
|
-
}
|
|
80
|
-
;['info', 'wrap', 'col', 'title'].forEach((name) => {
|
|
81
|
-
ctx.prop[name] = mergeProps(
|
|
82
|
-
[this.options[name] || {}, ctx.prop[name] || {}],
|
|
83
|
-
def[name]
|
|
84
|
-
)
|
|
85
|
-
})
|
|
86
|
-
|
|
87
|
-
// 为 upload 组件自动添加 onPreview,确保始终向父窗口发送预览通知
|
|
88
|
-
if (ctx.rule.type === 'upload' && !ctx.prop.props.onPreview) {
|
|
89
|
-
const sendPreviewMessage = function (file) {
|
|
90
|
-
if (window.parent && window.parent !== window) {
|
|
91
|
-
window.parent.postMessage(
|
|
92
|
-
{
|
|
93
|
-
type: 'upload-preview',
|
|
94
|
-
file: {
|
|
95
|
-
url: file.url,
|
|
96
|
-
name: file.name,
|
|
97
|
-
uid: file.uid,
|
|
98
|
-
size: file.size,
|
|
99
|
-
type: file.type
|
|
100
|
-
},
|
|
101
|
-
timestamp: Date.now()
|
|
102
|
-
},
|
|
103
|
-
'*'
|
|
104
|
-
)
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
ctx.prop.props.onPreview = function (file) {
|
|
108
|
-
sendPreviewMessage(file)
|
|
109
|
-
// 不执行默认预览,只发送消息
|
|
110
|
-
}
|
|
111
|
-
} else if (ctx.rule.type === 'upload' && ctx.prop.props.onPreview) {
|
|
112
|
-
// 如果用户已经设置了 onPreview,包装它以确保先发送消息
|
|
113
|
-
const originalOnPreview = ctx.prop.props.onPreview
|
|
114
|
-
const sendPreviewMessage = function (file) {
|
|
115
|
-
if (window.parent && window.parent !== window) {
|
|
116
|
-
window.parent.postMessage(
|
|
117
|
-
{
|
|
118
|
-
type: 'upload-preview',
|
|
119
|
-
file: {
|
|
120
|
-
url: file.url,
|
|
121
|
-
name: file.name,
|
|
122
|
-
uid: file.uid,
|
|
123
|
-
size: file.size,
|
|
124
|
-
type: file.type
|
|
125
|
-
},
|
|
126
|
-
timestamp: Date.now()
|
|
127
|
-
},
|
|
128
|
-
'*'
|
|
129
|
-
)
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
ctx.prop.props.onPreview = function (file) {
|
|
133
|
-
sendPreviewMessage(file)
|
|
134
|
-
if (originalOnPreview && typeof originalOnPreview === 'function') {
|
|
135
|
-
originalOnPreview.apply(this, arguments)
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
},
|
|
140
|
-
getDefaultOptions() {
|
|
141
|
-
return getConfig()
|
|
142
|
-
},
|
|
143
|
-
adapterValidate(validate, validator) {
|
|
144
|
-
validate.validator = (rule, value) => {
|
|
145
|
-
return new Promise((resolve, reject) => {
|
|
146
|
-
const callback = (err) => {
|
|
147
|
-
if (err) {
|
|
148
|
-
reject(err)
|
|
149
|
-
} else {
|
|
150
|
-
resolve()
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
return validator(value, callback)
|
|
154
|
-
})
|
|
155
|
-
}
|
|
156
|
-
return validate
|
|
157
|
-
},
|
|
158
|
-
update() {
|
|
159
|
-
const form = this.options.form
|
|
160
|
-
this.rule = {
|
|
161
|
-
props: { ...form },
|
|
162
|
-
on: {
|
|
163
|
-
submit: (e) => {
|
|
164
|
-
e.preventDefault()
|
|
165
|
-
}
|
|
166
|
-
},
|
|
167
|
-
style: form.style,
|
|
168
|
-
type: 'form'
|
|
169
|
-
}
|
|
170
|
-
},
|
|
171
|
-
beforeRender() {
|
|
172
|
-
const { key, ref, $handle } = this
|
|
173
|
-
const form = this.options.form
|
|
174
|
-
extend(this.rule, {
|
|
175
|
-
key,
|
|
176
|
-
ref,
|
|
177
|
-
class: [
|
|
178
|
-
form.className,
|
|
179
|
-
form.class,
|
|
180
|
-
'form-create',
|
|
181
|
-
this.$handle.preview ? 'is-preview' : ''
|
|
182
|
-
]
|
|
183
|
-
})
|
|
184
|
-
extend(this.rule.props, {
|
|
185
|
-
model: $handle.formData
|
|
186
|
-
})
|
|
187
|
-
},
|
|
188
|
-
render(children) {
|
|
189
|
-
if (children.slotLen() && !this.$handle.preview) {
|
|
190
|
-
children.setSlot(undefined, () => this.makeFormBtn())
|
|
191
|
-
}
|
|
192
|
-
return this.$r(
|
|
193
|
-
this.rule,
|
|
194
|
-
isFalse(this.options.row.show)
|
|
195
|
-
? children.getSlots()
|
|
196
|
-
: [this.makeRow(children)]
|
|
197
|
-
)
|
|
198
|
-
},
|
|
199
|
-
makeWrap(ctx, children) {
|
|
200
|
-
const rule = ctx.prop
|
|
201
|
-
const uni = `${this.key}${ctx.key}`
|
|
202
|
-
const col = rule.col
|
|
203
|
-
const isTitle = this.isTitle(rule) && rule.wrap.title !== false
|
|
204
|
-
const { layout, col: _col } = this.rule.props
|
|
205
|
-
const cls = rule.wrap.class
|
|
206
|
-
delete rule.wrap.class
|
|
207
|
-
delete rule.wrap.title
|
|
208
|
-
const item = isFalse(rule.wrap.show)
|
|
209
|
-
? children
|
|
210
|
-
: this.$r(
|
|
211
|
-
mergeProps([
|
|
212
|
-
rule.wrap,
|
|
213
|
-
{
|
|
214
|
-
props: {
|
|
215
|
-
...tidyRule(rule.wrap || {}),
|
|
216
|
-
hasFeedback: rule.hasFeedback || false,
|
|
217
|
-
name: ctx.id,
|
|
218
|
-
rules: ctx.injectValidate(),
|
|
219
|
-
...(layout !== 'horizontal'
|
|
220
|
-
? { labelCol: {}, wrapperCol: {} }
|
|
221
|
-
: {})
|
|
222
|
-
},
|
|
223
|
-
class: this.$render.mergeClass(
|
|
224
|
-
cls || rule.className,
|
|
225
|
-
'fc-form-item'
|
|
226
|
-
),
|
|
227
|
-
key: `${uni}fi`,
|
|
228
|
-
ref: ctx.wrapRef,
|
|
229
|
-
type: 'formItem'
|
|
230
|
-
}
|
|
231
|
-
]),
|
|
232
|
-
{
|
|
233
|
-
default: () => children,
|
|
234
|
-
...(isTitle ? { label: () => this.makeInfo(rule, uni, ctx) } : {})
|
|
235
|
-
}
|
|
236
|
-
)
|
|
237
|
-
return layout === 'inline' || isFalse(_col) || isFalse(col.show)
|
|
238
|
-
? item
|
|
239
|
-
: this.makeCol(rule, uni, [item])
|
|
240
|
-
},
|
|
241
|
-
isTitle(rule) {
|
|
242
|
-
if (this.options.form.title === false) return false
|
|
243
|
-
const title = rule.title
|
|
244
|
-
return !((!title.title && !title.native) || isFalse(title.show))
|
|
245
|
-
},
|
|
246
|
-
makeInfo(rule, uni, ctx) {
|
|
247
|
-
const titleProp = { ...rule.title }
|
|
248
|
-
const infoProp = { ...rule.info }
|
|
249
|
-
if (this.options.form.title === false) return false
|
|
250
|
-
if ((!titleProp.title && !titleProp.native) || isFalse(titleProp.show))
|
|
251
|
-
return
|
|
252
|
-
const isTip = isTooltip(infoProp)
|
|
253
|
-
const titleSlot = this.getSlot('title')
|
|
254
|
-
const children = [
|
|
255
|
-
titleSlot
|
|
256
|
-
? titleSlot({
|
|
257
|
-
title: ctx.refRule?.__$title?.value,
|
|
258
|
-
rule: ctx.rule,
|
|
259
|
-
options: this.options
|
|
260
|
-
})
|
|
261
|
-
: ctx.refRule?.__$title?.value
|
|
262
|
-
]
|
|
263
|
-
|
|
264
|
-
if (
|
|
265
|
-
!isFalse(infoProp.show) &&
|
|
266
|
-
(infoProp.info || infoProp.native) &&
|
|
267
|
-
!isFalse(infoProp.icon)
|
|
268
|
-
) {
|
|
269
|
-
const prop = {
|
|
270
|
-
type: infoProp.type || 'popover',
|
|
271
|
-
props: tidyRule(infoProp),
|
|
272
|
-
key: `${uni}pop`
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
delete prop.props.icon
|
|
276
|
-
delete prop.props.show
|
|
277
|
-
delete prop.props.info
|
|
278
|
-
delete prop.props.align
|
|
279
|
-
delete prop.props.native
|
|
280
|
-
|
|
281
|
-
const field = isTip ? 'title' : 'content'
|
|
282
|
-
if (infoProp.info && !hasProperty(prop.props, field)) {
|
|
283
|
-
prop.props[field] = ctx.refRule?.__$info?.value
|
|
284
|
-
}
|
|
285
|
-
children[infoProp.align !== 'left' ? 'unshift' : 'push'](
|
|
286
|
-
this.$r(mergeProps([infoProp, prop]), {
|
|
287
|
-
[titleProp.slot || 'default']: () =>
|
|
288
|
-
this.$r({
|
|
289
|
-
type:
|
|
290
|
-
infoProp.icon === true
|
|
291
|
-
? 'QuestionCircleOutlined'
|
|
292
|
-
: infoProp.icon || '',
|
|
293
|
-
props: {
|
|
294
|
-
type:
|
|
295
|
-
infoProp.icon === true
|
|
296
|
-
? 'QuestionCircleOutlined'
|
|
297
|
-
: infoProp.icon
|
|
298
|
-
},
|
|
299
|
-
key: `${uni}i`
|
|
300
|
-
})
|
|
301
|
-
})
|
|
302
|
-
)
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
const _prop = mergeProps([
|
|
306
|
-
titleProp,
|
|
307
|
-
{
|
|
308
|
-
props: tidyRule(titleProp),
|
|
309
|
-
key: `${uni}tit`,
|
|
310
|
-
class: 'fc-form-title',
|
|
311
|
-
type: titleProp.type || 'span'
|
|
312
|
-
}
|
|
313
|
-
])
|
|
314
|
-
|
|
315
|
-
delete _prop.props.show
|
|
316
|
-
delete _prop.props.title
|
|
317
|
-
delete _prop.props.native
|
|
318
|
-
|
|
319
|
-
return this.$r(_prop, children)
|
|
320
|
-
},
|
|
321
|
-
makeCol(rule, uni, children) {
|
|
322
|
-
const col = rule.col
|
|
323
|
-
return this.$r(
|
|
324
|
-
{
|
|
325
|
-
class: this.$render.mergeClass(col.class, 'fc-form-col'),
|
|
326
|
-
type: 'col',
|
|
327
|
-
props: col || { span: 24 },
|
|
328
|
-
key: `${uni}col`
|
|
329
|
-
},
|
|
330
|
-
children
|
|
331
|
-
)
|
|
332
|
-
},
|
|
333
|
-
makeRow(children) {
|
|
334
|
-
const row = this.options.row || {}
|
|
335
|
-
return this.$r(
|
|
336
|
-
{
|
|
337
|
-
type: 'row',
|
|
338
|
-
props: row,
|
|
339
|
-
class: this.$render.mergeClass(row.class, 'fc-form-row'),
|
|
340
|
-
key: `${this.key}row`
|
|
341
|
-
},
|
|
342
|
-
children
|
|
343
|
-
)
|
|
344
|
-
},
|
|
345
|
-
makeFormBtn() {
|
|
346
|
-
let vn = []
|
|
347
|
-
if (!isFalse(this.options.submitBtn.show)) {
|
|
348
|
-
vn.push(this.makeSubmitBtn())
|
|
349
|
-
}
|
|
350
|
-
if (!isFalse(this.options.resetBtn.show)) {
|
|
351
|
-
vn.push(this.makeResetBtn())
|
|
352
|
-
}
|
|
353
|
-
if (!vn.length) {
|
|
354
|
-
return
|
|
355
|
-
}
|
|
356
|
-
let { labelCol, wrapperCol, layout } = this.rule.props
|
|
357
|
-
if (layout !== 'horizontal') {
|
|
358
|
-
labelCol = wrapperCol = {}
|
|
359
|
-
}
|
|
360
|
-
const item = this.$r(
|
|
361
|
-
{
|
|
362
|
-
type: 'formItem',
|
|
363
|
-
class: 'fc-form-item fc-form-footer',
|
|
364
|
-
key: `${this.key}fb`,
|
|
365
|
-
props: {
|
|
366
|
-
labelCol,
|
|
367
|
-
wrapperCol,
|
|
368
|
-
label: ' ',
|
|
369
|
-
colon: false
|
|
370
|
-
}
|
|
371
|
-
},
|
|
372
|
-
vn
|
|
373
|
-
)
|
|
374
|
-
|
|
375
|
-
return layout === 'inline'
|
|
376
|
-
? item
|
|
377
|
-
: this.$r(
|
|
378
|
-
{
|
|
379
|
-
type: 'col',
|
|
380
|
-
class: 'fc-form-col',
|
|
381
|
-
props: { span: 24 },
|
|
382
|
-
key: `${this.key}fc`
|
|
383
|
-
},
|
|
384
|
-
[item]
|
|
385
|
-
)
|
|
386
|
-
},
|
|
387
|
-
|
|
388
|
-
makeResetBtn() {
|
|
389
|
-
const resetBtn = { ...this.options.resetBtn }
|
|
390
|
-
const innerText =
|
|
391
|
-
resetBtn.innerText || this.$handle.api.t('reset') || '重置'
|
|
392
|
-
delete resetBtn.innerText
|
|
393
|
-
delete resetBtn.click
|
|
394
|
-
delete resetBtn.col
|
|
395
|
-
delete resetBtn.show
|
|
396
|
-
return this.$r(
|
|
397
|
-
{
|
|
398
|
-
type: 'button',
|
|
399
|
-
props: resetBtn,
|
|
400
|
-
class: 'fc-reset-btn',
|
|
401
|
-
style: { width: resetBtn.width, marginLeft: '10px' },
|
|
402
|
-
on: {
|
|
403
|
-
click: () => {
|
|
404
|
-
const fApi = this.$handle.api
|
|
405
|
-
this.options.resetBtn.click
|
|
406
|
-
? this.options.resetBtn.click(fApi)
|
|
407
|
-
: fApi.resetFields()
|
|
408
|
-
}
|
|
409
|
-
},
|
|
410
|
-
key: `${this.key}b2`
|
|
411
|
-
},
|
|
412
|
-
[innerText]
|
|
413
|
-
)
|
|
414
|
-
},
|
|
415
|
-
makeSubmitBtn() {
|
|
416
|
-
const submitBtn = { ...this.options.submitBtn }
|
|
417
|
-
const innerText =
|
|
418
|
-
submitBtn.innerText || this.$handle.api.t('submit') || '提交'
|
|
419
|
-
delete submitBtn.innerText
|
|
420
|
-
delete submitBtn.click
|
|
421
|
-
delete submitBtn.col
|
|
422
|
-
delete submitBtn.show
|
|
423
|
-
return this.$r(
|
|
424
|
-
{
|
|
425
|
-
type: 'button',
|
|
426
|
-
props: submitBtn,
|
|
427
|
-
class: 'fc-submit-btn',
|
|
428
|
-
style: { width: submitBtn.width },
|
|
429
|
-
on: {
|
|
430
|
-
click: () => {
|
|
431
|
-
const fApi = this.$handle.api
|
|
432
|
-
this.options.submitBtn.click
|
|
433
|
-
? this.options.submitBtn.click(fApi)
|
|
434
|
-
: fApi.submit().catch(() => {})
|
|
435
|
-
}
|
|
436
|
-
},
|
|
437
|
-
key: `${this.key}b1`
|
|
438
|
-
},
|
|
439
|
-
[innerText]
|
|
440
|
-
)
|
|
441
|
-
}
|
|
442
|
-
}
|
|
1
|
+
import getConfig from './config'
|
|
2
|
+
import mergeProps from '@form-create/utils/lib/mergeprops'
|
|
3
|
+
import is, { hasProperty } from '@form-create/utils/lib/type'
|
|
4
|
+
import extend from '@form-create/utils/lib/extend'
|
|
5
|
+
|
|
6
|
+
function isTooltip(info) {
|
|
7
|
+
return info.type === 'tooltip'
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function tidy(props, name) {
|
|
11
|
+
if (!hasProperty(props, name)) return
|
|
12
|
+
if (is.String(props[name])) {
|
|
13
|
+
props[name] = { [name]: props[name], show: true }
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function isFalse(val) {
|
|
18
|
+
return val === false
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function tidyBool(opt, name) {
|
|
22
|
+
if (hasProperty(opt, name) && !is.Object(opt[name])) {
|
|
23
|
+
opt[name] = { show: !!opt[name] }
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function tidyRule(rule) {
|
|
28
|
+
const _rule = { ...rule }
|
|
29
|
+
delete _rule.children
|
|
30
|
+
return _rule
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export default {
|
|
34
|
+
validate() {
|
|
35
|
+
const form = this.form()
|
|
36
|
+
if (form) {
|
|
37
|
+
return form.validate()
|
|
38
|
+
} else {
|
|
39
|
+
return new Promise((v) => v())
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
validateField(field) {
|
|
43
|
+
const form = this.form()
|
|
44
|
+
if (form) {
|
|
45
|
+
return form.validateFields(field)
|
|
46
|
+
} else {
|
|
47
|
+
return new Promise((v) => v())
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
clearValidateState(ctx) {
|
|
51
|
+
const fItem = this.vm.refs[ctx.wrapRef]
|
|
52
|
+
if (fItem) {
|
|
53
|
+
fItem.clearValidate()
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
tidyOptions(options) {
|
|
57
|
+
;['submitBtn', 'resetBtn', 'row', 'info', 'wrap', 'col', 'title'].forEach(
|
|
58
|
+
(name) => {
|
|
59
|
+
tidyBool(options, name)
|
|
60
|
+
}
|
|
61
|
+
)
|
|
62
|
+
return options
|
|
63
|
+
},
|
|
64
|
+
tidyRule({ prop }) {
|
|
65
|
+
tidy(prop, 'title')
|
|
66
|
+
tidy(prop, 'info')
|
|
67
|
+
return prop
|
|
68
|
+
},
|
|
69
|
+
mergeProp(ctx) {
|
|
70
|
+
const def = {
|
|
71
|
+
info: {
|
|
72
|
+
type: 'popover',
|
|
73
|
+
placement: 'topLeft',
|
|
74
|
+
icon: 'QuestionCircleOutlined'
|
|
75
|
+
},
|
|
76
|
+
title: {},
|
|
77
|
+
col: { span: 24 },
|
|
78
|
+
wrap: {}
|
|
79
|
+
}
|
|
80
|
+
;['info', 'wrap', 'col', 'title'].forEach((name) => {
|
|
81
|
+
ctx.prop[name] = mergeProps(
|
|
82
|
+
[this.options[name] || {}, ctx.prop[name] || {}],
|
|
83
|
+
def[name]
|
|
84
|
+
)
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
// 为 upload 组件自动添加 onPreview,确保始终向父窗口发送预览通知
|
|
88
|
+
if (ctx.rule.type === 'upload' && !ctx.prop.props.onPreview) {
|
|
89
|
+
const sendPreviewMessage = function (file) {
|
|
90
|
+
if (window.parent && window.parent !== window) {
|
|
91
|
+
window.parent.postMessage(
|
|
92
|
+
{
|
|
93
|
+
type: 'upload-preview',
|
|
94
|
+
file: {
|
|
95
|
+
url: file.url,
|
|
96
|
+
name: file.name,
|
|
97
|
+
uid: file.uid,
|
|
98
|
+
size: file.size,
|
|
99
|
+
type: file.type
|
|
100
|
+
},
|
|
101
|
+
timestamp: Date.now()
|
|
102
|
+
},
|
|
103
|
+
'*'
|
|
104
|
+
)
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
ctx.prop.props.onPreview = function (file) {
|
|
108
|
+
sendPreviewMessage(file)
|
|
109
|
+
// 不执行默认预览,只发送消息
|
|
110
|
+
}
|
|
111
|
+
} else if (ctx.rule.type === 'upload' && ctx.prop.props.onPreview) {
|
|
112
|
+
// 如果用户已经设置了 onPreview,包装它以确保先发送消息
|
|
113
|
+
const originalOnPreview = ctx.prop.props.onPreview
|
|
114
|
+
const sendPreviewMessage = function (file) {
|
|
115
|
+
if (window.parent && window.parent !== window) {
|
|
116
|
+
window.parent.postMessage(
|
|
117
|
+
{
|
|
118
|
+
type: 'upload-preview',
|
|
119
|
+
file: {
|
|
120
|
+
url: file.url,
|
|
121
|
+
name: file.name,
|
|
122
|
+
uid: file.uid,
|
|
123
|
+
size: file.size,
|
|
124
|
+
type: file.type
|
|
125
|
+
},
|
|
126
|
+
timestamp: Date.now()
|
|
127
|
+
},
|
|
128
|
+
'*'
|
|
129
|
+
)
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
ctx.prop.props.onPreview = function (file) {
|
|
133
|
+
sendPreviewMessage(file)
|
|
134
|
+
if (originalOnPreview && typeof originalOnPreview === 'function') {
|
|
135
|
+
originalOnPreview.apply(this, arguments)
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
getDefaultOptions() {
|
|
141
|
+
return getConfig()
|
|
142
|
+
},
|
|
143
|
+
adapterValidate(validate, validator) {
|
|
144
|
+
validate.validator = (rule, value) => {
|
|
145
|
+
return new Promise((resolve, reject) => {
|
|
146
|
+
const callback = (err) => {
|
|
147
|
+
if (err) {
|
|
148
|
+
reject(err)
|
|
149
|
+
} else {
|
|
150
|
+
resolve()
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return validator(value, callback)
|
|
154
|
+
})
|
|
155
|
+
}
|
|
156
|
+
return validate
|
|
157
|
+
},
|
|
158
|
+
update() {
|
|
159
|
+
const form = this.options.form
|
|
160
|
+
this.rule = {
|
|
161
|
+
props: { ...form },
|
|
162
|
+
on: {
|
|
163
|
+
submit: (e) => {
|
|
164
|
+
e.preventDefault()
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
style: form.style,
|
|
168
|
+
type: 'form'
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
beforeRender() {
|
|
172
|
+
const { key, ref, $handle } = this
|
|
173
|
+
const form = this.options.form
|
|
174
|
+
extend(this.rule, {
|
|
175
|
+
key,
|
|
176
|
+
ref,
|
|
177
|
+
class: [
|
|
178
|
+
form.className,
|
|
179
|
+
form.class,
|
|
180
|
+
'form-create',
|
|
181
|
+
this.$handle.preview ? 'is-preview' : ''
|
|
182
|
+
]
|
|
183
|
+
})
|
|
184
|
+
extend(this.rule.props, {
|
|
185
|
+
model: $handle.formData
|
|
186
|
+
})
|
|
187
|
+
},
|
|
188
|
+
render(children) {
|
|
189
|
+
if (children.slotLen() && !this.$handle.preview) {
|
|
190
|
+
children.setSlot(undefined, () => this.makeFormBtn())
|
|
191
|
+
}
|
|
192
|
+
return this.$r(
|
|
193
|
+
this.rule,
|
|
194
|
+
isFalse(this.options.row.show)
|
|
195
|
+
? children.getSlots()
|
|
196
|
+
: [this.makeRow(children)]
|
|
197
|
+
)
|
|
198
|
+
},
|
|
199
|
+
makeWrap(ctx, children) {
|
|
200
|
+
const rule = ctx.prop
|
|
201
|
+
const uni = `${this.key}${ctx.key}`
|
|
202
|
+
const col = rule.col
|
|
203
|
+
const isTitle = this.isTitle(rule) && rule.wrap.title !== false
|
|
204
|
+
const { layout, col: _col } = this.rule.props
|
|
205
|
+
const cls = rule.wrap.class
|
|
206
|
+
delete rule.wrap.class
|
|
207
|
+
delete rule.wrap.title
|
|
208
|
+
const item = isFalse(rule.wrap.show)
|
|
209
|
+
? children
|
|
210
|
+
: this.$r(
|
|
211
|
+
mergeProps([
|
|
212
|
+
rule.wrap,
|
|
213
|
+
{
|
|
214
|
+
props: {
|
|
215
|
+
...tidyRule(rule.wrap || {}),
|
|
216
|
+
hasFeedback: rule.hasFeedback || false,
|
|
217
|
+
name: ctx.id,
|
|
218
|
+
rules: ctx.injectValidate(),
|
|
219
|
+
...(layout !== 'horizontal'
|
|
220
|
+
? { labelCol: {}, wrapperCol: {} }
|
|
221
|
+
: {})
|
|
222
|
+
},
|
|
223
|
+
class: this.$render.mergeClass(
|
|
224
|
+
cls || rule.className,
|
|
225
|
+
'fc-form-item'
|
|
226
|
+
),
|
|
227
|
+
key: `${uni}fi`,
|
|
228
|
+
ref: ctx.wrapRef,
|
|
229
|
+
type: 'formItem'
|
|
230
|
+
}
|
|
231
|
+
]),
|
|
232
|
+
{
|
|
233
|
+
default: () => children,
|
|
234
|
+
...(isTitle ? { label: () => this.makeInfo(rule, uni, ctx) } : {})
|
|
235
|
+
}
|
|
236
|
+
)
|
|
237
|
+
return layout === 'inline' || isFalse(_col) || isFalse(col.show)
|
|
238
|
+
? item
|
|
239
|
+
: this.makeCol(rule, uni, [item])
|
|
240
|
+
},
|
|
241
|
+
isTitle(rule) {
|
|
242
|
+
if (this.options.form.title === false) return false
|
|
243
|
+
const title = rule.title
|
|
244
|
+
return !((!title.title && !title.native) || isFalse(title.show))
|
|
245
|
+
},
|
|
246
|
+
makeInfo(rule, uni, ctx) {
|
|
247
|
+
const titleProp = { ...rule.title }
|
|
248
|
+
const infoProp = { ...rule.info }
|
|
249
|
+
if (this.options.form.title === false) return false
|
|
250
|
+
if ((!titleProp.title && !titleProp.native) || isFalse(titleProp.show))
|
|
251
|
+
return
|
|
252
|
+
const isTip = isTooltip(infoProp)
|
|
253
|
+
const titleSlot = this.getSlot('title')
|
|
254
|
+
const children = [
|
|
255
|
+
titleSlot
|
|
256
|
+
? titleSlot({
|
|
257
|
+
title: ctx.refRule?.__$title?.value,
|
|
258
|
+
rule: ctx.rule,
|
|
259
|
+
options: this.options
|
|
260
|
+
})
|
|
261
|
+
: ctx.refRule?.__$title?.value
|
|
262
|
+
]
|
|
263
|
+
|
|
264
|
+
if (
|
|
265
|
+
!isFalse(infoProp.show) &&
|
|
266
|
+
(infoProp.info || infoProp.native) &&
|
|
267
|
+
!isFalse(infoProp.icon)
|
|
268
|
+
) {
|
|
269
|
+
const prop = {
|
|
270
|
+
type: infoProp.type || 'popover',
|
|
271
|
+
props: tidyRule(infoProp),
|
|
272
|
+
key: `${uni}pop`
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
delete prop.props.icon
|
|
276
|
+
delete prop.props.show
|
|
277
|
+
delete prop.props.info
|
|
278
|
+
delete prop.props.align
|
|
279
|
+
delete prop.props.native
|
|
280
|
+
|
|
281
|
+
const field = isTip ? 'title' : 'content'
|
|
282
|
+
if (infoProp.info && !hasProperty(prop.props, field)) {
|
|
283
|
+
prop.props[field] = ctx.refRule?.__$info?.value
|
|
284
|
+
}
|
|
285
|
+
children[infoProp.align !== 'left' ? 'unshift' : 'push'](
|
|
286
|
+
this.$r(mergeProps([infoProp, prop]), {
|
|
287
|
+
[titleProp.slot || 'default']: () =>
|
|
288
|
+
this.$r({
|
|
289
|
+
type:
|
|
290
|
+
infoProp.icon === true
|
|
291
|
+
? 'QuestionCircleOutlined'
|
|
292
|
+
: infoProp.icon || '',
|
|
293
|
+
props: {
|
|
294
|
+
type:
|
|
295
|
+
infoProp.icon === true
|
|
296
|
+
? 'QuestionCircleOutlined'
|
|
297
|
+
: infoProp.icon
|
|
298
|
+
},
|
|
299
|
+
key: `${uni}i`
|
|
300
|
+
})
|
|
301
|
+
})
|
|
302
|
+
)
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
const _prop = mergeProps([
|
|
306
|
+
titleProp,
|
|
307
|
+
{
|
|
308
|
+
props: tidyRule(titleProp),
|
|
309
|
+
key: `${uni}tit`,
|
|
310
|
+
class: 'fc-form-title',
|
|
311
|
+
type: titleProp.type || 'span'
|
|
312
|
+
}
|
|
313
|
+
])
|
|
314
|
+
|
|
315
|
+
delete _prop.props.show
|
|
316
|
+
delete _prop.props.title
|
|
317
|
+
delete _prop.props.native
|
|
318
|
+
|
|
319
|
+
return this.$r(_prop, children)
|
|
320
|
+
},
|
|
321
|
+
makeCol(rule, uni, children) {
|
|
322
|
+
const col = rule.col
|
|
323
|
+
return this.$r(
|
|
324
|
+
{
|
|
325
|
+
class: this.$render.mergeClass(col.class, 'fc-form-col'),
|
|
326
|
+
type: 'col',
|
|
327
|
+
props: col || { span: 24 },
|
|
328
|
+
key: `${uni}col`
|
|
329
|
+
},
|
|
330
|
+
children
|
|
331
|
+
)
|
|
332
|
+
},
|
|
333
|
+
makeRow(children) {
|
|
334
|
+
const row = this.options.row || {}
|
|
335
|
+
return this.$r(
|
|
336
|
+
{
|
|
337
|
+
type: 'row',
|
|
338
|
+
props: row,
|
|
339
|
+
class: this.$render.mergeClass(row.class, 'fc-form-row'),
|
|
340
|
+
key: `${this.key}row`
|
|
341
|
+
},
|
|
342
|
+
children
|
|
343
|
+
)
|
|
344
|
+
},
|
|
345
|
+
makeFormBtn() {
|
|
346
|
+
let vn = []
|
|
347
|
+
if (!isFalse(this.options.submitBtn.show)) {
|
|
348
|
+
vn.push(this.makeSubmitBtn())
|
|
349
|
+
}
|
|
350
|
+
if (!isFalse(this.options.resetBtn.show)) {
|
|
351
|
+
vn.push(this.makeResetBtn())
|
|
352
|
+
}
|
|
353
|
+
if (!vn.length) {
|
|
354
|
+
return
|
|
355
|
+
}
|
|
356
|
+
let { labelCol, wrapperCol, layout } = this.rule.props
|
|
357
|
+
if (layout !== 'horizontal') {
|
|
358
|
+
labelCol = wrapperCol = {}
|
|
359
|
+
}
|
|
360
|
+
const item = this.$r(
|
|
361
|
+
{
|
|
362
|
+
type: 'formItem',
|
|
363
|
+
class: 'fc-form-item fc-form-footer',
|
|
364
|
+
key: `${this.key}fb`,
|
|
365
|
+
props: {
|
|
366
|
+
labelCol,
|
|
367
|
+
wrapperCol,
|
|
368
|
+
label: ' ',
|
|
369
|
+
colon: false
|
|
370
|
+
}
|
|
371
|
+
},
|
|
372
|
+
vn
|
|
373
|
+
)
|
|
374
|
+
|
|
375
|
+
return layout === 'inline'
|
|
376
|
+
? item
|
|
377
|
+
: this.$r(
|
|
378
|
+
{
|
|
379
|
+
type: 'col',
|
|
380
|
+
class: 'fc-form-col',
|
|
381
|
+
props: { span: 24 },
|
|
382
|
+
key: `${this.key}fc`
|
|
383
|
+
},
|
|
384
|
+
[item]
|
|
385
|
+
)
|
|
386
|
+
},
|
|
387
|
+
|
|
388
|
+
makeResetBtn() {
|
|
389
|
+
const resetBtn = { ...this.options.resetBtn }
|
|
390
|
+
const innerText =
|
|
391
|
+
resetBtn.innerText || this.$handle.api.t('reset') || '重置'
|
|
392
|
+
delete resetBtn.innerText
|
|
393
|
+
delete resetBtn.click
|
|
394
|
+
delete resetBtn.col
|
|
395
|
+
delete resetBtn.show
|
|
396
|
+
return this.$r(
|
|
397
|
+
{
|
|
398
|
+
type: 'button',
|
|
399
|
+
props: resetBtn,
|
|
400
|
+
class: 'fc-reset-btn',
|
|
401
|
+
style: { width: resetBtn.width, marginLeft: '10px' },
|
|
402
|
+
on: {
|
|
403
|
+
click: () => {
|
|
404
|
+
const fApi = this.$handle.api
|
|
405
|
+
this.options.resetBtn.click
|
|
406
|
+
? this.options.resetBtn.click(fApi)
|
|
407
|
+
: fApi.resetFields()
|
|
408
|
+
}
|
|
409
|
+
},
|
|
410
|
+
key: `${this.key}b2`
|
|
411
|
+
},
|
|
412
|
+
[innerText]
|
|
413
|
+
)
|
|
414
|
+
},
|
|
415
|
+
makeSubmitBtn() {
|
|
416
|
+
const submitBtn = { ...this.options.submitBtn }
|
|
417
|
+
const innerText =
|
|
418
|
+
submitBtn.innerText || this.$handle.api.t('submit') || '提交'
|
|
419
|
+
delete submitBtn.innerText
|
|
420
|
+
delete submitBtn.click
|
|
421
|
+
delete submitBtn.col
|
|
422
|
+
delete submitBtn.show
|
|
423
|
+
return this.$r(
|
|
424
|
+
{
|
|
425
|
+
type: 'button',
|
|
426
|
+
props: submitBtn,
|
|
427
|
+
class: 'fc-submit-btn',
|
|
428
|
+
style: { width: submitBtn.width },
|
|
429
|
+
on: {
|
|
430
|
+
click: () => {
|
|
431
|
+
const fApi = this.$handle.api
|
|
432
|
+
this.options.submitBtn.click
|
|
433
|
+
? this.options.submitBtn.click(fApi)
|
|
434
|
+
: fApi.submit().catch(() => {})
|
|
435
|
+
}
|
|
436
|
+
},
|
|
437
|
+
key: `${this.key}b1`
|
|
438
|
+
},
|
|
439
|
+
[innerText]
|
|
440
|
+
)
|
|
441
|
+
}
|
|
442
|
+
}
|