register.model.ts 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. import { toCamelCase } from '@/tools';
  2. import type { FieldRule, NumberKeyboardProps, PasswordInputProps } from 'vant';
  3. export interface RegisterModel {
  4. cardno: string;
  5. phone: string;
  6. code: string;
  7. name: string;
  8. sex: string;
  9. age: number;
  10. height: number;
  11. weight: number;
  12. isEasyAllergy: boolean;
  13. }
  14. export interface Field {
  15. control: {
  16. label: string; placeholder?: string;
  17. type?: string; min?: number; max?: number; minlength?: number; maxlength?: number;
  18. clearable?: boolean; border?: boolean; readonly?: boolean;
  19. };
  20. component?: |
  21. { name: 'radio', options: { label: string; value: string; }[] } |
  22. { name: 'code', props?: Partial<PasswordInputProps> };
  23. keyboard?: { show: boolean; } & Partial<NumberKeyboardProps>;
  24. suffix?: string;
  25. rules: FieldRule[];
  26. }
  27. export type FieldKey = keyof RegisterModel;
  28. export type Fields = ( Field & { name: FieldKey } )[];
  29. const Fields: Record<FieldKey, Field> = {
  30. height: {
  31. control: {
  32. label: '身高', placeholder: '请输入身高',
  33. type: 'number', min: 1, max: 300, clearable: true, readonly: true,
  34. maxlength: 5,
  35. },
  36. keyboard: { show: false, title: '身高', extraKey: '.', closeButtonText: '完成' },
  37. suffix: 'cm',
  38. rules: [],
  39. },
  40. weight: {
  41. control: {
  42. label: '体重', placeholder: '请输入体重',
  43. type: 'number', min: 1, max: 300, clearable: true, readonly: true,
  44. maxlength: 5,
  45. },
  46. keyboard: { show: false, title: '体重', extraKey: '.', closeButtonText: '完成' },
  47. suffix: 'kg',
  48. rules: [],
  49. },
  50. age: {
  51. control: {
  52. label: '年龄', placeholder: '请输入年龄',
  53. type: 'digit', min: 0, max: 300, clearable: true, readonly: true,
  54. maxlength: 3,
  55. },
  56. keyboard: { show: false, title: '年龄', closeButtonText: '完成' },
  57. suffix: '岁',
  58. rules: [],
  59. },
  60. sex: {
  61. control: { label: '性别', border: false },
  62. component: {
  63. name: 'radio' as const,
  64. options: [
  65. { label: '男', value: '0' },
  66. { label: '女', value: '1' },
  67. ],
  68. },
  69. rules: [],
  70. },
  71. isEasyAllergy: {
  72. control: { label: '容易过敏', border: false },
  73. component: {
  74. name: 'radio' as const,
  75. options: [
  76. { label: '是', value: 'Y' },
  77. { label: '否', value: 'N' },
  78. ],
  79. },
  80. rules: [],
  81. },
  82. name: {
  83. control: {
  84. label: '姓名', placeholder: '请输入姓名',
  85. type: 'text', maxlength: 10, clearable: true,
  86. },
  87. rules: [],
  88. },
  89. cardno: {
  90. control: {
  91. label: '身份证号', placeholder: '请输入身份证号',
  92. type: 'text', maxlength: 18, minlength: 18, clearable: true, readonly: true,
  93. },
  94. keyboard: { show: false, title: '身份证号', extraKey: 'X', closeButtonText: '完成' },
  95. rules: [
  96. {
  97. validator: (value: string) => value && value.length === 18,
  98. message: '请输入正确的身份证',
  99. trigger: 'onBlur',
  100. },
  101. ],
  102. },
  103. phone: {
  104. control: {
  105. label: '手机号码', placeholder: '请输入手机号码',
  106. type: 'tel', maxlength: 11, minlength: 11, clearable: true, readonly: true,
  107. },
  108. keyboard: { show: false, title: '手机号码', closeButtonText: '完成' },
  109. rules: [
  110. {
  111. validator: (value: string) => value && value.length === 11,
  112. message: '请输入正确的手机号码',
  113. trigger: 'onBlur',
  114. },
  115. ],
  116. },
  117. code: {
  118. control: {
  119. label: '验证码', placeholder: '请输入验证码',
  120. type: 'digit', maxlength: 6, minlength: 6, clearable: true,
  121. border: false,
  122. },
  123. component: {
  124. name: 'code' as const,
  125. props: { mask: false },
  126. },
  127. keyboard: { show: false, title: '验证码', closeButtonText: '完成' },
  128. rules: [
  129. {
  130. validator: (value: string) => value && value.length === 6,
  131. message: '请输入验证码',
  132. trigger: [ 'onChange', 'onBlur' ],
  133. },
  134. ],
  135. },
  136. };
  137. export function fromRegisterFields(options: string[]): Fields {
  138. // 修正 phone,code
  139. const k1 = 'phone';
  140. const k2 = 'code';
  141. const index = options.findIndex(key => key.startsWith(k1));
  142. if ( index !== -1 && !options.find(key => key.startsWith(k2)) ) {
  143. const value = options[ index ].replace(k1, k2);
  144. options.splice(index + 1, 0, value);
  145. }
  146. return options.map(option => {
  147. const values = option.split(':');
  148. const name = toCamelCase(values[ 0 ]);
  149. const field = Fields[ name as unknown as FieldKey ] ?? {
  150. control: { label: name, type: 'text' },
  151. rules: [],
  152. };
  153. if ( values[ 1 ] === 'required' ) field.rules.push({ required: true, message: field.control.placeholder ?? '请补充完整' });
  154. return { ...field, name } as Fields[number];
  155. });
  156. }