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.

400 lines
10 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/* eslint-disable no-nested-ternary */
/* eslint-disable no-restricted-syntax */
/* eslint-disable guard-for-in */
/**
* num 小于0左缩进num*2个空格 大于0右缩进num*2个空格。
* @param {string} str 代码
* @param {number} num 缩进次数
* @param {number} len 【可选】缩进单位,空格数
*/
export function indent(str, num, len = 2) {
if (num === 0) return str
const isLeft = num < 0;
const result = [];
let reg;
let
spaces = ''
if (isLeft) {
num *= -1
reg = new RegExp(`(^\\s{0,${num * len}})`, 'g')
} else {
for (let i = 0; i < num * len; i++) spaces += ' '
}
str.split('\n').forEach(line => {
line = isLeft ? line.replace(reg, '') : spaces + line
result.push(line)
})
return result.join('\n')
}
// 首字母大小
export function titleCase(str) {
return str.replace(/( |^)[a-z]/g, L => L.toUpperCase())
}
// 下划转驼峰
export function camelCase(str) {
return str.replace(/-[a-z]/g, str1 => str1.substr(-1).toUpperCase())
}
export function isNumberStr(str) {
return /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(str)
}
export const exportDefault = 'export default '
export const beautifierConf = {
html: {
indent_size: '2',
indent_char: ' ',
max_preserve_newlines: '-1',
preserve_newlines: false,
keep_array_indentation: false,
break_chained_methods: false,
indent_scripts: 'separate',
brace_style: 'end-expand',
space_before_conditional: true,
unescape_strings: false,
jslint_happy: false,
end_with_newline: true,
wrap_line_length: '110',
indent_inner_html: true,
comma_first: false,
e4x: true,
indent_empty_lines: true
},
js: {
indent_size: '2',
indent_char: ' ',
max_preserve_newlines: '-1',
preserve_newlines: false,
keep_array_indentation: false,
break_chained_methods: false,
indent_scripts: 'normal',
brace_style: 'end-expand',
space_before_conditional: true,
unescape_strings: false,
jslint_happy: true,
end_with_newline: true,
wrap_line_length: '110',
indent_inner_html: true,
comma_first: false,
e4x: true,
indent_empty_lines: true
}
}
function stringify(obj) {
return JSON.stringify(obj, (key, val) => {
if (typeof val === 'function') {
return `${val}`
}
return val
})
}
function parse(str) {
JSON.parse(str, (k, v) => {
if (v.indexOf && v.indexOf('function') > -1) {
return eval(`(${v})`)
}
return v
})
}
export function jsonClone(obj) {
return parse(stringify(obj))
}
// 深拷贝对象
export function deepClone(obj) {
const _toString = Object.prototype.toString
// null, undefined, non-object, function
if (!obj || typeof obj !== 'object') {
return obj
}
// DOM Node
if (obj.nodeType && 'cloneNode' in obj) {
return obj.cloneNode(true)
}
// Date
if (_toString.call(obj) === '[object Date]') {
return new Date(obj.getTime())
}
// RegExp
if (_toString.call(obj) === '[object RegExp]') {
const flags = []
if (obj.global) {
flags.push('g')
}
if (obj.multiline) {
flags.push('m')
}
if (obj.ignoreCase) {
flags.push('i')
}
return new RegExp(obj.source, flags.join(''))
}
const result = Array.isArray(obj) ? [] : obj.constructor ? new obj.constructor() : {}
for (const key in obj) {
result[key] = deepClone(obj[key])
}
return result
}
/**
* 将用户输入的连续单个数字合并为一个数
* @param {Array} expressions - 记录计算表达式的数组
* @returns {Array} 新的数组
*/
export const mergeNumberOfExps = expressions => {
const res = []
const isNumChar = n => /^[\d|\.]$/.test(n)
for (let i = 0; i < expressions.length; i++) {
if (i > 0 && isNumChar(expressions[i - 1]) && isNumChar(expressions[i])) {
res[res.length - 1] += expressions[i]
continue
}
res.push(expressions[i])
}
return res
}
/**
* 校验表达式是否符合计算法则
* @param {Array} expressions - 合并数字后的表达式数组
* @returns {Boolean}
*/
export const validExp = (expressions, mergeNum = true) => {
const temp = mergeNum ? mergeNumberOfExps(expressions) : expressions
const arr = temp.filter(t => !'()'.includes(t))
// 去括号后 length应该为奇数 并且第一个字符和最后一个字符应该为数字而非计算符号
if (temp.length % 2 === 0 || arr.length % 2 === 0 || Number.isNaN(+arr[0]) || Number.isNaN(+arr[arr.length -
1])) {
return false
}
for (let i = 0; i < arr.length - 1; i += 2) {
if (typeof(+arr[i]) !== 'number' || !Number.isNaN(+arr[i + 1])) return false
}
return true
}
/**
* 中缀转后缀(逆波兰 Reverse Polish Notation
* @param {Array} exps - 中缀表达式数组
*/
export const toRPN = exps => {
const s1 = [] // 符号栈
const s2 = [] // 输出栈
const getTopVal = (stack) => stack.length > 0 ? stack[stack.length - 1] : null
const levelCompare = (c1, c2) => {
const getIndex = c => ['+-', '×÷', '()'].findIndex(t => t.includes(c))
return getIndex(c1) - getIndex(c2)
}
exps.forEach(t => {
if (typeof t === 'string' && Number.isNaN(Number(t))) { // 是符号
if (t === '(') {
s1.push(t)
} else if (t === ')') {
let popVal
do {
popVal = s1.pop()
popVal !== '(' && s2.push(popVal)
} while (s1.length && popVal !== '(')
} else {
let topVal = getTopVal(s1)
if (!topVal) { // s1 为空 直接push
s1.push(t)
} else {
while (topVal && topVal !== '(' && levelCompare(topVal, t) >= 0) { // 优先级 >= t 弹出到s2
s2.push(s1.pop())
topVal = getTopVal(s1)
}
s1.push(t)
}
}
return
}
s2.push(t) // 数字直接入栈
})
while (s1.length) {
s2.push(s1.pop())
}
return s2
}
/**
* 计算后缀表达式的值
* @param {Array} rpnExps - 后缀表达式
*/
export const calcRPN = rpnExps => {
rpnExps = rpnExps.concat()
const calc = (x, y, type) => {
let a1 = Number(x),
a2 = Number(y)
switch (type) {
case '+':
return a1 + a2;
case '-':
return a1 - a2;
case '×':
return a1 * a2;
case '÷':
return a1 / a2;
}
}
for (let i = 2; i < rpnExps.length; i++) {
if ('+-×÷'.includes(rpnExps[i])) {
let val = calc(rpnExps[i - 2], rpnExps[i - 1], rpnExps[i])
rpnExps.splice(i - 2, 3, val)
i = i - 2
}
}
return rpnExps[0]
}
/**
* 简易防抖函数
* @param {Function} func -防抖目标函数
* @param {Number} gap - 防抖时间间隔
*/
export const debounce = (func, gap) => {
let timer
return function() {
timer && clearTimeout(timer)
timer = setTimeout(() => {
func.apply(this, arguments)
}, gap)
}
}
//计算年或者月
export function getDateDay(Target, type, monthNum) {
let date = new Date()
let year = date.getFullYear() //获取当前日期的年份
let month = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) //获取当前日期的月份
let day = date.getDate() //获取当前日期的日
let hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours()
let minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
let seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
let days = new Date(year, month, 0)
days = days.getDate(); //获取当前日期中的月的天数
let year2 = year;
let month2;
if (Target == 2) {
if (type == 5) {
month2 = parseInt(month) + parseInt(monthNum)
if (month2 > 12) {
year2 = parseInt(year2) + parseInt((parseInt(month2) / 12 == 0 ? 1 : parseInt(month2) / 12));
month2 = parseInt(month2) % 12;
}
} else if (type == 4) {
month2 = parseInt(month) - monthNum;
if (month2 <= 0) {
let absM = Math.abs(month2);
year2 = parseInt(year2) - Math.ceil(absM / 12 == 0 ? 1 : parseInt(absM) / 12);
month2 = 12 - (absM % 12);
}
}
} else if (Target == 1) {
month2 = parseInt(month)
if (type == 5) {
year2 = parseInt(year) + parseInt(monthNum)
} else if (type == 4) {
year2 = parseInt(year) - parseInt(monthNum)
}
}
let day2 = day;
let days2 = new Date(year2, month2, 0);
days2 = days2.getDate();
if (day2 > days2) {
day2 = days2;
}
if (month2 < 10) {
month2 = '0' + month2;
}
let t2 = year2 + '-' + month2 + '-' + day2 + ' ' + hours + ':' + minutes + ':' + seconds;
return t2;
}
//计算日
export function getLaterData(days) {
let date = new Date();
date.setDate(date.getDate() + days);
let month = date.getMonth() + 1;
let day = date.getDate();
let hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours()
let minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
let seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
return date.getFullYear() + '-' + ('0' + month).slice(-2) + '-' + ('0' + day).slice(-2) + ' ' + hours + ':' +
minutes + ':' + seconds;
}
export function getBeforeData(num) {
let dateArray = []
//获取今天日期
let myDate = new Date()
let hours = myDate.getHours() < 10 ? '0' + myDate.getHours() : myDate.getHours()
let minutes = myDate.getMinutes() < 10 ? '0' + myDate.getMinutes() : myDate.getMinutes()
let seconds = myDate.getSeconds() < 10 ? '0' + myDate.getSeconds() : myDate.getSeconds()
let today = myDate.getFullYear() + '-' + (myDate.getMonth() + 1) + "-" + myDate.getDate();
myDate.setDate(myDate.getDate() - num)
let dateTemp; // 临时日期数据
let flag = 1;
for (let i = 0; i < num; i++) {
dateTemp = myDate.getFullYear() + '-' + (myDate.getMonth() + 1) + "-" + myDate.getDate()
dateArray.push({
date: dateTemp
})
myDate.setDate(myDate.getDate() + flag);
}
dateArray.push({
date: today
})
let arr = []
let newArr = []
dateArray.forEach(item => {
arr.push(item.date.split('-'))
})
for (let i = 0; i < arr.length; i++) {
if (arr[i][1] < 10) {
arr[i][1] = "0" + arr[i][1]
}
if (arr[i][2] < 10) {
arr[i][2] = "0" + arr[i][2]
}
}
for (let j = 0; j < arr.length; j++) {
newArr.push(arr[j].join("-"))
}
return newArr[0] + ' ' + hours + ':' + minutes + ':' + seconds
}
export function getBeforeTime(type, val) {
let date = new Date()
if (type == 4 || type == 1) {
date.setHours((Number(date.getHours()) - Number(val)))
} else if (type == 5 || type == 2) {
date.setMinutes((Number(date.getMinutes()) - Number(val)))
} else if (type == 6 || type == 3) {
date.setSeconds((Number(date.getSeconds()) - Number(val)))
}
return date
}
export function getLaterTime(type, val) {
let date = new Date()
if (type == 4 || type == 1) {
date.setHours((Number(date.getHours()) + Number(val)))
} else if (type == 5 || type == 2) {
date.setMinutes((Number(date.getMinutes()) + Number(val)))
} else if (type == 6 || type == 3) {
date.setSeconds((Number(date.getSeconds()) + Number(val)))
}
return date
}