index.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  1. /* eslint-disable no-nested-ternary */
  2. /* eslint-disable no-restricted-syntax */
  3. /* eslint-disable guard-for-in */
  4. /**
  5. * num 小于0,左缩进num*2个空格; 大于0,右缩进num*2个空格。
  6. * @param {string} str 代码
  7. * @param {number} num 缩进次数
  8. * @param {number} len 【可选】缩进单位,空格数
  9. */
  10. export function indent(str, num, len = 2) {
  11. if (num === 0) return str
  12. const isLeft = num < 0;
  13. const result = [];
  14. let reg;
  15. let
  16. spaces = ''
  17. if (isLeft) {
  18. num *= -1
  19. reg = new RegExp(`(^\\s{0,${num * len}})`, 'g')
  20. } else {
  21. for (let i = 0; i < num * len; i++) spaces += ' '
  22. }
  23. str.split('\n').forEach(line => {
  24. line = isLeft ? line.replace(reg, '') : spaces + line
  25. result.push(line)
  26. })
  27. return result.join('\n')
  28. }
  29. // 首字母大小
  30. export function titleCase(str) {
  31. return str.replace(/( |^)[a-z]/g, L => L.toUpperCase())
  32. }
  33. // 下划转驼峰
  34. export function camelCase(str) {
  35. return str.replace(/-[a-z]/g, str1 => str1.substr(-1).toUpperCase())
  36. }
  37. export function isNumberStr(str) {
  38. return /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(str)
  39. }
  40. export const exportDefault = 'export default '
  41. export const beautifierConf = {
  42. html: {
  43. indent_size: '2',
  44. indent_char: ' ',
  45. max_preserve_newlines: '-1',
  46. preserve_newlines: false,
  47. keep_array_indentation: false,
  48. break_chained_methods: false,
  49. indent_scripts: 'separate',
  50. brace_style: 'end-expand',
  51. space_before_conditional: true,
  52. unescape_strings: false,
  53. jslint_happy: false,
  54. end_with_newline: true,
  55. wrap_line_length: '110',
  56. indent_inner_html: true,
  57. comma_first: false,
  58. e4x: true,
  59. indent_empty_lines: true
  60. },
  61. js: {
  62. indent_size: '2',
  63. indent_char: ' ',
  64. max_preserve_newlines: '-1',
  65. preserve_newlines: false,
  66. keep_array_indentation: false,
  67. break_chained_methods: false,
  68. indent_scripts: 'normal',
  69. brace_style: 'end-expand',
  70. space_before_conditional: true,
  71. unescape_strings: false,
  72. jslint_happy: true,
  73. end_with_newline: true,
  74. wrap_line_length: '110',
  75. indent_inner_html: true,
  76. comma_first: false,
  77. e4x: true,
  78. indent_empty_lines: true
  79. }
  80. }
  81. function stringify(obj) {
  82. return JSON.stringify(obj, (key, val) => {
  83. if (typeof val === 'function') {
  84. return `${val}`
  85. }
  86. return val
  87. })
  88. }
  89. function parse(str) {
  90. JSON.parse(str, (k, v) => {
  91. if (v.indexOf && v.indexOf('function') > -1) {
  92. return eval(`(${v})`)
  93. }
  94. return v
  95. })
  96. }
  97. export function jsonClone(obj) {
  98. return parse(stringify(obj))
  99. }
  100. // 深拷贝对象
  101. export function deepClone(obj) {
  102. const _toString = Object.prototype.toString
  103. // null, undefined, non-object, function
  104. if (!obj || typeof obj !== 'object') {
  105. return obj
  106. }
  107. // DOM Node
  108. if (obj.nodeType && 'cloneNode' in obj) {
  109. return obj.cloneNode(true)
  110. }
  111. // Date
  112. if (_toString.call(obj) === '[object Date]') {
  113. return new Date(obj.getTime())
  114. }
  115. // RegExp
  116. if (_toString.call(obj) === '[object RegExp]') {
  117. const flags = []
  118. if (obj.global) {
  119. flags.push('g')
  120. }
  121. if (obj.multiline) {
  122. flags.push('m')
  123. }
  124. if (obj.ignoreCase) {
  125. flags.push('i')
  126. }
  127. return new RegExp(obj.source, flags.join(''))
  128. }
  129. const result = Array.isArray(obj) ? [] : obj.constructor ? new obj.constructor() : {}
  130. for (const key in obj) {
  131. result[key] = deepClone(obj[key])
  132. }
  133. return result
  134. }
  135. /**
  136. * 将用户输入的连续单个数字合并为一个数
  137. * @param {Array} expressions - 记录计算表达式的数组
  138. * @returns {Array} 新的数组
  139. */
  140. export const mergeNumberOfExps = expressions => {
  141. const res = []
  142. const isNumChar = n => /^[\d|\.]$/.test(n)
  143. for (let i = 0; i < expressions.length; i++) {
  144. if (i > 0 && isNumChar(expressions[i - 1]) && isNumChar(expressions[i])) {
  145. res[res.length - 1] += expressions[i]
  146. continue
  147. }
  148. res.push(expressions[i])
  149. }
  150. return res
  151. }
  152. /**
  153. * 校验表达式是否符合计算法则
  154. * @param {Array} expressions - 合并数字后的表达式数组
  155. * @returns {Boolean}
  156. */
  157. export const validExp = (expressions, mergeNum = true) => {
  158. const temp = mergeNum ? mergeNumberOfExps(expressions) : expressions
  159. const arr = temp.filter(t => !'()'.includes(t))
  160. // 去括号后 length应该为奇数 并且第一个字符和最后一个字符应该为数字而非计算符号
  161. if (temp.length % 2 === 0 || arr.length % 2 === 0 || Number.isNaN(+arr[0]) || Number.isNaN(+arr[arr.length -
  162. 1])) {
  163. return false
  164. }
  165. for (let i = 0; i < arr.length - 1; i += 2) {
  166. if (typeof(+arr[i]) !== 'number' || !Number.isNaN(+arr[i + 1])) return false
  167. }
  168. return true
  169. }
  170. /**
  171. * 中缀转后缀(逆波兰 Reverse Polish Notation)
  172. * @param {Array} exps - 中缀表达式数组
  173. */
  174. export const toRPN = exps => {
  175. const s1 = [] // 符号栈
  176. const s2 = [] // 输出栈
  177. const getTopVal = (stack) => stack.length > 0 ? stack[stack.length - 1] : null
  178. const levelCompare = (c1, c2) => {
  179. const getIndex = c => ['+-', '×÷', '()'].findIndex(t => t.includes(c))
  180. return getIndex(c1) - getIndex(c2)
  181. }
  182. exps.forEach(t => {
  183. if (typeof t === 'string' && Number.isNaN(Number(t))) { // 是符号
  184. if (t === '(') {
  185. s1.push(t)
  186. } else if (t === ')') {
  187. let popVal
  188. do {
  189. popVal = s1.pop()
  190. popVal !== '(' && s2.push(popVal)
  191. } while (s1.length && popVal !== '(')
  192. } else {
  193. let topVal = getTopVal(s1)
  194. if (!topVal) { // s1 为空 直接push
  195. s1.push(t)
  196. } else {
  197. while (topVal && topVal !== '(' && levelCompare(topVal, t) >= 0) { // 优先级 >= t 弹出到s2
  198. s2.push(s1.pop())
  199. topVal = getTopVal(s1)
  200. }
  201. s1.push(t)
  202. }
  203. }
  204. return
  205. }
  206. s2.push(t) // 数字直接入栈
  207. })
  208. while (s1.length) {
  209. s2.push(s1.pop())
  210. }
  211. return s2
  212. }
  213. /**
  214. * 计算后缀表达式的值
  215. * @param {Array} rpnExps - 后缀表达式
  216. */
  217. export const calcRPN = rpnExps => {
  218. rpnExps = rpnExps.concat()
  219. const calc = (x, y, type) => {
  220. let a1 = Number(x),
  221. a2 = Number(y)
  222. switch (type) {
  223. case '+':
  224. return a1 + a2;
  225. case '-':
  226. return a1 - a2;
  227. case '×':
  228. return a1 * a2;
  229. case '÷':
  230. return a1 / a2;
  231. }
  232. }
  233. for (let i = 2; i < rpnExps.length; i++) {
  234. if ('+-×÷'.includes(rpnExps[i])) {
  235. let val = calc(rpnExps[i - 2], rpnExps[i - 1], rpnExps[i])
  236. rpnExps.splice(i - 2, 3, val)
  237. i = i - 2
  238. }
  239. }
  240. return rpnExps[0]
  241. }
  242. /**
  243. * 简易防抖函数
  244. * @param {Function} func -防抖目标函数
  245. * @param {Number} gap - 防抖时间间隔
  246. */
  247. export const debounce = (func, gap) => {
  248. let timer
  249. return function() {
  250. timer && clearTimeout(timer)
  251. timer = setTimeout(() => {
  252. func.apply(this, arguments)
  253. }, gap)
  254. }
  255. }
  256. //计算年或者月
  257. export function getDateDay(Target, type, monthNum) {
  258. let date = new Date()
  259. let year = date.getFullYear() //获取当前日期的年份
  260. let month = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) //获取当前日期的月份
  261. let day = date.getDate() //获取当前日期的日
  262. let hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours()
  263. let minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
  264. let seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
  265. let days = new Date(year, month, 0)
  266. days = days.getDate(); //获取当前日期中的月的天数
  267. let year2 = year;
  268. let month2;
  269. if (Target == 2) {
  270. if (type == 5) {
  271. month2 = parseInt(month) + parseInt(monthNum)
  272. if (month2 > 12) {
  273. year2 = parseInt(year2) + parseInt((parseInt(month2) / 12 == 0 ? 1 : parseInt(month2) / 12));
  274. month2 = parseInt(month2) % 12;
  275. }
  276. } else if (type == 4) {
  277. month2 = parseInt(month) - monthNum;
  278. if (month2 <= 0) {
  279. let absM = Math.abs(month2);
  280. year2 = parseInt(year2) - Math.ceil(absM / 12 == 0 ? 1 : parseInt(absM) / 12);
  281. month2 = 12 - (absM % 12);
  282. }
  283. }
  284. } else if (Target == 1) {
  285. month2 = parseInt(month)
  286. if (type == 5) {
  287. year2 = parseInt(year) + parseInt(monthNum)
  288. } else if (type == 4) {
  289. year2 = parseInt(year) - parseInt(monthNum)
  290. }
  291. }
  292. let day2 = day;
  293. let days2 = new Date(year2, month2, 0);
  294. days2 = days2.getDate();
  295. if (day2 > days2) {
  296. day2 = days2;
  297. }
  298. if (month2 < 10) {
  299. month2 = '0' + month2;
  300. }
  301. let t2 = year2 + '-' + month2 + '-' + day2 + ' ' + hours + ':' + minutes + ':' + seconds;
  302. return t2;
  303. }
  304. //计算日
  305. export function getLaterData(days) {
  306. let date = new Date();
  307. date.setDate(date.getDate() + days);
  308. let month = date.getMonth() + 1;
  309. let day = date.getDate();
  310. let hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours()
  311. let minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
  312. let seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
  313. return date.getFullYear() + '-' + ('0' + month).slice(-2) + '-' + ('0' + day).slice(-2) + ' ' + hours + ':' +
  314. minutes + ':' + seconds;
  315. }
  316. export function getBeforeData(num) {
  317. let dateArray = []
  318. //获取今天日期
  319. let myDate = new Date()
  320. let hours = myDate.getHours() < 10 ? '0' + myDate.getHours() : myDate.getHours()
  321. let minutes = myDate.getMinutes() < 10 ? '0' + myDate.getMinutes() : myDate.getMinutes()
  322. let seconds = myDate.getSeconds() < 10 ? '0' + myDate.getSeconds() : myDate.getSeconds()
  323. let today = myDate.getFullYear() + '-' + (myDate.getMonth() + 1) + "-" + myDate.getDate();
  324. myDate.setDate(myDate.getDate() - num)
  325. let dateTemp; // 临时日期数据
  326. let flag = 1;
  327. for (let i = 0; i < num; i++) {
  328. dateTemp = myDate.getFullYear() + '-' + (myDate.getMonth() + 1) + "-" + myDate.getDate()
  329. dateArray.push({
  330. date: dateTemp
  331. })
  332. myDate.setDate(myDate.getDate() + flag);
  333. }
  334. dateArray.push({
  335. date: today
  336. })
  337. let arr = []
  338. let newArr = []
  339. dateArray.forEach(item => {
  340. arr.push(item.date.split('-'))
  341. })
  342. for (let i = 0; i < arr.length; i++) {
  343. if (arr[i][1] < 10) {
  344. arr[i][1] = "0" + arr[i][1]
  345. }
  346. if (arr[i][2] < 10) {
  347. arr[i][2] = "0" + arr[i][2]
  348. }
  349. }
  350. for (let j = 0; j < arr.length; j++) {
  351. newArr.push(arr[j].join("-"))
  352. }
  353. return newArr[0] + ' ' + hours + ':' + minutes + ':' + seconds
  354. }
  355. export function getBeforeTime(type, val) {
  356. let date = new Date()
  357. if (type == 4 || type == 1) {
  358. date.setHours((Number(date.getHours()) - Number(val)))
  359. } else if (type == 5 || type == 2) {
  360. date.setMinutes((Number(date.getMinutes()) - Number(val)))
  361. } else if (type == 6 || type == 3) {
  362. date.setSeconds((Number(date.getSeconds()) - Number(val)))
  363. }
  364. return date
  365. }
  366. export function getLaterTime(type, val) {
  367. let date = new Date()
  368. if (type == 4 || type == 1) {
  369. date.setHours((Number(date.getHours()) + Number(val)))
  370. } else if (type == 5 || type == 2) {
  371. date.setMinutes((Number(date.getMinutes()) + Number(val)))
  372. } else if (type == 6 || type == 3) {
  373. date.setSeconds((Number(date.getSeconds()) + Number(val)))
  374. }
  375. return date
  376. }