feat(admin): 整合财务模块导航为侧边栏子菜单与顶部联动Tab
- 侧边栏收敛:将散落在运营分组下的销售毛利、商品与成本、钱包管理、收支明细整合入「财务」二级子菜单,并支持智能展开与角色权限隔离 - 顶部导航联动:新增 FinanceSubNav 通用组件,在销售毛利、商品与成本中心、钱包管理、收支明细 4 个页面顶部统一提供一键切换 Tab - 语义规范化:将原“财务”流水页面标题明确为“收支明细”,消除模块与页面的命名歧义 - 验证方式:npm run check 全量检查通过(Prettier、ESLint、tsc、单测 100% 通过),构建产物已同步至运行容器并验证路由与交互
This commit is contained in:
@@ -168,52 +168,81 @@ export default function AdminLayout() {
|
||||
},
|
||||
})
|
||||
|
||||
const selectedKey = resolveSelectedKey(location.pathname)
|
||||
const isFinanceKey = [
|
||||
'/admin/sales-profit',
|
||||
'/admin/cost-center',
|
||||
'/admin/fund',
|
||||
'/admin/finance',
|
||||
].includes(selectedKey)
|
||||
const [openKeys, setOpenKeys] = useState<string[]>(['sub-finance'])
|
||||
|
||||
useEffect(() => {
|
||||
if (isFinanceKey && !openKeys.includes('sub-finance')) {
|
||||
setOpenKeys((prev) => [...prev, 'sub-finance'])
|
||||
}
|
||||
}, [isFinanceKey])
|
||||
|
||||
const menuItems = useMemo<MenuProps['items']>(() => {
|
||||
const financeSubItems: MenuProps['items'] = [
|
||||
{ key: '/admin/sales-profit', icon: <LineChartOutlined />, label: '销售毛利' },
|
||||
{ key: '/admin/cost-center', icon: <ApartmentOutlined />, label: '商品与成本' },
|
||||
{ key: '/admin/fund', icon: <WalletOutlined />, label: '钱包管理' },
|
||||
{ key: '/admin/finance', icon: <AccountBookOutlined />, label: '收支明细' },
|
||||
]
|
||||
|
||||
const financeSubMenu = {
|
||||
key: 'sub-finance',
|
||||
icon: <AccountBookOutlined />,
|
||||
label: '财务',
|
||||
children: financeSubItems,
|
||||
}
|
||||
|
||||
const operationItems: MenuProps['items'] =
|
||||
role === 'finance'
|
||||
? [
|
||||
{ key: '/admin/finance', icon: <AccountBookOutlined />, label: '财务' },
|
||||
{ key: '/admin/sales-profit', icon: <LineChartOutlined />, label: '销售毛利' },
|
||||
{ key: '/admin/cost-center', icon: <ApartmentOutlined />, label: '商品与成本' },
|
||||
{ key: '/admin/fund', icon: <WalletOutlined />, label: '钱包管理' },
|
||||
financeSubMenu,
|
||||
{ key: '/admin/worker-platform', icon: <TrophyOutlined />, label: '资金审核' },
|
||||
]
|
||||
: [
|
||||
{ key: '/admin/dashboard', icon: <DashboardOutlined />, label: '概览' },
|
||||
{ key: '/admin/orders', icon: <OrderedListOutlined />, label: '订单' },
|
||||
{
|
||||
key: '/admin/fund',
|
||||
icon: <WalletOutlined />,
|
||||
label: role === 'support' ? '我的钱包' : '钱包管理',
|
||||
},
|
||||
...(role === 'support'
|
||||
? []
|
||||
: [
|
||||
{ key: '/admin/finance', icon: <AccountBookOutlined />, label: '财务' },
|
||||
{
|
||||
key: '/admin/sales-profit',
|
||||
icon: <LineChartOutlined />,
|
||||
label: '销售毛利',
|
||||
},
|
||||
{
|
||||
key: '/admin/cost-center',
|
||||
icon: <ApartmentOutlined />,
|
||||
label: '商品与成本',
|
||||
},
|
||||
]),
|
||||
{ key: '/admin/tasks', icon: <UnorderedListOutlined />, label: '任务' },
|
||||
{ key: '/admin/worker-platform', icon: <TrophyOutlined />, label: '接单平台' },
|
||||
{
|
||||
key: '/admin/kuaishou-industry',
|
||||
icon: <SafetyCertificateOutlined />,
|
||||
label: '电子凭证',
|
||||
},
|
||||
{
|
||||
key: '/admin/douyin-mashida-certificates',
|
||||
icon: <SafetyCertificateOutlined />,
|
||||
label: '抖音券核销',
|
||||
},
|
||||
]
|
||||
: role === 'support'
|
||||
? [
|
||||
{ key: '/admin/dashboard', icon: <DashboardOutlined />, label: '概览' },
|
||||
{ key: '/admin/orders', icon: <OrderedListOutlined />, label: '订单' },
|
||||
{
|
||||
key: '/admin/fund',
|
||||
icon: <WalletOutlined />,
|
||||
label: '我的钱包',
|
||||
},
|
||||
{ key: '/admin/tasks', icon: <UnorderedListOutlined />, label: '任务' },
|
||||
{ key: '/admin/worker-platform', icon: <TrophyOutlined />, label: '接单平台' },
|
||||
{
|
||||
key: '/admin/kuaishou-industry',
|
||||
icon: <SafetyCertificateOutlined />,
|
||||
label: '电子凭证',
|
||||
},
|
||||
{
|
||||
key: '/admin/douyin-mashida-certificates',
|
||||
icon: <SafetyCertificateOutlined />,
|
||||
label: '抖音券核销',
|
||||
},
|
||||
]
|
||||
: [
|
||||
{ key: '/admin/dashboard', icon: <DashboardOutlined />, label: '概览' },
|
||||
{ key: '/admin/orders', icon: <OrderedListOutlined />, label: '订单' },
|
||||
financeSubMenu,
|
||||
{ key: '/admin/tasks', icon: <UnorderedListOutlined />, label: '任务' },
|
||||
{ key: '/admin/worker-platform', icon: <TrophyOutlined />, label: '接单平台' },
|
||||
{
|
||||
key: '/admin/kuaishou-industry',
|
||||
icon: <SafetyCertificateOutlined />,
|
||||
label: '电子凭证',
|
||||
},
|
||||
{
|
||||
key: '/admin/douyin-mashida-certificates',
|
||||
icon: <SafetyCertificateOutlined />,
|
||||
label: '抖音券核销',
|
||||
},
|
||||
]
|
||||
|
||||
const items: MenuProps['items'] = [
|
||||
{
|
||||
@@ -333,8 +362,6 @@ export default function AdminLayout() {
|
||||
</div>
|
||||
)
|
||||
|
||||
const selectedKey = resolveSelectedKey(location.pathname)
|
||||
|
||||
return (
|
||||
<Layout className="admin-shell">
|
||||
<Layout.Sider
|
||||
@@ -377,6 +404,8 @@ export default function AdminLayout() {
|
||||
mode="inline"
|
||||
inlineIndent={16}
|
||||
selectedKeys={[selectedKey]}
|
||||
openKeys={openKeys}
|
||||
onOpenChange={(keys) => setOpenKeys(keys as string[])}
|
||||
items={menuItems}
|
||||
className="admin-menu"
|
||||
onClick={({ key }) => navigate(String(key))}
|
||||
@@ -802,8 +831,10 @@ function playNotificationSound(kind: NotificationAlertKind) {
|
||||
|
||||
function resolveSelectedKey(pathname: string) {
|
||||
if (pathname.startsWith('/admin/orders')) return '/admin/orders'
|
||||
if (pathname.startsWith('/admin/finance')) return '/admin/finance'
|
||||
if (pathname.startsWith('/admin/sales-profit')) return '/admin/sales-profit'
|
||||
if (pathname.startsWith('/admin/cost-center')) return '/admin/cost-center'
|
||||
if (pathname.startsWith('/admin/fund')) return '/admin/fund'
|
||||
if (pathname.startsWith('/admin/finance')) return '/admin/finance'
|
||||
if (pathname.startsWith('/admin/tasks')) return '/admin/tasks'
|
||||
if (pathname.startsWith('/admin/worker-platform')) return '/admin/worker-platform'
|
||||
if (pathname.startsWith('/admin/kuaishou-industry')) return '/admin/kuaishou-industry'
|
||||
|
||||
Reference in New Issue
Block a user