index.ts 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. import { h, unref } from 'vue'
  2. import type { App, Plugin } from 'vue'
  3. import { NIcon, NTag } from 'naive-ui'
  4. import { PageEnum } from '@/enums/pageEnum'
  5. import { isObject } from './is/index'
  6. import { cloneDeep } from 'lodash-es'
  7. /**
  8. * render 图标
  9. * */
  10. export function renderIcon(icon: any) {
  11. return () => h(NIcon, null, { default: () => h(icon) })
  12. }
  13. /**
  14. * font 图标(Font class)
  15. * */
  16. export function renderFontClassIcon(icon: string, iconName = 'iconfont') {
  17. return () => h('span', { class: [iconName, icon] })
  18. }
  19. /**
  20. * font 图标(Unicode)
  21. * */
  22. export function renderUnicodeIcon(icon: string, iconName = 'iconfont') {
  23. return () => h('span', { class: [iconName], innerHTML: icon })
  24. }
  25. /**
  26. * font svg 图标
  27. * */
  28. export function renderfontsvg(icon: any) {
  29. return () =>
  30. h(NIcon, null, {
  31. default: () =>
  32. h('svg', { class: `icon`, 'aria-hidden': 'true' }, h('use', { 'xlink:href': `#${icon}` }))
  33. })
  34. }
  35. /**
  36. * render new Tag
  37. * */
  38. const newTagColors = { color: '#f90', textColor: '#fff', borderColor: '#f90' }
  39. export function renderNew(type = 'warning', text = 'New', color: object = newTagColors) {
  40. return () =>
  41. h(
  42. NTag as any,
  43. {
  44. type,
  45. round: true,
  46. size: 'small',
  47. color
  48. },
  49. { default: () => text }
  50. )
  51. }
  52. /**
  53. * 递归组装菜单格式
  54. */
  55. export function generatorMenu(routerMap: Array<any>) {
  56. return filterRouter(routerMap).map((item) => {
  57. const isRoot = isRootRouter(item)
  58. if (isRoot) {
  59. console.log(item.children[0], 'isRoot')
  60. }
  61. const info = isRoot ? item.children[0] : item
  62. // console.log(item)
  63. const currentMenu = {
  64. ...info,
  65. ...info.meta,
  66. label: info.meta?.title,
  67. key: info.key,
  68. icon: info.meta?.icon
  69. }
  70. // 是否有子菜单,并递归处理
  71. if (info.children && info.children.length > 0) {
  72. // Recursion
  73. currentMenu.children = generatorMenu(info.children)
  74. }
  75. return currentMenu
  76. })
  77. }
  78. /**
  79. * 混合菜单
  80. * */
  81. export function generatorMenuMix(routerMap: Array<any>, routerName: string, location: string) {
  82. const cloneRouterMap = cloneDeep(routerMap)
  83. const newRouter = filterRouter(cloneRouterMap)
  84. if (location === 'header') {
  85. const firstRouter: any[] = []
  86. newRouter.forEach((item) => {
  87. const isRoot = isRootRouter(item)
  88. const info = isRoot ? item.children[0] : item
  89. info.children = undefined
  90. const currentMenu = {
  91. ...info,
  92. ...info.meta,
  93. label: info.meta?.title,
  94. key: info.name
  95. }
  96. firstRouter.push(currentMenu)
  97. })
  98. return firstRouter
  99. } else {
  100. // 混合菜单
  101. console.log('混合菜单')
  102. return getChildrenRouter(newRouter.filter((item) => item.name === routerName))
  103. }
  104. }
  105. /**
  106. * 递归组装子菜单
  107. * */
  108. export function getChildrenRouter(routerMap: Array<any>) {
  109. return filterRouter(routerMap).map((item) => {
  110. const isRoot = isRootRouter(item)
  111. const info = isRoot ? item.children[0] : item
  112. const currentMenu = {
  113. ...info,
  114. ...info.meta,
  115. label: info.meta?.title,
  116. key: info.name
  117. }
  118. // 是否有子菜单,并递归处理
  119. if (info.children && info.children.length > 0) {
  120. // Recursion
  121. currentMenu.children = getChildrenRouter(info.children)
  122. }
  123. return currentMenu
  124. })
  125. }
  126. /**
  127. * 判断根路由 Router
  128. * */
  129. export function isRootRouter(item: any) {
  130. return item.meta?.isRoot === true
  131. }
  132. /**
  133. * 排除Router
  134. * */
  135. export function filterRouter(routerMap: Array<any>) {
  136. return routerMap.filter((item) => {
  137. // console.log(
  138. // (item.meta?.hidden || false) != true &&
  139. // !['/:path(.*)*', PageEnum.REDIRECT, PageEnum.BASE_LOGIN].includes(item.path),
  140. // '过滤完之后的路由'
  141. // )
  142. return (
  143. (item.meta?.hidden || false) != true &&
  144. !['/:path(.*)*', PageEnum.REDIRECT, PageEnum.BASE_LOGIN].includes(item.path)
  145. )
  146. })
  147. }
  148. export const withInstall = <T>(component: T, alias?: string) => {
  149. const comp = component as any
  150. comp.install = (app: App) => {
  151. app.component(comp.name || comp.displayName, component as any)
  152. if (alias) {
  153. app.config.globalProperties[alias] = component
  154. }
  155. }
  156. return component as T & Plugin
  157. }
  158. /**
  159. * 找到对应的节点
  160. * */
  161. let result = null as any
  162. export function getTreeItem(data: any[], key?: string | number): any {
  163. data.map((item) => {
  164. if (item.key === key) {
  165. result = item
  166. } else {
  167. if (item.children && item.children.length) {
  168. getTreeItem(item.children, key)
  169. }
  170. }
  171. })
  172. return result
  173. }
  174. /**
  175. * 找到所有节点
  176. * */
  177. const treeAll: any[] = []
  178. export function getTreeAll(data: any[]): any[] {
  179. data.map((item) => {
  180. treeAll.push(item.key)
  181. if (item.children && item.children.length) {
  182. getTreeAll(item.children)
  183. }
  184. })
  185. return treeAll
  186. }
  187. export function deepMerge<T = any>(src: any = {}, target: any = {}): T {
  188. let key: string
  189. for (key in target) {
  190. src[key] = isObject(src[key]) ? deepMerge(src[key], target[key]) : (src[key] = target[key])
  191. }
  192. return src
  193. }
  194. /**
  195. * Sums the passed percentage to the R, G or B of a HEX color
  196. * @param {string} color The color to change
  197. * @param {number} amount The amount to change the color by
  198. * @returns {string} The processed part of the color
  199. */
  200. function addLight(color: string, amount: number) {
  201. const cc = parseInt(color, 16) + amount
  202. const c = cc > 255 ? 255 : cc
  203. return c.toString(16).length > 1 ? c.toString(16) : `0${c.toString(16)}`
  204. }
  205. /**
  206. * Lightens a 6 char HEX color according to the passed percentage
  207. * @param {string} color The color to change
  208. * @param {number} amount The amount to change the color by
  209. * @returns {string} The processed color represented as HEX
  210. */
  211. export function lighten(color: string, amount: number) {
  212. color = color.indexOf('#') >= 0 ? color.substring(1, color.length) : color
  213. amount = Math.trunc((255 * amount) / 100)
  214. return `#${addLight(color.substring(0, 2), amount)}${addLight(
  215. color.substring(2, 4),
  216. amount
  217. )}${addLight(color.substring(4, 6), amount)}`
  218. }
  219. /**
  220. * 判断是否 url
  221. * */
  222. export function isUrl(url: string) {
  223. return /^(http|https):\/\//g.test(url)
  224. }
  225. /** 递归清除空数据 */
  226. export function clearEmtryData(list: any[], key: string) {
  227. for (let i = 0; i < list.length; i++) {
  228. if (Array.isArray(list[i][key]) && !list[i][key].length) {
  229. list[i][key] = ''
  230. } else {
  231. list[i][key] = clearEmtryData(list[i][key], key)
  232. }
  233. }
  234. return list
  235. }
  236. /** 检测链接格式 */
  237. export function checkUrlType(urlType: string) {
  238. const subfix = (urlType || '').split('.').pop()
  239. if (subfix === 'wav' || subfix === 'mp3' || subfix === 'm4a') {
  240. return 'audio'
  241. }
  242. return 'video'
  243. }