pay-company/src/common/libs/umi/layoutConfig.tsx
2026-02-04 12:32:17 +08:00

303 lines
9.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { MyIcons, MyIconsType, PermissionsType, useMyState } from '@/common';
import AvatarProps from '@/common/components/layout/AvatarProps';
import { Apis } from '@/gen/Apis';
import { Link, RuntimeConfig, history, useNavigate } from '@umijs/max';
import { AutoComplete, Input, Menu, MenuProps, Select, Space } from 'antd';
import { useEffect, 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 [getSelectProject, setSelectProject] = useState<LevelKeysProps[]>([]);
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 handleLoadProject = async () => {
let res = await Apis.Common.Auth.GetProjects();
setSelectProject(
res?.data?.map((item) => ({
value: item.id,
label: item.name,
})),
);
};
const [stateOpenKeys, setStateOpenKeys] = useState(['2', '23']);
const getLevelKeys: any = (items1: LevelKeysProps[]) => {
const key: Record<string, number> = {};
const func = (items2: LevelKeysProps[], level = 1) => {
items2?.forEach((item) => {
if (item.key) {
key[item.key] = level;
}
if (item.children) {
func(item.children, level + 1);
}
});
};
func(items1);
return key;
};
useEffect(() => {
handleLoadProject('');
}, []);
return {
title: '',
// 首页 logo
logo: (
<div style={{ width: 136, display: 'flex', justifyContent: 'center' }}>
<img
src={
snap.session?.company_configs?.config_value?.admin_logo
? snap.session?.company_configs?.config_value?.admin_logo[0]?.url
: ''
}
style={{ width: 'auto', 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} />
</div>
<Space size={10}>
{/* <Button
type="default"
shape="circle"
icon={<SettingOutlined />}
onClick={() => history.push('/system/sys_permissions')}
/> */}
<Select
onSearch={handleLoadProject}
options={getSelectProject}
allowClear
style={{ width: 160 }}
defaultValue={snap.session.current_project?.id}
onChange={(e: any) => {
Apis.Common.Auth.SwitchProject({
project_id: e ? e?.toString() : 'all',
}).then(() => {
window.location.reload();
});
console.log(e, 'e');
}}
placeholder="选择项目"
/>
</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>
);
};