import { defineStore } from 'pinia'; import { ref, computed, markRaw, type Component } from 'vue'; // 标签页类型 export type TabType = 'page' | 'browser'; // 标签页接口 export interface Tab { id: string; title: string; type: TabType; // 页面类型标签页的路由路径 path?: string; // 页面组件(用于缓存) component?: Component; // 浏览器类型标签页的数据 browserData?: { platform: string; sessionId?: string; url?: string; cookieData?: string; // 预设的 Cookie 数据(JSON 格式) status?: 'loading' | 'ready' | 'login_pending' | 'login_success' | 'login_failed'; groupId?: number; isAdminMode?: boolean; // 是否是管理后台模式(从后台按钮打开,不需要登录检测和保存账号) }; // 是否可关闭 closable?: boolean; // 图标 icon?: string; } // 页面路由配置 export const PAGE_CONFIG: Record = { '/': { title: '数据看板', icon: 'DataAnalysis' }, '/accounts': { title: '账号管理', icon: 'User' }, '/works': { title: '作品管理', icon: 'Film' }, '/publish': { title: '发布管理', icon: 'Upload' }, '/comments': { title: '评论管理', icon: 'ChatDotRound' }, '/schedule': { title: '定时任务', icon: 'Clock' }, '/analytics/overview': { title: '数据总览', icon: 'TrendCharts' }, '/analytics/platform': { title: '平台数据', icon: 'TrendCharts' }, '/analytics/account': { title: '账号数据', icon: 'TrendCharts' }, '/analytics/work': { title: '作品数据', icon: 'TrendCharts' }, '/settings': { title: '系统设置', icon: 'Setting' }, '/profile': { title: '个人中心', icon: 'User' }, }; export const useTabsStore = defineStore('tabs', () => { // 所有标签页 const tabs = ref([]); // 当前激活的标签页ID const activeTabId = ref(''); // 账号列表刷新计数器(当计数器变化时,Accounts 页面会刷新) const accountRefreshTrigger = ref(0); // 当前激活的标签页 const activeTab = computed(() => tabs.value.find(tab => tab.id === activeTabId.value) ); // 浏览器类型的标签页 const browserTabs = computed(() => tabs.value.filter(tab => tab.type === 'browser') ); // 页面类型的标签页 const pageTabs = computed(() => tabs.value.filter(tab => tab.type === 'page') ); // 生成唯一ID function generateId(): string { return `tab_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`; } // 添加标签页 function addTab(tab: Omit & { id?: string }): Tab { const newTab: Tab = { ...tab, id: tab.id || generateId(), closable: tab.closable ?? true, }; // 检查是否已存在相同路径的页面标签 if (tab.type === 'page' && tab.path) { const existingTab = tabs.value.find(t => t.type === 'page' && t.path === tab.path); if (existingTab) { activeTabId.value = existingTab.id; return existingTab; } } tabs.value.push(newTab); activeTabId.value = newTab.id; return newTab; } // 打开页面标签页 function openPageTab(path: string, component?: Component): Tab { // 检查是否已存在(支持动态路由匹配) const existingTab = tabs.value.find(t => { if (t.type === 'page' && t.path) { // 精确匹配 if (t.path === path) return true; // 动态路由匹配:/analytics/platform-detail/:platform if (path.startsWith('/analytics/platform-detail/') && t.path?.startsWith('/analytics/platform-detail/')) { return true; } } return false; }); if (existingTab) { // 如果路径不同,更新路径(用于动态路由) if (existingTab.path !== path) { existingTab.path = path; } activeTabId.value = existingTab.id; return existingTab; } // 获取页面配置(支持动态路由) let config = PAGE_CONFIG[path]; if (!config && path.startsWith('/analytics/platform-detail/')) { // 从路径中提取平台名称 const platform = path.split('/').pop() || ''; const platformNames: Record = { 'douyin': '抖音', 'xiaohongshu': '小红书', 'baijiahao': '百家号', 'weixin_video': '视频号', }; config = { title: `${platformNames[platform] || platform}平台数据详情`, icon: 'TrendCharts' }; } const finalConfig = config || { title: '未知页面', icon: 'Document' }; const tab = addTab({ title: finalConfig.title, type: 'page', path, component: component ? markRaw(component) : undefined, icon: finalConfig.icon, // 首页不可关闭 closable: path !== '/', }); return tab; } // 打开浏览器标签页 function openBrowserTab(platform: string, title?: string, groupId?: number, url?: string, cookieData?: string, isAdminMode?: boolean): Tab { const tab = addTab({ title: title || `${platform} 浏览器`, type: 'browser', browserData: { platform, status: 'loading', groupId, url, // 可选的初始 URL cookieData, // 可选的预设 Cookie isAdminMode, // 是否是管理后台模式 }, icon: 'Monitor', }); return tab; } // 更新标签页 function updateTab(id: string, updates: Partial) { const index = tabs.value.findIndex(tab => tab.id === id); if (index !== -1) { tabs.value[index] = { ...tabs.value[index], ...updates }; } } // 更新浏览器标签页数据 function updateBrowserTab(id: string, browserData: Partial) { const tab = tabs.value.find(t => t.id === id); if (tab && tab.browserData) { tab.browserData = { ...tab.browserData, ...browserData }; } } // 关闭标签页 function closeTab(id: string) { const index = tabs.value.findIndex(tab => tab.id === id); if (index === -1) return; const tab = tabs.value[index]; if (!tab.closable) return; tabs.value.splice(index, 1); // 如果关闭的是当前激活的标签页,激活相邻的标签页 if (activeTabId.value === id) { if (tabs.value.length > 0) { // 激活前一个或后一个标签页 const newIndex = Math.min(index, tabs.value.length - 1); activeTabId.value = tabs.value[newIndex].id; } else { activeTabId.value = ''; } } } // 关闭所有标签页 function closeAllTabs() { tabs.value = tabs.value.filter(tab => !tab.closable); if (tabs.value.length > 0) { activeTabId.value = tabs.value[0].id; } else { activeTabId.value = ''; } } // 关闭其他标签页 function closeOtherTabs(id: string) { tabs.value = tabs.value.filter(tab => tab.id === id || !tab.closable); activeTabId.value = id; } // 关闭右侧标签页 function closeRightTabs(id: string) { const index = tabs.value.findIndex(tab => tab.id === id); if (index === -1) return; tabs.value = tabs.value.filter((tab, i) => i <= index || !tab.closable); // 如果当前激活的标签页被关闭了,激活指定的标签页 if (!tabs.value.find(t => t.id === activeTabId.value)) { activeTabId.value = id; } } // 激活标签页 function activateTab(id: string) { if (tabs.value.find(tab => tab.id === id)) { activeTabId.value = id; } } // 通过路径激活标签页 function activateTabByPath(path: string): boolean { const tab = tabs.value.find(t => t.type === 'page' && t.path === path); if (tab) { activeTabId.value = tab.id; return true; } return false; } // 通过浏览器会话ID查找标签页 function findTabBySessionId(sessionId: string): Tab | undefined { return tabs.value.find( tab => tab.type === 'browser' && tab.browserData?.sessionId === sessionId ); } // 获取当前激活的页面路径 function getActivePagePath(): string | undefined { const tab = activeTab.value; if (tab?.type === 'page') { return tab.path; } return undefined; } // 触发账号列表刷新 function triggerAccountRefresh() { accountRefreshTrigger.value++; } return { // 状态 tabs, activeTabId, accountRefreshTrigger, // 计算属性 activeTab, browserTabs, pageTabs, // 方法 addTab, openPageTab, openBrowserTab, updateTab, updateBrowserTab, closeTab, closeAllTabs, closeOtherTabs, closeRightTabs, activateTab, activateTabByPath, findTabBySessionId, getActivePagePath, triggerAccountRefresh, }; });