/** * 判断对象类型 * @param {*} obj 对象 */ export function objTypeOf(obj: any): string { const map = { '[object Boolean]': 'boolean', '[object Number]': 'number', '[object String]': 'string', '[object Function]': 'function', '[object Array]': 'array', '[object Date]': 'date', '[object RegExp]': 'regExp', '[object Undefined]': 'undefined', '[object Null]': 'null', '[object Object]': 'object', '[object Blob]': 'blob', }; return map[Object.prototype.toString.call(obj)]; } /** * 将目标对象中有的属性值与源对象中的属性值合并 * @param {Object} target 目标对象 * @param {Object} sources 源对象 */ export function objAssign(target: T, sources: object): T { const targ = { ...target }; Object.keys(targ).forEach((k) => { targ[k] = Object.prototype.hasOwnProperty.call(sources, k) ? sources[k] : targ[k]; }); return targ; } /** * 使用目标对象中有的属性值修改源对象中的属性值 * @param {Object} target 目标对象 * @param {Object} sources 源对象 */ export function objModifyAssign(target: object, sources: object): void { Object.keys(target).forEach((k) => { if (Object.prototype.hasOwnProperty.call(sources, k)) { target[k] = sources[k]; } }); } /** * 获取随机code,默认获取16位 * @param {Number} len 推荐8的倍数 * */ export function randomCode(len = 16) { if (len <= 0) return ''; const steps = Math.ceil(len / 8); const stepNums = []; for (let i = 0; i < steps; i++) { const ranNum = Math.random().toString(32).slice(-8); stepNums.push(ranNum); } return stepNums.join(''); } /** * 序列化参数 * @param {Object} params 参数对象 */ export function qsParams(params: Record) { return Object.entries(params) .map((el) => `${el[0]}=${el[1]}`) .join('&'); } /** * * @param {String} format 时间格式 * @param {Date} date 需要格式化的时间对象 */ export function formatDate( format = 'YYYY/MM/DD HH:mm:ss', date = new Date() ): string { if (objTypeOf(date) !== 'date') return ''; const options = { 'Y+': date.getFullYear(), 'M+': date.getMonth() + 1, 'D+': date.getDate(), 'H+': date.getHours(), 'm+': date.getMinutes(), 's+': date.getSeconds(), }; Object.entries(options).forEach(([key, val]) => { if (new RegExp(`(${key})`).test(format)) { const zeros = key === 'Y+' ? '0000' : '00'; const valLen = `${val}`.length; const value = (zeros + val).substr(valLen); format = format.replace(RegExp.$1, value); } }); return format; } /** * 获取时间长度文字 * @param {Number} timeNumber 时间数值,单位:毫秒 */ export function timeNumberToText(timeNumber: number): string { const DAY_TIME = 24 * 60 * 60 * 1000; const HOUR_TIME = 60 * 60 * 1000; const MINUTE_TIME = 60 * 1000; const SECOND_TIME = 1000; let [day, hour, minute, second] = [0, 0, 0, 0]; let residueTime = timeNumber; if (residueTime >= DAY_TIME) { day = Math.floor(residueTime / DAY_TIME); residueTime -= day * DAY_TIME; } if (residueTime >= HOUR_TIME) { hour = Math.floor(residueTime / HOUR_TIME); residueTime -= hour * HOUR_TIME; } if (residueTime >= MINUTE_TIME) { minute = Math.floor(residueTime / MINUTE_TIME); residueTime -= minute * MINUTE_TIME; } if (residueTime >= SECOND_TIME) { second = Math.round(residueTime / SECOND_TIME); } return [`${day}天`, `${hour}小时`, `${minute}分钟`, `${second}秒`] .filter((item) => !!item) .join(''); } /** * 警告时间 * @param {Number} timeNumber 时间数值,单位:毫秒 * @param {Number} wainingTime 最大剩余警告时间数值,单位:毫秒 */ export function residueFloorTime(timeNumber: number, wainingTime = 0) { if (timeNumber < 0) { return { status: 'danger', title: '已过期' }; } const DAY_TIME = 24 * 60 * 60 * 1000; const HOUR_TIME = 60 * 60 * 1000; const MINUTE_TIME = 60 * 1000; const status = timeNumber < wainingTime ? 'warning' : 'primary'; let [day, hour, minute] = [0, 0, 0]; let residueTime = timeNumber; if (residueTime >= DAY_TIME) { day = Math.floor(residueTime / DAY_TIME); residueTime -= day * DAY_TIME; return { status, title: `剩余${day}天`, }; } if (residueTime >= HOUR_TIME) { hour = Math.floor(residueTime / HOUR_TIME); residueTime -= hour * HOUR_TIME; return { status, title: `剩余${hour}小时`, }; } if (residueTime >= MINUTE_TIME) { minute = Math.floor(residueTime / MINUTE_TIME); return { status, title: `剩余${minute}分钟`, }; } return { status, title: `不足1分钟`, }; } export function parseTimeRangeDateAndTime(startTime: number, endTime: number) { if (!startTime || !endTime) return { date: '', time: '', }; const st = formatDate('YYYY-MM-DD HH:mm', new Date(startTime)).split(' '); const et = formatDate('YYYY-MM-DD HH:mm', new Date(endTime)).split(' '); return { date: st[0], time: `${st[1]}-${et[1]}`, }; } export function parseTimeRangeDateAndTimeContent( startTime: number, endTime: number ) { const { date, time } = parseTimeRangeDateAndTime(startTime, endTime); return `${date} ${time}`; } /** * 获取本地时间,格式:年月日时分秒 */ export function localNowDateTime() { return formatDate('YYYY年MM月DD日HH时mm分ss秒'); } /** * * @param {Number} time 时间戳 */ export function getTimeDatestamp(time: number) { const date = formatDate('YYYY-MM-DD HH:mm', new Date(time)).split(' ')[0]; return new Date(`${date} 00:00:00`).getTime(); } /** * 获取指定元素个数的数组 * @param {Number} num */ export function getNumList(num: number) { return '#'.repeat(num).split(''); } /** * 清除html标签 * @param {String} str html字符串 */ export function removeHtmlTag(str: string) { return str.replace(/<[^>]+>/g, ''); } /** * 计算总数 * @param {Array} dataList 需要统计的数组 */ export function calcSum(dataList: number[]) { if (!dataList.length) return 0; return dataList.reduce((total, item) => { return total + item; }, 0); } /** * 计算评卷数 * @param {Array} dataList 需要统计的数组 */ export function calcAvg(dataList: number[]) { if (!dataList.length) return 0; return calcSum(dataList) / dataList.length; } /** 获取数组最大数 */ export function maxNum(dataList: number[]) { if (!dataList.length) return 0; return Math.max.apply(null, dataList); } export function isEmptyObject(obj: object) { return !Object.keys(obj).length; } export function humpToLowLine(a: string) { return a .replace(/([A-Z])/g, '-$1') .toLowerCase() .slice(1); } export function pickByNotNull(params: Record) { const nData = {}; (Object.entries(params) as [string, any][]).forEach(([key, val]) => { if (val === null || val === 'null' || val === '') return; nData[key] = val; }); return nData; } export function autoSubmitForm(url: string, params: Record) { const form = document.createElement('form'); form.action = url; form.method = 'post'; (Object.entries(params) as [string, any][]).forEach(([key, val]) => { const input = document.createElement('input'); input.type = 'hidden'; input.name = key; input.value = val; form.appendChild(input); }); document.body.appendChild(form); form.submit(); } export function blobToText(blob: Blob): Promise { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.readAsText(blob, 'utf-8'); reader.onload = () => { resolve(reader.result); }; reader.onerror = () => { reject(); }; }); } export function parseHrefParam( urlStr: string, paramName = '' ): Record | null { if (!urlStr) return null; const url = new URL(urlStr); const urlParams = new URLSearchParams(url.search); if (paramName) return urlParams.get(paramName as string); const params = {}; (urlParams.entries() as [string, string][]).forEach(([k, v]) => { params[k] = v; }); return params; } /** * 将字典数据转成为option列表数据 * @param data 字典数据 * @returns option列表 */ export function dictToOption(dict: Record) { const options = [] as Array<{ value: number | string | boolean; label: string; }>; const booleanStrs = ['true', 'false']; Object.keys(dict).forEach((k) => { options.push({ value: booleanStrs.includes(k) ? (JSON.parse(k) as boolean) : k, label: dict[k], }); }); return options; } /** * 蛇形转驼峰 * @param name 蛇形字符 * @returns 驼峰字符 */ export function snakeToHump(name: string): string { return name .split('-') .map((item) => item[0].toLocaleUpperCase() + item.substring(1)) .join(''); } export function deepCopy(data: T): T { return JSON.parse(JSON.stringify(data)); }