useTabStack.ts 2.58 KB
// REQ-USR-003: 顶栏标签栈逻辑(复刻原型 tabsOpen/openTab/.close,BR4/BR5/BR6)。
// 纯逻辑 hook:只管标签集合 + activeKey;路由跳转由调用方据 routePath 执行。
import { useCallback, useMemo, useState } from 'react';

/** 业务标签 key(跨组件一致的合同级常量) */
export type BizTabKey = 'userlist' | 'userdetail';
export type TabKey = 'home' | BizTabKey;

export interface TabItem {
  key: string;
  title: string;
  closable: boolean;
  routePath: string;
}

/** 固定主页标签:不可关闭,恒在最左 */
export const HOME_TAB: TabItem = {
  key: 'home',
  title: '主页',
  closable: false,
  routePath: '/',
};

/** 业务标签定义(标题 / 路由 / 可关闭) */
export const BIZ_TABS: Record<BizTabKey, TabItem> = {
  userlist: { key: 'userlist', title: '用户列表', closable: true, routePath: '/usr/users' },
  userdetail: { key: 'userdetail', title: '用户信息单据', closable: true, routePath: '/usr/users/new' },
};

export interface TabStack {
  tabs: TabItem[];
  activeKey: string;
  openTab: (key: BizTabKey) => void;
  closeTab: (key: string) => void;
  setActive: (key: string) => void;
}

export function useTabStack(): TabStack {
  // 已打开的业务标签集合(home 恒在,不入此集合)
  const [userlistOpen, setUserlistOpen] = useState(false);
  const [userdetailOpen, setUserdetailOpen] = useState(false);
  const [activeKey, setActiveKey] = useState<string>('home');

  const tabs = useMemo<TabItem[]>(() => {
    const list: TabItem[] = [HOME_TAB];
    if (userlistOpen) list.push(BIZ_TABS.userlist);
    if (userdetailOpen) list.push(BIZ_TABS.userdetail);
    return list;
  }, [userlistOpen, userdetailOpen]);

  const openTab = useCallback((key: BizTabKey) => {
    if (key === 'userlist') {
      setUserlistOpen(true);
      setActiveKey('userlist');
    } else if (key === 'userdetail') {
      // 打开单据前先确保用户列表存在(BR6)
      setUserlistOpen(true);
      setUserdetailOpen(true);
      setActiveKey('userdetail');
    }
  }, []);

  const closeTab = useCallback((key: string) => {
    if (key === 'userlist') {
      // 关用户列表联动关用户信息单据并回主页(BR5)
      setUserlistOpen(false);
      setUserdetailOpen(false);
      setActiveKey('home');
    } else if (key === 'userdetail') {
      // 关用户信息单据回用户列表
      setUserdetailOpen(false);
      setActiveKey('userlist');
    }
  }, []);

  const setActive = useCallback((key: string) => {
    setActiveKey(key);
  }, []);

  return { tabs, activeKey, openTab, closeTab, setActive };
}