util.js 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. export function timeFix () {
  2. const time = new Date()
  3. const hour = time.getHours()
  4. return hour < 9 ? '早上好' : hour <= 11 ? '上午好' : hour <= 13 ? '中午好' : hour < 20 ? '下午好' : '晚上好'
  5. }
  6. export function welcome () {
  7. const arr = ['休息一会儿吧', '准备吃什么呢?', '要不要打一把 DOTA', '我猜你可能累了']
  8. const index = Math.floor(Math.random() * arr.length)
  9. return arr[index]
  10. }
  11. /**
  12. * 触发 window.resize
  13. */
  14. export function triggerWindowResizeEvent () {
  15. const event = document.createEvent('HTMLEvents')
  16. event.initEvent('resize', true, true)
  17. event.eventType = 'message'
  18. window.dispatchEvent(event)
  19. }
  20. export function handleScrollHeader (callback) {
  21. let timer = 0
  22. let beforeScrollTop = window.pageYOffset
  23. callback = callback || function () {}
  24. window.addEventListener(
  25. 'scroll',
  26. event => {
  27. clearTimeout(timer)
  28. timer = setTimeout(() => {
  29. let direction = 'up'
  30. const afterScrollTop = window.pageYOffset
  31. const delta = afterScrollTop - beforeScrollTop
  32. if (delta === 0) {
  33. return false
  34. }
  35. direction = delta > 0 ? 'down' : 'up'
  36. callback(direction)
  37. beforeScrollTop = afterScrollTop
  38. }, 50)
  39. },
  40. false
  41. )
  42. }
  43. /**
  44. * Remove loading animate
  45. * @param id parent element id or class
  46. * @param timeout
  47. */
  48. export function removeLoadingAnimate (id = '', timeout = 1500) {
  49. if (id === '') {
  50. return
  51. }
  52. setTimeout(() => {
  53. document.body.removeChild(document.getElementById(id))
  54. }, timeout)
  55. }
  56. /**
  57. * @param {String|Number} value 要验证的字符串或数值
  58. * @param {*} validList 用来验证的列表
  59. */
  60. export function oneOf (value, validList) {
  61. for (let i = 0; i < validList.length; i++) {
  62. if (value === validList[i]) {
  63. return true
  64. }
  65. }
  66. return false
  67. }
  68. /**
  69. * @param {Function} fn 防抖函数
  70. * @param {Number} delay 延迟时间
  71. */
  72. export function debounce(fn, delay) {
  73. var timer;
  74. return function () {
  75. var context = this;
  76. var args = arguments;
  77. clearTimeout(timer);
  78. timer = setTimeout(function () {
  79. fn.apply(context, args);
  80. }, delay);
  81. };
  82. }
  83. /**
  84. * @param {date} time 需要转换的时间
  85. * @param {String} fmt 需要转换的格式 如 yyyy-MM-dd、yyyy-MM-dd HH:mm:ss
  86. */
  87. export function formatTime(time, fmt) {
  88. if (!time) return '';
  89. else {
  90. const date = new Date(time);
  91. const o = {
  92. 'M+': date.getMonth() + 1,
  93. 'd+': date.getDate(),
  94. 'H+': date.getHours(),
  95. 'm+': date.getMinutes(),
  96. 's+': date.getSeconds(),
  97. 'q+': Math.floor((date.getMonth() + 3) / 3),
  98. S: date.getMilliseconds(),
  99. };
  100. if (/(y+)/.test(fmt))
  101. fmt = fmt.replace(
  102. RegExp.$1,
  103. (date.getFullYear() + '').substr(4 - RegExp.$1.length)
  104. );
  105. for (const k in o) {
  106. if (new RegExp('(' + k + ')').test(fmt)) {
  107. fmt = fmt.replace(
  108. RegExp.$1,
  109. RegExp.$1.length === 1
  110. ? o[k]
  111. : ('00' + o[k]).substr(('' + o[k]).length)
  112. );
  113. }
  114. }
  115. return fmt;
  116. }
  117. }
  118. // 千分位分隔符
  119. export function formatThousands (number) {
  120. if(!number){return 0}
  121. const arr = number.toString().split('.')
  122. const numbers = arr[0].split('').reverse()
  123. const segs = []
  124. while (numbers.length) segs.push(numbers.splice(0, 3).join(''))
  125. return segs.join(',').split('').reverse().join('') + (arr.length>1 ? ("."+arr[1]) : '')
  126. }
  127. /**
  128. * 数组转树形结构
  129. * @param {array} list 被转换的数组
  130. * @param {number|string} root 根节点(最外层节点)的 id
  131. * @return array
  132. */
  133. export function arrayToTree(list, root) {
  134. const result = [] // 用于存放结果
  135. const map = {} // 用于存放 list 下的节点
  136. // 1. 遍历 list,将 list 下的所有节点以 id 作为索引存入 map
  137. for (const item of list) {
  138. map[item.id] = { ...item } // 浅拷贝
  139. }
  140. // 2. 再次遍历,将根节点放入最外层,子节点放入父节点
  141. for (const item of list) {
  142. // 3. 获取节点的 id 和 父 id
  143. const { id, parentId } = item // ES6 解构赋值
  144. // 4. 如果是根节点,存入 result
  145. if (item.parentId == root) {
  146. result.push(map[id])
  147. } else {
  148. // 5. 反之,存入到父节点
  149. map[parentId].children
  150. ? map[parentId].children.push(map[id])
  151. : (map[parentId].children = [map[id]])
  152. }
  153. }
  154. // 将结果返回
  155. return result
  156. }
  157. // 树查找
  158. export function treeFind (tree, func) {
  159. for (const data of tree) {
  160. if (func(data)) return data
  161. if (data.children) {
  162. const res = treeFind(data.children, func)
  163. if (res) return res
  164. }
  165. }
  166. return null
  167. }
  168. // 是否有价格权限
  169. export function hasPriceAuth(authNode, priceOptions, userAuthCode){
  170. const codes = []
  171. const ret = []
  172. // 过滤当前节点下的非价格权限菜单
  173. authNode.map(item=>{
  174. const a = item.code.split('_')
  175. const hasCode = priceOptions.find(k => k.value == a[a.length-1])
  176. const hasRoles = userAuthCode.includes(item.code)
  177. // 获取当前用户的角色拥有的价格权限
  178. if(hasCode && hasRoles){
  179. codes.push(a[a.length-1])
  180. }
  181. })
  182. // console.log(codes)
  183. // 根据拥有的价格权限生成数组标记[1,0,1,0,0],每一位对应一个价格权限
  184. // 有权限标记1,否则标记0
  185. priceOptions.map(item => {
  186. ret.push(codes.includes(item.value)?1:0)
  187. })
  188. // console.log(ret)
  189. return ret
  190. }
  191. // 获取接口对应的价格权限code
  192. export function getAuthPriceCode (config, router, store) {
  193. // 通过路由打开的页面的权限code
  194. const permission = router.history.current.meta.permission
  195. // 手动指定的权限code,如打开的弹框页面或导出、打印
  196. // 手动指定的权限在使用完后需要清空,如在关闭弹框或导出、打印接口调用完成后清空
  197. const curActionPermission = store.state.app.curActionPermission
  198. // 价格权限的所有选项,销售价、成本价、省、市、特约价
  199. const priceOptions = store.state.app.priceAuthOptions
  200. // 最终获取的权限code,手动指定的优先级高于路由打开的页面权限code
  201. const authCode = curActionPermission || permission
  202. // 当前角色的分配的价格权限,这里过滤非价格权限code
  203. const roles = store.state.user.roles
  204. const userAuthCode = roles.permissionList.filter(item => {
  205. const a = item.split('_')
  206. return priceOptions.find(k => k.value == a[a.length-1])
  207. })
  208. // 如果有权限code
  209. if(authCode){
  210. // 当前正在调用的接口url
  211. const url = config.url
  212. // 所有的权限菜单数据
  213. const authTree = store.state.app.authMenusList
  214. // 从所有的权限菜单中查找当前权限code对应的权限菜单数据
  215. const authNode = treeFind(authTree,(item)=>item.code == authCode)
  216. // console.log(authNode)
  217. if(!authNode.permission){return []}
  218. // 从找到的对应权限菜单数据中判断当前调用接口的url是否存在,这里和权限菜单中的后台权限code比较
  219. const hasReqUrl = authNode.permission.split(',').find(item => url.replace(/\//g,'_').indexOf(item)>=0)
  220. // 如果存在则返回一个如 [1,0,1,0,0] 的格式的价格权限字符串给后台接口
  221. if(hasReqUrl&&authNode.children&&authNode.children.length){
  222. return hasPriceAuth(authNode.children,priceOptions,userAuthCode)
  223. }
  224. return []
  225. }
  226. return []
  227. }