import moment from 'moment'; import Reg from '../constants/validate'; import * as Pictures from '../pictures'; import qs from 'qs'; const dateFrom = 'YYYY/MM/DD'; export const dateFormatter = { YYYYMMDDHM: 'YYYY-MM-DD HH:mm', }; export const formDateText = value => { if (value) { value = value < 0 ? 0 : value; let day = parseInt(value / 1000 / 60 / 60 / 24); let hour = parseInt((value / 1000 / 60 / 60) % 24); let minutes = parseInt((value / 1000 / 60) % 60); let seconds = parseInt((value / 1000) % 60); if (seconds > 0) { minutes += 1; } return `${day > 0 ? `${day} 天` : ''} ${hour > 9 ? hour : `0${hour}`} 小时 ${ minutes > 9 ? minutes : `0${minutes}` } 分`; } return ''; }; export const formDate = (value, type = dateFrom) => { if (value) { return moment(value * 1000).format(type); } return ''; }; export const percentageStay = (value, all, id, fn) => { if (value) { return (value / all).toFixed(2) * 100 > 100 ? 0 : (value / all).toFixed(2) * 100; } fn && fn(id); return 0; }; export const dateFormatToMoment = (timestamp, format = dateFrom) => { return moment(new Date(timestamp * 1000), format); }; export const dateFormatToString = (timestamp, format = dateFrom) => { return moment(new Date(timestamp * 1000)).format(format); }; export const dateFormatToTimestamp = (date, format = dateFrom) => { if (!date) return null; return parseInt(moment(date).valueOf() / 1000); }; //获取两个时间戳的时间差值 // unit:years,months,minutes,seconds // new Date 是 13 位的时间戳,使用的时候注意targetTimestamp,是否一致 export const dateDiffTimestamp = (currTimestamp, targetTimestamp, unit = 'days') => { currTimestamp = currTimestamp ? currTimestamp : new Date(); return moment(currTimestamp).diff(moment(targetTimestamp), unit); }; //获取两个时间冲的差值,单位为天,不按照小时计算 export const dateDiffTimestampByDay = (currTimestamp, targetTimestamp) => { currTimestamp = currTimestamp ? currTimestamp : new Date(); return moment(moment(currTimestamp).format(dateFrom)).diff( moment(targetTimestamp * 1000).format(dateFrom), 'days' ); }; export const setSessionStorageItem = (key, val) => { sessionStorage.setItem(key, JSON.stringify(val)); }; export const removeSessionStorageItem = (key, val) => { sessionStorage.removeItem(key); }; export const getSessionStorageItem = key => { const value = sessionStorage.getItem(key); if (value) { return JSON.parse(value); } return null; }; export const setLocalStorageItem = (key, val) => { localStorage.setItem(key, JSON.stringify(val)); }; export const getLocalStorageItem = key => { const value = localStorage.getItem(key); if (value) { return JSON.parse(value); } return null; }; // Format money into thousandth format export const moneyFormat = (val, needDigital = false) => { if (!val && val !== 0) return ''; val = (val + '').replace(Reg.number1, ','); if (needDigital && !val.includes('.')) { return val + '.00'; } return val; }; export const trimSpace = val => { if (!val || typeof val !== 'string') return val; return val.trim(); }; // InputNumber 输入框格式化方法 export const inputNumberMoneyFormatter = value => (value ? '¥' + moneyFormat(value) : ''); // Limit only 0~9 and . can be input export const parseNumber = value => { if (!value && value !== 0) return; return value.replace(Reg.nonNumber, ''); }; // Limit only number can be input export const parseInterge = value => { if (!value && value !== 0) return; return value.toString().replace(Reg.nonInteger, ''); }; export const formatMoney = (number, places, symbol, thousand, decimal) => { number = number || 0; places = !isNaN((places = Math.abs(places))) ? places : 2; symbol = symbol || '¥'; thousand = thousand || ','; decimal = decimal || '.'; var negative = number < 0 ? '-' : '', i = parseInt((number = Math.abs(+number || 0).toFixed(places)), 10) + '', // eslint-disable-next-line j = (j = i.length) > 3 ? j % 3 : 0; return ( symbol + negative + (j ? i.substr(0, j) + thousand : '') + i.substr(j).replace(/(d{3})(?=d)/g, '$1' + thousand) + (places ? decimal + Math.abs(number - i) .toFixed(places) .slice(2) : '') ); }; /** * 在contructor函数调用 bindMethods(this), 会自动绑定组件以on和handle开头的函数 * @param {*} comInstance 组件实例 * @param {*} comClass 组件类 */ export function bindMethods(comInstance, comClass) { const prototype = comClass ? comClass.prototype : comInstance.constructor.prototype; Reflect.ownKeys(prototype).forEach(key => { if (key.startsWith('on') || key.startsWith('handle')) { comInstance[key] = comInstance[key].bind(comInstance); } }); } /** * 剔除参数中的null、undefine、NaN等 * @param {*} params 参数 */ export function getVaildParams(params) { let newParams = {}; Object.entries(params).forEach(([key, value]) => { if (![null, undefined, NaN].includes(value)) { newParams[key] = value; } }); return newParams; } /** * 将对象中的null值改为undefine * @param {*} obj */ export function replaceNullValue(obj) { if (typeof obj !== 'object') { return; } // 数组 if (Array.isArray(obj)) { obj.forEach(value => { replaceNullValue(value); }); return; } // 对象 Object.entries(obj).forEach(([key, value]) => { if (value === null) { obj[key] = undefined; } else { replaceNullValue(value); } }); } /** * 对象数组根据指定属性去重 * @param {array} 源数组 * @param {key} 属性名 * @returns 去重后的数组 */ export const uniqueArray = (array, key) => { let result = []; let obj = {}; if (!array || array.length === 0 || !array[0].hasOwnProperty(key)) return []; array.forEach(a => { if (!obj[a[key]]) { result.push(a); obj[a[key]] = true; } }); return result; }; /** * 浮点数转百位数 * @param {var} 浮点数 * @param {places} 小数位数 * @returns 转换后的百位数 */ export const floatToPercent = (val, places = 0) => { if (!val) { return val; } return (val * 100).toFixed(places); }; /** * sort object desc based on its props * @param {prop} property name * @returns result */ export const compare = (prop, desc = 1) => { return (obj1, obj2) => { var val1 = obj1[prop]; var val2 = obj2[prop]; return !desc ? val1 - val2 : val2 - val1; }; }; /** * 数字转换 * @param {var} 原始数据 */ export const formatNumber = (val, range = 1, places = 0) => { if (!val) { return val; } return Number((val * range).toFixed(places)); }; // 数字字符串 去重排序 '0,1,2,2,2,3,2,,,1' to '0,1,2,3' export const formatRangeNumber = str => { return Array.from(new Set(str.split(',').filter(item => item))) .map(item => parseInt(item)) .sort((a, b) => a - b) .join(','); }; //将base64转换为文件 export const convertBase64URLtoFile = (urlData, filename) => { const arr = urlData.split(','); const mime = arr[0].match(/:(.*?);/)[1]; const bytes = window.atob(arr[1]); var buffer = new ArrayBuffer(bytes.length); var u8arr = new Uint8Array(buffer); for (let i = 0, length = bytes.length; i < length; i++) { u8arr[i] = bytes.charCodeAt(i); } return new File([u8arr], filename, { type: mime, }); }; export const checkLong = val => { // eslint-disable-next-line var longrg = /^(-|+)?(((d|[1-9]d|1[0-7]d|0{1,3}).d{0,6})|(d|[1-9]d|1[0-7]d|0{1,3})|180.0{0,6}|180)$/; if (!longrg.test(val)) { return '经度整数部分为0-180,小数部分为0到6位!'; } return true; }; export const checkLat = val => { // eslint-disable-next-line var latreg = /^(-|+)?([0-8]?d{1}.d{0,6}|90.0{0,6}|[0-8]?d{1}|90)$/; if (!latreg.test(val)) { return '纬度整数部分为0-90,小数部分为0到6位!'; } return true; }; export const isPc = (userAgentStr = navigator.userAgent) => userAgentStr.match( /(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i ) ? false : true; export function checkDataType(target) { const typeList = { '[object Array]': 'array', '[object Object]': 'object', '[object Number]': 'number-object', '[object Boolean]': 'Boolean-object', '[object String]': 'string-object', }; if (target == null) { return 'null'; } if (typeof target === 'object') { let type = Object.prototype.toString.call(target); return typeList[type]; } else { return typeof target; } } export function isEmpty(obj) { let empty = false; switch (checkDataType(obj)) { case 'object': empty = !Boolean(Object.keys(obj).length); break; case 'array': empty = !Boolean(obj.length); break; case 'null': empty = true; break; default: break; } return empty; } /** * 检查两个数字或者字符串数组是否有交集 * @param {*} arr1 * @param {*} arr2 */ export function isIntersection(arr1, arr2) { const len = arr1.length + arr2.length; return len > new Set([...arr1, ...arr2]).size; } /** * 数值保留位数 * @param {number, string} value * @param {number} count 保留几位 * @param {boolean} round 是否四舍五入 */ export const saveDecimal = (value, count = 2, round = false) => { let newValue = parseFloat(value); if (!newValue) return 0; // 不是数字 const fn = round ? Math.round : Math.floor; if (count === 0) return fn(newValue); const tens = Math.pow(10, count); return fn(newValue * tens) / tens; }; /** * format range picker value * @param {*} validFrom eg: 1594964693 * @param {*} validTo eg: 1594964693 */ export const formatRangePickerValue = (validFrom, validTo) => [moment(validFrom), moment(validTo)]; // 费率转利率 export function interest2Rate(nper, pmt, pv, fv, type, guess) { // Sets default values for missing parameters fv = typeof fv !== 'undefined' ? fv : 0; type = typeof type !== 'undefined' ? type : 0; guess = typeof guess !== 'undefined' ? guess : 0.1; // Sets the limits for possible guesses to any // number between 0% and 100% var lowLimit = 0; var highLimit = 1; // Defines a tolerance of up to +/- 0.00005% of pmt, to accept // the solution as valid. var tolerance = Math.abs(0.00000005 * pmt); // Tries at most 40 times to find a solution within the tolerance. for (var i = 0; i < 40; i++) { // Resets the balance to the original pv. var balance = pv; // Calculates the balance at the end of the loan, based // on loan conditions. for (var j = 0; j < nper; j++) { if (type === 0) { // Interests applied before payment balance = balance * (1 + guess) + pmt; } else { // Payments applied before insterests balance = (balance + pmt) * (1 + guess); } } // Returns the guess if balance is within tolerance. If not, adjusts // the limits and starts with a new guess. if (Math.abs(balance + fv) < tolerance) { return guess; } else if (balance + fv > 0) { // Sets a new highLimit knowing that // the current guess was too big. highLimit = guess; } else { // Sets a new lowLimit knowing that // the current guess was too small. lowLimit = guess; } // Calculates the new guess. guess = (highLimit + lowLimit) / 2; } // Returns null if no acceptable result was found after 40 tries. return null; } /** * 获取对象的深层属性,不存在返回undefine * getDeepProp({ a: { b: { c: 1 } } }, 'a.b') * @param {* object} obj * @param {* string} propStr */ export function getDeepProp(obj, propStr) { if (!obj) return undefined; if (!propStr) return obj; const props = propStr.split('.'); return getDeepProp(obj[props[0]], props.slice(1).join('.')); } //手机号检验 export const checkPhone = function (phone) { if (!/^1[3456789]d{9}$/.test(phone)) { return false; } else { return true; } }; //邮箱校验 export const checkEmail = function (email) { if (!/^(w-*.*)+@(w-?)+(.w{2,})+$/.test(email)) { return false; } else { return true; } }; export const deepClone = obj => { if (!Object.prototype.toString.call(obj) === '[object Object]') { return obj; } return JSON.parse(JSON.stringify(obj)); }; export const sleep = ms => { return new Promise(resolve => setTimeout(resolve, ms)); }; // 获取搜索栏搜索参数 export const getSearchParams = () => { return qs.parse(window.location.search.slice(1)) || {}; }; //身份证截取(YYYY-MM-DD) export const getBirthdatByIdNo = iIdNo => { let tmpStr = ''; iIdNo = iIdNo.replace(/^s+|s+$/g, ''); if (iIdNo.length == 15) { tmpStr = iIdNo.substring(6, 12); tmpStr = '19' + tmpStr; tmpStr = tmpStr.substring(0, 4) + '-' + tmpStr.substring(4, 6) + '-' + tmpStr.substring(6); return tmpStr; } else { tmpStr = iIdNo.substring(6, 14); tmpStr = tmpStr.substring(0, 4) + '-' + tmpStr.substring(4, 6) + '-' + tmpStr.substring(6); return tmpStr; } }; //计算年龄(YYYY-MM-DD推出年龄) export const getAge = strAge => { let birArr = strAge.split('-'); let birYear = birArr[0]; let birMonth = birArr[1]; let birDay = birArr[2]; d = new Date(); let nowMonth = d.getMonth() + 1; //记得加1 let nowYear = d.getFullYear(); let nowDay = d.getDate(); let returnAge; if (birArr == null) { return false; } let d = new Date(birYear, birMonth - 1, birDay); if (d.getFullYear() == birYear && d.getMonth() + 1 == birMonth && d.getDate() == birDay) { if (nowYear == birYear) { returnAge = 0; } else { let ageDiff = nowYear - birYear; if (ageDiff > 0) { if (nowMonth == birMonth) { let dayDiff = nowDay - birDay; if (dayDiff < 0) { returnAge = ageDiff - 1; } else { returnAge = ageDiff; } } else { let monthDiff = nowMonth - birMonth; if (monthDiff < 0) { returnAge = ageDiff - 1; } else { returnAge = ageDiff; } } } } return returnAge; } };