sh-view 1.7.5 → 1.7.6
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/packages/components/global-components/{sh-layout → sh-split}/index.vue +1 -1
- package/packages/components/global-components/sh-upload/index.vue +182 -325
- package/packages/components/global-components/sh-upload/js/ajax.js +80 -0
- package/packages/components/global-components/sh-upload/js/mixin.js +257 -0
- package/packages/components/global-components/sh-vxe-form/js/methods.js +28 -41
- package/packages/components/global-components/sh-vxe-list/index.vue +25 -5
- package/packages/components/global-components/sh-vxe-query/index.vue +56 -32
- package/packages/components/global-components/sh-vxe-table/js/methods.js +81 -88
- package/packages/components/global-components/sh-vxe-toolbar/index.vue +3 -3
- package/packages/vxeTable/index.js +5 -6
- package/packages/components/global-components/sh-upload/components/u-img.vue +0 -63
- package/packages/components/global-components/sh-upload/components/u-list.vue +0 -100
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
// 上传组件通用方法
|
|
2
|
+
|
|
3
|
+
import ajax from './ajax'
|
|
4
|
+
|
|
5
|
+
export default {
|
|
6
|
+
props: {
|
|
7
|
+
modelValue: {
|
|
8
|
+
type: Array,
|
|
9
|
+
default() {
|
|
10
|
+
return []
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
action: {
|
|
14
|
+
type: String,
|
|
15
|
+
default: 'fileservice/v2/upload'
|
|
16
|
+
},
|
|
17
|
+
headers: {
|
|
18
|
+
type: Object,
|
|
19
|
+
default() {
|
|
20
|
+
return {}
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
disabled: {
|
|
24
|
+
type: Boolean,
|
|
25
|
+
default: false
|
|
26
|
+
},
|
|
27
|
+
maxSize: {
|
|
28
|
+
type: Number,
|
|
29
|
+
default: 1024 * 2 // 文件大小限制,单位 kb
|
|
30
|
+
},
|
|
31
|
+
accept: {
|
|
32
|
+
type: String,
|
|
33
|
+
default: '.doc,.docx,.xls,.xlsx,.txt,.pdf,.jpg,.jpeg,.png,.txt,.7z,.zip,.rar'
|
|
34
|
+
},
|
|
35
|
+
name: {
|
|
36
|
+
type: String,
|
|
37
|
+
default: 'file'
|
|
38
|
+
},
|
|
39
|
+
beforeUpload: {
|
|
40
|
+
type: Function
|
|
41
|
+
},
|
|
42
|
+
webkitdirectory: {
|
|
43
|
+
type: Boolean,
|
|
44
|
+
default: false // 是否开启选择文件夹,部分浏览器适用
|
|
45
|
+
},
|
|
46
|
+
withCredentials: {
|
|
47
|
+
type: Boolean,
|
|
48
|
+
default: false // 支持发送 cookie 凭证信息
|
|
49
|
+
},
|
|
50
|
+
paste: {
|
|
51
|
+
type: Boolean,
|
|
52
|
+
default: false // 是否支持粘贴上传文件
|
|
53
|
+
},
|
|
54
|
+
format: {
|
|
55
|
+
type: Array,
|
|
56
|
+
default() {
|
|
57
|
+
return []
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
onFormatError: {
|
|
61
|
+
type: Function
|
|
62
|
+
},
|
|
63
|
+
onExceededSize: {
|
|
64
|
+
type: Function
|
|
65
|
+
},
|
|
66
|
+
onProgress: {
|
|
67
|
+
type: Function,
|
|
68
|
+
default() {}
|
|
69
|
+
},
|
|
70
|
+
onSuccess: {
|
|
71
|
+
type: Function,
|
|
72
|
+
default() {}
|
|
73
|
+
},
|
|
74
|
+
onError: {
|
|
75
|
+
type: Function,
|
|
76
|
+
default() {}
|
|
77
|
+
},
|
|
78
|
+
onRemove: {
|
|
79
|
+
type: Function,
|
|
80
|
+
default() {}
|
|
81
|
+
},
|
|
82
|
+
onPreview: {
|
|
83
|
+
type: Function,
|
|
84
|
+
default() {}
|
|
85
|
+
},
|
|
86
|
+
onDownload: {
|
|
87
|
+
type: Function,
|
|
88
|
+
default() {}
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
data() {
|
|
92
|
+
return {
|
|
93
|
+
tempIndex: 1,
|
|
94
|
+
dragOver: false,
|
|
95
|
+
fileList: []
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
methods: {
|
|
99
|
+
progressConfig(file) {
|
|
100
|
+
return {
|
|
101
|
+
textInside: true,
|
|
102
|
+
strokeWidth: 20,
|
|
103
|
+
percent: parseInt(file.percentage, 10),
|
|
104
|
+
status: file.status
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
handleClick() {
|
|
108
|
+
if (this.disabled) return
|
|
109
|
+
this.$refs.input.click()
|
|
110
|
+
},
|
|
111
|
+
handleChange(e) {
|
|
112
|
+
const files = e.target.files
|
|
113
|
+
if (!files) return
|
|
114
|
+
this.uploadFiles(files)
|
|
115
|
+
this.$refs.input.value = null
|
|
116
|
+
},
|
|
117
|
+
handleStart(file) {
|
|
118
|
+
file.uid = Date.now() + this.tempIndex++
|
|
119
|
+
const _file = {
|
|
120
|
+
status: 'active',
|
|
121
|
+
name: file.name,
|
|
122
|
+
size: file.size,
|
|
123
|
+
percentage: 0,
|
|
124
|
+
uid: file.uid,
|
|
125
|
+
showProgress: true
|
|
126
|
+
}
|
|
127
|
+
this.fileList.push(_file)
|
|
128
|
+
},
|
|
129
|
+
handlePaste(e) {
|
|
130
|
+
if (this.disabled) return
|
|
131
|
+
if (this.paste) {
|
|
132
|
+
this.uploadFiles(e.clipboardData.files)
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
handleProgress(e, file) {
|
|
136
|
+
const _file = this.getFile(file)
|
|
137
|
+
this.onProgress(e, _file, this.fileList)
|
|
138
|
+
_file.percentage = e.percent || 0
|
|
139
|
+
},
|
|
140
|
+
handleSuccess(res, file) {
|
|
141
|
+
const _file = this.getFile(file)
|
|
142
|
+
if (_file) {
|
|
143
|
+
_file.status = 'success'
|
|
144
|
+
_file.response = res
|
|
145
|
+
this.emitValue()
|
|
146
|
+
this.onSuccess(res, _file, this.fileList)
|
|
147
|
+
setTimeout(() => {
|
|
148
|
+
_file.showProgress = false
|
|
149
|
+
}, 1000)
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
handleError(err, response, file) {
|
|
153
|
+
const _file = this.getFile(file)
|
|
154
|
+
const fileList = this.fileList
|
|
155
|
+
_file.status = 'wrong'
|
|
156
|
+
fileList.splice(fileList.indexOf(_file), 1)
|
|
157
|
+
this.onError(err, response, file)
|
|
158
|
+
},
|
|
159
|
+
handleRemove(file) {
|
|
160
|
+
const fileList = this.fileList
|
|
161
|
+
fileList.splice(fileList.indexOf(file), 1)
|
|
162
|
+
this.emitValue()
|
|
163
|
+
this.onRemove(file, fileList)
|
|
164
|
+
},
|
|
165
|
+
handlePreview(file) {
|
|
166
|
+
const fileList = this.fileList
|
|
167
|
+
fileList.splice(fileList.indexOf(file), 1)
|
|
168
|
+
this.onRemove(file, fileList)
|
|
169
|
+
},
|
|
170
|
+
handleDownload(file) {
|
|
171
|
+
const fileList = this.fileList
|
|
172
|
+
fileList.splice(fileList.indexOf(file), 1)
|
|
173
|
+
this.onDownload(file, fileList)
|
|
174
|
+
},
|
|
175
|
+
onDrop(e) {
|
|
176
|
+
this.dragOver = false
|
|
177
|
+
if (this.disabled) return
|
|
178
|
+
this.uploadFiles(e.dataTransfer.files)
|
|
179
|
+
},
|
|
180
|
+
uploadFiles(files) {
|
|
181
|
+
let postFiles = Array.prototype.slice.call(files)
|
|
182
|
+
if (!this.multiple) postFiles = postFiles.slice(0, 1)
|
|
183
|
+
if (postFiles.length === 0) return
|
|
184
|
+
postFiles.forEach(file => {
|
|
185
|
+
this.upload(file)
|
|
186
|
+
})
|
|
187
|
+
},
|
|
188
|
+
upload(file) {
|
|
189
|
+
if (!this.beforeUpload) {
|
|
190
|
+
return this.post(file)
|
|
191
|
+
}
|
|
192
|
+
const before = this.beforeUpload(file)
|
|
193
|
+
if (before && before.then) {
|
|
194
|
+
before.then(processedFile => {
|
|
195
|
+
if (Object.prototype.toString.call(processedFile) === '[object File]') {
|
|
196
|
+
this.post(processedFile)
|
|
197
|
+
} else {
|
|
198
|
+
this.post(file)
|
|
199
|
+
}
|
|
200
|
+
})
|
|
201
|
+
} else if (before !== false) {
|
|
202
|
+
this.post(file)
|
|
203
|
+
}
|
|
204
|
+
},
|
|
205
|
+
async post(file) {
|
|
206
|
+
let { headers, name, params, action, withCredentials } = this
|
|
207
|
+
if (this.validateFile) {
|
|
208
|
+
let valResult = this.validateFile(file)
|
|
209
|
+
if (!valResult) return
|
|
210
|
+
}
|
|
211
|
+
this.handleStart(file)
|
|
212
|
+
ajax({
|
|
213
|
+
headers: headers,
|
|
214
|
+
withCredentials: withCredentials,
|
|
215
|
+
file: file,
|
|
216
|
+
data: params,
|
|
217
|
+
filename: name,
|
|
218
|
+
action: action,
|
|
219
|
+
onProgress: e => {
|
|
220
|
+
this.handleProgress(e, file)
|
|
221
|
+
},
|
|
222
|
+
onSuccess: res => {
|
|
223
|
+
this.handleSuccess(res, file)
|
|
224
|
+
},
|
|
225
|
+
onError: (err, response) => {
|
|
226
|
+
this.handleError(err, response, file)
|
|
227
|
+
}
|
|
228
|
+
})
|
|
229
|
+
},
|
|
230
|
+
getFile(file) {
|
|
231
|
+
const fileList = this.fileList
|
|
232
|
+
let target
|
|
233
|
+
fileList.every(item => {
|
|
234
|
+
target = file.uid === item.uid ? item : null
|
|
235
|
+
return !target
|
|
236
|
+
})
|
|
237
|
+
return target
|
|
238
|
+
},
|
|
239
|
+
clearFiles() {
|
|
240
|
+
this.fileList = []
|
|
241
|
+
this.emitValue()
|
|
242
|
+
},
|
|
243
|
+
emitValue() {
|
|
244
|
+
let list = this.getModelValue ? this.getModelValue() : this.fileList
|
|
245
|
+
this.$emit('update:modelValue', list)
|
|
246
|
+
}
|
|
247
|
+
},
|
|
248
|
+
watch: {
|
|
249
|
+
modelValue: {
|
|
250
|
+
handler(fileList) {
|
|
251
|
+
this.fileList = fileList
|
|
252
|
+
},
|
|
253
|
+
immediate: true,
|
|
254
|
+
deep: true
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
@@ -51,38 +51,34 @@ const shMethods = {
|
|
|
51
51
|
// 初始化
|
|
52
52
|
initCreated() {
|
|
53
53
|
this.initFormItems()
|
|
54
|
-
this.initFormData()
|
|
55
54
|
},
|
|
56
55
|
// 初始化表单字段
|
|
57
56
|
initFormData() {
|
|
58
|
-
const
|
|
59
|
-
|
|
57
|
+
const { items, data, $vUtils } = this
|
|
58
|
+
$vUtils.eachTree(items, item => {
|
|
60
59
|
let renderProps = item.renderProps || item.itemRender?.props || {}
|
|
61
|
-
if (
|
|
62
|
-
|
|
60
|
+
if (!$vUtils.isNone(renderProps?.defaultValue) && $vUtils.isNone($vUtils.get(data, item.field))) {
|
|
61
|
+
$vUtils.set(data, item.field, renderProps.defaultValue)
|
|
63
62
|
}
|
|
64
63
|
})
|
|
65
64
|
},
|
|
66
65
|
// 初始化表单项
|
|
67
66
|
initFormItems(items) {
|
|
68
|
-
|
|
69
|
-
let
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
that.generateFormItem(originItems, formItemsArr, rules)
|
|
73
|
-
that.initEditRules(rules)
|
|
74
|
-
that.formItems = formItemsArr
|
|
67
|
+
let originItems = items || this.items
|
|
68
|
+
let { formItemsArr, rules } = this.generateFormItem(originItems)
|
|
69
|
+
this.initEditRules(rules)
|
|
70
|
+
this.formItems = formItemsArr
|
|
75
71
|
this.initFormData()
|
|
76
72
|
},
|
|
77
73
|
// 初始化验证规则
|
|
78
74
|
initEditRules(rules) {
|
|
79
|
-
const
|
|
80
|
-
if (rules &&
|
|
75
|
+
const { formRules, $vUtils } = this
|
|
76
|
+
if (rules && $vUtils.isPlainObject(rules)) {
|
|
81
77
|
Object.keys(rules).forEach(key => {
|
|
82
|
-
if (
|
|
83
|
-
|
|
78
|
+
if (formRules[key]) {
|
|
79
|
+
formRules[key] = Array.from(new Set(formRules[key].concat(rules[key])))
|
|
84
80
|
} else {
|
|
85
|
-
|
|
81
|
+
formRules[key] = rules[key]
|
|
86
82
|
}
|
|
87
83
|
})
|
|
88
84
|
}
|
|
@@ -102,64 +98,55 @@ const shMethods = {
|
|
|
102
98
|
isTrue(value) {
|
|
103
99
|
return String(value) === '1' || String(value).toLowerCase() === 'true'
|
|
104
100
|
},
|
|
105
|
-
// 生成全表头
|
|
106
|
-
generateColumnsAll(columns, resultColumns = []) {
|
|
107
|
-
columns.forEach((column, index) => {
|
|
108
|
-
if (column.children && Array.isArray(column.children) && column.children.length) {
|
|
109
|
-
this.generateColumnsAll(column.children, resultColumns)
|
|
110
|
-
} else {
|
|
111
|
-
resultColumns.push(column)
|
|
112
|
-
}
|
|
113
|
-
})
|
|
114
|
-
return resultColumns
|
|
115
|
-
},
|
|
116
101
|
// 自动生成表单渲染项
|
|
117
|
-
generateFormItem(
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
102
|
+
generateFormItem(items = []) {
|
|
103
|
+
const { itemConfigDefault, isItemTitle, titleConfigDefault, readonly, disabled, isTrue, getDefaultMessage, $vUtils } = this
|
|
104
|
+
let formItemsArr = []
|
|
105
|
+
let rules = {}
|
|
106
|
+
$vUtils.eachTree(items, ori => {
|
|
107
|
+
let tar = Object.assign({}, itemConfigDefault, ori)
|
|
121
108
|
if (ori.children && ori.children.length > 0) {
|
|
122
109
|
let childrenArr = []
|
|
123
|
-
|
|
124
|
-
if (that.isItemTitle) {
|
|
110
|
+
if (isItemTitle) {
|
|
125
111
|
// 补入标题渲染器
|
|
126
|
-
let groupTitleRender = Object.assign({},
|
|
112
|
+
let groupTitleRender = Object.assign({}, titleConfigDefault, tar, { span: 24, field: '' })
|
|
127
113
|
delete groupTitleRender.children
|
|
128
114
|
childrenArr.unshift(groupTitleRender)
|
|
129
115
|
}
|
|
130
116
|
tar.children = childrenArr
|
|
131
117
|
if (!tar.span) tar.span = 24
|
|
132
|
-
|
|
118
|
+
formItemsArr.push(tar)
|
|
133
119
|
} else {
|
|
134
120
|
let renderConfig = {
|
|
135
121
|
name: ori.renderName || '$vInput',
|
|
136
122
|
props: Object.assign({}, ori.renderProps || {})
|
|
137
123
|
}
|
|
138
|
-
if (
|
|
124
|
+
if (readonly || disabled) {
|
|
139
125
|
renderConfig.props.disabled = true
|
|
140
126
|
}
|
|
141
127
|
tar.itemRender = Object.assign({}, renderConfig, ori.itemRender || {})
|
|
142
128
|
// 首先提取校验配置
|
|
143
|
-
if (
|
|
129
|
+
if (isTrue(ori['renderRequire'])) {
|
|
144
130
|
// 若配置了校验参数则走校验参数,没配置则给默认校验条件
|
|
145
131
|
if (ori['requireProps'] && Array.isArray(ori['requireProps']) && ori['requireProps'].length > 0) {
|
|
146
132
|
rules[ori['field']] = ori['requireProps']
|
|
147
133
|
} else {
|
|
148
134
|
let dataType = 'string'
|
|
149
135
|
let arrayType = ['$vCheckgroup', '$vUpload', '$vTable']
|
|
150
|
-
if (arrayType.includes(ori['renderName']) || ((ori['renderName'] === '$vSelect' || ori['renderName'] === '$vTree') &&
|
|
136
|
+
if (arrayType.includes(ori['renderName']) || ((ori['renderName'] === '$vSelect' || ori['renderName'] === '$vTree') && isTrue(renderConfig.props.multiple))) {
|
|
151
137
|
dataType = 'array'
|
|
152
138
|
}
|
|
153
|
-
rules[ori['field']] = [{ required: true, message:
|
|
139
|
+
rules[ori['field']] = [{ required: true, message: getDefaultMessage(ori['renderName'], ori['title']), type: dataType }]
|
|
154
140
|
}
|
|
155
141
|
}
|
|
156
142
|
// 表单不支持编辑渲染过滤
|
|
157
143
|
let notRenderName = ['seq', 'checkbox', 'radio', '$vImg', '$vHref', '$vGlobalOption']
|
|
158
144
|
if (!((ori.renderName && notRenderName.includes(ori.renderName)) || notRenderName.includes(ori.type))) {
|
|
159
|
-
|
|
145
|
+
formItemsArr.push(tar)
|
|
160
146
|
}
|
|
161
147
|
}
|
|
162
148
|
})
|
|
149
|
+
return { formItemsArr, rules }
|
|
163
150
|
}
|
|
164
151
|
}
|
|
165
152
|
|
|
@@ -1,16 +1,23 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="sh-list">
|
|
3
3
|
<template v-if="$slots.header"><slot name="header"></slot></template>
|
|
4
|
-
<vxe-list ref="vxeList"
|
|
4
|
+
<vxe-list ref="vxeList" v-bind="listConfig">
|
|
5
5
|
<template #default="{ items }">
|
|
6
6
|
<sh-empty v-if="items.length === 0 && !loading" :no-data-icon="noDataIcon" :no-data-text="noDataText"></sh-empty>
|
|
7
|
-
<Row :gutter="grid.gutter">
|
|
7
|
+
<Row v-if="grid" :gutter="grid.gutter">
|
|
8
8
|
<Col v-for="(item, itemindex) in items" :key="itemindex" v-bind="grid">
|
|
9
9
|
<div class="sh-list-item" :class="itemClassName">
|
|
10
|
-
<slot name="item"
|
|
10
|
+
<slot name="item" v-bind="item"></slot>
|
|
11
11
|
</div>
|
|
12
12
|
</Col>
|
|
13
13
|
</Row>
|
|
14
|
+
<template v-else>
|
|
15
|
+
<template v-for="(item, itemindex) in items" :key="itemindex">
|
|
16
|
+
<div class="sh-list-item" :class="itemClassName">
|
|
17
|
+
<slot name="item" v-bind="item"></slot>
|
|
18
|
+
</div>
|
|
19
|
+
</template>
|
|
20
|
+
</template>
|
|
14
21
|
</template>
|
|
15
22
|
</vxe-list>
|
|
16
23
|
<template v-if="$slots.footer"><slot name="footer"></slot></template>
|
|
@@ -67,7 +74,7 @@ export default {
|
|
|
67
74
|
type: String
|
|
68
75
|
},
|
|
69
76
|
grid: {
|
|
70
|
-
type: Object,
|
|
77
|
+
type: [Object, Boolean],
|
|
71
78
|
default() {
|
|
72
79
|
return { gutter: 0, span: 24 }
|
|
73
80
|
}
|
|
@@ -84,7 +91,20 @@ export default {
|
|
|
84
91
|
listPagerConfig: {}
|
|
85
92
|
}
|
|
86
93
|
},
|
|
87
|
-
computed: {
|
|
94
|
+
computed: {
|
|
95
|
+
listConfig() {
|
|
96
|
+
return {
|
|
97
|
+
data: this.dataSourse,
|
|
98
|
+
size: this.size,
|
|
99
|
+
className: this.className,
|
|
100
|
+
loading: this.loading,
|
|
101
|
+
height: this.height,
|
|
102
|
+
autoResize: this.autoResize,
|
|
103
|
+
syncResize: this.syncResize,
|
|
104
|
+
scrollY: this.scrollY
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
},
|
|
88
108
|
watch: {
|
|
89
109
|
pagerConfig: {
|
|
90
110
|
handler(newvalue, oldValue) {
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
v-bind="queryFormConfig"
|
|
8
8
|
:items="formItems"
|
|
9
9
|
:data="data"
|
|
10
|
-
:rules="
|
|
10
|
+
:rules="valid ? formRules : {}"
|
|
11
11
|
:valid-config="validConfig"
|
|
12
12
|
@submit="onFormSubmit"
|
|
13
13
|
@reset="onFormReset"
|
|
@@ -88,6 +88,9 @@ export default {
|
|
|
88
88
|
transformitem: {
|
|
89
89
|
type: Boolean,
|
|
90
90
|
default: true
|
|
91
|
+
},
|
|
92
|
+
valid: {
|
|
93
|
+
type: Boolean
|
|
91
94
|
}
|
|
92
95
|
},
|
|
93
96
|
emits: ['submit', 'reset', 'edit-closed', 'submit-invalid', 'collapsed'],
|
|
@@ -103,6 +106,8 @@ export default {
|
|
|
103
106
|
formOriginItems: [],
|
|
104
107
|
// 表单渲染项
|
|
105
108
|
formItems: [],
|
|
109
|
+
// 表单校验规则
|
|
110
|
+
formRules: {},
|
|
106
111
|
// 表格高级搜索默认配置
|
|
107
112
|
formConfigDefault: {
|
|
108
113
|
titleWidth: 100,
|
|
@@ -138,6 +143,13 @@ export default {
|
|
|
138
143
|
},
|
|
139
144
|
deep: true,
|
|
140
145
|
immediate: false
|
|
146
|
+
},
|
|
147
|
+
rules: {
|
|
148
|
+
handler(newvalue, oldValue) {
|
|
149
|
+
this.initEditRules(newvalue)
|
|
150
|
+
},
|
|
151
|
+
deep: true,
|
|
152
|
+
immediate: true
|
|
141
153
|
}
|
|
142
154
|
},
|
|
143
155
|
created() {
|
|
@@ -153,54 +165,66 @@ export default {
|
|
|
153
165
|
},
|
|
154
166
|
// 初始化表单字段
|
|
155
167
|
initFormData() {
|
|
156
|
-
const
|
|
157
|
-
let
|
|
158
|
-
|
|
168
|
+
const { items, data, $vUtils } = this
|
|
169
|
+
let queryItems = items.filter(item => item.search && item.search !== '0')
|
|
170
|
+
$vUtils.eachTree(queryItems, item => {
|
|
159
171
|
let renderProps = item.renderProps || item.itemRender?.props || {}
|
|
160
|
-
if (
|
|
161
|
-
|
|
172
|
+
if (!$vUtils.isNone(renderProps?.defaultValue) && $vUtils.isNone($vUtils.get(data, item.field))) {
|
|
173
|
+
$vUtils.set(data, item.field, renderProps.defaultValue)
|
|
162
174
|
}
|
|
163
175
|
})
|
|
164
176
|
},
|
|
165
177
|
// 初始化搜索表单
|
|
166
178
|
initFormItems() {
|
|
167
|
-
const that = this
|
|
168
179
|
let formItemsArr = [] // 表单项
|
|
169
|
-
let formItems =
|
|
180
|
+
let formItems = this.items.filter(item => item.search && item.search !== '0')
|
|
170
181
|
if (this.transformitem) {
|
|
171
|
-
let { itemsArr,
|
|
182
|
+
let { itemsArr, rules } = this.generateFormItem(formItems)
|
|
172
183
|
formItemsArr = itemsArr
|
|
184
|
+
this.initEditRules(rules)
|
|
173
185
|
} else {
|
|
174
186
|
formItemsArr = formItems
|
|
187
|
+
this.initEditRules(this.rules)
|
|
175
188
|
}
|
|
176
189
|
formItemsArr.forEach(item => {
|
|
177
190
|
item.visible = true
|
|
178
191
|
item.itemRender.props.disabled = false
|
|
179
192
|
})
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
if (formItemsArr.length >
|
|
183
|
-
|
|
184
|
-
|
|
193
|
+
this.formOriginItems = formItemsArr
|
|
194
|
+
this.formItems = formItemsArr
|
|
195
|
+
if (formItemsArr.length > this.globalConfig.formToggleNum && this.globalConfig.formToggle) {
|
|
196
|
+
this.formToggleBtnShow = true // 显示展开全部按钮
|
|
197
|
+
this.formBtnCollapsed(false)
|
|
185
198
|
}
|
|
186
199
|
this.initFormData()
|
|
187
200
|
},
|
|
201
|
+
// 初始化验证规则
|
|
202
|
+
initEditRules(rules) {
|
|
203
|
+
const { formRules, $vUtils } = this
|
|
204
|
+
if (rules && $vUtils.isPlainObject(rules)) {
|
|
205
|
+
Object.keys(rules).forEach(key => {
|
|
206
|
+
if (formRules[key]) {
|
|
207
|
+
formRules[key] = Array.from(new Set(formRules[key].concat(rules[key])))
|
|
208
|
+
} else {
|
|
209
|
+
formRules[key] = rules[key]
|
|
210
|
+
}
|
|
211
|
+
})
|
|
212
|
+
}
|
|
213
|
+
},
|
|
188
214
|
// 表单展开全部/收起切换事件
|
|
189
215
|
formBtnCollapsed(value) {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
that.formItems = value ? that.formOriginItems : that.formOriginItems.slice(0, that.globalConfig.formToggleNum)
|
|
216
|
+
this.formCollapsed = value
|
|
217
|
+
this.formItems = value ? this.formOriginItems : this.formOriginItems.slice(0, this.globalConfig.formToggleNum)
|
|
193
218
|
this.$emit('collapsed', value)
|
|
194
219
|
},
|
|
195
220
|
// -------- 搜索
|
|
196
221
|
async onFormSubmit() {
|
|
197
|
-
let
|
|
198
|
-
let errMap = await
|
|
199
|
-
let data = that.data
|
|
222
|
+
let { data } = this
|
|
223
|
+
let errMap = await this.queryFormRef().validate()
|
|
200
224
|
if (!errMap) {
|
|
201
|
-
|
|
225
|
+
this.$emit('submit', data)
|
|
202
226
|
} else {
|
|
203
|
-
|
|
227
|
+
this.onFormSubmitInvalid({ data, errMap })
|
|
204
228
|
}
|
|
205
229
|
},
|
|
206
230
|
// 表单重置
|
|
@@ -223,31 +247,31 @@ export default {
|
|
|
223
247
|
},
|
|
224
248
|
// 自动生成表单渲染项
|
|
225
249
|
generateFormItem(items = []) {
|
|
226
|
-
const that = this
|
|
227
250
|
let itemsArr = []
|
|
228
|
-
let
|
|
229
|
-
|
|
230
|
-
|
|
251
|
+
let rules = {}
|
|
252
|
+
const { itemConfigDefault, readonly, disabled, isTrue, getDefaultMessage, $vUtils } = this
|
|
253
|
+
$vUtils.eachTree(items, ori => {
|
|
254
|
+
let tar = Object.assign({}, itemConfigDefault, ori)
|
|
231
255
|
let renderConfig = {
|
|
232
256
|
name: ori.renderName || '$vInput',
|
|
233
257
|
props: Object.assign({}, ori.renderProps || {})
|
|
234
258
|
}
|
|
235
|
-
if (
|
|
259
|
+
if (readonly || disabled) {
|
|
236
260
|
renderConfig.props.disabled = true
|
|
237
261
|
}
|
|
238
262
|
tar.itemRender = Object.assign({}, renderConfig, ori.itemRender || {})
|
|
239
263
|
// 首先提取校验配置
|
|
240
|
-
if (
|
|
264
|
+
if (isTrue(ori['renderRequire'])) {
|
|
241
265
|
// 若配置了校验参数则走校验参数,没配置则给默认校验条件
|
|
242
266
|
if (ori['requireProps'] && Array.isArray(ori['requireProps']) && ori['requireProps'].length > 0) {
|
|
243
|
-
|
|
267
|
+
rules[ori['field']] = ori['requireProps']
|
|
244
268
|
} else {
|
|
245
269
|
let dataType = 'string'
|
|
246
270
|
let arrayType = ['$vCheckgroup', '$vUpload', '$vTable']
|
|
247
|
-
if (arrayType.includes(ori['renderName']) || ((ori['renderName'] === '$vSelect' || ori['renderName'] === '$vTree') &&
|
|
271
|
+
if (arrayType.includes(ori['renderName']) || ((ori['renderName'] === '$vSelect' || ori['renderName'] === '$vTree') && isTrue(renderConfig.props.multiple))) {
|
|
248
272
|
dataType = 'array'
|
|
249
273
|
}
|
|
250
|
-
|
|
274
|
+
rules[ori['field']] = [{ required: true, message: getDefaultMessage(ori['renderName'], ori['title']), type: dataType }]
|
|
251
275
|
}
|
|
252
276
|
}
|
|
253
277
|
// 表单不支持编辑渲染过滤
|
|
@@ -256,7 +280,7 @@ export default {
|
|
|
256
280
|
itemsArr.push(tar)
|
|
257
281
|
}
|
|
258
282
|
})
|
|
259
|
-
return { itemsArr,
|
|
283
|
+
return { itemsArr, rules }
|
|
260
284
|
}
|
|
261
285
|
}
|
|
262
286
|
}
|