78 lines
4.6 KiB
TypeScript
78 lines
4.6 KiB
TypeScript
import type { MenuDataItem } from '@ant-design/pro-components';
|
|
import {
|
|
CloudDownloadOutlined,
|
|
UserOutlined,
|
|
EyeOutlined,
|
|
LineChartOutlined,
|
|
CommentOutlined,
|
|
SettingOutlined,
|
|
ProfileOutlined,
|
|
ClusterOutlined,
|
|
GatewayOutlined,
|
|
DashboardOutlined,
|
|
} from '@ant-design/icons';
|
|
|
|
// 页头标题/副标题规则:语义对齐 web.archived/src/app/Layout.jsx 的 pageMetadataRules。
|
|
const rules: Array<{ test: (path: string) => boolean; title: string; subtitle: string }> = [
|
|
{ test: (p) => p === '/' || p === '/dashboard', title: '工作台', subtitle: '运营概况与快捷入口。' },
|
|
{ test: (p) => p === '/accounts/import', title: '账号导入', subtitle: '管理分享链接解析任务,解析成功后自动加入监控账号。' },
|
|
{ test: (p) => p === '/accounts', title: '我的账号', subtitle: '创建和管理自己维护的账号。' },
|
|
{ test: (p) => p === '/accounts/monitoring', title: '监控账号', subtitle: '管理需要持续跟踪的竞品账号及采集状态。' },
|
|
{ test: (p) => /^\/accounts\/monitoring\/.+/.test(p), title: '监控账号详情', subtitle: '查看监控账号画像与作品列表,点击作品可追溯指标统计。' },
|
|
{ test: (p) => /\/edit$/.test(p) && p.startsWith('/accounts/'), title: '编辑社媒账号', subtitle: '维护账号资料、登录核验与自动响应策略。' },
|
|
{ test: (p) => p.startsWith('/accounts/'), title: '账号详情', subtitle: '查看账号状态、登录身份与运行环境绑定。' },
|
|
{ test: (p) => p === '/creator/competitors', title: '竞品分析', subtitle: '查看竞品作品与指标,分享链接导入请前往账号导入。' },
|
|
{ test: (p) => p === '/creator/settings', title: '采集设置', subtitle: '统一配置采集窗口、指标采集和已批准的服务。' },
|
|
{ test: (p) => p.startsWith('/creator/competitors/'), title: '竞品账号详情', subtitle: '查看竞品画像与作品列表,点击作品可追溯指标统计。' },
|
|
{ test: (p) => p === '/network-exits', title: '网络出口', subtitle: '维护固定出口、健康观测与账号绑定。' },
|
|
{ test: (p) => p.startsWith('/network-exits/'), title: '网络出口详情', subtitle: '查看出口配置、健康状态和绑定关系。' },
|
|
{ test: (p) => p === '/gateways', title: '网关管理', subtitle: '注册并检查宿主机 native browser gateway。' },
|
|
];
|
|
|
|
// 菜单结构:工作台置顶(对标 pro 官方 workplace 预览),其余与 web.archived/src/app/Layout.jsx 一致(运营 / 资源 两组);
|
|
// icon 选用 antd 图标库里语义常见、用户一眼可识别的隐喻。
|
|
export const menu: MenuDataItem[] = [
|
|
{ path: '/dashboard', name: '工作台', icon: <DashboardOutlined /> },
|
|
{
|
|
name: '运营',
|
|
children: [
|
|
{ path: '/accounts/import', name: '账号导入', icon: <CloudDownloadOutlined /> },
|
|
{ path: '/accounts', name: '我的账号', icon: <UserOutlined /> },
|
|
{ path: '/accounts/monitoring', name: '监控账号', icon: <EyeOutlined /> },
|
|
{ path: '/creator/competitors', name: '竞品分析', icon: <LineChartOutlined /> },
|
|
{ path: '/creator/settings', name: '采集设置', icon: <SettingOutlined /> },
|
|
],
|
|
},
|
|
{
|
|
name: '资源',
|
|
children: [
|
|
{ path: '/network-exits', name: '网络出口', icon: <ClusterOutlined /> },
|
|
{ path: '/gateways', name: '网关管理', icon: <GatewayOutlined /> },
|
|
],
|
|
},
|
|
];
|
|
|
|
export function pageMetadata(pathname: string): { title: string; subtitle: string } {
|
|
const matched = rules.find((item) => item.test(pathname));
|
|
if (matched) return { title: matched.title, subtitle: matched.subtitle };
|
|
for (const group of menu) {
|
|
const hit = (group.children ?? []).find((item) => item.path && (pathname === item.path || pathname.startsWith(`${item.path}/`)));
|
|
if (hit) return { title: hit.name ?? '', subtitle: 'CreatorHub 运营控制台' };
|
|
}
|
|
return { title: 'CreatorHub', subtitle: '运营控制台' };
|
|
}
|
|
|
|
export function menuSelectedKey(pathname: string): string {
|
|
const leafPaths = menu.flatMap((group) => (group.children ?? []).map((item) => item.path ?? ''));
|
|
const segments = pathname.split('/').filter(Boolean);
|
|
for (let i = segments.length; i >= 1; i--) {
|
|
const candidate = `/${segments.slice(0, i).join('/')}`;
|
|
if (leafPaths.includes(candidate)) return candidate;
|
|
}
|
|
return pathname;
|
|
}
|
|
|
|
// 侧栏选中态:ProLayout 默认按路径前缀高亮(/accounts 是 /accounts/import 的前缀,两项会同时高亮)。
|
|
// 这里改为受控 selectedKeys:从完整路径逐段向前回退,仅精确命中菜单叶路径;
|
|
// 详情页(如 /accounts/123)回落到父级菜单项。
|