This commit is contained in:
zhoutianchi
2026-03-04 18:22:46 +08:00
parent 1600b44440
commit 39bab0f1c2
4 changed files with 95 additions and 15 deletions

View File

@@ -114,6 +114,34 @@ const isActive = (v: RouteItem) => {
}
}
};
/** 标题为「轮播图」的 tag 不展示(切换角色后常误出现,直接过滤) */
const isCarouselTag = (v: RouteItem) => other.setTagsViewNameI18n(v) === '轮播图';
/** 仅首页作为固定 tag其它 isAffix如后端菜单的轮播图不再默认占一条 tag */
const isAffixTagAllowed = (v: RouteItem) => v.path === '/home' || v.path === '/home/index';
/** 后端菜单 sortOrder/sort_order/weight 为 1 的项常被误当“默认”加载为 tag排除首页除外 */
const isSortOrderOneExcluded = (v: RouteItem) => {
const meta = v.meta as any;
const order =
meta?.sortOrder ?? meta?.sort_order ?? meta?.weight ?? (v as any).sort_order ?? (v as any).weight;
return Number(order) === 1 && !isAffixTagAllowed(v);
};
/** 递归扁平化路由(含 children用于校验 path 是否在当前角色菜单中 */
const flattenRoutes = (routes: RouteItem[]): RouteItem[] => {
let list: RouteItem[] = [];
(routes || []).forEach((r: RouteItem) => {
list.push(r);
if ((r as any).children?.length) list.push(...flattenRoutes((r as any).children));
});
return list;
};
/** 当前 tag 的 path 是否存在于当前角色路由列表中(避免恢复出“不存在的 tag” */
const pathInCurrentRoutes = (tag: RouteItem): boolean => {
const flat = flattenRoutes(state.tagsViewRoutesList);
return flat.some(
(r: RouteItem) =>
r.path === tag.path || (r.meta?.isDynamic && (r.meta as any).isDynamicPath === tag.path)
);
};
// 存储 tagsViewList 到浏览器临时缓存中,页面刷新时,保留记录
const addBrowserSetSession = (tagsViewList: Array<object>) => {
Session.set('tagsViewList', tagsViewList);
@@ -128,11 +156,20 @@ const getTagsViewRoutes = async () => {
};
// pinia 中获取路由信息如果是设置了固定的isAffix进行初始化显示
const initTagsView = async () => {
if (Session.get('tagsViewList') && getThemeConfig.value.isCacheTagsView) {
state.tagsViewList = await Session.get('tagsViewList');
const cached = Session.get('tagsViewList');
const hasValidCache = cached && getThemeConfig.value.isCacheTagsView && Array.isArray(cached);
// 仅当当前角色已有路由列表时,才从缓存恢复;恢复时只保留当前路由中存在的 path避免切换角色后出现“不存在的 tag”
if (hasValidCache && state.tagsViewRoutesList.length > 0) {
state.tagsViewList = cached.filter(
(v: RouteItem) =>
!isCarouselTag(v) &&
!isSortOrderOneExcluded(v) &&
pathInCurrentRoutes(v) &&
(v.meta?.isAffix ? isAffixTagAllowed(v) : true)
);
} else {
await state.tagsViewRoutesList.map((v: RouteItem) => {
if (v.meta?.isAffix && !v.meta.isHide) {
if (v.meta?.isAffix && !v.meta.isHide && !isCarouselTag(v) && isAffixTagAllowed(v) && !isSortOrderOneExcluded(v)) {
v.url = setTagsViewHighlight(v);
state.tagsViewList.push({ ...v });
storesKeepALiveNames.addCachedView(v);
@@ -158,6 +195,8 @@ const solveAddTagsView = async (path: string, to?: RouteToFrom) => {
// 防止Avoid app logic that relies on enumerating keys on a component instance. The keys will be empty in production mode to avoid performance overhead.
let findItem = state.tagsViewRoutesList.find((v: RouteItem) => v.path === isDynamicPath);
if (!findItem) return false;
if (isCarouselTag(findItem)) return false;
if (isSortOrderOneExcluded(findItem)) return false;
if (findItem.meta.isAffix) return false;
if (findItem.meta.isLink && !findItem.meta.isIframe) return false;
to?.meta?.isDynamic ? (findItem.params = to.params) : (findItem.query = to?.query);
@@ -211,6 +250,8 @@ const addTagsView = (path: string, to?: RouteToFrom) => {
item = state.tagsViewRoutesList.find((v: RouteItem) => v.path === path);
}
if (!item) return false;
if (isCarouselTag(item)) return false;
if (isSortOrderOneExcluded(item)) return false;
if (item?.meta?.isLink && !item.meta.isIframe) return false;
if (to?.meta?.isDynamic) item.params = to?.params ? to?.params : route.params;
else item.query = to?.query ? to?.query : route.query;
@@ -279,7 +320,7 @@ const closeOtherTagsView = (path: string) => {
if (Session.get('tagsViewList')) {
state.tagsViewList = [];
Session.get('tagsViewList').map((v: RouteItem) => {
if (v.meta?.isAffix && !v.meta.isHide) {
if (v.meta?.isAffix && !v.meta?.isHide && !isCarouselTag(v) && pathInCurrentRoutes(v) && isAffixTagAllowed(v) && !isSortOrderOneExcluded(v)) {
v.url = setTagsViewHighlight(v);
storesKeepALiveNames.delOthersCachedViews(v);
state.tagsViewList.push({ ...v });
@@ -295,7 +336,7 @@ const closeAllTagsView = () => {
storesKeepALiveNames.delAllCachedViews();
state.tagsViewList = [];
Session.get('tagsViewList').map((v: RouteItem) => {
if (v.meta?.isAffix && !v.meta.isHide) {
if (v.meta?.isAffix && !v.meta?.isHide && !isCarouselTag(v) && pathInCurrentRoutes(v) && isAffixTagAllowed(v) && !isSortOrderOneExcluded(v)) {
v.url = setTagsViewHighlight(v);
state.tagsViewList.push({ ...v });
router.push({ path: state.tagsViewList[state.tagsViewList.length - 1].path });
@@ -547,7 +588,7 @@ onBeforeMount(() => {
router.push('/home/index');
state.tagsViewList = [];
state.tagsViewRoutesList.map((v: RouteItem) => {
if (v.meta?.isAffix && !v.meta.isHide) {
if (v.meta?.isAffix && !v.meta?.isHide && !isCarouselTag(v) && isAffixTagAllowed(v) && !isSortOrderOneExcluded(v)) {
v.url = setTagsViewHighlight(v);
state.tagsViewList.push({ ...v });
}