create-iking-admin
Version:
金合技术中台脚手架
140 lines (132 loc) • 4.65 kB
text/typescript
import type { RouteLocationNormalized, RouteRecordRaw } from 'vue-router'
import { userApi } from '@main/api/modules/user'
import { resolveRoutePath } from '@main/utils'
import useSettingsStore from './settings'
import useUserStore from './user'
import useRouteStore from './route'
import useMenuStore from './menu'
import type { Favorites, Menu } from '#/global'
const useFavoritesStore = defineStore(
// 唯一ID
'favorites',
() => {
const settingsStore = useSettingsStore()
const userStore = useUserStore()
const routeStore = useRouteStore()
const menuStore = useMenuStore()
const list = ref<Favorites.recordRaw[]>([])
function hasChildren(item: RouteRecordRaw) {
let flag = true
if (item.children?.every(i => i.meta?.sidebar === false)) {
flag = false
}
return flag
}
function getSourceList(arr: RouteRecordRaw[], basePath?: string) {
const list: string[] = []
arr.forEach((item) => {
if (item.meta?.sidebar !== false) {
if (item.children && hasChildren(item)) {
list.push(...getSourceList(item.children, resolveRoutePath(basePath, item.path)))
}
else {
list.push((item.redirect as string) ?? resolveRoutePath(basePath, item.path))
}
}
})
return list
}
function getSourceListByMenus(arr: Menu.recordRaw[]) {
const list: string[] = []
arr.forEach((item) => {
if (item.children && item.children.length > 0) {
list.push(...getSourceListByMenus(item.children))
}
else {
list.push(item.path as string)
}
})
return list
}
const flatSidebarMenu = computed(() => {
const list: string[] = []
if (settingsStore.settings.app.routeBaseOn !== 'filesystem') {
routeStore.routes.forEach((item) => {
item.children && list.push(...getSourceList(item.children as RouteRecordRaw[]))
})
}
else {
menuStore.menus.forEach((item) => {
list.push(...getSourceListByMenus(item.children))
})
}
return list
})
// 判断路由是否可添加进收藏夹
function canAdd(fullPath: Favorites.recordRaw['fullPath']) {
return flatSidebarMenu.value.includes(fullPath) || flatSidebarMenu.value.includes(fullPath.substring(1))
}
// 判断路由是否已经添加进收藏夹
function isAdd(fullPath: Favorites.recordRaw['fullPath']) {
return list.value.some(item => item.fullPath === fullPath)
}
// 新增收藏
function add(route: RouteLocationNormalized) {
const meta = route.matched.at(-1)?.meta
if (!list.value.find(item => item.fullPath === route.fullPath)) {
list.value.push({
fullPath: route.fullPath,
title: meta?.title,
i18n: meta?.i18n,
icon: meta?.icon ?? meta?.breadcrumbNeste?.findLast(item => item.icon)?.icon,
})
}
updateStorage()
}
// 删除收藏
function remove(fullPath: Favorites.recordRaw['fullPath']) {
list.value = list.value.filter((item) => {
return item.fullPath !== fullPath
})
updateStorage()
}
// 拖拽排序
function sort(newIndex: number, oldIndex: number) {
list.value.splice(newIndex, 0, list.value.splice(oldIndex, 1)[0])
updateStorage()
}
// 更新 ikStore 数据
async function updateStorage() {
if (settingsStore.settings.favorites.storageTo === 'local') {
const favoritesData = ikStore.local.has('favoritesData') ? JSON.parse(ikStore.local.getItem('favoritesData') as string) : {}
favoritesData[userStore.account] = list.value
ikStore.local.setItem('favoritesData', JSON.stringify(favoritesData))
}
else if (settingsStore.settings.favorites.storageTo === 'server') {
await apiUser.favoritesEdit(JSON.stringify(list.value))
}
}
// 根据 ikStore 数据复原当前帐号的标签页
async function recoveryStorage() {
if (settingsStore.settings.favorites.storageTo === 'local') {
if (ikStore.local.has('favoritesData')) {
list.value = JSON.parse(ikStore.local.getItem('favoritesData') as string)[userStore.account] || []
}
}
else if (settingsStore.settings.favorites.storageTo === 'server') {
const res = await apiUser.favorites()
list.value = JSON.parse(res.data.favorites || '[]')
}
}
return {
list,
canAdd,
isAdd,
add,
remove,
sort,
recoveryStorage,
}
},
)
export default useFavoritesStore