import dayjs from 'dayjs'; import { toast } from '@/utils/widget'; import validate from "@/utils/validate"; const FormRule = { date: checkDate, input: checkInput, radio: checkListItem, select: checkListItem, textarea: checkInput, selectMobile: checkInput, selectAndOther: checkInput, selectAndImage: checkListItem, multiSelectAndOther: checkMultiList, files: checkFiles, runTime: checkInput, } const fixedRule = { mobile: checkMobile, idCard: checkIdCard, } export default function verify(items, rule = {}, data = {}) { const rules = { ...fixedRule, ...rule }; for (let item of items) { const value = data[item.title]; // 非自定义表单 数据验证 if (item.operateType === 'formCell' && FormRule[item.type]) { const valid = FormRule[item.type](item, value); if (!valid) return false } // 自定义校验规则 检验表单 // 自定义校验表单规则 必须是函数且返回结果只能是 错误信息或者 true if (typeof rules[item.title] === 'function') { const res = rules[item.title](value, item.name); if (typeof res === 'string') { toast(res); return false } else if (res !== true) { console.error('自定义检验规则只能返回 字符串或者true') } } } return true } function checkDate({ name, required }, value) { if (!required && !isTrueValue(value)) return true; if (required && !isTrueValue(value)) { toast(`请选择${name}`) return false } if (!dayjs(value).isValid()) { toast(`${name}格式不正确`) return false } return true } function checkListItem({ range, name, required }, value) { if (isTrueValue(value)) { if (!Array.isArray(range) || range.length === 0) { toast(`${name}所选值无效,请重新选择`) return false } const candidate = typeof value === 'string' || typeof value === 'number' ? String(value) : value; const isObjectRange = range.length > 0 && range[0] && typeof range[0] === 'object'; if (isObjectRange) { const values = range .map((i) => (i && typeof i === 'object' && 'value' in i ? i.value : undefined)) .filter((i) => i !== undefined && i !== null) .map((i) => String(i)); if (!values.includes(String(candidate))) { toast(`${name}所选值无效,请重新选择`) return false } } else if (!range.map((i) => String(i)).includes(String(candidate))) { toast(`${name}所选值无效,请重新选择`) return false } } else { if (required) { toast(`请选择${name}`) return false } } return true } function checkMobile(value, name) { if (isTrueValue(value)) { const res = validate.isMobile(value); if (res) return true; else return `${name}格式不正确` } return true } function checkIdCard(value, name) { if (isTrueValue(value)) { const [res, msg] = validate.isChinaId(value); if (res) return true; else return msg || `${name}格式不正确` } return true } function checkInput({ name, required, wordLimit, inputType }, value) { if (!required && !isTrueValue(value)) return true; if (required && !isTrueValue(value)) { toast(`请输入${name}`) return false } if (wordLimit > 0 && inputType === 'text' && value.toString().length > wordLimit) { toast(`${name}最多输入${wordLimit}个字符`) return false } return true } function checkMultiList({ name, required }, value) { const list = Array.isArray(value) ? value.filter(isTrueValue) : []; if (required && list.length === 0) { toast(`请选择${name}`) return false } return true } function checkFiles({ name, required }, value) { const list = Array.isArray(value) ? value .map((i) => { if (typeof i === 'string') return i; if (i && typeof i === 'object' && i.url) return String(i.url); return ''; }) .filter((i) => typeof i === 'string' && i.trim() !== '') : typeof value === 'string' && value.trim() !== '' ? [value] : []; if (required && list.length === 0) { toast(`请上传${name}`) return false } return true } function isTrueValue(value) { if (typeof value === 'string') return value.trim() !== ''; if (typeof value === 'number') return true; return Boolean(value) }