tools.js 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. // +----------------------------------------------------------------------
  2. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  3. // +----------------------------------------------------------------------
  4. // | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
  5. // +----------------------------------------------------------------------
  6. // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  7. // +----------------------------------------------------------------------
  8. // | Author: CRMEB Team <admin@crmeb.com>
  9. // +----------------------------------------------------------------------
  10. export const forEach = (arr, fn) => {
  11. if (!arr.length || !fn) return
  12. let i = -1
  13. let len = arr.length
  14. while (++i < len) {
  15. let item = arr[i]
  16. fn(item, i, arr)
  17. }
  18. }
  19. /**
  20. * @param {Array} arr1
  21. * @param {Array} arr2
  22. * @description 得到两个数组的交集, 两个数组的元素为数值或字符串
  23. */
  24. export const getIntersection = (arr1, arr2) => {
  25. let len = Math.min(arr1.length, arr2.length)
  26. let i = -1
  27. let res = []
  28. while (++i < len) {
  29. const item = arr2[i]
  30. if (arr1.indexOf(item) > -1) res.push(item)
  31. }
  32. return res
  33. }
  34. /**
  35. * @param {Array} arr1
  36. * @param {Array} arr2
  37. * @description 得到两个数组的并集, 两个数组的元素为数值或字符串
  38. */
  39. export const getUnion = (arr1, arr2) => {
  40. return Array.from(new Set([...arr1, ...arr2]))
  41. }
  42. /**
  43. * @param {Array} target 目标数组
  44. * @param {Array} arr 需要查询的数组
  45. * @description 判断要查询的数组是否至少有一个元素包含在目标数组中
  46. */
  47. export const hasOneOf = (targetarr, arr) => {
  48. return targetarr.some(_ => arr.indexOf(_) > -1)
  49. }
  50. /**
  51. * @param {String|Number} value 要验证的字符串或数值
  52. * @param {*} validList 用来验证的列表
  53. */
  54. export function oneOf (value, validList) {
  55. for (let i = 0; i < validList.length; i++) {
  56. if (value === validList[i]) {
  57. return true
  58. }
  59. }
  60. return false
  61. }
  62. /**
  63. * @param {Number} timeStamp 判断时间戳格式是否是毫秒
  64. * @returns {Boolean}
  65. */
  66. const isMillisecond = timeStamp => {
  67. const timeStr = String(timeStamp)
  68. return timeStr.length > 10
  69. }
  70. /**
  71. * @param {Number} timeStamp 传入的时间戳
  72. * @param {Number} currentTime 当前时间时间戳
  73. * @returns {Boolean} 传入的时间戳是否早于当前时间戳
  74. */
  75. const isEarly = (timeStamp, currentTime) => {
  76. return timeStamp < currentTime
  77. }
  78. /**
  79. * @param {Number} num 数值
  80. * @returns {String} 处理后的字符串
  81. * @description 如果传入的数值小于10,即位数只有1位,则在前面补充0
  82. */
  83. const getHandledValue = num => {
  84. return num < 10 ? '0' + num : num
  85. }
  86. /**
  87. * @param {Number} timeStamp 传入的时间戳
  88. * @param {Number} startType 要返回的时间字符串的格式类型,传入'year'则返回年开头的完整时间
  89. */
  90. const getDate = (timeStamp, startType) => {
  91. const d = new Date(timeStamp * 1000)
  92. const year = d.getFullYear()
  93. const month = getHandledValue(d.getMonth() + 1)
  94. const date = getHandledValue(d.getDate())
  95. const hours = getHandledValue(d.getHours())
  96. const minutes = getHandledValue(d.getMinutes())
  97. const second = getHandledValue(d.getSeconds())
  98. let resStr = ''
  99. if (startType === 'year') resStr = year + '-' + month + '-' + date + ' ' + hours + ':' + minutes + ':' + second
  100. else resStr = month + '-' + date + ' ' + hours + ':' + minutes
  101. return resStr
  102. }
  103. /**
  104. * @param {String|Number} timeStamp 时间戳
  105. * @returns {String} 相对时间字符串
  106. */
  107. export const getRelativeTime = timeStamp => {
  108. // 判断当前传入的时间戳是秒格式还是毫秒
  109. const IS_MILLISECOND = isMillisecond(timeStamp)
  110. // 如果是毫秒格式则转为秒格式
  111. if (IS_MILLISECOND) Math.floor(timeStamp /= 1000)
  112. // 传入的时间戳可以是数值或字符串类型,这里统一转为数值类型
  113. timeStamp = Number(timeStamp)
  114. // 获取当前时间时间戳
  115. const currentTime = Math.floor(Date.parse(new Date()) / 1000)
  116. // 判断传入时间戳是否早于当前时间戳
  117. const IS_EARLY = isEarly(timeStamp, currentTime)
  118. // 获取两个时间戳差值
  119. let diff = currentTime - timeStamp
  120. // 如果IS_EARLY为false则差值取反
  121. if (!IS_EARLY) diff = -diff
  122. let resStr = ''
  123. const dirStr = IS_EARLY ? '前' : '后'
  124. // 少于等于59秒
  125. if (diff <= 59) resStr = diff + '秒' + dirStr
  126. // 多于59秒,少于等于59分钟59秒
  127. else if (diff > 59 && diff <= 3599) resStr = Math.floor(diff / 60) + '分钟' + dirStr
  128. // 多于59分钟59秒,少于等于23小时59分钟59秒
  129. else if (diff > 3599 && diff <= 86399) resStr = Math.floor(diff / 3600) + '小时' + dirStr
  130. // 多于23小时59分钟59秒,少于等于29天59分钟59秒
  131. else if (diff > 86399 && diff <= 2623859) resStr = Math.floor(diff / 86400) + '天' + dirStr
  132. // 多于29天59分钟59秒,少于364天23小时59分钟59秒,且传入的时间戳早于当前
  133. else if (diff > 2623859 && diff <= 31567859 && IS_EARLY) resStr = getDate(timeStamp)
  134. else resStr = getDate(timeStamp, 'year')
  135. return resStr
  136. }
  137. /**
  138. * @returns {String} 当前浏览器名称
  139. */
  140. export const getExplorer = () => {
  141. const ua = window.navigator.userAgent
  142. const isExplorer = (exp) => {
  143. return ua.indexOf(exp) > -1
  144. }
  145. if (isExplorer('MSIE')) return 'IE'
  146. else if (isExplorer('Firefox')) return 'Firefox'
  147. else if (isExplorer('Chrome')) return 'Chrome'
  148. else if (isExplorer('Opera')) return 'Opera'
  149. else if (isExplorer('Safari')) return 'Safari'
  150. }
  151. /**
  152. * @description 绑定事件 on(element, event, handler)
  153. */
  154. export const on = (function () {
  155. if (document.addEventListener) {
  156. return function (element, event, handler) {
  157. if (element && event && handler) {
  158. element.addEventListener(event, handler, false)
  159. }
  160. }
  161. } else {
  162. return function (element, event, handler) {
  163. if (element && event && handler) {
  164. element.attachEvent('on' + event, handler)
  165. }
  166. }
  167. }
  168. })()
  169. /**
  170. * @description 解绑事件 off(element, event, handler)
  171. */
  172. export const off = (function () {
  173. if (document.removeEventListener) {
  174. return function (element, event, handler) {
  175. if (element && event) {
  176. element.removeEventListener(event, handler, false)
  177. }
  178. }
  179. } else {
  180. return function (element, event, handler) {
  181. if (element && event) {
  182. element.detachEvent('on' + event, handler)
  183. }
  184. }
  185. }
  186. })()
  187. /**
  188. * 判断一个对象是否存在key,如果传入第二个参数key,则是判断这个obj对象是否存在key这个属性
  189. * 如果没有传入key这个参数,则判断obj对象是否有键值对
  190. */
  191. export const hasKey = (obj, key) => {
  192. if (key) return key in obj
  193. else {
  194. let keysArr = Object.keys(obj)
  195. return keysArr.length
  196. }
  197. }
  198. /**
  199. * @param {*} obj1 对象
  200. * @param {*} obj2 对象
  201. * @description 判断两个对象是否相等,这两个对象的值只能是数字或字符串
  202. */
  203. export const objEqual = (obj1, obj2) => {
  204. const keysArr1 = Object.keys(obj1)
  205. const keysArr2 = Object.keys(obj2)
  206. if (keysArr1.length !== keysArr2.length) return false
  207. else if (keysArr1.length === 0 && keysArr2.length === 0) return true
  208. /* eslint-disable-next-line */
  209. else return !keysArr1.some(key => obj1[key] != obj2[key])
  210. }
  211. /**
  212. * 去除乘法计算出现多位小数
  213. * @param arg1返回值,arg2乘以的参数
  214. */
  215. export const accMul = (arg1, arg2) => {
  216. var m=0,s1=arg1.toString(),s2=arg2.toString();
  217. try{m+=s1.split(".")[1].length}catch(e){}
  218. try{m+=s2.split(".")[1].length}catch(e){}
  219. return Number(s1.replace(".",""))*Number(s2.replace(".",""))/Math.pow(10,m)
  220. }