refactor: 优化代码结构并修复类型问题
- 移除未使用的TabPane组件 - 修复类型定义和导入方式 - 优化mock数据源的环境变量判断逻辑 - 更新文档结构并归档旧文件 - 添加新的UI组件和Memo组件 - 调整API路径和响应处理
This commit is contained in:
@@ -26,31 +26,30 @@ import {
|
||||
import { Link, useLocation, useNavigate, Outlet } from 'react-router-dom';
|
||||
import type { MenuProps } from 'antd';
|
||||
import { UserProvider, useUser, MOCK_USERS, ROLE_CONFIG, FEATURES, PERMISSIONS, UserRole } from '@/contexts/UserContext';
|
||||
import { useLocale } from '@/contexts/LocaleContext';
|
||||
|
||||
const { Header, Sider, Content } = Layout;
|
||||
const { Title, Text } = Typography;
|
||||
|
||||
interface CustomMenuItem {
|
||||
key: string;
|
||||
icon?: React.ReactNode;
|
||||
label?: React.ReactNode;
|
||||
requiredPermission?: string | null;
|
||||
requiredFeature?: string | null;
|
||||
children?: CustomMenuItem[];
|
||||
type?: 'divider' | 'group';
|
||||
}
|
||||
|
||||
type MenuItem = Required<MenuProps>['items'][number];
|
||||
|
||||
const ALL_MENU_ITEMS: MenuItem[] = [
|
||||
const ALL_MENU_ITEMS: CustomMenuItem[] = [
|
||||
{
|
||||
key: '/dashboard',
|
||||
icon: <DashboardOutlined />,
|
||||
label: <Link to="/dashboard">数据概览</Link>,
|
||||
requiredPermission: null,
|
||||
},
|
||||
{
|
||||
key: 'aggregation',
|
||||
icon: <ClusterOutlined />,
|
||||
label: '聚合管理',
|
||||
children: [
|
||||
{ key: '/dashboard/aggregation/products', label: <Link to="/dashboard/aggregation/products">聚合商品</Link> },
|
||||
{ key: '/dashboard/aggregation/orders', label: <Link to="/dashboard/aggregation/orders">聚合订单</Link> },
|
||||
{ key: '/dashboard/aggregation/inventory', label: <Link to="/dashboard/aggregation/inventory">聚合库存</Link> },
|
||||
{ key: '/dashboard/aggregation/customers', label: <Link to="/dashboard/aggregation/customers">聚合客户</Link> },
|
||||
{ key: '/dashboard/aggregation/authorization', label: <Link to="/dashboard/aggregation/authorization">授权管理</Link> },
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'ai-operations',
|
||||
icon: <RobotOutlined />,
|
||||
@@ -71,14 +70,12 @@ const ALL_MENU_ITEMS: MenuItem[] = [
|
||||
icon: <ShoppingOutlined />,
|
||||
label: '商品闭环',
|
||||
children: [
|
||||
{ key: '/dashboard/product', label: <Link to="/dashboard/product">商品列表</Link>, requiredPermission: PERMISSIONS.PRODUCT_READ },
|
||||
{ key: '/dashboard/product', label: <Link to="/dashboard/product">商品管理</Link>, requiredPermission: PERMISSIONS.PRODUCT_READ },
|
||||
{ key: '/dashboard/product/publish', label: <Link to="/dashboard/product/publish">商品发布</Link>, requiredPermission: PERMISSIONS.PRODUCT_WRITE },
|
||||
{ key: '/dashboard/product/cross-platform', label: <Link to="/dashboard/product/cross-platform">跨平台管理</Link>, requiredFeature: FEATURES.MULTI_SHOP },
|
||||
{ key: '/dashboard/inventory', label: <Link to="/dashboard/inventory">库存管理</Link>, requiredPermission: PERMISSIONS.INVENTORY_READ },
|
||||
{ key: '/dashboard/inventory/warehouses', label: <Link to="/dashboard/inventory/warehouses">仓库管理</Link> },
|
||||
{ key: '/dashboard/product/ai-pricing', label: <Link to="/dashboard/product/ai-pricing">AI定价</Link>, requiredFeature: FEATURES.AUTO_PRICING },
|
||||
{ key: '/dashboard/product/profit-monitor', label: <Link to="/dashboard/product/profit-monitor">利润监控</Link> },
|
||||
{ key: '/dashboard/inventory', label: <Link to="/dashboard/inventory">库存管理</Link>, requiredPermission: PERMISSIONS.INVENTORY_READ },
|
||||
{ key: '/dashboard/inventory/forecast', label: <Link to="/dashboard/inventory/forecast">库存预测</Link> },
|
||||
{ key: '/dashboard/inventory/warehouses', label: <Link to="/dashboard/inventory/warehouses">仓库管理</Link> },
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -86,12 +83,10 @@ const ALL_MENU_ITEMS: MenuItem[] = [
|
||||
icon: <FileTextOutlined />,
|
||||
label: '订单闭环',
|
||||
children: [
|
||||
{ key: '/dashboard/orders', label: <Link to="/dashboard/orders">订单列表</Link>, requiredPermission: PERMISSIONS.ORDER_READ },
|
||||
{ key: '/dashboard/orders', label: <Link to="/dashboard/orders">订单管理</Link>, requiredPermission: PERMISSIONS.ORDER_READ },
|
||||
{ key: '/dashboard/orders/exception', label: <Link to="/dashboard/orders/exception">异常订单</Link> },
|
||||
{ key: '/dashboard/orders/aggregation', label: <Link to="/dashboard/orders/aggregation">订单聚合</Link> },
|
||||
{ key: '/dashboard/after-sales', label: <Link to="/dashboard/after-sales">售后服务</Link> },
|
||||
{ key: '/dashboard/after-sales/refund', label: <Link to="/dashboard/after-sales/refund">退款处理</Link> },
|
||||
{ key: '/dashboard/after-sales/customer-service', label: <Link to="/dashboard/after-sales/customer-service">客服工单</Link> },
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -101,7 +96,6 @@ const ALL_MENU_ITEMS: MenuItem[] = [
|
||||
requiredPermission: PERMISSIONS.INVENTORY_READ,
|
||||
children: [
|
||||
{ key: '/dashboard/logistics', label: <Link to="/dashboard/logistics">物流查询</Link> },
|
||||
{ key: '/dashboard/logistics/track', label: <Link to="/dashboard/logistics/track">物流追踪</Link> },
|
||||
{ key: '/dashboard/logistics/freight-calc', label: <Link to="/dashboard/logistics/freight-calc">运费计算</Link> },
|
||||
],
|
||||
},
|
||||
@@ -115,8 +109,6 @@ const ALL_MENU_ITEMS: MenuItem[] = [
|
||||
{ key: '/dashboard/finance/transactions', label: <Link to="/dashboard/finance/transactions">交易记录</Link> },
|
||||
{ key: '/dashboard/finance/reconciliation', label: <Link to="/dashboard/finance/reconciliation">财务对账</Link> },
|
||||
{ key: '/dashboard/user-asset', label: <Link to="/dashboard/user-asset">用户资产</Link> },
|
||||
{ key: '/dashboard/user-asset/member-level', label: <Link to="/dashboard/user-asset/member-level">会员等级</Link> },
|
||||
{ key: '/dashboard/user-asset/points', label: <Link to="/dashboard/user-asset/points">积分管理</Link> },
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -125,12 +117,9 @@ const ALL_MENU_ITEMS: MenuItem[] = [
|
||||
label: '营销闭环',
|
||||
children: [
|
||||
{ key: '/dashboard/ad', label: <Link to="/dashboard/ad">广告管理</Link> },
|
||||
{ key: '/dashboard/ad/auto-adjustment', label: <Link to="/dashboard/ad/auto-adjustment">自动调价</Link>, requiredFeature: FEATURES.AUTO_PRICING },
|
||||
{ key: '/dashboard/ad/ai-optimization', label: <Link to="/dashboard/ad/ai-optimization">AI优化</Link>, requiredFeature: FEATURES.AI_OPERATIONS },
|
||||
{ key: '/dashboard/marketing/competitors', label: <Link to="/dashboard/marketing/competitors">竞品分析</Link> },
|
||||
{ key: '/dashboard/dynamic-pricing', label: <Link to="/dashboard/dynamic-pricing">动态定价</Link>, requiredFeature: FEATURES.AUTO_PRICING },
|
||||
{ key: '/dashboard/ab-test', label: <Link to="/dashboard/ab-test">AB测试</Link> },
|
||||
{ key: '/dashboard/ab-test/results', label: <Link to="/dashboard/ab-test/results">测试结果</Link> },
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -151,9 +140,7 @@ const ALL_MENU_ITEMS: MenuItem[] = [
|
||||
requiredFeature: FEATURES.B2B_TRADE,
|
||||
children: [
|
||||
{ key: '/dashboard/merchant', label: <Link to="/dashboard/merchant">商户管理</Link> },
|
||||
{ key: '/dashboard/merchant/orders', label: <Link to="/dashboard/merchant/orders">商户订单</Link> },
|
||||
{ key: '/dashboard/b2b', label: <Link to="/dashboard/b2b">B2B贸易</Link> },
|
||||
{ key: '/dashboard/b2b-trade', label: <Link to="/dashboard/b2b-trade">B2B交易</Link> },
|
||||
{ key: '/dashboard/suppliers', label: <Link to="/dashboard/suppliers">供应商</Link> },
|
||||
],
|
||||
},
|
||||
@@ -163,10 +150,7 @@ const ALL_MENU_ITEMS: MenuItem[] = [
|
||||
label: '独立站',
|
||||
requiredFeature: FEATURES.INDEPENDENT_SITE,
|
||||
children: [
|
||||
{ key: '/dashboard/independent-site', label: <Link to="/dashboard/independent-site">站点列表</Link> },
|
||||
{ key: '/dashboard/independent-site/create', label: <Link to="/dashboard/independent-site/create">对接外部站点</Link> },
|
||||
{ key: '/dashboard/independent-site/builder', label: <Link to="/dashboard/independent-site/builder">自建站点</Link> },
|
||||
{ key: '/dashboard/independent-site/templates', label: <Link to="/dashboard/independent-site/templates">网站模板</Link> },
|
||||
{ key: '/dashboard/independent-site', label: <Link to="/dashboard/independent-site">站点管理</Link> },
|
||||
{ key: '/dashboard/independent-site/domains', label: <Link to="/dashboard/independent-site/domains">域名管理</Link> },
|
||||
],
|
||||
},
|
||||
@@ -177,9 +161,7 @@ const ALL_MENU_ITEMS: MenuItem[] = [
|
||||
children: [
|
||||
{ key: '/dashboard/compliance', label: <Link to="/dashboard/compliance">合规概览</Link> },
|
||||
{ key: '/dashboard/compliance/certificates', label: <Link to="/dashboard/compliance/certificates">证书管理</Link> },
|
||||
{ key: '/dashboard/compliance/check', label: <Link to="/dashboard/compliance/check">合规检查</Link> },
|
||||
{ key: '/dashboard/blacklist', label: <Link to="/dashboard/blacklist">黑名单</Link> },
|
||||
{ key: '/dashboard/arbitrage-monitor', label: <Link to="/dashboard/arbitrage-monitor">套利监控</Link> },
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -188,11 +170,10 @@ const ALL_MENU_ITEMS: MenuItem[] = [
|
||||
label: '系统设置',
|
||||
children: [
|
||||
{ key: '/dashboard/settings', label: <Link to="/dashboard/settings">设置概览</Link> },
|
||||
{ key: '/dashboard/settings/profile', label: <Link to="/dashboard/settings/profile">个人设置</Link> },
|
||||
{ key: '/dashboard/settings/users', label: <Link to="/dashboard/settings/users">用户管理</Link>, requiredPermission: PERMISSIONS.USER_MANAGE },
|
||||
{ key: '/dashboard/settings/system', label: <Link to="/dashboard/settings/system">系统配置</Link>, requiredPermission: PERMISSIONS.SYSTEM_CONFIG },
|
||||
{ key: '/dashboard/role', label: <Link to="/dashboard/role">角色管理</Link>, requiredPermission: PERMISSIONS.USER_MANAGE },
|
||||
{ key: '/dashboard/settings/subscription', label: <Link to="/dashboard/settings/subscription">订阅管理</Link> },
|
||||
{ key: '/dashboard/settings/platform-auth', label: <Link to="/dashboard/settings/platform-auth">平台授权</Link> },
|
||||
{ key: '/dashboard/settings/service-manager', label: <Link to="/dashboard/settings/service-manager">服务管理</Link> },
|
||||
{ key: '/dashboard/user', label: <Link to="/dashboard/user">用户管理</Link> },
|
||||
{ key: '/dashboard/role', label: <Link to="/dashboard/role">角色权限</Link> },
|
||||
],
|
||||
},
|
||||
];
|
||||
@@ -202,37 +183,33 @@ const MainLayoutContent: React.FC = () => {
|
||||
const location = useLocation();
|
||||
const navigate = useNavigate();
|
||||
const { currentUser, setCurrentUser, hasPermission, hasFeature, getPlanLabel, isPaidUser } = useUser();
|
||||
const { locale, setLocale } = useLocale();
|
||||
|
||||
const menuItems = useMemo(() => {
|
||||
const stripCustomProps = (item: any): MenuItem => {
|
||||
const stripCustomProps = (item: CustomMenuItem): MenuItem => {
|
||||
const { requiredPermission, requiredFeature, ...rest } = item;
|
||||
return rest;
|
||||
return rest as MenuItem;
|
||||
};
|
||||
|
||||
const filterMenuItems = (items: MenuItem[]): MenuItem[] => {
|
||||
return items
|
||||
.filter((item): item is NonNullable<MenuItem> & { key: string } => item != null && 'key' in item)
|
||||
.filter((item) => {
|
||||
const itemWithMeta = item as any;
|
||||
if (itemWithMeta.requiredFeature && !hasFeature(itemWithMeta.requiredFeature)) {
|
||||
return false;
|
||||
const filterMenuItems = (items: CustomMenuItem[]): MenuItem[] => {
|
||||
const result: MenuItem[] = [];
|
||||
items.forEach((item) => {
|
||||
if (item.requiredFeature && !hasFeature(item.requiredFeature)) {
|
||||
return;
|
||||
}
|
||||
if (item.requiredPermission && !hasPermission(item.requiredPermission)) {
|
||||
return;
|
||||
}
|
||||
if (item.children && Array.isArray(item.children)) {
|
||||
const filteredChildren = filterMenuItems(item.children);
|
||||
if (filteredChildren.length > 0) {
|
||||
result.push(stripCustomProps({ ...item, children: filteredChildren as CustomMenuItem[] }));
|
||||
}
|
||||
if (itemWithMeta.requiredPermission && !hasPermission(itemWithMeta.requiredPermission)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.map((item) => {
|
||||
if ('children' in item && Array.isArray(item.children)) {
|
||||
const filteredChildren = filterMenuItems(item.children);
|
||||
if (filteredChildren.length === 0) {
|
||||
return null;
|
||||
}
|
||||
return stripCustomProps({ ...item, children: filteredChildren });
|
||||
}
|
||||
return stripCustomProps(item);
|
||||
})
|
||||
.filter((item): item is NonNullable<MenuItem> => item !== null);
|
||||
} else {
|
||||
result.push(stripCustomProps(item));
|
||||
}
|
||||
});
|
||||
return result;
|
||||
};
|
||||
return filterMenuItems(ALL_MENU_ITEMS);
|
||||
}, [hasPermission, hasFeature]);
|
||||
@@ -285,7 +262,7 @@ const MainLayoutContent: React.FC = () => {
|
||||
};
|
||||
|
||||
findParent(menuItems);
|
||||
return [...new Set(openKeys)];
|
||||
return Array.from(new Set(openKeys));
|
||||
};
|
||||
|
||||
const selectedKeys = getSelectedKeys();
|
||||
@@ -508,6 +485,22 @@ const MainLayoutContent: React.FC = () => {
|
||||
<BellOutlined style={{ fontSize: '18px', cursor: 'pointer', color: '#666' }} />
|
||||
</Badge>
|
||||
|
||||
<Dropdown
|
||||
menu={{
|
||||
items: [
|
||||
{ key: 'zh-CN', label: '简体中文' },
|
||||
{ key: 'en-US', label: 'English' },
|
||||
],
|
||||
onClick: ({ key }) => setLocale(key),
|
||||
selectedKeys: [locale],
|
||||
}}
|
||||
placement="bottomRight"
|
||||
>
|
||||
<Button type="text" icon={<GlobalOutlined />} style={{ height: '32px' }}>
|
||||
{locale === 'zh-CN' ? '中文' : 'EN'}
|
||||
</Button>
|
||||
</Dropdown>
|
||||
|
||||
<Dropdown
|
||||
menu={{ items: userMenuItems, onClick: handleUserMenuClick }}
|
||||
placement="bottomRight"
|
||||
|
||||
Reference in New Issue
Block a user