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

2 months ago
/* 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
}