leisure-core 0.6.62 → 0.6.65

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.
@@ -11,11 +11,28 @@
11
11
  @clear="handleClear"
12
12
  @focus="handleFocus"
13
13
  >
14
+ <!-- 显式透传 prepend 插槽 -->
15
+ <template v-if="$slots.prepend" #prepend>
16
+ <slot name="prepend" />
17
+ </template>
18
+
19
+ <!-- 显式透传 append 插槽 -->
20
+ <template v-if="$slots.append" #append>
21
+ <slot name="append" />
22
+ </template>
23
+
24
+ <!-- 显式透传 prefix 插槽 -->
25
+ <template v-if="$slots.prefix" #prefix>
26
+ <slot name="prefix" />
27
+ </template>
14
28
  <template v-if="showCount" #suffix>
15
29
  <span class="input-count" :class="{ 'is-error': isOverMaxLength }">
16
30
  {{ valueLength }}/{{ computedMaxlength }}
17
31
  </span>
18
32
  </template>
33
+ <template v-else-if="$slots.suffix" #suffix>
34
+ <slot name="suffix" />
35
+ </template>
19
36
  </el-input>
20
37
 
21
38
  <div v-if="hasError && errorMessage" class="error-message">
@@ -30,57 +47,46 @@ export default {
30
47
  inheritAttrs: false,
31
48
 
32
49
  props: {
33
- // 数值类型
34
50
  number: {
35
51
  type: Boolean,
36
52
  default: false,
37
53
  },
38
- // 手机号类型
39
54
  mobile: {
40
55
  type: Boolean,
41
56
  default: false,
42
57
  },
43
- // 邮箱类型
44
58
  email: {
45
59
  type: Boolean,
46
60
  default: false,
47
61
  },
48
- // 金额类型
49
62
  amount: {
50
63
  type: Boolean,
51
64
  default: false,
52
65
  },
53
- // 最大长度
54
66
  maxlength: {
55
67
  type: [Number, String],
56
68
  default: null,
57
69
  },
58
- // 是否显示字数统计
59
70
  showCount: {
60
71
  type: Boolean,
61
72
  default: false,
62
73
  },
63
- // 自定义验证函数
64
74
  validator: {
65
75
  type: Function,
66
76
  default: null,
67
77
  },
68
- // 值
69
78
  value: {
70
79
  type: [String, Number],
71
80
  default: "",
72
81
  },
73
- // 是否允许小数
74
82
  allowDecimal: {
75
83
  type: Boolean,
76
84
  default: true,
77
85
  },
78
- // 小数位数限制
79
86
  decimalLimit: {
80
87
  type: Number,
81
88
  default: 2,
82
89
  },
83
- // 新增:是否允许负数(仅对 number 和 amount 类型生效)
84
90
  allowNegative: {
85
91
  type: Boolean,
86
92
  default: false,
@@ -101,11 +107,8 @@ export default {
101
107
  mergedAttrs() {
102
108
  const attrs = { ...this.$attrs };
103
109
 
104
- // 移除已单独处理的属性
105
110
  delete attrs.class;
106
111
  delete attrs.style;
107
-
108
- // 移除props中定义的属性,避免重复
109
112
  delete attrs.number;
110
113
  delete attrs.mobile;
111
114
  delete attrs.email;
@@ -116,9 +119,8 @@ export default {
116
119
  delete attrs.value;
117
120
  delete attrs.allowDecimal;
118
121
  delete attrs.decimalLimit;
119
- delete attrs.allowNegative; // 新增
122
+ delete attrs.allowNegative;
120
123
 
121
- // 合并值,确保我们的 value 逻辑优先
122
124
  return {
123
125
  ...attrs,
124
126
  value: this.displayValue,
@@ -130,7 +132,6 @@ export default {
130
132
  if (this.maxlength) {
131
133
  return Number(this.maxlength);
132
134
  }
133
- // 手机号默认11位
134
135
  if (this.mobile) {
135
136
  return 11;
136
137
  }
@@ -148,7 +149,6 @@ export default {
148
149
  },
149
150
 
150
151
  displayValue() {
151
- // 金额类型在非聚焦状态下显示格式化后的值
152
152
  if (
153
153
  this.amount &&
154
154
  !this.isFocused &&
@@ -168,7 +168,6 @@ export default {
168
168
 
169
169
  internalValue(newVal) {
170
170
  this.validateInput(newVal);
171
- // 触发外部监听的事件
172
171
  this.$listeners.change && this.$listeners.change(newVal);
173
172
  },
174
173
  },
@@ -177,22 +176,18 @@ export default {
177
176
  handleInput(value) {
178
177
  let processedValue = value;
179
178
 
180
- // 数值类型处理
181
179
  if (this.number) {
182
180
  processedValue = this.formatNumber(value);
183
181
  }
184
182
 
185
- // 手机号类型处理
186
183
  if (this.mobile) {
187
184
  processedValue = this.formatMobile(value);
188
185
  }
189
186
 
190
- // 金额类型处理
191
187
  if (this.amount) {
192
188
  processedValue = this.formatAmountInput(value);
193
189
  }
194
190
 
195
- // 长度限制
196
191
  if (
197
192
  this.computedMaxlength &&
198
193
  processedValue.length > this.computedMaxlength
@@ -202,8 +197,6 @@ export default {
202
197
 
203
198
  this.internalValue = processedValue;
204
199
  this.$emit("input", processedValue);
205
-
206
- // 触发外部监听的事件
207
200
  this.$listeners.input && this.$listeners.input(processedValue);
208
201
  },
209
202
 
@@ -212,16 +205,12 @@ export default {
212
205
  this.isFocused = false;
213
206
  this.validateInput(this.internalValue, true);
214
207
  this.$emit("blur", event);
215
-
216
- // 触发外部监听的事件
217
208
  this.$listeners.blur && this.$listeners.blur(event);
218
209
  },
219
210
 
220
211
  handleFocus(event) {
221
212
  this.isFocused = true;
222
213
  this.$emit("focus", event);
223
-
224
- // 触发外部监听的事件
225
214
  this.$listeners.focus && this.$listeners.focus(event);
226
215
  },
227
216
 
@@ -229,37 +218,29 @@ export default {
229
218
  this.hasError = false;
230
219
  this.errorMessage = "";
231
220
  this.$emit("clear");
232
-
233
- // 触发外部监听的事件
234
221
  this.$listeners.clear && this.$listeners.clear();
235
222
  },
236
223
 
237
224
  formatNumber(value) {
238
- // 根据 allowNegative 决定是否保留负号
239
225
  let filtered = value;
240
226
  if (this.allowNegative) {
241
- // 允许负数:保留数字、小数点、负号,但负号只能出现在开头,多个负号只保留第一个
227
+ // 允许负数:保留数字、小数点、负号,负号只能出现在开头
242
228
  filtered = value.replace(/[^\d.-]/g, "");
243
- // 处理多个负号的情况:只保留第一个负号,并确保负号在开头
244
229
  const hasNegative = filtered.startsWith("-");
245
230
  filtered = filtered.replace(/-/g, "");
246
231
  if (hasNegative) {
247
232
  filtered = "-" + filtered;
248
233
  }
249
- // 处理小数点后多余的小数点
250
234
  filtered = filtered.replace(/(\..*)\./g, "$1");
251
235
  } else {
252
- // 不允许负数:直接过滤掉负号
253
236
  filtered = value.replace(/[^\d.]/g, "");
254
237
  filtered = filtered.replace(/(\..*)\./g, "$1");
255
238
  }
256
239
 
257
- // 如果不允许小数,移除小数点
258
240
  if (this.number && !this.allowDecimal) {
259
241
  filtered = filtered.replace(/\./g, "");
260
242
  }
261
243
 
262
- // 如果允许小数,限制小数位数
263
244
  if (this.number && this.allowDecimal && this.decimalLimit > 0) {
264
245
  const parts = filtered.split(".");
265
246
  if (parts.length === 2 && parts[1].length > this.decimalLimit) {
@@ -271,69 +252,62 @@ export default {
271
252
  },
272
253
 
273
254
  formatMobile(value) {
274
- // 只允许数字
275
255
  return value.replace(/\D/g, "");
276
256
  },
277
257
 
278
258
  formatAmountInput(value) {
279
- // 金额输入过滤
280
259
  let filteredValue = value;
281
260
 
282
261
  if (this.allowNegative) {
283
- // 允许负数:保留数字、小数点、负号,负号只能出现在开头
284
262
  filteredValue = value.replace(/[^\d.-]/g, "");
285
263
  const hasNegative = filteredValue.startsWith("-");
286
264
  filteredValue = filteredValue.replace(/-/g, "");
287
265
  if (hasNegative) {
288
266
  filteredValue = "-" + filteredValue;
289
267
  }
268
+ // 修复:允许临时输入 '-' 或 '-.',不清空,以便用户继续输入小数部分
269
+ if (filteredValue === "-" || filteredValue === "-.") {
270
+ return filteredValue;
271
+ }
290
272
  } else {
291
- // 不允许负数:只保留数字和小数点
292
273
  filteredValue = value.replace(/[^\d.]/g, "");
293
274
  }
294
275
 
295
- // 如果禁止小数,则删除所有小数点
296
276
  if (!this.allowDecimal) {
297
277
  return filteredValue.replace(/\./g, "");
298
278
  }
299
279
 
300
- // 处理多个小数点的情况
301
280
  const parts = filteredValue.split(".");
302
281
  if (parts.length > 2) {
303
282
  filteredValue = parts[0] + "." + parts.slice(1).join("");
304
283
  }
305
284
 
306
- // 限制小数位数
307
285
  if (parts.length === 2 && parts[1].length > this.decimalLimit) {
308
286
  filteredValue =
309
287
  parts[0] + "." + parts[1].substring(0, this.decimalLimit);
310
288
  }
311
289
 
312
- // 特殊情况:单独的负号或负号+小数点不允许,清除无效输入
313
- if (filteredValue === "-" || filteredValue === "-.") {
314
- filteredValue = "";
315
- }
316
-
317
290
  return filteredValue;
318
291
  },
319
292
 
320
293
  formatAmount(value) {
321
294
  if (value === undefined || value === null || value === "") return "";
322
295
 
323
- // 将值转换为字符串,处理负数
324
296
  const strValue = String(value);
325
297
  const isNegative = strValue.startsWith("-");
326
298
  let absValue = isNegative ? strValue.slice(1) : strValue;
327
299
 
328
- // 分割整数和小数部分
300
+ // 修复:处理无效的中间状态,如 '-' 或 '-.'
301
+ if (absValue === "" || absValue === ".") {
302
+ return strValue;
303
+ }
304
+
329
305
  const parts = absValue.split(".");
330
306
  let integerPart = parts[0];
331
307
  let decimalPart = parts.length > 1 ? parts[1] : "";
332
308
 
333
- // 对整数部分添加千分位分隔符
334
309
  integerPart = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
335
310
 
336
- // 组合整数和小数部分
337
311
  let formatted = "";
338
312
  if (decimalPart && this.allowDecimal) {
339
313
  formatted = `${integerPart}.${decimalPart}`;
@@ -341,7 +315,6 @@ export default {
341
315
  formatted = integerPart;
342
316
  }
343
317
 
344
- // 添加负号
345
318
  if (isNegative && formatted !== "") {
346
319
  formatted = "-" + formatted;
347
320
  }
@@ -354,15 +327,12 @@ export default {
354
327
 
355
328
  let isValid = true;
356
329
  let message = "";
357
-
358
330
  const strValue = String(value || "");
359
331
 
360
- // 数值验证
361
332
  if (this.number && strValue) {
362
333
  let numberPattern;
363
334
  if (this.allowNegative) {
364
- // 允许负数:可选负号,整数或小数
365
- numberPattern = new RegExp(`^-?\\d*\\.?\\d*$`);
335
+ numberPattern = /^-?\d*\.?\d*$/;
366
336
  } else {
367
337
  numberPattern = /^\d*\.?\d*$/;
368
338
  }
@@ -372,7 +342,6 @@ export default {
372
342
  }
373
343
  }
374
344
 
375
- // 手机号验证
376
345
  if (this.mobile && strValue) {
377
346
  if (!/^1[3-9]\d{9}$/.test(strValue)) {
378
347
  isValid = false;
@@ -380,7 +349,6 @@ export default {
380
349
  }
381
350
  }
382
351
 
383
- // 邮箱验证
384
352
  if (this.email && strValue) {
385
353
  if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(strValue)) {
386
354
  isValid = false;
@@ -388,40 +356,56 @@ export default {
388
356
  }
389
357
  }
390
358
 
391
- // 金额验证
392
359
  if (this.amount && strValue) {
393
- // 去除千分位分隔符后再验证
394
360
  const cleanValue = strValue.replace(/,/g, "");
395
361
  let amountPattern;
396
362
  if (this.allowNegative) {
397
- amountPattern = this.allowDecimal
398
- ? new RegExp(`^-?\\d+(\\.\\d{0,${this.decimalLimit}})?$`)
399
- : /^-?\d+$/;
363
+ // 更严格的金额正则:不允许单独的负号、小数点、负号+小数点
364
+ if (this.allowDecimal) {
365
+ amountPattern = /^-?(?:[1-9]\d*|0)(?:\.\d{0,2})?$|^-?0\.\d{0,2}$/;
366
+ } else {
367
+ amountPattern = /^-?(?:[1-9]\d*|0)$/;
368
+ }
369
+ // 临时允许用户输入过程中的不完整状态,但最终提交时需完整
370
+ // 这里先检查完整格式,如果是不完整状态(如 '-'、'-.'、'.')也认为无效
371
+ if (
372
+ cleanValue === "-" ||
373
+ cleanValue === "-." ||
374
+ cleanValue === "." ||
375
+ cleanValue === ""
376
+ ) {
377
+ isValid = false;
378
+ message = this.allowDecimal
379
+ ? "请输入有效的金额"
380
+ : "请输入有效的整数金额";
381
+ } else if (!amountPattern.test(cleanValue)) {
382
+ isValid = false;
383
+ message = this.allowDecimal
384
+ ? `请输入有效的金额(最多${this.decimalLimit}位小数)`
385
+ : "请输入有效的金额(整数)";
386
+ }
400
387
  } else {
401
388
  amountPattern = this.allowDecimal
402
- ? new RegExp(`^\\d+(\\.\\d{0,${this.decimalLimit}})?$`)
403
- : /^\d+$/;
404
- }
405
- if (!amountPattern.test(cleanValue)) {
406
- isValid = false;
407
- message = this.allowDecimal
408
- ? `请输入有效的金额(最多${this.decimalLimit}位小数)`
409
- : "请输入有效的金额(整数)";
389
+ ? /^(?:[1-9]\d*|0)(?:\.\d{0,2})?$|^0\.\d{0,2}$/
390
+ : /^(?:[1-9]\d*|0)$/;
391
+ if (!amountPattern.test(cleanValue)) {
392
+ isValid = false;
393
+ message = this.allowDecimal
394
+ ? `请输入有效的金额(最多${this.decimalLimit}位小数)`
395
+ : "请输入有效的金额(整数)";
396
+ }
410
397
  }
411
- // 额外检查负数是否允许
412
398
  if (!this.allowNegative && cleanValue.startsWith("-")) {
413
399
  isValid = false;
414
400
  message = "不允许输入负数";
415
401
  }
416
402
  }
417
403
 
418
- // 最大长度验证
419
404
  if (this.computedMaxlength && strValue.length > this.computedMaxlength) {
420
405
  isValid = false;
421
406
  message = `输入内容不能超过${this.computedMaxlength}个字符`;
422
407
  }
423
408
 
424
- // 自定义验证
425
409
  if (this.validator && typeof this.validator === "function") {
426
410
  const customResult = this.validator(value);
427
411
  if (customResult !== true) {
@@ -436,25 +420,21 @@ export default {
436
420
  return isValid;
437
421
  },
438
422
 
439
- // 公开方法:手动验证
440
423
  validate() {
441
424
  this.isTouched = true;
442
425
  return this.validateInput(this.internalValue, true);
443
426
  },
444
427
 
445
- // 公开方法:清除验证状态
446
428
  clearValidate() {
447
429
  this.hasError = false;
448
430
  this.errorMessage = "";
449
431
  this.isTouched = false;
450
432
  },
451
433
 
452
- // 公开方法:聚焦输入框
453
434
  focus() {
454
435
  this.$refs.inputRef?.focus();
455
436
  },
456
437
 
457
- // 公开方法:失焦输入框
458
438
  blur() {
459
439
  this.$refs.inputRef?.blur();
460
440
  },
@@ -19,6 +19,16 @@
19
19
  <el-option label="是" value="1" key="1"></el-option>
20
20
  </el-select>
21
21
  </el-form-item>
22
+ <el-form-item label="后台用户">
23
+ <el-select
24
+ v-model="searchData.managered"
25
+ clearable
26
+ placeholder="请选择"
27
+ >
28
+ <el-option label="否" value="0" key="0"></el-option>
29
+ <el-option label="是" value="1" key="1"></el-option>
30
+ </el-select>
31
+ </el-form-item>
22
32
  <el-form-item>
23
33
  <el-button type="primary" @click="list">查询</el-button>
24
34
  <el-button type="primary" @click="addUser">新建</el-button>
@@ -211,6 +221,7 @@ export default {
211
221
  dataValue: [],
212
222
  pageNo: 1,
213
223
  total: 1,
224
+ managered: "",
214
225
  },
215
226
  userTypelsShow: true,
216
227
  showYhj: false,
@@ -363,6 +374,9 @@ export default {
363
374
  if (this.searchData.membered && this.searchData.membered.length > 0) {
364
375
  params.membered = this.searchData.membered;
365
376
  }
377
+ if (this.searchData.managered && this.searchData.managered.length > 0) {
378
+ params.managered = this.searchData.managered;
379
+ }
366
380
  if (this.searchData.id && this.searchData.id.length > 0) {
367
381
  params.id = this.searchData.id;
368
382
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "leisure-core",
3
- "version": "0.6.62",
3
+ "version": "0.6.65",
4
4
  "description": "leisure-core是京心数据基于vue2.x开发的一套后台管理系统桌面端组件库,封装了大量实用的UI控件模板,非常方便开发者快速搭建前端应用",
5
5
  "private": false,
6
6
  "author": "北方乐逍遥(zcx7878)",