效验相关
/**
* 手机号码
* @param val 当前值字符串
* @returns 返回 true: 手机号码正确
*/
export function verifyPhone(val) {
// false: 手机号码不正确
// if (
// !/^((12[0-9])|(13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(16([0-3]|[5-9]))|(17([0-3]|[5-9]))|(18[0,5-9]))\d{8}$/.test(
// val
// )
// ) {
if (!/^1[3-9]\d{9}$/.test(val)) {
return false
} else {
return true
}
}
/**
* 国内电话号码
* @param val 当前值字符串
* @returns 返回 true: 国内电话号码正确
*/
export function verifyTelPhone(val) {
// false: 国内电话号码不正确
if (!/\d{3}-\d{8}|\d{4}-\d{7}/.test(val)) return false
// true: 国内电话号码正确
else return true
}
/**
* 密码 (以字母开头,长度在6~16之间,只能包含字母、数字和下划线)
* @param val 当前值字符串
* @returns 返回 true: 密码正确
*/
export function verifyPassword(val) {
// false: 密码不正确
if (!/^[a-zA-Z]\w{5,15}$/.test(val)) return false
// true: 密码正确
else return true
}
/**
* 强密码 (字母+数字+特殊字符,长度在6-16之间)
* @param val 当前值字符串
* @returns 返回 true: 强密码正确
*/
export function verifyPasswordPowerful(val) {
// false: 强密码不正确
if (
!/^(?![a-zA-z]+$)(?!\d+$)(?![!@#$%^&\.*]+$)(?![a-zA-z\d]+$)(?![a-zA-z!@#$%^&\.*]+$)(?![\d!@#$%^&\.*]+$)[a-zA-Z\d!@#$%^&\.*]{6,16}$/.test(
val
)
) {
return false
} else {
return true
}
}
/**
* 密码强度
* @param val 当前值字符串
* @description 弱:纯数字,纯字母,纯特殊字符
* @description 中:字母+数字,字母+特殊字符,数字+特殊字符
* @description 强:字母+数字+特殊字符
* @returns 返回处理后的字符串:弱、中、强
*/
export function verifyPasswordStrength(val) {
let v = ''
// 弱:纯数字,纯字母,纯特殊字符
if (/^(?:\d+|[a-zA-Z]+|[!@#$%^&\.*]+){6,16}$/.test(val)) v = '弱'
// 中:字母+数字,字母+特殊字符,数字+特殊字符
if (/^(?![a-zA-z]+$)(?!\d+$)(?![!@#$%^&\.*]+$)[a-zA-Z\d!@#$%^&\.*]{6,16}$/.test(val)) v = '中'
// 强:字母+数字+特殊字符
if (
/^(?![a-zA-z]+$)(?!\d+$)(?![!@#$%^&\.*]+$)(?![a-zA-z\d]+$)(?![a-zA-z!@#$%^&\.*]+$)(?![\d!@#$%^&\.*]+$)[a-zA-Z\d!@#$%^&\.*]{6,16}$/.test(
val
)
) {
v = '强'
}
// 返回结果
return v
}
/**
* IP地址
* @param val 当前值字符串
* @returns 返回 true: IP地址正确
*/
export function verifyIPAddress(val) {
// false: IP地址不正确
if (
!/^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/.test(
val
)
) {
return false
} else {
return true
}
}
/**
* 邮箱
* @param val 当前值字符串
* @returns 返回 true: 邮箱正确
*/
export function verifyEmail(val) {
// false: 邮箱不正确
if (
!/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(
val
)
) {
return false
} else {
return true
}
}
/**
* 身份证
* @param val 当前值字符串
* @returns 返回 true: 身份证正确
*/
export function verifyIdCard(val) {
// false: 身份证不正确
/**
* 表达式解释
* ^[1-9]\d{5}:身份证号码的前6位是行政区划代码,以1-9的数字开头,后面跟着5个数字。
* (18|19|20)\d{2}:接下来的4位是年份,可以是18、19或20开头的年份。
* (0[1-9]|1[0-2]):接下来的2位是月份,01到12之间的数字。
* (0[1-9]|[12]\d|3[01]):接下来的2位是日期,可以是01到31之间的数字。
* \d{3}:接下来的3位是顺序码,通常是随机生成的数字。
* [\dxX]$:最后一位是校验位,可以是数字、小写字母x或大写字母X,用于校验身份证号码的合法性。
*/
if (!/^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dxX]$/.test(val)) {
return false
} else {
return true
}
}
/**
* 姓名
* @param val 当前值字符串
* @returns 返回 true: 姓名正确
*/
export function verifyFullName(val) {
// false: 姓名不正确
if (!/^[\u4e00-\u9fa5]{1,6}(·[\u4e00-\u9fa5]{1,6}){0,2}$/.test(val)) return false
// true: 姓名正确
else return true
}
/**
* 邮政编码
* @param val 当前值字符串
* @returns 返回 true: 邮政编码正确
*/
export function verifyPostalCode(val) {
// false: 邮政编码不正确
if (!/^[1-9][0-9]{5}$/.test(val)) return false
// true: 邮政编码正确
else return true
}
/**
* url 处理
* @param val 当前值字符串
* @returns 返回 true: url 正确
*/
export function verifyUrl(val) {
// false: url不正确
if (
!/^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test(
val
)
) {
return false
} else {
return true
}
}
/**
* 验证码位数校验
* @param {*} val 验证码
* @param {*} num 验证码位数
*/
export function verifyCode(val) {
const reg = new RegExp(/^[0-9]\d{5}$/)
if (!reg.test(val)) return false
else return true
}
/**
* 验证百分比(不可以小数)
* @param val 当前值字符串
* @returns 返回处理后的字符串
*/
export function verifyNumberPercentage(val) {
// 匹配空格
let v = val.replace(/(^\s*)|(\s*$)/g, '')
// 只能是数字和小数点,不能是其他输入
v = v.replace(/[^\d]/g, '')
// 不能以0开始
v = v.replace(/^0/g, '')
// 数字超过100,赋值成最大值100
v = v.replace(/^[1-9]\d\d{1,3}$/, '100')
// 返回结果
return v
}
/**
* 验证百分比(可以小数)
* @param val 当前值字符串
* @returns 返回处理后的字符串
*/
export function verifyNumberPercentageFloat(val) {
let v = verifyNumberIntegerAndFloat(val)
// 数字超过100,赋值成最大值100
v = v.replace(/^[1-9]\d\d{1,3}$/, '100')
// 超过100之后不给再输入值
v = v.replace(/^100\.$/, '100')
// 返回结果
return v
}
/**
* 小数或整数(不可以负数)
* @param val 当前值字符串
* @returns 返回处理后的字符串
*/
export function verifyNumberIntegerAndFloat(val) {
// 匹配空格
let v = val.replace(/(^\s*)|(\s*$)/g, '')
// 只能是数字和小数点,不能是其他输入
v = v.replace(/[^\d.]/g, '')
// 以0开始只能输入一个
v = v.replace(/^0{2}$/g, '0')
// 保证第一位只能是数字,不能是点
v = v.replace(/^\./g, '')
// 小数只能出现1位
v = v.replace('.', '$#$').replace(/\./g, '').replace('$#$', '.')
// 小数点后面保留2位
v = v.replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3')
// 返回结果
return v
}
/**
* 检测是否是Number类型,排除NaN
*/
export function isNumber(number) {
return /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(number)
}
/**
* 正整数验证
* @param val 当前值字符串
* @returns 返回处理后的字符串
*/
export function verifiyNumberInteger(val) {
// 匹配空格
let v = val.replace(/(^\s*)|(\s*$)/g, '')
// 去掉 '.' , 防止贴贴的时候出现问题 如 0.1.12.12
v = v.replace(/[\.]*/g, '')
// 去掉以 0 开始后面的数, 防止贴贴的时候出现问题 如 00121323
v = v.replace(/(^0[\d]*)$/g, '0')
// 首位是0,只能出现一次
v = v.replace(/^0\d$/g, '0')
// 只匹配数字
v = v.replace(/[^\d]/g, '')
// 返回结果
return v
}
/**
* 去掉中文及空格
* @param val 当前值字符串
* @returns 返回处理后的字符串
*/
export function verifyCnAndSpace(val) {
// 匹配中文与空格
let v = val.replace(/[\u4e00-\u9fa5\s]+/g, '')
// 匹配空格
v = v.replace(/(^\s*)|(\s*$)/g, '')
// 返回结果
return v
}
/**
* 去掉英文及空格
* @param val 当前值字符串
* @returns 返回处理后的字符串
*/
export function verifyEnAndSpace(val) {
// 匹配英文与空格
let v = val.replace(/[a-zA-Z]+/g, '')
// 匹配空格
v = v.replace(/(^\s*)|(\s*$)/g, '')
// 返回结果
return v
}
/**
* 禁止输入空格
* @param val 当前值字符串
* @returns 返回处理后的字符串
*/
export function verifyAndSpace(val) {
// 匹配空格
const v = val.replace(/(^\s*)|(\s*$)/g, '')
// 返回结果
return v
}
文件相关
export const downloadFile = (url = '', fileName = '未知文件', cb) => {
const a = document.createElement('a')
a.style.display = 'none'
a.setAttribute('target', '_blank')
/*
* download的属性是HTML5新增的属性
* href属性的地址必须是非跨域的地址,如果引用的是第三方的网站或者说是前后端分离的项目(调用后台的接口),这时download就会不起作用。
* 此时,如果是下载浏览器无法解析的文件,例如.exe,.xlsx..那么浏览器会自动下载,但是如果使用浏览器可以解析的文件,比如.txt,.png,.pdf....浏览器就会采取预览模式
* 所以,对于.txt,.png,.pdf等的预览功能我们就可以直接不设置download属性(前提是后端响应头的Content-Type: application/octet-stream,如果为application/pdf浏览器则会判断文件为 pdf ,自动执行预览的策略)
*/
fileName && a.setAttribute('download', fileName)
a.href = url
document.body.appendChild(a)
a.click()
document.body.removeChild(a)
cb && cb()
}
export const downloadBlob = (data, fileName = '未知文件.xlsx', type) => {
const blob = new Blob([data], { type }) // 处理文档流
const a = document.createElement('a') // 创建a标签
a.download = fileName.replace(new RegExp('"', 'g'), '')
a.style.display = 'none'
a.href = URL.createObjectURL(blob) // 创建blob地址
document.body.appendChild(a) // 将a标签添加到body中
a.click()
URL.revokeObjectURL(a.href) // 释放URL对象
document.body.removeChild(a) // 从body中移除a标签
}
/**
* 文件大小转换对应单位大小
* @param size 文件大小,字节(B)单位
* @returns 返回 string
*/
export function transformFileSizeUnit(size) {
if (!size) return ''
let sizestr = ''
if (size < 0.1 * 1024) {
// 如果小于0.1KB转化成B
sizestr = size.toFixed(2) + 'B'
} else if (size < 1 * 1024 * 1024) {
// 如果小于1MB转化成KB
sizestr = (size / 1024).toFixed(2) + 'KB'
} else if (size < 1 * 1024 * 1024 * 1024) {
// 如果小于1GB转化成MB
sizestr = (size / (1024 * 1024)).toFixed(2) + 'MB'
} else {
// 其他转化成GB
sizestr = (size / (1024 * 1024 * 1024)).toFixed(2) + 'GB'
}
return sizestr.replace('.00', '')
}
/**
* @description: 将 BASE64 转换文件
* @param {*}
* @return {*}
*/
export const dataURLtoFile = (dataurl, filename) => {
const arr = dataurl.split(',');
const mime = arr[0].match(/:(.*?);/)[1];
if (!filename) filename = `${Date.parse(new Date())}.jpg`;
const bstr = window.atob(arr[1]);
let n = bstr.length;
const u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], filename, { type: mime });
}
工具函数
/**
* 金额用 `,` 区分开
* @param val 当前值字符串
* @returns 返回处理后的字符串
*/
export function verifyNumberComma(val) {
// 调用小数或整数(不可以负数)方法
let v = verifyNumberIntegerAndFloat(val)
// 字符串转成数组
v = v.toString().split('.')
// \B 匹配非单词边界,两边都是单词字符或者两边都是非单词字符
v[0] = v[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',')
// 数组转字符串
v = v.join('.')
// 返回结果
return v
}
/**
* 匹配文字变色(搜索时)
* @param val 当前值字符串
* @param text 要处理的字符串值
* @param color 搜索到时字体高亮颜色
* @returns 返回处理后的字符串
*/
export function verifyTextColor(val, text = '', color = 'red') {
// 返回内容,添加颜色
const v = text.replace(new RegExp(val, 'gi'), `<span style='color: ${color}'>${val}</span>`)
// 返回结果
return v
}
/**
* 数字转中文大写
* @param val 当前值字符串
* @param unit 默认:仟佰拾亿仟佰拾万仟佰拾元角分
* @returns 返回处理后的字符串
*/
export function verifyNumberCnUppercase(val, unit = '仟佰拾亿仟佰拾万仟佰拾元角分', v = '') {
// 当前内容字符串添加 2个0,为什么??
val += '00'
// 返回某个指定的字符串值在字符串中首次出现的位置,没有出现,则该方法返回 -1
const lookup = val.indexOf('.')
// substring:不包含结束下标内容,substr:包含结束下标内容
if (lookup >= 0) val = val.substring(0, lookup) + val.substr(lookup + 1, 2)
// 根据内容 val 的长度,截取返回对应大写
unit = unit.substr(unit.length - val.length)
// 循环截取拼接大写
for (let i = 0; i < val.length; i++) {
v += '零壹贰叁肆伍陆柒捌玖'.substr(val.substr(i, 1), 1) + unit.substr(i, 1)
}
// 正则处理
v = v
.replace(/零角零分$/, '整')
.replace(/零[仟佰拾]/g, '零')
.replace(/零{2,}/g, '零')
.replace(/零([亿|万])/g, '$1')
.replace(/零+元/, '元')
.replace(/亿零{0,3}万/, '亿')
.replace(/^元/, '零元')
// 返回结果
return v
}
/**
* 多维数组去重(包含对象)
* @param {Array} arrayData // 需要去重的数组
* @param {String} key // 根据属性进行去重
*/
export const multiArrayDedup = (arrayData = [], key = '') => {
const hashKey = {}
const result = [
...new Set(
arrayData.reduce((item, next) => {
return item.concat(next)
}, [])
)
].reduce((item, next) => {
if (next[key]) {
// eslint-disable-next-line no-unused-expressions
hashKey[next[key]] ? '' : (hashKey[next[key]] = true && item.push(next))
} else {
item.push(next)
}
return item
}, [])
return result
}
/**
* 对象数组去重
* @param {Array} arrayData // 需要去重的数组
* @param {String} key // 根据属性进行去重
*/
export const objectArrayDedup = (arrayData = [], key = '') => {
const hash = {} // 缓存对象数组里的某一个属性
const result = arrayData.reduce((item, next, index, data) => {
// eslint-disable-next-line no-unused-expressions
hash[next[key]] ? '' : (hash[next[key]] = true && item.push(next))
return item
}, [])
return result
}
/**
* 普通数组去重
* @param {Array} arrayData // 需要去重的数组
*/
export const normalArrayDedup = (arrayData = []) => {
const result = arrayData.reduce((item, next) => {
item.indexOf(next) === -1 && item.push(next)
return item
}, [])
return result
}
/**
* 判断是否文本溢出
* @param e 事件对象
* @returns 返回true为未溢出 false溢出
*/
export const isBeyond = e => {
const ev = window.event || e
const textRange = el => {
const textContent = el
const targetW = textContent.getBoundingClientRect().width
const range = document.createRange()
range.setStart(textContent, 0)
range.setEnd(textContent, textContent.childNodes.length)
const rangeWidth = range.getBoundingClientRect().width
return rangeWidth > targetW
}
return !textRange(ev.target)
}
// 获取字数 中文单字算一个字数 英文按空格算一个字数
// 例如:a app 两个字数
// a app 很好 四个字数
export const tokenizeLens = text => {
// 英文分词:按空格分词
const englishTokens = text.split(' ')
// 中文分词:按单个字符分词
const chineseTokens = text.split('').filter(char => /[\u4e00-\u9fff]/.test(char))
// 合并英文字符和中文单字
const tokens = englishTokens.concat(chineseTokens)
// 返回词汇总数
return tokens.length
}
评论