import { h, unref } from 'vue' import type { App, Component, Plugin } from 'vue' import { NIcon, NTag } from 'naive-ui' import { cloneDeep } from 'lodash-es' import { isObject } from './is/index' import { PageEnum } from '@/enums/pageEnum' /** * render 图标 */ export function renderIcon(icon) { return () => h(NIcon, null, { default: () => h(icon) }) } /** * font 图标(Font class) */ export function renderFontClassIcon(icon: string, iconName = 'iconfont') { return () => h('span', { class: [iconName, icon] }) } /** * font 图标(Unicode) */ export function renderUnicodeIcon(icon: string, iconName = 'iconfont') { return () => h('span', { class: [iconName], innerHTML: icon }) } /** * font svg 图标 */ export function renderfontsvg(icon) { return () => h(NIcon, null, { default: () => h('svg', { 'class': `icon`, 'aria-hidden': 'true' }, h('use', { 'xlink:href': `#${icon}` })), }) } /** * render new Tag */ const newTagColors = { color: '#f90', textColor: '#fff', borderColor: '#f90' } export function renderNew(type = 'warning', text = 'New', color: object = newTagColors) { return () => h( NTag as any, { type, round: true, size: 'small', color, }, { default: () => text }, ) } /** * 递归组装菜单格式 */ export function generatorMenu(routerMap: Array) { return filterRouter(routerMap).map((item) => { const isRoot = isRootRouter(item) const info = isRoot ? item.children[0] : item const currentMenu = { ...info, ...info.meta, label: info.meta?.title, key: info.name, icon: isRoot ? item.meta?.icon : info.meta?.icon, svgname: isRoot ? item.meta?.svgname : info.meta?.svgname, svgsize: isRoot ? item.meta?.svgsize : info.meta?.svgsize, } // 是否有子菜单,并递归处理 if (info.children && info.children.length > 0) { // Recursion currentMenu.children = generatorMenu(info.children) } return currentMenu }) } /** * 混合菜单 */ export function generatorMenuMix(routerMap: Array, routerName: string, location: string) { const cloneRouterMap = cloneDeep(routerMap) const newRouter = filterRouter(cloneRouterMap) if (location === 'header') { const firstRouter: any[] = [] newRouter.forEach((item) => { const isRoot = isRootRouter(item) const info = isRoot ? item.children[0] : item info.children = undefined const currentMenu = { ...info, ...info.meta, label: info.meta?.title, key: info.name, } firstRouter.push(currentMenu) }) return firstRouter } else { return getChildrenRouter(newRouter.filter(item => item.name === routerName)) } } /** * 递归组装子菜单 */ export function getChildrenRouter(routerMap: Array) { return filterRouter(routerMap).map((item) => { const isRoot = isRootRouter(item) const info = isRoot ? item.children[0] : item const currentMenu = { ...info, ...info.meta, label: info.meta?.title, key: info.name, } // 是否有子菜单,并递归处理 if (info.children && info.children.length > 0) { // Recursion currentMenu.children = getChildrenRouter(info.children) } return currentMenu }) } /** * 判断根路由 Router */ export function isRootRouter(item) { return ( item.meta?.alwaysShow !== true && item?.children?.filter(item => !item?.meta?.hidden)?.length === 1 ) } /** * 排除Router */ export function filterRouter(routerMap: Array) { return routerMap.filter((item) => { return ( (item.meta?.hidden || false) !== true && !['/:path(.*)*', PageEnum.REDIRECT, PageEnum.BASE_LOGIN].includes(item.path) ) }) } export function withInstall(component: T, alias?: string) { const comp = component as any comp.install = (app: App) => { app.component(comp.name || comp.displayName, component) if (alias) app.config.globalProperties[alias] = component } return component as T & Plugin } /** * 找到对应的节点 */ let result = null export function getTreeItem(data: any[], key?: string | number): any { // eslint-disable-next-line array-callback-return data.map((item) => { if (item.key === key) { result = item } else { if (item.children && item.children.length) getTreeItem(item.children, key) } }) return result } /** * 找到所有节点 */ const treeAll: any[] = [] export function getTreeAll(data: any[]): any[] { // eslint-disable-next-line array-callback-return data.map((item) => { treeAll.push(item.key) if (item.children && item.children.length) getTreeAll(item.children) }) return treeAll } // dynamic use hook props export function getDynamicProps(props: T): Partial { const ret: Recordable = {} // eslint-disable-next-line array-callback-return Object.keys(props).map((key) => { ret[key] = unref((props as Recordable)[key]) }) return ret as Partial } export function deepMerge(src: any = {}, target: any = {}): T { let key: string for (key in target) src[key] = isObject(src[key]) ? deepMerge(src[key], target[key]) : (src[key] = target[key]) return src } /** * Sums the passed percentage to the R, G or B of a HEX color * @param {string} color The color to change * @param {number} amount The amount to change the color by * @returns {string} The processed part of the color */ function addLight(color: string, amount: number) { const cc = Number.parseInt(color, 16) + amount const c = cc > 255 ? 255 : cc return c.toString(16).length > 1 ? c.toString(16) : `0${c.toString(16)}` } /** * Lightens a 6 char HEX color according to the passed percentage * @param {string} color The color to change * @param {number} amount The amount to change the color by * @returns {string} The processed color represented as HEX */ export function lighten(color: string, amount: number) { color = color.includes('#') ? color.substring(1, color.length) : color amount = Math.trunc((255 * amount) / 100) return `#${addLight(color.substring(0, 2), amount)}${addLight( color.substring(2, 4), amount, )}${addLight(color.substring(4, 6), amount)}` } /** * 判断是否 url */ export function isUrl(url: string) { return /^(http|https):\/\//g.test(url) } /** * 获取min~max的随机整数 * @param min * @param max * @returns */ export function randomInt(min: number, max: number) { return Math.floor(Math.random() * (max - min) + min) } /** * 比较两个数组是否相等 * @param a * @param b * @returns */ export function arrayEquals(a, b) { return Array.isArray(a) && Array.isArray(b) && a.length === b.length && a.every((val, index) => val === b[index]) } /** * 值是否为空 * @param value * @returns */ export function notEmpty(value: any) { return !(value === undefined || value === '' || value === null || (Array.isArray(value) && value.length === 0)) } /** * 值是否为空 * @param value * @returns */ export function isEmpty(value: any) { return (value === undefined || value === '' || value === null) }