xt-element-ui 2.0.1 → 2.0.3
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/docs/README.md +2 -1
- package/docs/components/base/xt-badge.md +2 -2
- package/docs/components/base/xt-scroll-arrow.md +155 -0
- package/lib/index.common.js +455 -64
- package/lib/index.css +1 -1
- package/lib/index.umd.js +455 -64
- package/lib/index.umd.min.js +4 -4
- package/package.json +3 -2
- package/src/components/index.scss +4 -1
- package/src/components/xt-input/index.vue +86 -6
- package/src/components/xt-scroll-arrow/index.js +8 -0
- package/src/components/xt-scroll-arrow/index.vue +190 -0
- package/src/components/xt-scroll-arrow/style/index.scss +89 -0
- package/src/components/xt-step-price/index.vue +129 -20
- package/src/components/xt-step-price-item/index.vue +18 -5
- package/src/index.js +5 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xt-element-ui",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.3",
|
|
4
4
|
"description": "基于 Vue 2.7 + ElementUI 的企业级组件库,提供丰富的自定义组件和扩展组件",
|
|
5
5
|
"main": "lib/index.common.js",
|
|
6
6
|
"module": "lib/index.esm.js",
|
|
@@ -36,7 +36,8 @@
|
|
|
36
36
|
"echarts": "^6.1.0",
|
|
37
37
|
"element-ui": "^2.15.14",
|
|
38
38
|
"sass": "^1.32.13",
|
|
39
|
-
"vue-server-renderer": "^2.7.14"
|
|
39
|
+
"vue-server-renderer": "^2.7.14",
|
|
40
|
+
"xt-element-ui": "^2.0.2"
|
|
40
41
|
},
|
|
41
42
|
"keywords": [
|
|
42
43
|
"vue",
|
|
@@ -7,17 +7,17 @@
|
|
|
7
7
|
]"
|
|
8
8
|
>
|
|
9
9
|
<el-input
|
|
10
|
-
:value="
|
|
10
|
+
:value="displayValue"
|
|
11
11
|
:placeholder="placeholder"
|
|
12
|
-
:type="type"
|
|
12
|
+
:type="isNumberType ? 'text' : type"
|
|
13
13
|
:size="size"
|
|
14
14
|
:disabled="disabled"
|
|
15
15
|
:readonly="readonly"
|
|
16
16
|
:style="inputStyle"
|
|
17
|
-
@input="
|
|
18
|
-
@change="
|
|
19
|
-
@focus="
|
|
20
|
-
@blur="
|
|
17
|
+
@input="handleInput"
|
|
18
|
+
@change="handleChange"
|
|
19
|
+
@focus="handleFocus"
|
|
20
|
+
@blur="handleBlur"
|
|
21
21
|
/>
|
|
22
22
|
</div>
|
|
23
23
|
</template>
|
|
@@ -52,7 +52,22 @@ export default {
|
|
|
52
52
|
default: ''
|
|
53
53
|
}
|
|
54
54
|
},
|
|
55
|
+
data() {
|
|
56
|
+
return {
|
|
57
|
+
currentStr: '',
|
|
58
|
+
isFocused: false
|
|
59
|
+
}
|
|
60
|
+
},
|
|
55
61
|
computed: {
|
|
62
|
+
isNumberType() {
|
|
63
|
+
return this.type === 'number'
|
|
64
|
+
},
|
|
65
|
+
displayValue() {
|
|
66
|
+
if (this.isNumberType) {
|
|
67
|
+
return this.currentStr
|
|
68
|
+
}
|
|
69
|
+
return this.value
|
|
70
|
+
},
|
|
56
71
|
inputStyle() {
|
|
57
72
|
if (this.color) {
|
|
58
73
|
return {
|
|
@@ -61,6 +76,71 @@ export default {
|
|
|
61
76
|
}
|
|
62
77
|
return {}
|
|
63
78
|
}
|
|
79
|
+
},
|
|
80
|
+
watch: {
|
|
81
|
+
value: {
|
|
82
|
+
immediate: true,
|
|
83
|
+
handler(val) {
|
|
84
|
+
if (this.isNumberType && !this.isFocused) {
|
|
85
|
+
this.currentStr = val === null || val === undefined || val === '' ? '' : String(val)
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
methods: {
|
|
91
|
+
isValidNumber(str) {
|
|
92
|
+
return /^[+-]?\d*\.?\d*$/.test(str)
|
|
93
|
+
},
|
|
94
|
+
handleInput(val) {
|
|
95
|
+
if (this.isNumberType) {
|
|
96
|
+
if (this.isValidNumber(val)) {
|
|
97
|
+
this.currentStr = val
|
|
98
|
+
const num = this.parseToNumber(val)
|
|
99
|
+
if (num !== undefined) {
|
|
100
|
+
this.$emit('input', num)
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
} else {
|
|
104
|
+
this.$emit('input', val)
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
handleChange(val) {
|
|
108
|
+
if (this.isNumberType) {
|
|
109
|
+
const num = this.parseToNumber(val)
|
|
110
|
+
this.$emit('change', num)
|
|
111
|
+
} else {
|
|
112
|
+
this.$emit('change', val)
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
handleFocus(e) {
|
|
116
|
+
this.isFocused = true
|
|
117
|
+
this.$emit('focus', e)
|
|
118
|
+
},
|
|
119
|
+
handleBlur(e) {
|
|
120
|
+
this.isFocused = false
|
|
121
|
+
if (this.isNumberType) {
|
|
122
|
+
const num = this.parseToNumber(this.currentStr)
|
|
123
|
+
this.$emit('blur', num, e)
|
|
124
|
+
if (num !== undefined) {
|
|
125
|
+
this.currentStr = String(num)
|
|
126
|
+
this.$emit('input', num)
|
|
127
|
+
} else {
|
|
128
|
+
if (this.currentStr !== '') {
|
|
129
|
+
this.currentStr = ''
|
|
130
|
+
this.$emit('input', undefined)
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
} else {
|
|
134
|
+
this.$emit('blur', e)
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
parseToNumber(str) {
|
|
138
|
+
if (!str || str === '+' || str === '-' || str === '.' || str === '+.' || str === '-.' || str === '-.') {
|
|
139
|
+
return undefined
|
|
140
|
+
}
|
|
141
|
+
const num = parseFloat(str)
|
|
142
|
+
return isNaN(num) ? undefined : num
|
|
143
|
+
}
|
|
64
144
|
}
|
|
65
145
|
}
|
|
66
146
|
</script>
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="xt-scroll-arrow" :class="[`xt-scroll-arrow--${direction}`]" :style="containerStyle">
|
|
3
|
+
<div
|
|
4
|
+
v-if="showLeftArrow"
|
|
5
|
+
class="xt-scroll-arrow__btn xt-scroll-arrow__btn--left"
|
|
6
|
+
@click="scrollLeft"
|
|
7
|
+
>
|
|
8
|
+
<i class="el-icon-arrow-left"></i>
|
|
9
|
+
</div>
|
|
10
|
+
|
|
11
|
+
<div ref="scrollContainer" class="xt-scroll-arrow__content" @scroll="handleScroll">
|
|
12
|
+
<slot></slot>
|
|
13
|
+
</div>
|
|
14
|
+
|
|
15
|
+
<div
|
|
16
|
+
v-if="showRightArrow"
|
|
17
|
+
class="xt-scroll-arrow__btn xt-scroll-arrow__btn--right"
|
|
18
|
+
@click="scrollRight"
|
|
19
|
+
>
|
|
20
|
+
<i class="el-icon-arrow-right"></i>
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
<div
|
|
24
|
+
v-if="showTopArrow && direction === 'vertical'"
|
|
25
|
+
class="xt-scroll-arrow__btn xt-scroll-arrow__btn--top"
|
|
26
|
+
@click="scrollTop"
|
|
27
|
+
>
|
|
28
|
+
<i class="el-icon-arrow-up"></i>
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
<div
|
|
32
|
+
v-if="showBottomArrow && direction === 'vertical'"
|
|
33
|
+
class="xt-scroll-arrow__btn xt-scroll-arrow__btn--bottom"
|
|
34
|
+
@click="scrollBottom"
|
|
35
|
+
>
|
|
36
|
+
<i class="el-icon-arrow-down"></i>
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
39
|
+
</template>
|
|
40
|
+
|
|
41
|
+
<script>
|
|
42
|
+
export default {
|
|
43
|
+
name: 'XtScrollArrow',
|
|
44
|
+
props: {
|
|
45
|
+
direction: {
|
|
46
|
+
type: String,
|
|
47
|
+
default: 'horizontal',
|
|
48
|
+
validator: (val) => ['horizontal', 'vertical'].includes(val)
|
|
49
|
+
},
|
|
50
|
+
scrollStep: {
|
|
51
|
+
type: Number,
|
|
52
|
+
default: 100
|
|
53
|
+
},
|
|
54
|
+
autoHide: {
|
|
55
|
+
type: Boolean,
|
|
56
|
+
default: true
|
|
57
|
+
},
|
|
58
|
+
height: {
|
|
59
|
+
type: [String, Number],
|
|
60
|
+
default: ''
|
|
61
|
+
},
|
|
62
|
+
width: {
|
|
63
|
+
type: [String, Number],
|
|
64
|
+
default: ''
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
data() {
|
|
68
|
+
return {
|
|
69
|
+
showLeftArrow: false,
|
|
70
|
+
showRightArrow: false,
|
|
71
|
+
showTopArrow: false,
|
|
72
|
+
showBottomArrow: false
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
computed: {
|
|
76
|
+
containerStyle() {
|
|
77
|
+
const style = {}
|
|
78
|
+
if (this.height) {
|
|
79
|
+
style.height = typeof this.height === 'number' ? `${this.height}px` : this.height
|
|
80
|
+
}
|
|
81
|
+
if (this.width) {
|
|
82
|
+
style.width = typeof this.width === 'number' ? `${this.width}px` : this.width
|
|
83
|
+
}
|
|
84
|
+
return style
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
watch: {
|
|
88
|
+
direction() {
|
|
89
|
+
this.$nextTick(() => {
|
|
90
|
+
this.checkScroll()
|
|
91
|
+
})
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
mounted() {
|
|
95
|
+
this.$nextTick(() => {
|
|
96
|
+
this.checkScroll()
|
|
97
|
+
})
|
|
98
|
+
this.addResizeObserver()
|
|
99
|
+
},
|
|
100
|
+
beforeDestroy() {
|
|
101
|
+
this.removeResizeObserver()
|
|
102
|
+
},
|
|
103
|
+
methods: {
|
|
104
|
+
addResizeObserver() {
|
|
105
|
+
if (typeof ResizeObserver !== 'undefined') {
|
|
106
|
+
this.resizeObserver = new ResizeObserver(() => {
|
|
107
|
+
this.$nextTick(() => {
|
|
108
|
+
this.checkScroll()
|
|
109
|
+
})
|
|
110
|
+
})
|
|
111
|
+
const container = this.$refs.scrollContainer
|
|
112
|
+
if (container) {
|
|
113
|
+
this.resizeObserver.observe(container)
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
removeResizeObserver() {
|
|
118
|
+
if (this.resizeObserver) {
|
|
119
|
+
this.resizeObserver.disconnect()
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
checkScroll() {
|
|
123
|
+
const container = this.$refs.scrollContainer
|
|
124
|
+
if (!container) return
|
|
125
|
+
|
|
126
|
+
if (this.direction === 'horizontal') {
|
|
127
|
+
const scrollLeft = container.scrollLeft
|
|
128
|
+
const scrollWidth = container.scrollWidth
|
|
129
|
+
const clientWidth = container.clientWidth
|
|
130
|
+
const maxScroll = scrollWidth - clientWidth
|
|
131
|
+
|
|
132
|
+
this.showTopArrow = false
|
|
133
|
+
this.showBottomArrow = false
|
|
134
|
+
|
|
135
|
+
if (this.autoHide) {
|
|
136
|
+
this.showLeftArrow = scrollLeft > 0
|
|
137
|
+
this.showRightArrow = maxScroll > 0 && scrollLeft < maxScroll
|
|
138
|
+
} else {
|
|
139
|
+
this.showLeftArrow = maxScroll > 0
|
|
140
|
+
this.showRightArrow = maxScroll > 0
|
|
141
|
+
}
|
|
142
|
+
} else {
|
|
143
|
+
const scrollTop = container.scrollTop
|
|
144
|
+
const scrollHeight = container.scrollHeight
|
|
145
|
+
const clientHeight = container.clientHeight
|
|
146
|
+
const maxScroll = scrollHeight - clientHeight
|
|
147
|
+
|
|
148
|
+
this.showLeftArrow = false
|
|
149
|
+
this.showRightArrow = false
|
|
150
|
+
|
|
151
|
+
if (this.autoHide) {
|
|
152
|
+
this.showTopArrow = scrollTop > 0
|
|
153
|
+
this.showBottomArrow = maxScroll > 0 && scrollTop < maxScroll
|
|
154
|
+
} else {
|
|
155
|
+
this.showTopArrow = maxScroll > 0
|
|
156
|
+
this.showBottomArrow = maxScroll > 0
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
handleScroll() {
|
|
161
|
+
this.checkScroll()
|
|
162
|
+
this.$emit('scroll', this.$refs.scrollContainer)
|
|
163
|
+
},
|
|
164
|
+
scrollLeft() {
|
|
165
|
+
const container = this.$refs.scrollContainer
|
|
166
|
+
if (container) {
|
|
167
|
+
container.scrollBy({ left: -this.scrollStep, behavior: 'smooth' })
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
scrollRight() {
|
|
171
|
+
const container = this.$refs.scrollContainer
|
|
172
|
+
if (container) {
|
|
173
|
+
container.scrollBy({ left: this.scrollStep, behavior: 'smooth' })
|
|
174
|
+
}
|
|
175
|
+
},
|
|
176
|
+
scrollTop() {
|
|
177
|
+
const container = this.$refs.scrollContainer
|
|
178
|
+
if (container) {
|
|
179
|
+
container.scrollBy({ top: -this.scrollStep, behavior: 'smooth' })
|
|
180
|
+
}
|
|
181
|
+
},
|
|
182
|
+
scrollBottom() {
|
|
183
|
+
const container = this.$refs.scrollContainer
|
|
184
|
+
if (container) {
|
|
185
|
+
container.scrollBy({ top: this.scrollStep, behavior: 'smooth' })
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
</script>
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
@import '../../../styles/variables.scss';
|
|
2
|
+
|
|
3
|
+
.xt-scroll-arrow {
|
|
4
|
+
position: relative;
|
|
5
|
+
display: flex;
|
|
6
|
+
align-items: center;
|
|
7
|
+
overflow: hidden;
|
|
8
|
+
|
|
9
|
+
&--horizontal {
|
|
10
|
+
flex-direction: row;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
&--vertical {
|
|
14
|
+
flex-direction: column;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
&__content {
|
|
18
|
+
flex: 1;
|
|
19
|
+
overflow: auto;
|
|
20
|
+
scrollbar-width: none;
|
|
21
|
+
-ms-overflow-style: none;
|
|
22
|
+
|
|
23
|
+
&::-webkit-scrollbar {
|
|
24
|
+
display: none;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
&__btn {
|
|
29
|
+
position: absolute;
|
|
30
|
+
z-index: 10;
|
|
31
|
+
width: 32px;
|
|
32
|
+
height: 32px;
|
|
33
|
+
display: flex;
|
|
34
|
+
align-items: center;
|
|
35
|
+
justify-content: center;
|
|
36
|
+
background: rgba(255, 255, 255, 0.9);
|
|
37
|
+
border-radius: 50%;
|
|
38
|
+
cursor: pointer;
|
|
39
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
|
40
|
+
transition: all 0.3s ease;
|
|
41
|
+
border: none;
|
|
42
|
+
padding: 0;
|
|
43
|
+
|
|
44
|
+
&:hover {
|
|
45
|
+
background: rgba(255, 255, 255, 1);
|
|
46
|
+
transform: scale(1.1);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
&:active {
|
|
50
|
+
transform: scale(0.95);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
&--left {
|
|
54
|
+
left: 8px;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
&--right {
|
|
58
|
+
right: 8px;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
&--top {
|
|
62
|
+
top: 8px;
|
|
63
|
+
left: 50%;
|
|
64
|
+
transform: translateX(-50%);
|
|
65
|
+
|
|
66
|
+
&:hover {
|
|
67
|
+
transform: translateX(-50%) scale(1.1);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
&:active {
|
|
71
|
+
transform: translateX(-50%) scale(0.95);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
&--bottom {
|
|
76
|
+
bottom: 8px;
|
|
77
|
+
left: 50%;
|
|
78
|
+
transform: translateX(-50%);
|
|
79
|
+
|
|
80
|
+
&:hover {
|
|
81
|
+
transform: translateX(-50%) scale(1.1);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
&:active {
|
|
85
|
+
transform: translateX(-50%) scale(0.95);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
icon="el-icon-plus"
|
|
11
11
|
plain
|
|
12
12
|
@click="onAdd"
|
|
13
|
-
|
|
13
|
+
>新增{{stepName}}</xt-button>
|
|
14
14
|
<xt-text v-if="isLimitReached" size="small" type-color="info">已达上限({{ localItems.length }}/{{ limit }})</xt-text>
|
|
15
15
|
</div>
|
|
16
16
|
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
:min-locked="idx !== 0 ? true : false"
|
|
28
28
|
:unit="unit"
|
|
29
29
|
:precision="precision"
|
|
30
|
+
:step-name="stepName"
|
|
30
31
|
:step="step"
|
|
31
32
|
:left-bracket="leftBracket"
|
|
32
33
|
:right-bracket="rightBracket"
|
|
@@ -36,11 +37,12 @@
|
|
|
36
37
|
@max-change="onMaxChange"
|
|
37
38
|
@min-change="onMinChange"
|
|
38
39
|
@delete="onDelete"
|
|
40
|
+
@blur="onFieldBlur"
|
|
39
41
|
/>
|
|
40
42
|
</div>
|
|
41
43
|
|
|
42
44
|
<div v-if="localItems.length === 0" class="xt-step-price__empty">
|
|
43
|
-
<span
|
|
45
|
+
<span>暂无数据,点击右上角「新增{{stepName}}」开始配置</span>
|
|
44
46
|
</div>
|
|
45
47
|
|
|
46
48
|
<div v-if="tip || $slots.tip" class="xt-step-price__tip">
|
|
@@ -59,6 +61,12 @@ export default {
|
|
|
59
61
|
|
|
60
62
|
components: { XtStepPriceItem },
|
|
61
63
|
|
|
64
|
+
inject: {
|
|
65
|
+
elFormItem: {
|
|
66
|
+
default: ''
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
|
|
62
70
|
computed: {
|
|
63
71
|
keyMin() { return (this.fieldKeys && this.fieldKeys.min) || 'min' },
|
|
64
72
|
keyMax() { return (this.fieldKeys && this.fieldKeys.max) || 'max' },
|
|
@@ -76,6 +84,7 @@ export default {
|
|
|
76
84
|
},
|
|
77
85
|
title: { type: String, default: '' },
|
|
78
86
|
unit: { type: String, default: '元' },
|
|
87
|
+
stepName: { type: String, default: '阶梯' },
|
|
79
88
|
precision: { type: Number, default: 2 },
|
|
80
89
|
// 左括号:默认 '[',传空字符串则不显示
|
|
81
90
|
leftBracket: { type: String, default: '[' },
|
|
@@ -125,11 +134,14 @@ export default {
|
|
|
125
134
|
|
|
126
135
|
cloneItems(items) {
|
|
127
136
|
if (!Array.isArray(items)) return []
|
|
128
|
-
return items.map((it) =>
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
137
|
+
return items.map((it) => {
|
|
138
|
+
const price = (it && it[this.keyPrice])
|
|
139
|
+
return {
|
|
140
|
+
[this.keyMin]: this.safeNumber(it && it[this.keyMin], 0),
|
|
141
|
+
[this.keyMax]: (it && it[this.keyMax] == null) || (it && it[this.keyMax] === '') ? null : this.safeNumber(it[this.keyMax], null),
|
|
142
|
+
[this.keyPrice]: (price === null || price === undefined || price === '') ? '' : this.safeNumber(price, 0)
|
|
143
|
+
}
|
|
144
|
+
})
|
|
133
145
|
},
|
|
134
146
|
|
|
135
147
|
normalize(items) {
|
|
@@ -160,7 +172,8 @@ export default {
|
|
|
160
172
|
} else {
|
|
161
173
|
cur[this.keyMax] = null
|
|
162
174
|
}
|
|
163
|
-
|
|
175
|
+
const price = cur[this.keyPrice]
|
|
176
|
+
cur[this.keyPrice] = (price === null || price === undefined || price === '') ? '' : this.safeNumber(price, 0)
|
|
164
177
|
}
|
|
165
178
|
},
|
|
166
179
|
|
|
@@ -169,15 +182,118 @@ export default {
|
|
|
169
182
|
const cloned = this.cloneItems(this.localItems)
|
|
170
183
|
this.$emit('input', cloned)
|
|
171
184
|
this.$emit('change', cloned)
|
|
185
|
+
this.dispatchFormEvent('el.form.change', cloned)
|
|
186
|
+
},
|
|
187
|
+
|
|
188
|
+
dispatchFormEvent(eventName, value) {
|
|
189
|
+
if (this.elFormItem) {
|
|
190
|
+
this.elFormItem.$emit(eventName, value)
|
|
191
|
+
}
|
|
192
|
+
},
|
|
193
|
+
|
|
194
|
+
onFieldBlur() {
|
|
195
|
+
this.dispatchFormEvent('el.form.blur', this.localItems)
|
|
196
|
+
},
|
|
197
|
+
|
|
198
|
+
validate(callback) {
|
|
199
|
+
const list = this.localItems
|
|
200
|
+
if (!Array.isArray(list) || list.length === 0) {
|
|
201
|
+
callback && callback(false, [{ field: 'stepPrice', message: `请配置${this.stepName}`, type: 'error' }])
|
|
202
|
+
return false
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
const errors = []
|
|
206
|
+
for (let i = 0; i < list.length; i++) {
|
|
207
|
+
const item = list[i]
|
|
208
|
+
const rawPrice = item[this.keyPrice]
|
|
209
|
+
const rawMin = item[this.keyMin]
|
|
210
|
+
const rawMax = item[this.keyMax]
|
|
211
|
+
const price = this.safeNumber(rawPrice, 0)
|
|
212
|
+
const min = this.safeNumber(rawMin, 0)
|
|
213
|
+
|
|
214
|
+
if (rawPrice === null || rawPrice === undefined || rawPrice === '') {
|
|
215
|
+
errors.push({
|
|
216
|
+
field: `stepPrice[${i}].price`,
|
|
217
|
+
message: `第${i + 1}${this.stepName}价格不能为空`,
|
|
218
|
+
type: 'error'
|
|
219
|
+
})
|
|
220
|
+
} else if (price < 0) {
|
|
221
|
+
errors.push({
|
|
222
|
+
field: `stepPrice[${i}].price`,
|
|
223
|
+
message: `第${i + 1}${this.stepName}价格不能为负数`,
|
|
224
|
+
type: 'error'
|
|
225
|
+
})
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
if (rawMin === null || rawMin === undefined || rawMin === '') {
|
|
229
|
+
errors.push({
|
|
230
|
+
field: `stepPrice[${i}].min`,
|
|
231
|
+
message: `第${i + 1}${this.stepName}下限不能为空`,
|
|
232
|
+
type: 'error'
|
|
233
|
+
})
|
|
234
|
+
} else if (min < 0) {
|
|
235
|
+
errors.push({
|
|
236
|
+
field: `stepPrice[${i}].min`,
|
|
237
|
+
message: `第${i + 1}${this.stepName}下限不能为负数`,
|
|
238
|
+
type: 'error'
|
|
239
|
+
})
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
if (!this.isLast(i)) {
|
|
243
|
+
if (rawMax === null || rawMax === undefined || rawMax === '') {
|
|
244
|
+
errors.push({
|
|
245
|
+
field: `stepPrice[${i}].max`,
|
|
246
|
+
message: `第${i + 1}${this.stepName}上限不能为空`,
|
|
247
|
+
type: 'error'
|
|
248
|
+
})
|
|
249
|
+
} else if (this.safeNumber(rawMax, 0) <= min) {
|
|
250
|
+
errors.push({
|
|
251
|
+
field: `stepPrice[${i}].max`,
|
|
252
|
+
message: `第${i + 1}${this.stepName}上限必须大于下限`,
|
|
253
|
+
type: 'error'
|
|
254
|
+
})
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
if (i > 0) {
|
|
259
|
+
const prev = list[i - 1]
|
|
260
|
+
const prevMax = prev[this.keyMax]
|
|
261
|
+
if (prevMax !== null && this.safeNumber(prevMax, 0) !== min) {
|
|
262
|
+
errors.push({
|
|
263
|
+
field: `stepPrice[${i}].min`,
|
|
264
|
+
message: `第${i + 1}${this.stepName}下限必须等于上一${this.stepName}上限`,
|
|
265
|
+
type: 'error'
|
|
266
|
+
})
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
if (errors.length > 0) {
|
|
272
|
+
callback && callback(false, errors)
|
|
273
|
+
return false
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
callback && callback(true)
|
|
277
|
+
return true
|
|
278
|
+
},
|
|
279
|
+
|
|
280
|
+
isLast(idx) {
|
|
281
|
+
return idx === this.localItems.length - 1
|
|
172
282
|
},
|
|
173
283
|
|
|
174
284
|
onItemInput(val, idx) {
|
|
175
285
|
const cur = this.localItems[idx]
|
|
176
286
|
if (!cur) return
|
|
177
287
|
if (val && val[this.keyPrice] !== undefined) {
|
|
178
|
-
|
|
179
|
-
p
|
|
180
|
-
|
|
288
|
+
const p = val[this.keyPrice]
|
|
289
|
+
if (p === null || p === undefined || p === '') {
|
|
290
|
+
cur[this.keyPrice] = ''
|
|
291
|
+
} else {
|
|
292
|
+
let num = this.safeNumber(p, 0)
|
|
293
|
+
num = Number(num.toFixed(this.precision))
|
|
294
|
+
cur[this.keyPrice] = num
|
|
295
|
+
}
|
|
296
|
+
this.emit()
|
|
181
297
|
}
|
|
182
298
|
},
|
|
183
299
|
|
|
@@ -232,15 +348,8 @@ export default {
|
|
|
232
348
|
const newMin = this.safeNumber(last[this.keyMin], 0)
|
|
233
349
|
const newMax = newMin + stepVal
|
|
234
350
|
|
|
235
|
-
// 新条 price
|
|
236
|
-
|
|
237
|
-
let newPrice = 10
|
|
238
|
-
if (prev) {
|
|
239
|
-
newPrice = this.safeNumber(prev[this.keyPrice], 10)
|
|
240
|
-
} else {
|
|
241
|
-
const lastPrice = this.safeNumber(last[this.keyPrice], 0)
|
|
242
|
-
newPrice = lastPrice > 0 ? lastPrice : 10
|
|
243
|
-
}
|
|
351
|
+
// 新条 price:使用默认值,由用户自行填写
|
|
352
|
+
let newPrice = 0
|
|
244
353
|
|
|
245
354
|
const newArr = [
|
|
246
355
|
...list.slice(0, -1),
|