You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
210 lines
5.9 KiB
210 lines
5.9 KiB
import { isObject } from '@vue/shared' |
|
import { cloneDeep } from 'lodash' |
|
import moment from 'moment' |
|
|
|
/** |
|
* @description 添加单位 |
|
* @param {String | Number} value 值 100 |
|
* @param {String} unit 单位 px em rem |
|
*/ |
|
export const addUnit = (value: string | number, unit = 'px') => { |
|
return !Object.is(Number(value), NaN) ? `${value}${unit}` : value |
|
} |
|
|
|
/** |
|
* @description 添加单位 |
|
* @param {unknown} value |
|
* @return {Boolean} |
|
*/ |
|
export const isEmpty = (value: unknown) => { |
|
return value == null && typeof value == 'undefined' |
|
} |
|
|
|
/** |
|
* @description 树转数组,队列实现广度优先遍历 |
|
* @param {Array} data 数据 |
|
* @param {Object} props `{ children: 'children' }` |
|
*/ |
|
|
|
export const treeToArray = (data: any[], props = { children: 'children' }) => { |
|
data = cloneDeep(data) |
|
const { children } = props |
|
const newData = [] |
|
const queue: any[] = [] |
|
data.forEach((child: any) => queue.push(child)) |
|
while (queue.length) { |
|
const item: any = queue.shift() |
|
if (item[children]) { |
|
item[children].forEach((child: any) => queue.push(child)) |
|
delete item[children] |
|
} |
|
newData.push(item) |
|
} |
|
return newData |
|
} |
|
|
|
/** |
|
* @description 数组转 |
|
* @param {Array} data 数据 |
|
* @param {Object} props `{ parent: 'pid', children: 'children' }` |
|
*/ |
|
|
|
export const arrayToTree = ( |
|
data: any[], |
|
props = { id: 'id', parentId: 'pid', children: 'children' } |
|
) => { |
|
data = cloneDeep(data) |
|
const { id, parentId, children } = props |
|
const result: any[] = [] |
|
const map = new Map() |
|
data.forEach((item) => { |
|
map.set(item[id], item) |
|
const parent = map.get(item[parentId]) |
|
if (parent) { |
|
parent[children] = parent[children] ?? [] |
|
parent[children].push(item) |
|
} else { |
|
result.push(item) |
|
} |
|
}) |
|
return result |
|
} |
|
|
|
/** |
|
* @description 获取正确的路经 |
|
* @param {String} path 数据 |
|
*/ |
|
export function getNormalPath(path: string) { |
|
if (path.length === 0 || !path || path == 'undefined') { |
|
return path |
|
} |
|
const newPath = path.replace('//', '/') |
|
const length = newPath.length |
|
if (newPath[length - 1] === '/') { |
|
return newPath.slice(0, length - 1) |
|
} |
|
return newPath |
|
} |
|
|
|
/** |
|
* @description对象格式化为Query语法 |
|
* @param { Object } params |
|
* @return {string} Query语法 |
|
*/ |
|
export function objectToQuery(params: Record<string, any>): string { |
|
let query = '' |
|
for (const props of Object.keys(params)) { |
|
const value = params[props] |
|
const part = encodeURIComponent(props) + '=' |
|
if (!isEmpty(value)) { |
|
if (isObject(value)) { |
|
for (const key of Object.keys(value)) { |
|
if (!isEmpty(value[key])) { |
|
const params = props + '[' + key + ']' |
|
const subPart = encodeURIComponent(params) + '=' |
|
query += subPart + encodeURIComponent(value[key]) + '&' |
|
} |
|
} |
|
} else { |
|
query += part + encodeURIComponent(value) + '&' |
|
} |
|
} |
|
} |
|
return query.slice(0, -1) |
|
} |
|
|
|
/** |
|
* @description 时间格式化 |
|
* @param dateTime { number } 时间戳 |
|
* @param fmt { string } 时间格式 |
|
* @return { string } |
|
*/ |
|
// yyyy:mm:dd|yyyy:mm|yyyy年mm月dd日|yyyy年mm月dd日 hh时MM分等,可自定义组合 |
|
export const timeFormat = (dateTime: number, fmt = 'yyyy-mm-dd') => { |
|
// 如果为null,则格式化当前时间 |
|
if (!dateTime) { |
|
dateTime = Number(new Date()) |
|
} |
|
// 如果dateTime长度为10或者13,则为秒和毫秒的时间戳,如果超过13位,则为其他的时间格式 |
|
if (dateTime.toString().length == 10) { |
|
dateTime *= 1000 |
|
} |
|
const date = new Date(dateTime) |
|
let ret |
|
const opt: any = { |
|
'y+': date.getFullYear().toString(), // 年 |
|
'm+': (date.getMonth() + 1).toString(), // 月 |
|
'd+': date.getDate().toString(), // 日 |
|
'h+': date.getHours().toString(), // 时 |
|
'M+': date.getMinutes().toString(), // 分 |
|
's+': date.getSeconds().toString() // 秒 |
|
} |
|
for (const k in opt) { |
|
ret = new RegExp('(' + k + ')').exec(fmt) |
|
if (ret) { |
|
fmt = fmt.replace( |
|
ret[1], |
|
ret[1].length == 1 ? opt[k] : opt[k].padStart(ret[1].length, '0') |
|
) |
|
} |
|
} |
|
return fmt |
|
} |
|
|
|
export const timeDiffSeconds = (dateStr1: string, dateStr2: string, fmt: string) => { |
|
return moment(dateStr1, fmt).diff(moment(dateStr2, fmt), 'seconds') |
|
} |
|
|
|
/** |
|
* |
|
* @param seconds |
|
* @returns |
|
*/ |
|
export const formatTimeText = (seconds: number) => { |
|
if (!seconds || seconds <= 0) { |
|
return '' |
|
} |
|
// 秒 |
|
if (seconds < 60) { |
|
return seconds + '秒' |
|
} |
|
// 分钟 |
|
if (seconds < 3600) { |
|
return `${ Math.floor(seconds / 60) }分${ seconds % 60 }秒` |
|
} |
|
// 小时 |
|
if (seconds < 86400) { |
|
const remainder = seconds % 3600; |
|
return `${ Math.floor(seconds / 3600) }小时${ parseInt(seconds % 3600 / 60) }分` |
|
} |
|
// 天 |
|
const remainder = seconds % 86400; |
|
return `${ Math.floor(seconds / 86400) }天${ parseInt(seconds % 86400 / 3600) }小时` |
|
} |
|
|
|
/** |
|
* @description 获取不重复的id |
|
* @param length { Number } id的长度 |
|
* @return { String } id |
|
*/ |
|
export const getNonDuplicateID = (length = 8) => { |
|
let idStr = Date.now().toString(36) |
|
idStr += Math.random().toString(36).substring(3, length) |
|
return idStr |
|
} |
|
|
|
/** |
|
* @description 单词首字母大写 |
|
* @param { String } str |
|
* @return { String } id |
|
*/ |
|
export const firstToUpperCase = (str = '') => { |
|
return str.toLowerCase().replace(/( |^)[a-z]/g, ($1) => $1.toUpperCase()) |
|
} |
|
|
|
export const getDictLable = (dictArr: any[], value: string) => { |
|
if (!value) { |
|
return '' |
|
} |
|
return dictArr.filter(item => item.value === value)[0].name |
|
} |