af-mobile-client-vue3 1.6.9 → 1.6.11

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "af-mobile-client-vue3",
3
3
  "type": "module",
4
- "version": "1.6.9",
4
+ "version": "1.6.11",
5
5
  "packageManager": "pnpm@10.13.1",
6
6
  "description": "Vue + Vite component lib",
7
7
  "engines": {
@@ -148,6 +148,12 @@ const resolvedSubmitButton = computed(() => {
148
148
  return props.submitButton
149
149
  })
150
150
 
151
+ const fieldErrors = ref<Record<string, string>>({})
152
+
153
+ function handleValidateError(model: string, error: string) {
154
+ fieldErrors.value[model] = error
155
+ }
156
+
151
157
  // 地图预览相关
152
158
  const previewMapRef = ref(null)
153
159
  const previewLonLatKey = computed(() => {
@@ -704,6 +710,14 @@ async function onSubmit() {
704
710
  }
705
711
  async function validate() {
706
712
  await xFormRef.value?.validate()
713
+ const hasError = Object.values(fieldErrors.value).some(err => err && err.length > 0)
714
+ if (hasError) {
715
+ // 将错误转换为 Vant 格式
716
+ const errors = Object.entries(fieldErrors.value)
717
+ .filter(([_, msg]) => msg)
718
+ .map(([model, message]) => ({ name: model, message }))
719
+ return Promise.reject(errors)
720
+ }
707
721
  }
708
722
  function emitFunc(func: any, data: any, value: any, attr: any) {
709
723
  emits(func, data, value, attr)
@@ -743,6 +757,7 @@ defineExpose({ init, form, formGroupName, validate, asyncSubmit, setForm, getFor
743
757
  :input-align="props.inputAlign"
744
758
  @set-form="setForm"
745
759
  @x-form-item-emit-func="emitFunc"
760
+ @validate-error="handleValidateError"
746
761
  />
747
762
  <slot name="extraFormItem" />
748
763
  </VanCellGroup>
@@ -119,7 +119,7 @@ const props = defineProps({
119
119
  },
120
120
  })
121
121
 
122
- const emits = defineEmits(['setForm', 'xFormItemEmitFunc', 'scanCodeOrNfc'])
122
+ const emits = defineEmits(['setForm', 'xFormItemEmitFunc', 'scanCodeOrNfc', 'validateError'])
123
123
 
124
124
  // 用 defineModel 替代 modelValue/emit
125
125
  const modelData = defineModel<string | number | boolean | any[] | Record<string, any>>()
@@ -457,87 +457,76 @@ function formTypeCheck(attr, value) {
457
457
  return
458
458
  // if (!attr.rule || !attr.rule.required || attr.rule.required === 'false')
459
459
  // return
460
+ let error = ''
460
461
  switch (attr.rule.type) {
461
462
  case 'string':
462
463
  if (value.length === 0) {
463
- errorMessage.value = `请输入${attr.name}`
464
- return
464
+ error = `请输入${attr.name}`
465
465
  }
466
466
  break
467
467
  case 'number':
468
468
  if (!/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)$/.test(value)) {
469
- errorMessage.value = `${attr.name}必须为数字`
470
- return
469
+ error = `${attr.name}必须为数字`
471
470
  }
472
471
  break
473
472
  case 'boolean':
474
473
  case 'array':
475
474
  case 'regexp':
476
475
  if (value) {
477
- errorMessage.value = ''
478
- return
476
+ error = ''
479
477
  }
480
478
  break
481
479
  case 'integer':
482
480
  if (!/^-?\d+$/.test(value)) {
483
- errorMessage.value = `${attr.name}必须为整数`
484
- return
481
+ error = `${attr.name}必须为整数`
485
482
  }
486
483
  break
487
484
  case 'float':
488
485
  if (!/^-?\d+\.\d+$/.test(value)) {
489
- errorMessage.value = `${attr.name}必须为小数`
490
- return
486
+ error = `${attr.name}必须为小数`
491
487
  }
492
488
  break
493
489
  case 'email':
494
490
  if (!/^[\w.%+-]+@[a-z0-9.-]+\.[a-z]{2,}$/i.test(value)) {
495
- errorMessage.value = `请输入正确的邮箱地址`
496
- return
491
+ error = `请输入正确的邮箱地址`
497
492
  }
498
493
  break
499
494
  case 'idNumber':
500
495
  if (!/^(?:\d{15}|\d{17}[0-9X])$/.test(value)) {
501
- errorMessage.value = `请输入正确的身份证号码`
502
- return
496
+ error = `请输入正确的身份证号码`
503
497
  }
504
498
  break
505
499
  case 'userPhone':
506
500
  if (!/^1[3-9]\d{9}$/.test(value)) {
507
- errorMessage.value = `请输入正确的手机号码`
508
- return
501
+ error = `请输入正确的手机号码`
509
502
  }
510
503
  break
511
504
  case 'landlineNumber':
512
505
  if (!/^0\d{2,3}[-\s]?\d{7,8}$/.test(value)) {
513
- errorMessage.value = `请输入正确的座机号码`
514
- return
506
+ error = `请输入正确的座机号码`
515
507
  }
516
508
  break
517
509
  case 'greaterThanZero':
518
510
  if (!/^(?:[1-9]\d*(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?$/i.test(value)) {
519
- errorMessage.value = `请输入一个大于0的数字`
520
- return
511
+ error = `请输入一个大于0的数字`
521
512
  }
522
513
  break
523
514
  case 'greaterThanOrEqualZero':
524
515
  if (!/^(?:\d+|\d*\.\d+)$/.test(value)) {
525
- errorMessage.value = `请输入一个大于等于0的数字`
526
- return
516
+ error = `请输入一个大于等于0的数字`
527
517
  }
528
518
  break
529
519
  case 'stringLength':
530
520
  if (!(value.length >= attr.rule.minLen && value.length < attr.rule.maxLen)) {
531
- errorMessage.value = `长度必须在${attr.rule.minLen}~${attr.rule.maxLen}之间`
532
- return
521
+ error = `长度必须在${attr.rule.minLen}~${attr.rule.maxLen}之间`
533
522
  }
534
523
  break
535
524
  case 'customJs':
536
525
  // eslint-disable-next-line no-case-declarations
537
526
  const funcStr = attr.rule.customValidatorFunc
538
527
  // 输入的数据是否符合条件
539
- // eslint-disable-next-line no-case-declarations
540
- const status = ref(true)
528
+
529
+ // const status = ref(true)
541
530
  // 提取函数体部分
542
531
  // eslint-disable-next-line no-case-declarations
543
532
  const funcBodyMatch = funcStr.match(/function\s*\(.*?\)\s*\{([\s\S]*)\}/)
@@ -550,10 +539,10 @@ function formTypeCheck(attr, value) {
550
539
  const customValidatorFunc = new Function('rule', 'value', 'callback', 'form', 'attr', 'util', funcBody)
551
540
  // 定义 callback 函数
552
541
  // eslint-disable-next-line no-case-declarations
553
- const callback = (error) => {
554
- if (error) {
555
- errorMessage.value = `${error}`
556
- status.value = false // 表示有错误发生
542
+ const callback = (errorMsg) => {
543
+ if (errorMsg) {
544
+ error = `${errorMsg}`
545
+ // status.value = false // 表示有错误发生
557
546
  }
558
547
  }
559
548
  // 调用自定义校验函数
@@ -565,14 +554,16 @@ function formTypeCheck(attr, value) {
565
554
  attr,
566
555
  {}, // util 对象(可以根据需要传递)
567
556
  )
568
- if (!status.value)
569
- return
557
+ // if (!status.value)
558
+ // return
570
559
  break
571
560
  default:
572
- errorMessage.value = ''
561
+ error = ''
573
562
  break
574
563
  }
575
- errorMessage.value = ''
564
+
565
+ errorMessage.value = error
566
+ emits('validateError', attr.model, errorMessage.value)
576
567
  }
577
568
 
578
569
  onBeforeMount(() => {
@@ -939,6 +939,19 @@ async function validateAllForms() {
939
939
  // 再次确保所有标签页已初始化
940
940
  await initAllTabs()
941
941
 
942
+ // 验证用户信息表单
943
+ if (userDetail.value && userInfoRef.value) {
944
+ try {
945
+ await userInfoRef.value.validate()
946
+ }
947
+ catch (error) {
948
+ // 更新错误计数
949
+ errorCounts.userInfo = error.length || 0
950
+ // 记录第一条错误信息
951
+ if (!firstErrorMessage && error && error[0])
952
+ firstErrorMessage = error[0]
953
+ }
954
+ }
942
955
  // 验证常规表单和slot组件
943
956
  for (let i = 0; i < config.data.length; i++) {
944
957
  const configItem = config.data[i]
@@ -52,6 +52,39 @@ defineExpose({
52
52
  getData() {
53
53
  return formData.value
54
54
  },
55
+ validate: async () => {
56
+ const errors = []
57
+
58
+ // 验证 XForm 表单
59
+ if (formRefs.value) {
60
+ try {
61
+ if (typeof formRefs.value.validate === 'function') {
62
+ await formRefs.value.validate()
63
+ }
64
+ else {
65
+ await formRefs.value.submit()
66
+ }
67
+ }
68
+ catch (error) {
69
+ if (Array.isArray(error)) {
70
+ errors.push(...error)
71
+ }
72
+ else if (error && error.message) {
73
+ errors.push(error.message)
74
+ }
75
+ else {
76
+ errors.push('表单验证失败')
77
+ }
78
+ }
79
+ }
80
+
81
+ // 如果有错误,抛出异常
82
+ if (errors.length > 0) {
83
+ return Promise.reject(errors)
84
+ }
85
+
86
+ return Promise.resolve()
87
+ },
55
88
  })
56
89
  </script>
57
90