formVerify.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. "use strict";
  2. import FieldCheck from "./fieldCheck";
  3. // import {formItemData, formObject, formOption, FormVerifyOption} from "./types/formVerify";
  4. let hasOwnProperty = Object.prototype.hasOwnProperty;
  5. function hasOwn(obj, key) {
  6. return hasOwnProperty.call(obj, key);
  7. }
  8. /**
  9. * @class FormItem 表单验证类
  10. * @description 表单项
  11. * @param {formObject} formObject 表单项数据
  12. * @param {FieldCheck} [fieldCheck] 字段验证对象
  13. * @param {object} [option] 配置项
  14. */
  15. class FormVerify {
  16. constructor(formObject, fieldCheck, option) {
  17. this.formData = null;
  18. this.defaultOption = {
  19. isMustMatchRule: false,
  20. };
  21. this.option = {
  22. isMustMatchRule: false,
  23. };
  24. this.formState_default = 0;
  25. this.formState_pass = 1;
  26. this.formState_notPass = 2;
  27. // onLog函数
  28. this.onLog = (msg) => {
  29. // 不进行任何操作.
  30. };
  31. this.fieldCheck = fieldCheck || new FieldCheck();
  32. // 合并配置项
  33. this.option = Object.assign(this.defaultOption, option);
  34. let errMsg;
  35. // 拿出其中的每一项来构建对应的表单项
  36. for (let key in formObject) {
  37. // this.formData[key] = object[key];
  38. // 验证表单项是否符合要求,不符合要求则抛出错误
  39. errMsg = FormVerify.buildFormItem(formObject, key, formObject[key], this.fieldCheck, this.option.isMustMatchRule);
  40. if (errMsg) {
  41. throw new Error(`表单项${key}不符合要求,err:${errMsg}`);
  42. }
  43. }
  44. this.formData = formObject;
  45. }
  46. static isObject(obj) {
  47. return obj !== null && typeof obj === 'object';
  48. }
  49. /**
  50. * 检查表单项是否符合要求
  51. * @param object 表单项数据
  52. * @param field 字段名
  53. * @param formItemData 表单项数据
  54. * @param fieldCheck 字段验证对象
  55. * @param isMustMatchRule 表单字段是否必须匹配到验证规则
  56. * @returns errMsg 错误信息
  57. */
  58. static buildFormItem(object, field, formItemData, fieldCheck, isMustMatchRule) {
  59. if (!FormVerify.isObject(formItemData)) {
  60. return `form item ${field} must be object`;
  61. }
  62. // 是否需要从验证规则表中查找对应的验证规则
  63. let isNeedMatchRule = true;
  64. // 用于匹配的字段
  65. let checkFieldStr = field;
  66. let disables = formItemData.disables;
  67. // 设置默认值
  68. formItemData.val = formItemData.val || formItemData.init || '';
  69. // 设置默认提示词
  70. formItemData.msg = formItemData.msg || '';
  71. // 设置默认状态
  72. formItemData.state = formItemData.state || FormVerify.formState_default;
  73. // 设置默认显示文本
  74. formItemData.label = formItemData.label || '';
  75. // 判断是否有 options 选项有则判断是否有 init 选项,没有则设置第一个为 init
  76. if (formItemData.options) {
  77. if (!formItemData.options.length || !formItemData.options[0]) {
  78. return `form item ${field} options must be array and has item`;
  79. }
  80. if (!formItemData.init) {
  81. formItemData.init = formItemData.options[0].key;
  82. }
  83. // 判断 val 与 init 是否存在于 options 中
  84. let hasInit = false;
  85. for (let i = 0; i < formItemData.options.length; i++) {
  86. let option = formItemData.options[i];
  87. if (option.key === formItemData.init) {
  88. hasInit = true;
  89. }
  90. // 判断该options是否为禁用项
  91. if (disables && disables.find(item => item === option.key)) {
  92. option.disabled = true;
  93. }
  94. }
  95. if (!hasInit) {
  96. return `form item ${field} init value must be in options`;
  97. }
  98. }
  99. // 判断是否有 depend 依赖字段 有依赖字段则依据依赖字段中的 option 中的 checkField 字段进行判断
  100. if (formItemData.depend && formItemData.reCheckField) {
  101. return `form item ${field} has depend and reCheckField, but depend and reCheckField can not exist at the same time`;
  102. }
  103. // 判断是否有 depend 依赖字段 有依赖字段则依据依赖字段中的 option 中的 checkField 字段进行判断
  104. if (formItemData.depend) {
  105. let hasCheckField = false;
  106. let dependStr = formItemData.depend;
  107. let dependOptions = [];
  108. // 判断object 是否为 formObject 并且不为undefined
  109. if (!object) {
  110. return `form item ${field} depend field ${dependStr} but the field not exist`;
  111. }
  112. // 设置 object 不为undefined
  113. object = object;
  114. // 判断依赖字段是否存在
  115. if (!object[dependStr]) {
  116. return `form item ${field} depend field ${dependStr} but the field not exist`;
  117. }
  118. // 判断依赖字段的 option 是否存在
  119. if (!object[dependStr].options) {
  120. return `form item ${field} depend field ${dependStr} has no options`;
  121. }
  122. // 判断依赖字段的 options 中是否有 checkField 字段
  123. dependOptions = object[dependStr].options;
  124. for (let i = 0; i < dependOptions.length; i++) {
  125. let option = object ? dependOptions[i] : null;
  126. if (option === null || option === void 0 ? void 0 : option.checkField) {
  127. hasCheckField = true;
  128. checkFieldStr = option.checkField;
  129. break;
  130. }
  131. }
  132. if (!hasCheckField) {
  133. return `form item ${field} depend field ${dependStr} has no checkField`;
  134. }
  135. }
  136. // 判断是否有 reCheckField 有则使用该字段的值进行规则验证
  137. if (formItemData.reCheckField) {
  138. checkFieldStr = formItemData.reCheckField;
  139. }
  140. // 判断是否有 rules 规则
  141. if (isMustMatchRule) {
  142. if (fieldCheck.getRuleItem(checkFieldStr)) {
  143. return `form item ${field} has no rules`;
  144. }
  145. }
  146. return '';
  147. }
  148. /**
  149. * 初始化表单项数据
  150. * @param { formObject } formObject 表单对象
  151. */
  152. static initFormItemData(formObject) {
  153. let keys = Object.keys(formObject);
  154. for (let i = 0; i < keys.length; i++) {
  155. let key = keys[i];
  156. formObject[key].val = formObject[key].init;
  157. formObject[key].msg = '';
  158. formObject[key].state = FormVerify.formState_default;
  159. formObject[key].showText = '';
  160. }
  161. }
  162. /**
  163. * 检查表单项是否符合要求
  164. * @param {formObject} form 表单对象
  165. * @param isMustMatch 是否必须全部匹配到验证规则
  166. * @returns {boolean}
  167. */
  168. checkForm(form, isMustMatch) {
  169. let r = true;
  170. let n_checkPass = 0, n_checkTotal = 0;
  171. let tmpOption = {};
  172. let logStr = '';
  173. let logHandle = (_str) => {
  174. try {
  175. this.onLog(_str);
  176. }
  177. catch (e) {
  178. console.log(_str);
  179. console.error(e);
  180. }
  181. };
  182. for (const fieldKey in form) {
  183. let formItem = form[fieldKey];
  184. logStr = '';
  185. let isFailed = false;
  186. if (!formItem) {
  187. continue;
  188. }
  189. let depend = form[formItem.depend || ''];
  190. let checkField = fieldKey;
  191. logHandle(`检测字段:${checkField},值:${formItem.val}`);
  192. n_checkTotal++;
  193. if (formItem.notCheck) {
  194. n_checkPass++;
  195. logStr = `项${fieldKey} 不进行检查`;
  196. formItem.state = this.formState_pass;
  197. formItem.msg = '';
  198. logHandle(logStr);
  199. continue;
  200. }
  201. if (formItem.reCheckField) {
  202. checkField = formItem.reCheckField;
  203. }
  204. // 禁用值判断 array
  205. if (formItem.disables) {
  206. if (formItem.disables.find(item => item === formItem.val)) {
  207. // console.log(`项${fieldKey} 的值为禁用值`)
  208. logStr = `项${fieldKey} 检测到禁用值`;
  209. formItem.msg = '该项内容不合法';
  210. formItem.state = this.formState_notPass;
  211. isFailed = true;
  212. if (logStr)
  213. logHandle(logStr);
  214. // 如果是匹配到禁用字段, 后续的检测不进行
  215. continue;
  216. }
  217. }
  218. // 枚举值判断
  219. if (formItem.options) {
  220. // 有枚举字段,只判断是否在枚举中
  221. // console.log(`检测枚举字段:${checkField},值:${formItem.val}`);
  222. tmpOption = formItem.options.find(item => item.value == formItem.val);
  223. // tmpInd = formItem.options.findIndex(item=>item.value == formItem.val);
  224. if (tmpOption) {
  225. if (tmpOption.disabled) {
  226. logStr = `项${fieldKey} 检测枚举字段:${checkField},值:${formItem.val}被禁用`;
  227. formItem.msg = '该选项已经被禁用';
  228. formItem.state = this.formState_notPass;
  229. isFailed = true;
  230. }
  231. // 检查通过
  232. formItem.state = this.formState_pass;
  233. formItem.msg = '';
  234. }
  235. else {
  236. logStr = `项${fieldKey} 检测枚举字段:${checkField},值:${formItem.val}不在范围内`;
  237. formItem.msg = '选项不在范围内';
  238. formItem.state = this.formState_notPass;
  239. isFailed = true;
  240. }
  241. if (logStr)
  242. logHandle(logStr);
  243. // 枚举值判断完毕,继续下一个字段
  244. n_checkPass++;
  245. continue;
  246. }
  247. // 依赖字段判断
  248. if (depend) {
  249. depend = depend;
  250. if (depend.options) {
  251. // 依赖的对象有枚举类型,检查该枚举类型是否有有检测值
  252. let optionItem = depend.options.find(item => item.value == formItem.val);
  253. if (!optionItem) {
  254. logStr = `检测依赖字段:${depend},但是选项${formItem.val}不在范围内`;
  255. depend.msg = '选项不在范围内';
  256. formItem.msg = '该值依赖项输入异常';
  257. isFailed = true;
  258. // continue;
  259. }
  260. optionItem = optionItem;
  261. if (optionItem.checkField) {
  262. // console.log(`采用依赖项的检测字段${optionItem.checkField}`)
  263. checkField = optionItem.checkField;
  264. }
  265. }
  266. else {
  267. logStr = `项${fieldKey} 依赖表单项:${depend},没有对应 options 内容`;
  268. isFailed = true;
  269. }
  270. if (!r) {
  271. logStr = `项${fieldKey} 检测依赖字段:${depend},但是选项${formItem.val}不在范围内`;
  272. depend.msg = '该项依赖项输入异常';
  273. formItem.msg = '该值依赖项输入异常';
  274. formItem.state = this.formState_notPass;
  275. }
  276. }
  277. // 使用验证规则进行
  278. formItem.msg = this.fieldCheck.verify({
  279. [checkField]: formItem.val,
  280. isMustMatch
  281. });
  282. if (formItem.msg) {
  283. isFailed = true;
  284. logStr = `检测字段:${checkField},值:${formItem.val}不符合规则,${formItem.msg}`;
  285. }
  286. if (isFailed) {
  287. logStr = `检测字段:${checkField},值:${formItem.val}不符合规则,${formItem.msg}`;
  288. formItem.state = this.formState_notPass;
  289. r = false;
  290. }
  291. else {
  292. n_checkPass++;
  293. logStr = `检测字段:${checkField},值:${formItem.val}符合规则`;
  294. formItem.state = this.formState_pass;
  295. formItem.msg = '';
  296. }
  297. if (logStr)
  298. logHandle(logStr);
  299. }
  300. logHandle(`检查表单项通过率:${n_checkPass}/${n_checkTotal}`);
  301. return r;
  302. }
  303. /**
  304. * 验证当前的表单是否符合要求
  305. * @param [isMustMatch] 是否必须全部匹配到验证规则
  306. */
  307. check(isMustMatch = false) {
  308. return this.checkForm(this.formData, isMustMatch);
  309. }
  310. /**
  311. * 检测特定表单项的内容是否符合规则
  312. * @param field 字段名
  313. * @param isMustMatch 是否必须匹配到验证规则 默认 true
  314. */
  315. checkItem(field, isMustMatch = true) {
  316. var _a, _b;
  317. // 获取表单项
  318. let formItem;
  319. let depend;
  320. let formObject = {};
  321. formItem = (_a = this === null || this === void 0 ? void 0 : this.formData) === null || _a === void 0 ? void 0 : _a[field];
  322. if (!formItem) {
  323. return null;
  324. }
  325. formObject[field] = formItem;
  326. // 判断是否有depend字段
  327. if (formItem.depend) {
  328. formObject[formItem.depend] = (_b = this.formData) === null || _b === void 0 ? void 0 : _b[formItem.depend];
  329. }
  330. let pass = this.checkForm(formObject, isMustMatch);
  331. // 检查表单项是否符合要求
  332. return formObject[field].msg ? formObject[field].msg : null;
  333. }
  334. /**
  335. * 使用该表单绑定的验证器进行验证字段与值是否符合规则
  336. * @param field 要验证的字段
  337. * @param value 要验证的值
  338. * @param isMustMatch
  339. */
  340. verifyKnV(field, value, isMustMatch = true) {
  341. return this.fieldCheck.verify({
  342. [field]: value,
  343. }, isMustMatch);
  344. }
  345. /**
  346. * 获取表单keyValue数据对
  347. * @returns {verifyForm} key:value
  348. */
  349. getFormData() {
  350. let formData = {};
  351. for (const key in this.formData) {
  352. if (hasOwn(this.formData, key)) {
  353. const formItem = this.formData[key];
  354. formData[key] = formItem.val;
  355. }
  356. }
  357. return formData;
  358. }
  359. init() {
  360. FormVerify.initFormItemData(this.formData);
  361. }
  362. }
  363. export default FormVerify;
  364. //# sourceMappingURL=formVerify.js.map