leisure-core 0.6.61 → 0.6.63
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.
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
:class="['customClass', $attrs.class]"
|
|
7
7
|
:style="$attrs.style"
|
|
8
8
|
:type="type"
|
|
9
|
-
@clear="handleClear"
|
|
10
9
|
></el-date-picker>
|
|
11
10
|
</template>
|
|
12
11
|
|
|
@@ -38,12 +37,6 @@ export default {
|
|
|
38
37
|
},
|
|
39
38
|
},
|
|
40
39
|
methods: {
|
|
41
|
-
handleClear() {
|
|
42
|
-
this.internalValue = new Date();
|
|
43
|
-
if (this.$listeners.clear) {
|
|
44
|
-
this.$listeners.clear();
|
|
45
|
-
}
|
|
46
|
-
},
|
|
47
40
|
isTimestampInSeconds(value) {
|
|
48
41
|
if (typeof value !== "number") return false;
|
|
49
42
|
|
|
@@ -30,56 +30,50 @@ export default {
|
|
|
30
30
|
inheritAttrs: false,
|
|
31
31
|
|
|
32
32
|
props: {
|
|
33
|
-
// 数值类型
|
|
34
33
|
number: {
|
|
35
34
|
type: Boolean,
|
|
36
35
|
default: false,
|
|
37
36
|
},
|
|
38
|
-
// 手机号类型
|
|
39
37
|
mobile: {
|
|
40
38
|
type: Boolean,
|
|
41
39
|
default: false,
|
|
42
40
|
},
|
|
43
|
-
// 邮箱类型
|
|
44
41
|
email: {
|
|
45
42
|
type: Boolean,
|
|
46
43
|
default: false,
|
|
47
44
|
},
|
|
48
|
-
// 金额类型
|
|
49
45
|
amount: {
|
|
50
46
|
type: Boolean,
|
|
51
47
|
default: false,
|
|
52
48
|
},
|
|
53
|
-
// 最大长度
|
|
54
49
|
maxlength: {
|
|
55
50
|
type: [Number, String],
|
|
56
51
|
default: null,
|
|
57
52
|
},
|
|
58
|
-
// 是否显示字数统计
|
|
59
53
|
showCount: {
|
|
60
54
|
type: Boolean,
|
|
61
55
|
default: false,
|
|
62
56
|
},
|
|
63
|
-
// 自定义验证函数
|
|
64
57
|
validator: {
|
|
65
58
|
type: Function,
|
|
66
59
|
default: null,
|
|
67
60
|
},
|
|
68
|
-
// 值
|
|
69
61
|
value: {
|
|
70
62
|
type: [String, Number],
|
|
71
63
|
default: "",
|
|
72
64
|
},
|
|
73
|
-
// 是否允许小数
|
|
74
65
|
allowDecimal: {
|
|
75
66
|
type: Boolean,
|
|
76
67
|
default: true,
|
|
77
68
|
},
|
|
78
|
-
// 小数位数限制
|
|
79
69
|
decimalLimit: {
|
|
80
70
|
type: Number,
|
|
81
71
|
default: 2,
|
|
82
72
|
},
|
|
73
|
+
allowNegative: {
|
|
74
|
+
type: Boolean,
|
|
75
|
+
default: false,
|
|
76
|
+
},
|
|
83
77
|
},
|
|
84
78
|
|
|
85
79
|
data() {
|
|
@@ -96,11 +90,8 @@ export default {
|
|
|
96
90
|
mergedAttrs() {
|
|
97
91
|
const attrs = { ...this.$attrs };
|
|
98
92
|
|
|
99
|
-
// 移除已单独处理的属性
|
|
100
93
|
delete attrs.class;
|
|
101
94
|
delete attrs.style;
|
|
102
|
-
|
|
103
|
-
// 移除props中定义的属性,避免重复
|
|
104
95
|
delete attrs.number;
|
|
105
96
|
delete attrs.mobile;
|
|
106
97
|
delete attrs.email;
|
|
@@ -111,8 +102,8 @@ export default {
|
|
|
111
102
|
delete attrs.value;
|
|
112
103
|
delete attrs.allowDecimal;
|
|
113
104
|
delete attrs.decimalLimit;
|
|
105
|
+
delete attrs.allowNegative;
|
|
114
106
|
|
|
115
|
-
// 合并值,确保我们的 value 逻辑优先
|
|
116
107
|
return {
|
|
117
108
|
...attrs,
|
|
118
109
|
value: this.displayValue,
|
|
@@ -124,7 +115,6 @@ export default {
|
|
|
124
115
|
if (this.maxlength) {
|
|
125
116
|
return Number(this.maxlength);
|
|
126
117
|
}
|
|
127
|
-
// 手机号默认11位
|
|
128
118
|
if (this.mobile) {
|
|
129
119
|
return 11;
|
|
130
120
|
}
|
|
@@ -142,8 +132,12 @@ export default {
|
|
|
142
132
|
},
|
|
143
133
|
|
|
144
134
|
displayValue() {
|
|
145
|
-
|
|
146
|
-
|
|
135
|
+
if (
|
|
136
|
+
this.amount &&
|
|
137
|
+
!this.isFocused &&
|
|
138
|
+
this.internalValue !== undefined &&
|
|
139
|
+
this.internalValue !== ""
|
|
140
|
+
) {
|
|
147
141
|
return this.formatAmount(this.internalValue);
|
|
148
142
|
}
|
|
149
143
|
return this.internalValue;
|
|
@@ -152,16 +146,11 @@ export default {
|
|
|
152
146
|
|
|
153
147
|
watch: {
|
|
154
148
|
value(newVal) {
|
|
155
|
-
// let cleaned = newVal;
|
|
156
|
-
// if (this.amount && !this.allowDecimal && cleaned) {
|
|
157
|
-
// cleaned = String(cleaned).replace(/\./g, "");
|
|
158
|
-
// }
|
|
159
149
|
this.internalValue = newVal;
|
|
160
150
|
},
|
|
161
151
|
|
|
162
152
|
internalValue(newVal) {
|
|
163
153
|
this.validateInput(newVal);
|
|
164
|
-
// 触发外部监听的事件
|
|
165
154
|
this.$listeners.change && this.$listeners.change(newVal);
|
|
166
155
|
},
|
|
167
156
|
},
|
|
@@ -170,22 +159,18 @@ export default {
|
|
|
170
159
|
handleInput(value) {
|
|
171
160
|
let processedValue = value;
|
|
172
161
|
|
|
173
|
-
// 数值类型处理
|
|
174
162
|
if (this.number) {
|
|
175
163
|
processedValue = this.formatNumber(value);
|
|
176
164
|
}
|
|
177
165
|
|
|
178
|
-
// 手机号类型处理
|
|
179
166
|
if (this.mobile) {
|
|
180
167
|
processedValue = this.formatMobile(value);
|
|
181
168
|
}
|
|
182
169
|
|
|
183
|
-
// 金额类型处理
|
|
184
170
|
if (this.amount) {
|
|
185
171
|
processedValue = this.formatAmountInput(value);
|
|
186
172
|
}
|
|
187
173
|
|
|
188
|
-
// 长度限制
|
|
189
174
|
if (
|
|
190
175
|
this.computedMaxlength &&
|
|
191
176
|
processedValue.length > this.computedMaxlength
|
|
@@ -195,8 +180,6 @@ export default {
|
|
|
195
180
|
|
|
196
181
|
this.internalValue = processedValue;
|
|
197
182
|
this.$emit("input", processedValue);
|
|
198
|
-
|
|
199
|
-
// 触发外部监听的事件
|
|
200
183
|
this.$listeners.input && this.$listeners.input(processedValue);
|
|
201
184
|
},
|
|
202
185
|
|
|
@@ -205,16 +188,12 @@ export default {
|
|
|
205
188
|
this.isFocused = false;
|
|
206
189
|
this.validateInput(this.internalValue, true);
|
|
207
190
|
this.$emit("blur", event);
|
|
208
|
-
|
|
209
|
-
// 触发外部监听的事件
|
|
210
191
|
this.$listeners.blur && this.$listeners.blur(event);
|
|
211
192
|
},
|
|
212
193
|
|
|
213
194
|
handleFocus(event) {
|
|
214
195
|
this.isFocused = true;
|
|
215
196
|
this.$emit("focus", event);
|
|
216
|
-
|
|
217
|
-
// 触发外部监听的事件
|
|
218
197
|
this.$listeners.focus && this.$listeners.focus(event);
|
|
219
198
|
},
|
|
220
199
|
|
|
@@ -222,20 +201,29 @@ export default {
|
|
|
222
201
|
this.hasError = false;
|
|
223
202
|
this.errorMessage = "";
|
|
224
203
|
this.$emit("clear");
|
|
225
|
-
|
|
226
|
-
// 触发外部监听的事件
|
|
227
204
|
this.$listeners.clear && this.$listeners.clear();
|
|
228
205
|
},
|
|
229
206
|
|
|
230
207
|
formatNumber(value) {
|
|
231
|
-
let filtered = value
|
|
208
|
+
let filtered = value;
|
|
209
|
+
if (this.allowNegative) {
|
|
210
|
+
// 允许负数:保留数字、小数点、负号,负号只能出现在开头
|
|
211
|
+
filtered = value.replace(/[^\d.-]/g, "");
|
|
212
|
+
const hasNegative = filtered.startsWith("-");
|
|
213
|
+
filtered = filtered.replace(/-/g, "");
|
|
214
|
+
if (hasNegative) {
|
|
215
|
+
filtered = "-" + filtered;
|
|
216
|
+
}
|
|
217
|
+
filtered = filtered.replace(/(\..*)\./g, "$1");
|
|
218
|
+
} else {
|
|
219
|
+
filtered = value.replace(/[^\d.]/g, "");
|
|
220
|
+
filtered = filtered.replace(/(\..*)\./g, "$1");
|
|
221
|
+
}
|
|
232
222
|
|
|
233
|
-
// 如果限制小数位数,且不允许小数,则移除小数点
|
|
234
223
|
if (this.number && !this.allowDecimal) {
|
|
235
224
|
filtered = filtered.replace(/\./g, "");
|
|
236
225
|
}
|
|
237
226
|
|
|
238
|
-
// 如果限制小数位数,且允许小数,则限制小数位数
|
|
239
227
|
if (this.number && this.allowDecimal && this.decimalLimit > 0) {
|
|
240
228
|
const parts = filtered.split(".");
|
|
241
229
|
if (parts.length === 2 && parts[1].length > this.decimalLimit) {
|
|
@@ -244,31 +232,39 @@ export default {
|
|
|
244
232
|
}
|
|
245
233
|
|
|
246
234
|
return filtered;
|
|
247
|
-
// 只允许数字、小数点、负号
|
|
248
|
-
// return value.replace(/[^\d.-]/g, "").replace(/(\..*)\./g, "$1");
|
|
249
235
|
},
|
|
250
236
|
|
|
251
237
|
formatMobile(value) {
|
|
252
|
-
// 只允许数字
|
|
253
238
|
return value.replace(/\D/g, "");
|
|
254
239
|
},
|
|
255
240
|
|
|
256
241
|
formatAmountInput(value) {
|
|
257
|
-
|
|
258
|
-
|
|
242
|
+
let filteredValue = value;
|
|
243
|
+
|
|
244
|
+
if (this.allowNegative) {
|
|
245
|
+
filteredValue = value.replace(/[^\d.-]/g, "");
|
|
246
|
+
const hasNegative = filteredValue.startsWith("-");
|
|
247
|
+
filteredValue = filteredValue.replace(/-/g, "");
|
|
248
|
+
if (hasNegative) {
|
|
249
|
+
filteredValue = "-" + filteredValue;
|
|
250
|
+
}
|
|
251
|
+
// 修复:允许临时输入 '-' 或 '-.',不清空,以便用户继续输入小数部分
|
|
252
|
+
if (filteredValue === "-" || filteredValue === "-.") {
|
|
253
|
+
return filteredValue;
|
|
254
|
+
}
|
|
255
|
+
} else {
|
|
256
|
+
filteredValue = value.replace(/[^\d.]/g, "");
|
|
257
|
+
}
|
|
259
258
|
|
|
260
|
-
// 如果禁止小数,则删除所有小数点
|
|
261
259
|
if (!this.allowDecimal) {
|
|
262
260
|
return filteredValue.replace(/\./g, "");
|
|
263
261
|
}
|
|
264
262
|
|
|
265
|
-
// 处理多个小数点的情况
|
|
266
263
|
const parts = filteredValue.split(".");
|
|
267
264
|
if (parts.length > 2) {
|
|
268
265
|
filteredValue = parts[0] + "." + parts.slice(1).join("");
|
|
269
266
|
}
|
|
270
267
|
|
|
271
|
-
// 限制小数位数
|
|
272
268
|
if (parts.length === 2 && parts[1].length > this.decimalLimit) {
|
|
273
269
|
filteredValue =
|
|
274
270
|
parts[0] + "." + parts[1].substring(0, this.decimalLimit);
|
|
@@ -278,25 +274,35 @@ export default {
|
|
|
278
274
|
},
|
|
279
275
|
|
|
280
276
|
formatAmount(value) {
|
|
281
|
-
if (
|
|
277
|
+
if (value === undefined || value === null || value === "") return "";
|
|
282
278
|
|
|
283
|
-
// 将值转换为字符串
|
|
284
279
|
const strValue = String(value);
|
|
280
|
+
const isNegative = strValue.startsWith("-");
|
|
281
|
+
let absValue = isNegative ? strValue.slice(1) : strValue;
|
|
285
282
|
|
|
286
|
-
//
|
|
287
|
-
|
|
283
|
+
// 修复:处理无效的中间状态,如 '-' 或 '-.'
|
|
284
|
+
if (absValue === "" || absValue === ".") {
|
|
285
|
+
return strValue;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
const parts = absValue.split(".");
|
|
288
289
|
let integerPart = parts[0];
|
|
289
290
|
let decimalPart = parts.length > 1 ? parts[1] : "";
|
|
290
291
|
|
|
291
|
-
// 对整数部分添加千分位分隔符
|
|
292
292
|
integerPart = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
293
293
|
|
|
294
|
-
|
|
294
|
+
let formatted = "";
|
|
295
295
|
if (decimalPart && this.allowDecimal) {
|
|
296
|
-
|
|
296
|
+
formatted = `${integerPart}.${decimalPart}`;
|
|
297
297
|
} else {
|
|
298
|
-
|
|
298
|
+
formatted = integerPart;
|
|
299
299
|
}
|
|
300
|
+
|
|
301
|
+
if (isNegative && formatted !== "") {
|
|
302
|
+
formatted = "-" + formatted;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
return formatted;
|
|
300
306
|
},
|
|
301
307
|
|
|
302
308
|
validateInput(value, showError = false) {
|
|
@@ -304,18 +310,21 @@ export default {
|
|
|
304
310
|
|
|
305
311
|
let isValid = true;
|
|
306
312
|
let message = "";
|
|
307
|
-
|
|
308
313
|
const strValue = String(value || "");
|
|
309
314
|
|
|
310
|
-
// 数值验证
|
|
311
315
|
if (this.number && strValue) {
|
|
312
|
-
|
|
316
|
+
let numberPattern;
|
|
317
|
+
if (this.allowNegative) {
|
|
318
|
+
numberPattern = /^-?\d*\.?\d*$/;
|
|
319
|
+
} else {
|
|
320
|
+
numberPattern = /^\d*\.?\d*$/;
|
|
321
|
+
}
|
|
322
|
+
if (!numberPattern.test(strValue)) {
|
|
313
323
|
isValid = false;
|
|
314
324
|
message = "请输入有效的数值";
|
|
315
325
|
}
|
|
316
326
|
}
|
|
317
327
|
|
|
318
|
-
// 手机号验证
|
|
319
328
|
if (this.mobile && strValue) {
|
|
320
329
|
if (!/^1[3-9]\d{9}$/.test(strValue)) {
|
|
321
330
|
isValid = false;
|
|
@@ -323,7 +332,6 @@ export default {
|
|
|
323
332
|
}
|
|
324
333
|
}
|
|
325
334
|
|
|
326
|
-
// 邮箱验证
|
|
327
335
|
if (this.email && strValue) {
|
|
328
336
|
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(strValue)) {
|
|
329
337
|
isValid = false;
|
|
@@ -331,27 +339,56 @@ export default {
|
|
|
331
339
|
}
|
|
332
340
|
}
|
|
333
341
|
|
|
334
|
-
// 金额验证
|
|
335
342
|
if (this.amount && strValue) {
|
|
336
|
-
const
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
343
|
+
const cleanValue = strValue.replace(/,/g, "");
|
|
344
|
+
let amountPattern;
|
|
345
|
+
if (this.allowNegative) {
|
|
346
|
+
// 更严格的金额正则:不允许单独的负号、小数点、负号+小数点
|
|
347
|
+
if (this.allowDecimal) {
|
|
348
|
+
amountPattern = /^-?(?:[1-9]\d*|0)(?:\.\d{0,2})?$|^-?0\.\d{0,2}$/;
|
|
349
|
+
} else {
|
|
350
|
+
amountPattern = /^-?(?:[1-9]\d*|0)$/;
|
|
351
|
+
}
|
|
352
|
+
// 临时允许用户输入过程中的不完整状态,但最终提交时需完整
|
|
353
|
+
// 这里先检查完整格式,如果是不完整状态(如 '-'、'-.'、'.')也认为无效
|
|
354
|
+
if (
|
|
355
|
+
cleanValue === "-" ||
|
|
356
|
+
cleanValue === "-." ||
|
|
357
|
+
cleanValue === "." ||
|
|
358
|
+
cleanValue === ""
|
|
359
|
+
) {
|
|
360
|
+
isValid = false;
|
|
361
|
+
message = this.allowDecimal
|
|
362
|
+
? "请输入有效的金额"
|
|
363
|
+
: "请输入有效的整数金额";
|
|
364
|
+
} else if (!amountPattern.test(cleanValue)) {
|
|
365
|
+
isValid = false;
|
|
366
|
+
message = this.allowDecimal
|
|
367
|
+
? `请输入有效的金额(最多${this.decimalLimit}位小数)`
|
|
368
|
+
: "请输入有效的金额(整数)";
|
|
369
|
+
}
|
|
370
|
+
} else {
|
|
371
|
+
amountPattern = this.allowDecimal
|
|
372
|
+
? /^(?:[1-9]\d*|0)(?:\.\d{0,2})?$|^0\.\d{0,2}$/
|
|
373
|
+
: /^(?:[1-9]\d*|0)$/;
|
|
374
|
+
if (!amountPattern.test(cleanValue)) {
|
|
375
|
+
isValid = false;
|
|
376
|
+
message = this.allowDecimal
|
|
377
|
+
? `请输入有效的金额(最多${this.decimalLimit}位小数)`
|
|
378
|
+
: "请输入有效的金额(整数)";
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
if (!this.allowNegative && cleanValue.startsWith("-")) {
|
|
341
382
|
isValid = false;
|
|
342
|
-
message =
|
|
343
|
-
? `请输入有效的金额(最多${this.decimalLimit}位小数)`
|
|
344
|
-
: "请输入有效的金额(整数)";
|
|
383
|
+
message = "不允许输入负数";
|
|
345
384
|
}
|
|
346
385
|
}
|
|
347
386
|
|
|
348
|
-
// 最大长度验证
|
|
349
387
|
if (this.computedMaxlength && strValue.length > this.computedMaxlength) {
|
|
350
388
|
isValid = false;
|
|
351
389
|
message = `输入内容不能超过${this.computedMaxlength}个字符`;
|
|
352
390
|
}
|
|
353
391
|
|
|
354
|
-
// 自定义验证
|
|
355
392
|
if (this.validator && typeof this.validator === "function") {
|
|
356
393
|
const customResult = this.validator(value);
|
|
357
394
|
if (customResult !== true) {
|
|
@@ -366,25 +403,21 @@ export default {
|
|
|
366
403
|
return isValid;
|
|
367
404
|
},
|
|
368
405
|
|
|
369
|
-
// 公开方法:手动验证
|
|
370
406
|
validate() {
|
|
371
407
|
this.isTouched = true;
|
|
372
408
|
return this.validateInput(this.internalValue, true);
|
|
373
409
|
},
|
|
374
410
|
|
|
375
|
-
// 公开方法:清除验证状态
|
|
376
411
|
clearValidate() {
|
|
377
412
|
this.hasError = false;
|
|
378
413
|
this.errorMessage = "";
|
|
379
414
|
this.isTouched = false;
|
|
380
415
|
},
|
|
381
416
|
|
|
382
|
-
// 公开方法:聚焦输入框
|
|
383
417
|
focus() {
|
|
384
418
|
this.$refs.inputRef?.focus();
|
|
385
419
|
},
|
|
386
420
|
|
|
387
|
-
// 公开方法:失焦输入框
|
|
388
421
|
blur() {
|
|
389
422
|
this.$refs.inputRef?.blur();
|
|
390
423
|
},
|