import { onBeforeUnmount, provide, ref } from 'vue' import { useRoute } from 'vue-router' import { isArray } from '@cip/utils/util' // 菜单徽标hook /** * 定时更新时间 * @param timer 为0时不进行更新 单位ms * @return {{badgeMap: ToRef<{}>, badgeFnMap: ToRef<{}>, collectBadgeFn: collectBadgeFn, consumptionBadgeFn: ((function(*): Promise)|*)}} */ export const useBadge = (times) => { const badgeMap = ref({}) // 徽标key-value关系 const badgeFnMap = ref({}) // 徽标key-fn关系 const collectBadgeFn = (menu = [], { key, fnKey, childrenKey = 'children' }) => { menu.forEach(item => { const fn = item?.[fnKey] if (typeof fn === 'function') { badgeFnMap.value[item[key]] = { fn, used: false, privilege: false } } const children = item[childrenKey] if (isArray(children)) { collectBadgeFn(children, { key, fnKey, childrenKey }) } }) } // 定时更新时使用 const resetComputed = () => { Object.keys(badgeFnMap.value).forEach(key => { badgeFnMap.value[key].used = false // !!!有权限的菜单的badge方法才会执行 if (badgeFnMap.value[key].privilege) { consumptionBadgeFn(key) } }) } if (times > 0) { const timer = setInterval(() => { resetComputed() }, times) onBeforeUnmount(() => { clearInterval(timer) }) } const consumptionBadgeFn = async (key) => { const badgeFn = badgeFnMap.value?.[key] if (badgeFn && !badgeFn.used) { badgeFn.used = true // 删除防止多次触发 badgeFn.privilege = true // 触发过一次及判断为拥有权限 const total = await badgeFn.fn() badgeMap.value[key] = total } } const setBadge = (key, badge) => { badgeMap.value[key] = badge } // 子孙组件直接修改徽标 provide('setBadge', setBadge) const refreshBadge = (key) => { const badgeFn = badgeFnMap.value?.[key] if (badgeFn) { badgeFn.used = false // 先把used设置为false才能触发更新 consumptionBadgeFn(key) } } // 子孙组件根据触发修改徽标 provide('refreshBadge', refreshBadge) return { badgeMap, badgeFnMap, collectBadgeFn, consumptionBadgeFn } } export const useMenuTitle = () => { const route = useRoute() const menuNameMap = ref(new Map()) // name 与 title 的关系 const menuPathMap = ref({}) // fullPath 与 title 的关系 const setCurrentTitle = (title) => { setTitle(route.fullPath, route.name, title) } const setTitle = (fullPath, name, title) => { menuNameMap.value.set(name, title) menuPathMap.value[fullPath] = title } // 兼容老代码[addMenuName]不建议再使用 provide('addMenuName', setCurrentTitle) provide('setCurrentTitle', setCurrentTitle) provide('setTitle', setTitle) return { menuNameMap, menuPathMap } }