web-component-gallery 2.3.12 → 2.3.13
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/js.umd.js +1 -1
- package/lib/form-comp/ACascaderMultiple.vue +19 -1
- package/lib/form-comp/style/ACascaderMultiple.less +9 -2
- package/lib/model/Model.js +126 -87
- package/lib/model/utils/render.js +33 -52
- package/package.json +1 -1
- package/utils/Filter.js +16 -9
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
<li
|
|
46
46
|
class="cascader-content-item cascader-content-item-check-all"
|
|
47
47
|
@click="handleCascaderAllItemClick(isCheckAll)"
|
|
48
|
-
v-if="levelIndex === 0"
|
|
48
|
+
v-if="levelIndex === 0 && showAll"
|
|
49
49
|
>
|
|
50
50
|
<Checkbox
|
|
51
51
|
:indeterminate="isIndeterminateAll"
|
|
@@ -148,6 +148,10 @@
|
|
|
148
148
|
type: String,
|
|
149
149
|
default: "全部"
|
|
150
150
|
},
|
|
151
|
+
showAll: {
|
|
152
|
+
type: Boolean,
|
|
153
|
+
default: true
|
|
154
|
+
},
|
|
151
155
|
noDataText: {
|
|
152
156
|
type: String,
|
|
153
157
|
default: "暂无数据"
|
|
@@ -417,6 +421,20 @@
|
|
|
417
421
|
handleFocus() {
|
|
418
422
|
this.isOpen = true;
|
|
419
423
|
this.isClickOutSide = false;
|
|
424
|
+
this.$nextTick(() => {
|
|
425
|
+
if (!this.treeDataList.length || !this.treeDataList[0].length) return;
|
|
426
|
+
const childrenTag = this.selectOptionsConfig.children;
|
|
427
|
+
const first = this.treeDataList[0][0];
|
|
428
|
+
if (!first || !first[childrenTag] || !first[childrenTag].length) return;
|
|
429
|
+
const clearActive = list => list.forEach(item => {
|
|
430
|
+
item.$active = false;
|
|
431
|
+
if (item[childrenTag] && item[childrenTag].length) clearActive(item[childrenTag]);
|
|
432
|
+
});
|
|
433
|
+
clearActive(this.treeDataList[0]);
|
|
434
|
+
first.$active = true;
|
|
435
|
+
this.addHideSelectedList(first[childrenTag]);
|
|
436
|
+
this.$set(this, 'treeDataList', [this.treeDataList[0], first[childrenTag]]);
|
|
437
|
+
});
|
|
420
438
|
},
|
|
421
439
|
updatePostData() {
|
|
422
440
|
const childrenTag = this.selectOptionsConfig.children;
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
|
|
2
2
|
.gb-ant-select-multiple-cascader {
|
|
3
|
+
cursor: pointer;
|
|
4
|
+
|
|
5
|
+
.ant-select-selection {
|
|
6
|
+
cursor: pointer;
|
|
7
|
+
}
|
|
8
|
+
|
|
3
9
|
.ant-select-dropdown-menu-item {
|
|
4
10
|
display: none;
|
|
5
11
|
}
|
|
@@ -7,9 +13,9 @@
|
|
|
7
13
|
.cascader-content-item {
|
|
8
14
|
.checkbox-text {
|
|
9
15
|
padding-left: @padding-xs;
|
|
10
|
-
font-size: @font-size-
|
|
16
|
+
font-size: @font-size-base;
|
|
11
17
|
color: @text-color;
|
|
12
|
-
cursor:
|
|
18
|
+
cursor: pointer;
|
|
13
19
|
flex: 1;
|
|
14
20
|
text-align: left;
|
|
15
21
|
.ellipsis();
|
|
@@ -99,6 +105,7 @@
|
|
|
99
105
|
margin-top: @padding-xs - 2;
|
|
100
106
|
align-items: center;
|
|
101
107
|
line-height: 1;
|
|
108
|
+
cursor: pointer;
|
|
102
109
|
.flex-layout();
|
|
103
110
|
|
|
104
111
|
&:hover {
|
package/lib/model/Model.js
CHANGED
|
@@ -4,78 +4,82 @@ import _ from 'lodash'
|
|
|
4
4
|
|
|
5
5
|
export default {
|
|
6
6
|
name: 'WModel',
|
|
7
|
+
// 定义组件的双向绑定模型,prop 为 value,事件为 Change:Model
|
|
7
8
|
model: {
|
|
8
9
|
prop: 'value',
|
|
9
10
|
event: 'Change:Model'
|
|
10
|
-
},
|
|
11
|
-
data() {
|
|
12
|
-
return {
|
|
13
|
-
formRules: {}
|
|
14
|
-
}
|
|
15
11
|
},
|
|
12
|
+
|
|
16
13
|
props: {
|
|
14
|
+
// 表单绑定的数据对象
|
|
17
15
|
value: {
|
|
18
16
|
type: Object,
|
|
19
17
|
default: () => ({})
|
|
20
|
-
},
|
|
21
|
-
|
|
22
|
-
layout: {
|
|
18
|
+
},
|
|
19
|
+
// 表单布局模式:'vertical' 或其他(水平布局)
|
|
20
|
+
layout: {
|
|
23
21
|
type: String,
|
|
24
22
|
default: 'vertical'
|
|
25
23
|
},
|
|
26
|
-
|
|
24
|
+
// 布局尺寸配置,用于计算表单项宽度
|
|
27
25
|
layoutSize: {
|
|
28
26
|
type: Number,
|
|
29
27
|
default: 4
|
|
30
28
|
},
|
|
31
|
-
|
|
32
|
-
formSetting:
|
|
29
|
+
// 表单配置项数组,定义每个表单项的属性
|
|
30
|
+
formSetting: {
|
|
31
|
+
type: Array,
|
|
32
|
+
default: () => []
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
data() {
|
|
37
|
+
return {
|
|
38
|
+
// 存储动态生成的表单验证规则
|
|
39
|
+
formRules: {}
|
|
40
|
+
}
|
|
33
41
|
},
|
|
42
|
+
|
|
34
43
|
computed: {
|
|
44
|
+
// 双向绑定的 form 数据,获取时触发字段验证,设置时发射更新事件
|
|
35
45
|
form: {
|
|
36
46
|
get() {
|
|
37
|
-
|
|
38
|
-
for (const k in this.value) {
|
|
39
|
-
Object.hasOwnProperty.call(this.formRules, k) && this.$refs.FormModel?.validateField(k)
|
|
40
|
-
}
|
|
47
|
+
this.validateChangedFields()
|
|
41
48
|
return this.value
|
|
42
49
|
},
|
|
43
50
|
set(value) {
|
|
44
|
-
this.$emit('Change:Model', value)
|
|
51
|
+
this.$emit('Change:Model', value)
|
|
45
52
|
}
|
|
46
53
|
},
|
|
54
|
+
|
|
55
|
+
// 根据布局模式计算表单属性(labelCol, wrapperCol 等)
|
|
47
56
|
formAttrs() {
|
|
48
57
|
const baseAttrs = {
|
|
49
|
-
// 是否禁用表单,默认否
|
|
50
58
|
disabled: false,
|
|
51
59
|
...this.$attrs
|
|
52
60
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
labelCol: { span: 4 },
|
|
58
|
-
wrapperCol: { span: 20 },
|
|
59
|
-
...baseAttrs
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
return baseAttrs
|
|
61
|
+
|
|
62
|
+
return this.layout !== 'vertical'
|
|
63
|
+
? { labelCol: { span: 4 }, wrapperCol: { span: 20 }, ...baseAttrs }
|
|
64
|
+
: baseAttrs
|
|
64
65
|
},
|
|
66
|
+
|
|
67
|
+
// 动态生成当前可见表单项的验证规则
|
|
65
68
|
dynamicFormRules() {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
formRules[node.model] = setFormItemRule.call(this, node)
|
|
71
|
-
})
|
|
72
|
-
return formRules
|
|
69
|
+
return this.visibleFormItems.reduce((rules, node) => {
|
|
70
|
+
rules[node.model] = setFormItemRule.call(this, node)
|
|
71
|
+
return rules
|
|
72
|
+
}, {})
|
|
73
73
|
},
|
|
74
|
+
|
|
75
|
+
// 过滤出未隐藏的表单项配置
|
|
74
76
|
visibleFormItems() {
|
|
75
|
-
return this.formSetting.filter(
|
|
77
|
+
return this.formSetting.filter(item => !item.hidden)
|
|
76
78
|
}
|
|
77
79
|
},
|
|
80
|
+
|
|
78
81
|
watch: {
|
|
82
|
+
// 监听动态规则变化,同步到 formRules 以触发重新渲染
|
|
79
83
|
dynamicFormRules: {
|
|
80
84
|
handler(newRules) {
|
|
81
85
|
this.formRules = newRules
|
|
@@ -83,81 +87,119 @@ export default {
|
|
|
83
87
|
immediate: true
|
|
84
88
|
}
|
|
85
89
|
},
|
|
90
|
+
|
|
86
91
|
mounted() {
|
|
92
|
+
// 将内部 FormModel 实例通过事件暴露给父组件
|
|
87
93
|
this.$emit('update:refForm', this.$refs.FormModel)
|
|
88
94
|
},
|
|
95
|
+
|
|
89
96
|
methods: {
|
|
97
|
+
// 验证发生变化的字段
|
|
98
|
+
validateChangedFields() {
|
|
99
|
+
Object.keys(this.value).forEach(key => {
|
|
100
|
+
if (this.formRules[key] && this.$refs.FormModel) {
|
|
101
|
+
this.$refs.FormModel.validateField(key)
|
|
102
|
+
}
|
|
103
|
+
})
|
|
104
|
+
},
|
|
105
|
+
|
|
106
|
+
// 解析模型路径(支持嵌套如 'user.name'),返回父级、子级及是否嵌套标志
|
|
107
|
+
parseModelPath(modelPath) {
|
|
108
|
+
const parts = modelPath.split('.')
|
|
109
|
+
return {
|
|
110
|
+
parent: parts[0],
|
|
111
|
+
child: parts[1],
|
|
112
|
+
isNested: parts.length > 1
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
|
|
116
|
+
// 渲染单个表单项
|
|
90
117
|
renderSingleFormItem(h, props) {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
118
|
+
const { parent, child, isNested } = this.parseModelPath(props.model)
|
|
119
|
+
const targetModel = isNested ? this.form[parent] : this.form
|
|
120
|
+
const finalModel = isNested ? child : parent
|
|
121
|
+
|
|
122
|
+
return setFormItem.call(this, h, targetModel, { ...props, model: finalModel }, {
|
|
123
|
+
prop: props.model
|
|
124
|
+
})
|
|
125
|
+
},
|
|
126
|
+
|
|
127
|
+
// 渲染动态多行表单项(适用于数组型数据)
|
|
94
128
|
renderDynamicFormItems(h, dynamicModel, props) {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
// 为动态项时重新定义绑定key、prop等来进行检验
|
|
98
|
-
return props.multipleConfig.map((configItem) => {
|
|
129
|
+
return dynamicModel.map((modelItem, index) =>
|
|
130
|
+
props.multipleConfig.map(configItem => {
|
|
99
131
|
const childAttrs = {
|
|
100
|
-
key,
|
|
101
|
-
|
|
132
|
+
key: index,
|
|
133
|
+
// 后续有空添加另一种形式([0, 1, 2])数组中仅一位,则省略configItem.model
|
|
134
|
+
prop: `${props.model}.${index}.${configItem.model}`,
|
|
102
135
|
style: getFormWidth.call(this, configItem, this.layoutSize ?? props.layoutSize),
|
|
103
136
|
rules: setFormItemRule.call(this, configItem, props),
|
|
104
137
|
parentModel: props.model
|
|
105
|
-
}
|
|
138
|
+
}
|
|
106
139
|
return setFormItem.call(this, h, modelItem, configItem, childAttrs)
|
|
107
140
|
})
|
|
108
|
-
|
|
109
|
-
},
|
|
110
|
-
|
|
141
|
+
)
|
|
142
|
+
},
|
|
143
|
+
|
|
144
|
+
// 根据配置渲染表单项容器(支持单条或多条模式)
|
|
111
145
|
setModelRender(h, props) {
|
|
112
|
-
const
|
|
146
|
+
const { parent, isNested } = this.parseModelPath(props.model)
|
|
147
|
+
const dynamicModel = this.form[parent]
|
|
148
|
+
|
|
149
|
+
const containerStyle = getFormWidth.call(
|
|
150
|
+
this,
|
|
151
|
+
props,
|
|
152
|
+
this.layoutSize,
|
|
153
|
+
props.multiple ? 0 : 24
|
|
154
|
+
)
|
|
155
|
+
|
|
113
156
|
return (
|
|
114
|
-
<div
|
|
115
|
-
class={props.multiple && ['MultipleForm']}
|
|
116
|
-
{...{ attrs: { style:
|
|
157
|
+
<div
|
|
158
|
+
class={props.multiple && ['MultipleForm']}
|
|
159
|
+
{...{ attrs: { style: containerStyle } }}
|
|
117
160
|
>
|
|
118
|
-
{
|
|
119
|
-
{
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
dynamicModel instanceof Array && props.multiple
|
|
123
|
-
? this.renderDynamicFormItems(h, dynamicModel, props)
|
|
124
|
-
: this.renderSingleFormItem(h, props)
|
|
161
|
+
{this.$scopedSlots[`${props.model}Tips`]?.(props)}
|
|
162
|
+
{dynamicModel instanceof Array && props.multiple
|
|
163
|
+
? this.renderDynamicFormItems(h, dynamicModel, props)
|
|
164
|
+
: this.renderSingleFormItem(h, props)
|
|
125
165
|
}
|
|
126
|
-
{
|
|
127
|
-
{this.$scopedSlots[`${props.model}Operate`] && this.$scopedSlots[`${props.model}Operate`](props)}
|
|
166
|
+
{this.$scopedSlots[`${props.model}Operate`]?.(props)}
|
|
128
167
|
</div>
|
|
129
168
|
)
|
|
130
169
|
},
|
|
131
|
-
|
|
170
|
+
|
|
171
|
+
// 记忆化计算表单宽度,避免重复计算
|
|
132
172
|
getFormWidth: _.memoize(function(props, layoutSize, multiple) {
|
|
133
173
|
return getFormWidth.call(this, props, layoutSize, multiple ? 24 : 0)
|
|
134
|
-
}),
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
174
|
+
}),
|
|
175
|
+
|
|
176
|
+
// 提交表单并处理验证错误
|
|
177
|
+
async formSubmit() {
|
|
178
|
+
try {
|
|
179
|
+
await this.$refs.FormModel.validate()
|
|
180
|
+
} catch (err) {
|
|
181
|
+
console.error('表单验证失败:', err)
|
|
182
|
+
this.scrollToFirstError()
|
|
183
|
+
throw err
|
|
184
|
+
}
|
|
185
|
+
},
|
|
186
|
+
|
|
187
|
+
// 滚动到第一个报错的表单项
|
|
188
|
+
scrollToFirstError() {
|
|
189
|
+
this.$nextTick(() => {
|
|
190
|
+
const errorElement = document.querySelector('.has-error')
|
|
191
|
+
errorElement?.scrollIntoView({ behavior: 'smooth', block: 'center' })
|
|
151
192
|
})
|
|
152
193
|
}
|
|
153
194
|
},
|
|
195
|
+
|
|
154
196
|
render(h) {
|
|
155
|
-
const {layout, formAttrs, setModelRender} = this
|
|
197
|
+
const { layout, formAttrs, setModelRender } = this
|
|
156
198
|
|
|
157
199
|
return (
|
|
158
200
|
<FormModel
|
|
159
201
|
ref="FormModel"
|
|
160
|
-
class="FormModel"
|
|
202
|
+
class="FormModel"
|
|
161
203
|
props={{
|
|
162
204
|
model: this.form,
|
|
163
205
|
rules: this.formRules,
|
|
@@ -165,11 +207,8 @@ export default {
|
|
|
165
207
|
...formAttrs
|
|
166
208
|
}}
|
|
167
209
|
>
|
|
168
|
-
{
|
|
169
|
-
this.$slots.default ??
|
|
170
|
-
this.visibleFormItems.map(props => setModelRender(h, props))
|
|
171
|
-
}
|
|
210
|
+
{this.$slots.default || this.visibleFormItems.map(props => setModelRender(h, props))}
|
|
172
211
|
</FormModel>
|
|
173
212
|
)
|
|
174
213
|
}
|
|
175
|
-
}
|
|
214
|
+
}
|
|
@@ -8,90 +8,75 @@ const FormModelItem = FormModel.Item
|
|
|
8
8
|
* @param {Object} child - 表单项配置
|
|
9
9
|
* @param {number} layoutSize - 一行显示的表单项数量
|
|
10
10
|
* @param {number} [gap=24] - 表单项间距
|
|
11
|
-
* @returns {string}
|
|
11
|
+
* @returns {string} CSS 样式字符串
|
|
12
12
|
*/
|
|
13
13
|
export function getFormWidth(child, layoutSize, gap = 24) {
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
const widthPercent = (100 / layoutSize) * (child.size ?? 1)
|
|
15
|
+
|
|
16
|
+
return this.layout === 'vertical'
|
|
17
|
+
? `width: calc(${widthPercent}% - ${gap}px); margin-right: ${gap}px;`
|
|
18
|
+
: `width: ${widthPercent}%;`
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
22
|
* 动态设置表单项验证规则
|
|
23
23
|
* @param {Object} node - 当前表单项配置
|
|
24
24
|
* @param {Object} [nodeParent={}] - 父表单项配置
|
|
25
|
-
* @returns {Array}
|
|
25
|
+
* @returns {Array} 验证规则数组
|
|
26
26
|
*/
|
|
27
27
|
export function setFormItemRule(node, nodeParent = {}) {
|
|
28
|
-
|
|
29
|
-
const required = (node.required ?? nodeParent.required ?? this.formAttrs.required) ?? true
|
|
28
|
+
const required = node.required ?? nodeParent.required ?? this.formAttrs.required ?? true
|
|
30
29
|
|
|
31
|
-
// 生成提示信息
|
|
32
30
|
const message = node.attrs?.placeholder ||
|
|
33
|
-
|
|
34
|
-
(node.label || '')
|
|
35
|
-
|
|
36
|
-
// 基础规则
|
|
37
|
-
const baseRules = []
|
|
31
|
+
`${/(select|picker|radio|upload)/.test((node.is ?? 'Input').toLowerCase()) ? '请选择' : '请输入'}${node.label || ''}`
|
|
38
32
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
})
|
|
45
|
-
}
|
|
33
|
+
const baseRules = required ? [{
|
|
34
|
+
required,
|
|
35
|
+
message,
|
|
36
|
+
trigger: ['change', 'blur']
|
|
37
|
+
}] : []
|
|
46
38
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
return rule
|
|
53
|
-
})
|
|
39
|
+
const customRules = (node.rules || []).map(rule =>
|
|
40
|
+
rule.pattern && typeof rule.pattern === 'string'
|
|
41
|
+
? { ...rule, pattern: new RegExp(rule.pattern) }
|
|
42
|
+
: rule
|
|
43
|
+
)
|
|
54
44
|
|
|
55
45
|
return [...baseRules, ...customRules]
|
|
56
|
-
}
|
|
46
|
+
}
|
|
57
47
|
|
|
58
48
|
/**
|
|
59
49
|
* 动态渲染表单项
|
|
60
|
-
* @param {Function} h - Vue的createElement函数
|
|
50
|
+
* @param {Function} h - Vue 的 createElement 函数
|
|
61
51
|
* @param {Object} vModel - 表单数据对象
|
|
62
52
|
* @param {Object} child - 表单项配置
|
|
63
53
|
* @param {Object} [childAttrs] - 表单项属性
|
|
64
|
-
* @returns {VNode}
|
|
54
|
+
* @returns {VNode} 渲染结果
|
|
65
55
|
*/
|
|
66
|
-
export function setFormItem(h, vModel, child, childAttrs) {
|
|
56
|
+
export function setFormItem(h, vModel, child, childAttrs = {}) {
|
|
67
57
|
const { layout, layoutSize, formAttrs, $scopedSlots } = this
|
|
58
|
+
const slotsName = `${childAttrs.parentModel || ''}${child.model}`
|
|
68
59
|
|
|
69
|
-
// 设置表单项属性
|
|
70
60
|
const formItemAttrs = {
|
|
71
61
|
key: child.model,
|
|
72
62
|
prop: child.model,
|
|
73
|
-
colon:
|
|
63
|
+
colon: layout !== 'inline',
|
|
74
64
|
...childAttrs
|
|
75
65
|
}
|
|
76
66
|
|
|
77
|
-
|
|
78
|
-
|
|
67
|
+
const contentAttrs = {
|
|
68
|
+
disabled: childAttrs.disabled ?? formAttrs.disabled ?? false,
|
|
69
|
+
...child.attrs
|
|
70
|
+
}
|
|
79
71
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
customLabel ? customLabel(vModel) : <span>{child.label}</span>
|
|
72
|
+
const renderLabel = () =>
|
|
73
|
+
child.customLabel ? child.customLabel(vModel) : <span>{child.label}</span>
|
|
83
74
|
|
|
84
|
-
// 渲染表单项内容
|
|
85
75
|
const renderContent = () => {
|
|
86
76
|
if ($scopedSlots[child.model]) {
|
|
87
77
|
return $scopedSlots[child.model](child)
|
|
88
78
|
}
|
|
89
79
|
|
|
90
|
-
const contentAttrs = {
|
|
91
|
-
disabled: childAttrs?.disabled ?? formAttrs.disabled ?? false,
|
|
92
|
-
...child.attrs
|
|
93
|
-
}
|
|
94
|
-
|
|
95
80
|
return (
|
|
96
81
|
<RenderComp
|
|
97
82
|
v-model={vModel[child.model]}
|
|
@@ -109,13 +94,9 @@ export function setFormItem(h, vModel, child, childAttrs) {
|
|
|
109
94
|
}}
|
|
110
95
|
{...{ attrs: formItemAttrs }}
|
|
111
96
|
>
|
|
112
|
-
<template slot="label">
|
|
113
|
-
{renderLabel(child.customLabel)}
|
|
114
|
-
</template>
|
|
115
|
-
{/* 当前表单项可slot进行单独开发配置 (目前仅支持非动态增减情况) */}
|
|
97
|
+
<template slot="label">{renderLabel()}</template>
|
|
116
98
|
{renderContent()}
|
|
117
|
-
{/* 如若再某个model后需添加按钮等场景(例如地图的选址按钮 */}
|
|
118
99
|
{$scopedSlots[`${slotsName}Handle`] && $scopedSlots[`${slotsName}Handle`](formItemAttrs)}
|
|
119
100
|
</FormModelItem>
|
|
120
101
|
)
|
|
121
|
-
}
|
|
102
|
+
}
|
package/package.json
CHANGED
package/utils/Filter.js
CHANGED
|
@@ -463,7 +463,8 @@ export function transferData(data, format, options = {}) {
|
|
|
463
463
|
* @param {Array} format - 格式配置
|
|
464
464
|
* - ['a', 'b', 'c'] - 默认转为 Number
|
|
465
465
|
* - [['a', 'b'], 'Number'] - 指定类型
|
|
466
|
-
* - [{ fields: ['a', 'b'], type: 'Number' }] -
|
|
466
|
+
* - [{ fields: ['a', 'b'], type: 'Number' }] - 单个对象配置
|
|
467
|
+
* - [{ fields: ['a', 'b'], type: 'Number', defaultValue: 0 }, { fields: ['c'], type: 'String' }] - 多个对象配置
|
|
467
468
|
* @param {Object} options - 配置选项
|
|
468
469
|
* @returns {*} 转换后的数据
|
|
469
470
|
*/
|
|
@@ -472,11 +473,14 @@ function transferDataByFields(data, format, options) {
|
|
|
472
473
|
return data ?? options.defaultValue
|
|
473
474
|
}
|
|
474
475
|
|
|
476
|
+
// 解析数组配置
|
|
477
|
+
if (format.length === 0) return data
|
|
478
|
+
|
|
475
479
|
let fields = []
|
|
476
480
|
let type = 'Number' // 默认转为 Number
|
|
477
481
|
|
|
478
|
-
//
|
|
479
|
-
|
|
482
|
+
// 对象处理:转换指定字段
|
|
483
|
+
const result = { ...data }
|
|
480
484
|
|
|
481
485
|
// 形式 1: ['a', 'b', 'c'] - 默认转 Number
|
|
482
486
|
if (typeof format[0] === 'string') {
|
|
@@ -489,18 +493,21 @@ function transferDataByFields(data, format, options) {
|
|
|
489
493
|
}
|
|
490
494
|
// 形式 3: [{ fields: ['a', 'b'], type: 'Number' }] - 对象配置
|
|
491
495
|
else if (typeof format[0] === 'object') {
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
496
|
+
format.forEach(config => {
|
|
497
|
+
// 转换指定字段
|
|
498
|
+
for (const field of config.fields) {
|
|
499
|
+
if (field in result) {
|
|
500
|
+
const fieldDefaultValue = config.defaultValue || options.defaultValue
|
|
501
|
+
result[field] = transferData(result[field], config.type, fieldDefaultValue)
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
})
|
|
495
505
|
}
|
|
496
506
|
|
|
497
507
|
// 如果是数组,递归处理每个元素
|
|
498
508
|
if (Array.isArray(data)) {
|
|
499
509
|
return data.map(item => transferDataByFields(item, format, options))
|
|
500
510
|
}
|
|
501
|
-
|
|
502
|
-
// 对象处理:转换指定字段
|
|
503
|
-
const result = { ...data }
|
|
504
511
|
|
|
505
512
|
for (const field of fields) {
|
|
506
513
|
if (field in result) {
|