pay-company/src/common/libs/umi/layoutConfig.tsx

299 lines
9.1 KiB
TypeScript
Raw Normal View History

2026-01-08 16:35:06 +08:00
import { MyIcons, MyIconsType, PermissionsType, useMyState } from '@/common';
import AvatarProps from '@/common/components/layout/AvatarProps';
2026-01-13 15:19:57 +08:00
import { SettingOutlined } from '@ant-design/icons';
2026-01-08 16:35:06 +08:00
import { Link, RuntimeConfig, history, useNavigate } from '@umijs/max';
2026-01-13 15:19:57 +08:00
import { AutoComplete, Button, Input, Menu, MenuProps, Space } from 'antd';
2026-01-08 16:35:06 +08:00
import { useState } from 'react';
import './allConfig.scss';
// import Logo from './logo.png';
interface LevelKeysProps {
key?: string;
children?: LevelKeysProps[];
}
const loopMenu = (permissions: PermissionsType[] | undefined) => {
let tree: PermissionsType[] = [];
let map: Record<number, PermissionsType> = {};
// 过滤掉Button和Tab类型的权限这些不应该显示在菜单中
const menuPermissions = permissions?.filter(
(p) => p.type !== 'Button' && p.type !== 'Tab',
);
menuPermissions?.forEach((permission) => {
map[permission.id] = {
path: permission.path,
name: permission.name,
icon: permission.icon && MyIcons[permission.icon as MyIconsType],
label: permission.name,
key: permission.path || permission.id.toString(),
hideInMenu: false, // 已经过滤过类型这里可以设置为false
};
});
menuPermissions?.forEach((permission) => {
let node = map[permission.id];
const parentId = permission?.parent_id;
if (parentId !== null && parentId !== undefined) {
const parentNode = map[parentId];
if (parentNode) {
// 初始化 children 如果不存在
if (!Array.isArray(parentNode.children)) {
parentNode.children = [];
}
parentNode.children.push(node);
} else {
// 父节点不存在,作为根节点处理
console.warn(
`Parent node with id ${parentId} not found for permission ${permission.id}`,
);
tree.push(node);
}
} else {
tree.push(node);
}
});
return tree?.[0]?.children;
};
export const LayoutConfig: RuntimeConfig['layout'] = () => {
const { snap } = useMyState();
const navigate = useNavigate();
const permissionsList = (snap.session.permissions || [])
.filter((p: any) => p.type !== 'Button' && p.path)
.sort((a: any, b: any) => a._lft - b._lft)
.map((p: any) => ({ value: p.path, label: p.name }));
const quickLinks = [
{ label: '工单Bi', path: '/work_order/work_bi' },
{ label: '合同Bi', path: '/contract/contracts_bi' },
{ label: '收费Bi', path: '/charge/charge_bi' },
{ label: '项目Bi', path: '/asset/asset_bi' },
];
const [stateOpenKeys, setStateOpenKeys] = useState(['2', '23']);
const getLevelKeys: any = (items1: LevelKeysProps[]) => {
const key: Record<string, number> = {};
const func = (items2: LevelKeysProps[], level = 1) => {
console.log(items2, 'level');
items2?.forEach((item) => {
if (item.key) {
key[item.key] = level;
}
if (item.children) {
func(item.children, level + 1);
}
});
};
func(items1);
return key;
};
return {
title: '',
// 首页 logo
logo: (
<div style={{ width: 181 }}>
{/* <img src={Logo} style={{ height: '42px' }} /> */}
</div>
),
layout: 'mix',
siderWidth: 180,
colorPrimary: '#1890ff',
pure: history.location.pathname === '/login',
avatarProps: {
render: () => <AvatarProps user={snap.session.user} />,
},
headerContentRender: () => (
<div className="headerContentRender">
<div style={{ display: 'flex', alignItems: 'center', gap: 20 }}>
<HeaderSearch permissionsList={permissionsList} />
2026-01-13 15:19:57 +08:00
{/* <Space size={20} style={{ color: '#666' }}>
2026-01-08 16:35:06 +08:00
:
{quickLinks.map((q) => (
<a
key={q.path}
onClick={() => history.push(q.path)}
className="quick_link"
>
{q.label}
</a>
))}
2026-01-13 15:19:57 +08:00
</Space> */}
2026-01-08 16:35:06 +08:00
</div>
<Space size={10}>
2026-01-13 15:19:57 +08:00
{/* <Popover
2026-01-08 16:35:06 +08:00
placement="bottom"
title="小程序二维码"
content={
<Space style={{ textAlign: 'center' }} size="large">
<div>
<Image src={ImgEmployeeWxApp} style={{ height: '120px' }} />
<div style={{ marginTop: 10 }}></div>
</div>
<div>
<Image src={ImgCustomerWxApp} style={{ height: '120px' }} />
<div style={{ marginTop: 10 }}></div>
</div>
</Space>
}
>
<Button type="default" shape="circle" icon={<TabletOutlined />} />
</Popover>
2026-01-13 15:19:57 +08:00
<Button type="default" shape="circle" icon={<BellOutlined />} /> */}
2026-01-08 16:35:06 +08:00
<Button
type="default"
shape="circle"
icon={<SettingOutlined />}
onClick={() => history.push('/system/sys_permissions')}
/>
</Space>
</div>
),
//水印设置
waterMarkProps: {
content: snap.session.user?.username,
},
defaultCollapsed: true,
collapsedButtonRender: false,
token: {
bgLayout: '#f6f6f6',
// header: {
// colorBgHeader: '#1B1F3B',
// colorHeaderTitle: '#f8f8f8',
// colorTextRightActionsItem: '#FFF',
// heightLayoutHeader: 50,
// },
//菜单背景色
sider: {
colorMenuBackground: '#fff',
colorTextMenuSelected: '#1890ff', // 菜单激活项字体颜色设置为蓝色
},
},
// 上下菜单
menuItemRender: (item, dom) => <Link to={item.path || '/'}>{dom}</Link>,
//点击目录,收起其他菜单
menuCollapse: true,
// //左右菜单
menuRender: () => {
let objjs: any = [];
snap.session.permissions?.forEach((res: any) => {
objjs.push(res);
});
let data = objjs.sort((a: any, b: any) => {
return a._lft - b._lft;
});
const menus = loopMenu(data);
const levelKeys: any = getLevelKeys(menus as LevelKeysProps[]);
const onOpenChange: MenuProps['onOpenChange'] = (openKeys) => {
const currentOpenKey = openKeys.find(
(key) => !stateOpenKeys.includes(key),
);
// open
if (currentOpenKey !== undefined) {
const repeatIndex = openKeys
.filter((key) => key !== currentOpenKey)
.findIndex((key) => levelKeys[key] === levelKeys[currentOpenKey]);
setStateOpenKeys(
openKeys
// remove repeat key
.filter((_, index) => index !== repeatIndex)
// remove current level all child
.filter((key) => levelKeys[key] <= levelKeys[currentOpenKey]),
);
} else {
// close
setStateOpenKeys(openKeys);
}
};
return (
<div
style={{
position: 'relative',
width: 180,
top: 0,
left: 0,
bottom: 0,
height: '100vh',
zIndex: 100,
boxShadow: '0 2px 10px rgba(0, 0, 0, 0.1)',
}}
>
<div
style={{
position: 'fixed',
paddingTop: 60,
top: 0,
left: 0,
bottom: 0,
backgroundColor: '#fff',
overflowY: 'auto',
}}
>
<Menu
style={{ width: '165px' }}
mode="inline"
defaultSelectedKeys={[history.location.pathname]}
theme="light"
items={menus}
openKeys={stateOpenKeys}
onOpenChange={onOpenChange}
onClick={({ key }) => {
sessionStorage.setItem('breadcrumbs', '');
navigate(key);
console.log(key, 'key2');
}}
onSelect={({ key }) => {
console.log(key, 'key');
}}
/>
</div>
</div>
);
},
menuMode: 'inline',
menu: {
params: snap.session.permissions,
mode: 'inline',
request: async () => {
let objjs: any = [];
snap.session.permissions?.forEach((res: any) => {
objjs.push(res);
});
let data = objjs.sort((a: any, b: any) => {
return a._lft - b._lft;
});
const menus = loopMenu(data);
return Promise.resolve(menus);
},
},
// unAccessible: <div>unAccessible</div>,
};
};
const HeaderSearch = ({ permissionsList }: { permissionsList: any[] }) => {
const [value, setValue] = useState<string>('');
return (
<AutoComplete
value={value}
options={permissionsList}
style={{ width: 280 }}
placeholder="~输入关键字,搜索系统功能"
filterOption={(inputValue, option) =>
(option?.label as string)
?.toLowerCase()
.includes(inputValue.toLowerCase())
}
onChange={(v) => setValue(v)}
onSelect={(v) => {
setValue('');
history.push(v as string);
}}
>
:
<Input allowClear size="middle" />
</AutoComplete>
);
};