feat: add portal home launcher, favorites UI, and WorkTab overflow eviction

Replace top-bar module navigation with a card home page, persist favorites via API, reopen favorite tabs on cold login, and enable portal multi-tabs with overflow-based eviction.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
zlwuandCursor committed 2026-08-08 12:06:49 +08:00
1 parent 7898d65437
commit 2df2ef0808
17 files changed
+2242 -157

No files matched your search

@@ -0,0 +1,80 @@
import { HOME_PAGE_PATH, router } from '@/router'
import { useMenuFavoriteStore } from '@/store/modules/menuFavorite'
import { useWorktabStore } from '@/store/modules/worktab'
import { useMenuStore } from '@/store/modules/menu'
import { collectPortalHomeSections, findHomeCardByPath } from '@/utils/router/portal-home-cards'
const PREOPEN_FLAG_KEY = 'portal-favorites-preopened-user'
/**
* 冷登录:按收藏预开 Tab,当前仍停在首页。
* 同用户刷新且已有业务 Tab 时跳过(依赖 worktab 本地持久化)。
*/
/** @returns 是否执行了冷登录预开(调用方应落点首页) */
export async function preopenFavoriteTabsIfNeeded(userId: string): Promise<boolean> {
if (!userId) return false
const home = HOME_PAGE_PATH || '/home'
const worktab = useWorktabStore()
const hasBusinessTabs = worktab.opened.some(
(t) => t.path && t.path !== home && !t.fixedTab
)
// 刷新恢复:已有业务 Tab 则不再按收藏重开
if (hasBusinessTabs) {
sessionStorage.setItem(PREOPEN_FLAG_KEY, userId)
return false
}
// 同会话已预开过(仅首页等)则跳过
if (sessionStorage.getItem(PREOPEN_FLAG_KEY) === userId) {
return false
}
const favStore = useMenuFavoriteStore()
await favStore.loadFavorites()
const menuStore = useMenuStore()
const sections = collectPortalHomeSections(menuStore.menuList || [])
worktab.openTab(
{
path: home,
title: '首页',
name: 'PortalHome',
fixedTab: true,
keepAlive: true
},
{ activate: true }
)
for (const item of [...favStore.items]) {
const card = findHomeCardByPath(sections, item.path)
if (!card) {
try {
await favStore.removeFavorite(item.path)
} catch {
// 忽略清理失败,继续预开其余项
}
continue
}
const resolved = router.resolve(card.path)
if (!resolved.matched.length) {
continue
}
worktab.openTab(
{
path: card.path,
title: card.title,
name: String(resolved.name || ''),
fixedTab: false,
keepAlive: true
},
{ activate: false }
)
}
sessionStorage.setItem(PREOPEN_FLAG_KEY, userId)
return true
}
export function clearFavoritePreopenFlag(): void {
sessionStorage.removeItem(PREOPEN_FLAG_KEY)
}