refactor: 重构项目结构并优化代码
- 删除无用的文件和错误日志 - 创建统一的 imports 模块集中管理依赖 - 重构组件使用新的 imports 方式 - 修复文档路径大小写问题 - 优化类型定义和接口导出 - 更新依赖版本 - 改进错误处理和API配置 - 统一组件导出方式
This commit is contained in:
@@ -1,6 +1,17 @@
|
||||
import React, { useState, useEffect, useMemo } from 'react';
|
||||
import { Layout, Menu, Typography, Avatar, Dropdown, Badge, Space, Tag, Divider, Switch, message, Button } from 'antd';
|
||||
import {
|
||||
useState,
|
||||
useEffect,
|
||||
useMemo,
|
||||
Layout,
|
||||
Menu,
|
||||
Typography,
|
||||
Avatar,
|
||||
Dropdown,
|
||||
Badge,
|
||||
Space,
|
||||
Tag,
|
||||
message,
|
||||
Button,
|
||||
DashboardOutlined,
|
||||
ShoppingOutlined,
|
||||
FileTextOutlined,
|
||||
@@ -18,19 +29,23 @@ import {
|
||||
RobotOutlined,
|
||||
AppstoreOutlined,
|
||||
LineChartOutlined,
|
||||
CloudServerOutlined,
|
||||
SafetyOutlined,
|
||||
CrownOutlined,
|
||||
SwapOutlined,
|
||||
ClusterOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import { Link, useLocation, useNavigate, Outlet } from 'react-router-dom';
|
||||
Header,
|
||||
Sider,
|
||||
Content,
|
||||
Title,
|
||||
Text,
|
||||
Link,
|
||||
useLocation,
|
||||
useNavigate,
|
||||
Outlet,
|
||||
FC,
|
||||
} from '@/imports';
|
||||
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;
|
||||
import { UserProvider, useUser, MOCK_USERS, ROLE_CONFIG, FEATURES, PERMISSIONS } from '@/contexts/UserContext';
|
||||
import { LocaleProvider, useLocale } from '@/contexts/LocaleContext';
|
||||
|
||||
interface CustomMenuItem {
|
||||
key: string;
|
||||
@@ -44,168 +59,166 @@ interface CustomMenuItem {
|
||||
|
||||
type MenuItem = Required<MenuProps>['items'][number];
|
||||
|
||||
const ALL_MENU_ITEMS: CustomMenuItem[] = [
|
||||
{
|
||||
key: '/dashboard',
|
||||
icon: <DashboardOutlined />,
|
||||
label: <Link to="/dashboard">数据概览</Link>,
|
||||
requiredPermission: null,
|
||||
},
|
||||
{
|
||||
key: 'ai-operations',
|
||||
icon: <RobotOutlined />,
|
||||
label: 'AI运营中心',
|
||||
requiredFeature: FEATURES.AI_OPERATIONS,
|
||||
children: [
|
||||
{ key: '/dashboard/operation-agent', label: <Link to="/dashboard/operation-agent">运营Agent</Link> },
|
||||
{ key: '/dashboard/auto-pilot', label: <Link to="/dashboard/auto-pilot">自动驾驶</Link> },
|
||||
{ key: '/dashboard/task-center', label: <Link to="/dashboard/task-center">任务中心</Link> },
|
||||
{ key: '/dashboard/ai-decision-log', label: <Link to="/dashboard/ai-decision-log">AI决策日志</Link> },
|
||||
{ key: '/dashboard/strategy-marketplace', label: <Link to="/dashboard/strategy-marketplace">策略市场</Link> },
|
||||
{ key: '/dashboard/auto-product-selection', label: <Link to="/dashboard/auto-product-selection">自动选品</Link> },
|
||||
{ key: '/dashboard/auto-execution', label: <Link to="/dashboard/auto-execution">自动执行</Link> },
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'product-cycle',
|
||||
icon: <ShoppingOutlined />,
|
||||
label: '商品闭环',
|
||||
children: [
|
||||
{ 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/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: 'order-cycle',
|
||||
icon: <FileTextOutlined />,
|
||||
label: '订单闭环',
|
||||
children: [
|
||||
{ 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/after-sales', label: <Link to="/dashboard/after-sales">售后服务</Link> },
|
||||
{ key: '/dashboard/after-sales/refund', label: <Link to="/dashboard/after-sales/refund">退款处理</Link> },
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'logistics-cycle',
|
||||
icon: <TruckOutlined />,
|
||||
label: '物流闭环',
|
||||
requiredPermission: PERMISSIONS.INVENTORY_READ,
|
||||
children: [
|
||||
{ key: '/dashboard/logistics', label: <Link to="/dashboard/logistics">物流查询</Link> },
|
||||
{ key: '/dashboard/logistics/freight-calc', label: <Link to="/dashboard/logistics/freight-calc">运费计算</Link> },
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'finance-cycle',
|
||||
icon: <WalletOutlined />,
|
||||
label: '财务闭环',
|
||||
requiredPermission: PERMISSIONS.FINANCE_READ,
|
||||
children: [
|
||||
{ key: '/dashboard/finance', label: <Link to="/dashboard/finance">财务概览</Link> },
|
||||
{ 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: 'marketing-cycle',
|
||||
icon: <LineChartOutlined />,
|
||||
label: '营销闭环',
|
||||
children: [
|
||||
{ key: '/dashboard/ad', label: <Link to="/dashboard/ad">广告管理</Link> },
|
||||
{ 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: 'analytics',
|
||||
icon: <AppstoreOutlined />,
|
||||
label: '数据分析',
|
||||
children: [
|
||||
{ key: '/dashboard/analytics', label: <Link to="/dashboard/analytics">数据分析</Link> },
|
||||
{ key: '/dashboard/reports', label: <Link to="/dashboard/reports">报表中心</Link> },
|
||||
{ key: '/dashboard/multi-shop-report', label: <Link to="/dashboard/multi-shop-report">多店报表</Link>, requiredFeature: FEATURES.MULTI_SHOP },
|
||||
{ key: '/dashboard/leaderboard', label: <Link to="/dashboard/leaderboard">收益排行</Link> },
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'b2b-trade',
|
||||
icon: <ShopOutlined />,
|
||||
label: 'B2B贸易',
|
||||
requiredFeature: FEATURES.B2B_TRADE,
|
||||
children: [
|
||||
{ key: '/dashboard/merchant', label: <Link to="/dashboard/merchant">商户管理</Link> },
|
||||
{ key: '/dashboard/b2b', label: <Link to="/dashboard/b2b">B2B贸易</Link> },
|
||||
{ key: '/dashboard/b2b/batch-order', label: <Link to="/dashboard/b2b/batch-order">批量订单</Link> },
|
||||
{ key: '/dashboard/b2b/enterprise-quote', label: <Link to="/dashboard/b2b/enterprise-quote">企业报价</Link> },
|
||||
{ key: '/dashboard/b2b/contract-manage', label: <Link to="/dashboard/b2b/contract-manage">合同管理</Link> },
|
||||
{ key: '/dashboard/procurement', label: <Link to="/dashboard/procurement">采购管理</Link> },
|
||||
{ key: '/dashboard/suppliers', label: <Link to="/dashboard/suppliers">供应商</Link> },
|
||||
{ key: '/dashboard/warehouse', label: <Link to="/dashboard/warehouse">仓库库存</Link> },
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'independent-site',
|
||||
icon: <GlobalOutlined />,
|
||||
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/templates', label: <Link to="/dashboard/independent-site/templates">站点模板</Link> },
|
||||
{ key: '/dashboard/independent-site/analytics', label: <Link to="/dashboard/independent-site/analytics">站点分析</Link> },
|
||||
{ key: '/dashboard/independent-site/orders', label: <Link to="/dashboard/independent-site/orders">独立站订单</Link> },
|
||||
{ key: '/dashboard/independent-site/products', label: <Link to="/dashboard/independent-site/products">独立站商品</Link> },
|
||||
{ key: '/dashboard/independent-site/domains', label: <Link to="/dashboard/independent-site/domains">域名管理</Link> },
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'risk-compliance',
|
||||
icon: <SafetyOutlined />,
|
||||
label: '风控合规',
|
||||
children: [
|
||||
{ key: '/dashboard/blacklist', label: <Link to="/dashboard/blacklist">风险监控</Link> },
|
||||
{ key: '/dashboard/compliance', label: <Link to="/dashboard/compliance">合规检查</Link> },
|
||||
{ key: '/dashboard/audit', label: <Link to="/dashboard/audit">审计日志</Link> },
|
||||
{ key: '/dashboard/governance', label: <Link to="/dashboard/governance">治理中心</Link> },
|
||||
{ key: '/dashboard/sovereignty', label: <Link to="/dashboard/sovereignty">主权管理</Link> },
|
||||
{ key: '/dashboard/compliance/certificates', label: <Link to="/dashboard/compliance/certificates">证书管理</Link> },
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'cloud-management',
|
||||
icon: <CloudServerOutlined />,
|
||||
label: '云服务器管理',
|
||||
children: [
|
||||
{ key: '/operation-agent-enhanced', label: <Link to="/operation-agent-enhanced">云服务器管理</Link> },
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'settings',
|
||||
icon: <SettingOutlined />,
|
||||
label: '系统设置',
|
||||
children: [
|
||||
{ key: '/dashboard/settings', label: <Link to="/dashboard/settings">设置概览</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> },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const MainLayoutContent: React.FC = () => {
|
||||
const MainLayoutContent: FC = () => {
|
||||
const [collapsed, setCollapsed] = useState(false);
|
||||
const location = useLocation();
|
||||
const navigate = useNavigate();
|
||||
const { currentUser, setCurrentUser, hasPermission, hasFeature, getPlanLabel, isPaidUser } = useUser();
|
||||
const { locale, setLocale } = useLocale();
|
||||
const { locale, setLocale, t } = useLocale();
|
||||
|
||||
const ALL_MENU_ITEMS = useMemo(() => [
|
||||
{
|
||||
key: '/dashboard',
|
||||
icon: <DashboardOutlined />,
|
||||
label: <Link to="/dashboard">{t('menu.dashboard')}</Link>,
|
||||
requiredPermission: null,
|
||||
},
|
||||
{
|
||||
key: 'ai-operations',
|
||||
icon: <RobotOutlined />,
|
||||
label: t('menu.aiOperations'),
|
||||
requiredFeature: FEATURES.AI_OPERATIONS,
|
||||
children: [
|
||||
{ key: '/dashboard/operation-agent-enhanced', label: <Link to="/dashboard/operation-agent-enhanced">{t('menu.operationAgent')}</Link> },
|
||||
{ key: '/dashboard/auto-pilot', label: <Link to="/dashboard/auto-pilot">{t('menu.autoPilot')}</Link> },
|
||||
{ key: '/dashboard/task-center', label: <Link to="/dashboard/task-center">{t('menu.taskCenter')}</Link> },
|
||||
{ key: '/dashboard/ai-action-task-manager', label: <Link to="/dashboard/ai-action-task-manager">{t('menu.taskManager')}</Link> },
|
||||
{ key: '/dashboard/ai-suggestion', label: <Link to="/dashboard/ai-suggestion">{t('menu.aiSuggestion')}</Link> },
|
||||
{ key: '/dashboard/human-approval', label: <Link to="/dashboard/human-approval">{t('menu.humanApproval')}</Link> },
|
||||
{ key: '/dashboard/client-management', label: <Link to="/dashboard/client-management">{t('menu.clientManagement')}</Link> },
|
||||
{ key: '/dashboard/execution-results', label: <Link to="/dashboard/execution-results">{t('menu.executionResults')}</Link> },
|
||||
{ key: '/dashboard/ai-decision-log', label: <Link to="/dashboard/ai-decision-log">{t('menu.aiDecisionLog')}</Link> },
|
||||
{ key: '/dashboard/strategy-marketplace', label: <Link to="/dashboard/strategy-marketplace">{t('menu.strategyMarketplace')}</Link> },
|
||||
{ key: '/dashboard/auto-product-selection', label: <Link to="/dashboard/auto-product-selection">{t('menu.autoProductSelection')}</Link> },
|
||||
{ key: '/dashboard/auto-execution', label: <Link to="/dashboard/auto-execution">{t('menu.autoExecution')}</Link> },
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'product-cycle',
|
||||
icon: <ShoppingOutlined />,
|
||||
label: t('menu.productCycle'),
|
||||
children: [
|
||||
{ key: '/dashboard/product', label: <Link to="/dashboard/product">{t('menu.productManagement')}</Link>, requiredPermission: PERMISSIONS.PRODUCT_READ },
|
||||
{ key: '/dashboard/product/publish', label: <Link to="/dashboard/product/publish">{t('menu.productPublish')}</Link>, requiredPermission: PERMISSIONS.PRODUCT_WRITE },
|
||||
{ key: '/dashboard/inventory', label: <Link to="/dashboard/inventory">{t('menu.inventoryManagement')}</Link>, requiredPermission: PERMISSIONS.INVENTORY_READ },
|
||||
{ key: '/dashboard/inventory/warehouses', label: <Link to="/dashboard/inventory/warehouses">{t('menu.warehouseManagement')}</Link> },
|
||||
{ key: '/dashboard/product/ai-pricing', label: <Link to="/dashboard/product/ai-pricing">{t('menu.aiPricing')}</Link>, requiredFeature: FEATURES.AUTO_PRICING },
|
||||
{ key: '/dashboard/product/profit-monitor', label: <Link to="/dashboard/product/profit-monitor">{t('menu.profitMonitor')}</Link> },
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'order-cycle',
|
||||
icon: <FileTextOutlined />,
|
||||
label: t('menu.orderCycle'),
|
||||
children: [
|
||||
{ key: '/dashboard/orders', label: <Link to="/dashboard/orders">{t('menu.orderManagement')}</Link>, requiredPermission: PERMISSIONS.ORDER_READ },
|
||||
{ key: '/dashboard/orders/exception', label: <Link to="/dashboard/orders/exception">{t('menu.exceptionOrders')}</Link> },
|
||||
{ key: '/dashboard/after-sales', label: <Link to="/dashboard/after-sales">{t('menu.afterSales')}</Link> },
|
||||
{ key: '/dashboard/after-sales/refund', label: <Link to="/dashboard/after-sales/refund">{t('menu.refundProcessing')}</Link> },
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'logistics-cycle',
|
||||
icon: <TruckOutlined />,
|
||||
label: t('menu.logisticsCycle'),
|
||||
requiredPermission: PERMISSIONS.INVENTORY_READ,
|
||||
children: [
|
||||
{ key: '/dashboard/logistics', label: <Link to="/dashboard/logistics">{t('menu.logisticsQuery')}</Link> },
|
||||
{ key: '/dashboard/logistics/freight-calc', label: <Link to="/dashboard/logistics/freight-calc">{t('menu.freightCalculation')}</Link> },
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'finance-cycle',
|
||||
icon: <WalletOutlined />,
|
||||
label: t('menu.financeCycle'),
|
||||
requiredPermission: PERMISSIONS.FINANCE_READ,
|
||||
children: [
|
||||
{ key: '/dashboard/finance', label: <Link to="/dashboard/finance">{t('menu.financeOverview')}</Link> },
|
||||
{ key: '/dashboard/finance/transactions', label: <Link to="/dashboard/finance/transactions">{t('menu.transactionRecords')}</Link> },
|
||||
{ key: '/dashboard/finance/reconciliation', label: <Link to="/dashboard/finance/reconciliation">{t('menu.financeReconciliation')}</Link> },
|
||||
{ key: '/dashboard/user-asset', label: <Link to="/dashboard/user-asset">{t('menu.userAssets')}</Link> },
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'marketing-cycle',
|
||||
icon: <LineChartOutlined />,
|
||||
label: t('menu.marketingCycle'),
|
||||
children: [
|
||||
{ key: '/dashboard/ad', label: <Link to="/dashboard/ad">{t('menu.adManagement')}</Link> },
|
||||
{ key: '/dashboard/marketing/competitors', label: <Link to="/dashboard/marketing/competitors">{t('menu.competitorAnalysis')}</Link> },
|
||||
{ key: '/dashboard/dynamic-pricing', label: <Link to="/dashboard/dynamic-pricing">{t('menu.dynamicPricing')}</Link>, requiredFeature: FEATURES.AUTO_PRICING },
|
||||
{ key: '/dashboard/ab-test', label: <Link to="/dashboard/ab-test">{t('menu.abTest')}</Link> },
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'analytics',
|
||||
icon: <AppstoreOutlined />,
|
||||
label: t('menu.analytics'),
|
||||
children: [
|
||||
{ key: '/dashboard/analytics', label: <Link to="/dashboard/analytics">{t('menu.dataAnalysis')}</Link> },
|
||||
{ key: '/dashboard/reports', label: <Link to="/dashboard/reports">{t('menu.reportCenter')}</Link> },
|
||||
{ key: '/dashboard/multi-shop-report', label: <Link to="/dashboard/multi-shop-report">{t('menu.multiShopReport')}</Link>, requiredFeature: FEATURES.MULTI_SHOP },
|
||||
{ key: '/dashboard/leaderboard', label: <Link to="/dashboard/leaderboard">{t('menu.leaderboard')}</Link> },
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'b2b-trade',
|
||||
icon: <ShopOutlined />,
|
||||
label: t('menu.b2bTrade'),
|
||||
requiredFeature: FEATURES.B2B_TRADE,
|
||||
children: [
|
||||
{ key: '/dashboard/merchant', label: <Link to="/dashboard/merchant">{t('menu.merchantManagement')}</Link> },
|
||||
{ key: '/dashboard/b2b', label: <Link to="/dashboard/b2b">{t('menu.b2bTradeManagement')}</Link> },
|
||||
{ key: '/dashboard/b2b/batch-order', label: <Link to="/dashboard/b2b/batch-order">{t('menu.batchOrder')}</Link> },
|
||||
{ key: '/dashboard/b2b/enterprise-quote', label: <Link to="/dashboard/b2b/enterprise-quote">{t('menu.enterpriseQuote')}</Link> },
|
||||
{ key: '/dashboard/b2b/contract-manage', label: <Link to="/dashboard/b2b/contract-manage">{t('menu.contractManagement')}</Link> },
|
||||
{ key: '/dashboard/procurement', label: <Link to="/dashboard/procurement">{t('menu.procurementManagement')}</Link> },
|
||||
{ key: '/dashboard/suppliers', label: <Link to="/dashboard/suppliers">{t('menu.suppliers')}</Link> },
|
||||
{ key: '/dashboard/warehouse', label: <Link to="/dashboard/warehouse">{t('menu.warehouseInventory')}</Link> },
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'independent-site',
|
||||
icon: <GlobalOutlined />,
|
||||
label: t('menu.independentSite'),
|
||||
requiredFeature: FEATURES.INDEPENDENT_SITE,
|
||||
children: [
|
||||
{ key: '/dashboard/independent-site', label: <Link to="/dashboard/independent-site">{t('menu.siteManagement')}</Link> },
|
||||
{ key: '/dashboard/independent-site/create', label: <Link to="/dashboard/independent-site/create">{t('menu.createSite')}</Link> },
|
||||
{ key: '/dashboard/independent-site/templates', label: <Link to="/dashboard/independent-site/templates">{t('menu.siteTemplates')}</Link> },
|
||||
{ key: '/dashboard/independent-site/analytics', label: <Link to="/dashboard/independent-site/analytics">{t('menu.siteAnalytics')}</Link> },
|
||||
{ key: '/dashboard/independent-site/orders', label: <Link to="/dashboard/independent-site/orders">{t('menu.independentSiteOrders')}</Link> },
|
||||
{ key: '/dashboard/independent-site/products', label: <Link to="/dashboard/independent-site/products">{t('menu.independentSiteProducts')}</Link> },
|
||||
{ key: '/dashboard/independent-site/domains', label: <Link to="/dashboard/independent-site/domains">{t('menu.domainManagement')}</Link> },
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'risk-compliance',
|
||||
icon: <SafetyOutlined />,
|
||||
label: t('menu.riskCompliance'),
|
||||
children: [
|
||||
{ key: '/dashboard/blacklist', label: <Link to="/dashboard/blacklist">{t('menu.riskMonitoring')}</Link> },
|
||||
{ key: '/dashboard/compliance', label: <Link to="/dashboard/compliance">{t('menu.complianceCheck')}</Link> },
|
||||
{ key: '/dashboard/audit', label: <Link to="/dashboard/audit">{t('menu.auditLogs')}</Link> },
|
||||
{ key: '/dashboard/operation-logs', label: <Link to="/dashboard/operation-logs">{t('menu.operationLogs')}</Link> },
|
||||
{ key: '/dashboard/governance', label: <Link to="/dashboard/governance">{t('menu.governanceCenter')}</Link> },
|
||||
{ key: '/dashboard/sovereignty', label: <Link to="/dashboard/sovereignty">{t('menu.sovereigntyManagement')}</Link> },
|
||||
{ key: '/dashboard/compliance/certificates', label: <Link to="/dashboard/compliance/certificates">{t('menu.certificateManagement')}</Link> },
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'settings',
|
||||
icon: <SettingOutlined />,
|
||||
label: t('menu.settings'),
|
||||
children: [
|
||||
{ key: '/dashboard/settings', label: <Link to="/dashboard/settings">{t('menu.settingsOverview')}</Link> },
|
||||
{ key: '/dashboard/settings/platform-auth', label: <Link to="/dashboard/settings/platform-auth">{t('menu.platformAuth')}</Link> },
|
||||
{ key: '/dashboard/settings/service-manager', label: <Link to="/dashboard/settings/service-manager">{t('menu.serviceManager')}</Link> },
|
||||
{ key: '/dashboard/user', label: <Link to="/dashboard/user">{t('menu.userManagement')}</Link> },
|
||||
{ key: '/dashboard/role', label: <Link to="/dashboard/role">{t('menu.rolePermissions')}</Link> },
|
||||
],
|
||||
},
|
||||
], [t]);
|
||||
|
||||
const menuItems = useMemo(() => {
|
||||
const stripCustomProps = (item: CustomMenuItem): MenuItem => {
|
||||
@@ -234,7 +247,7 @@ const MainLayoutContent: React.FC = () => {
|
||||
return result;
|
||||
};
|
||||
return filterMenuItems(ALL_MENU_ITEMS);
|
||||
}, [hasPermission, hasFeature]);
|
||||
}, [hasPermission, hasFeature, t]);
|
||||
|
||||
const getSelectedKeys = (): string[] => {
|
||||
const pathname = location.pathname;
|
||||
@@ -354,8 +367,13 @@ const MainLayoutContent: React.FC = () => {
|
||||
enterprise: 'purple',
|
||||
};
|
||||
|
||||
// 如果当前路径不是以 /dashboard 开头,则只渲染 Outlet,避免布局嵌套
|
||||
if (!location.pathname.startsWith('/dashboard')) {
|
||||
return <Outlet context={{ currentUser, hasPermission, hasFeature, isPaidUser }} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<Layout style={{ minHeight: '100vh' }}>
|
||||
<Layout style={{ minHeight: '100vh', display: 'flex' }}>
|
||||
<Sider
|
||||
trigger={null}
|
||||
collapsible
|
||||
@@ -363,11 +381,7 @@ const MainLayoutContent: React.FC = () => {
|
||||
width={collapsed ? 80 : 200}
|
||||
style={{
|
||||
background: '#001529',
|
||||
position: 'fixed',
|
||||
left: 0,
|
||||
top: 0,
|
||||
height: '100vh',
|
||||
zIndex: 100,
|
||||
zIndex: 99,
|
||||
padding: 0,
|
||||
}}
|
||||
>
|
||||
@@ -458,12 +472,7 @@ const MainLayoutContent: React.FC = () => {
|
||||
</div>
|
||||
</Sider>
|
||||
|
||||
<Layout
|
||||
style={{
|
||||
marginLeft: collapsed ? 80 : 200,
|
||||
transition: 'all 0.2s',
|
||||
}}
|
||||
>
|
||||
<div style={{ flex: 1, display: 'flex', flexDirection: 'column' }}>
|
||||
<Header
|
||||
style={{
|
||||
background: '#fff',
|
||||
@@ -472,13 +481,13 @@ const MainLayoutContent: React.FC = () => {
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
boxShadow: '0 1px 4px rgba(0, 21, 41, 0.08)',
|
||||
position: 'sticky',
|
||||
top: 0,
|
||||
zIndex: 99,
|
||||
zIndex: 100,
|
||||
height: '64px',
|
||||
flexShrink: 0,
|
||||
}}
|
||||
>
|
||||
<div style={{ fontSize: '16px', fontWeight: 500, color: '#333' }}>
|
||||
Crawlful Hub 管理后台
|
||||
{t('app.name')} {t('app.title')}
|
||||
</div>
|
||||
|
||||
<Space size={16}>
|
||||
@@ -510,8 +519,8 @@ const MainLayoutContent: React.FC = () => {
|
||||
<Dropdown
|
||||
menu={{
|
||||
items: [
|
||||
{ key: 'zh-CN', label: '简体中文' },
|
||||
{ key: 'en-US', label: 'English' },
|
||||
{ key: 'zh-CN', label: t('settings.language') === 'Language' ? '简体中文' : 'Chinese' },
|
||||
{ key: 'en-US', label: t('settings.language') === 'Language' ? 'English' : '英文' },
|
||||
],
|
||||
onClick: ({ key }) => setLocale(key),
|
||||
selectedKeys: [locale],
|
||||
@@ -519,7 +528,7 @@ const MainLayoutContent: React.FC = () => {
|
||||
placement="bottomRight"
|
||||
>
|
||||
<Button type="text" icon={<GlobalOutlined />} style={{ height: '32px' }}>
|
||||
{locale === 'zh-CN' ? '中文' : 'EN'}
|
||||
{locale === 'zh-CN' ? t('settings.language') === 'Language' ? '中文' : 'Chinese' : t('settings.language') === 'Language' ? 'EN' : '英文'}
|
||||
</Button>
|
||||
</Dropdown>
|
||||
|
||||
@@ -552,6 +561,7 @@ const MainLayoutContent: React.FC = () => {
|
||||
padding: '24px',
|
||||
background: '#f0f2f5',
|
||||
minHeight: 280,
|
||||
flex: 1,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
@@ -566,16 +576,18 @@ const MainLayoutContent: React.FC = () => {
|
||||
<Outlet context={{ currentUser, hasPermission, hasFeature, isPaidUser }} />
|
||||
</div>
|
||||
</Content>
|
||||
</Layout>
|
||||
</div>
|
||||
</Layout>
|
||||
);
|
||||
};
|
||||
|
||||
const MainLayout: React.FC = () => {
|
||||
const MainLayout: FC = () => {
|
||||
return (
|
||||
<UserProvider>
|
||||
<MainLayoutContent />
|
||||
</UserProvider>
|
||||
<LocaleProvider>
|
||||
<UserProvider>
|
||||
<MainLayoutContent />
|
||||
</UserProvider>
|
||||
</LocaleProvider>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user