| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641 |
- /*
- * @Author: your name
- * @Date: 2022-01-06 15:25:39
- * @LastEditTime: 2025-05-22 14:30:28
- * @LastEditors: code4eat awesomedema@gmail.com
- * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
- * @FilePath: /KC-MiddlePlatform/src/pages/platform/_layout.tsx
- */
- import { IRouteComponentProps, useModel, Helmet } from 'umi';
- // import { CrownOutlined, UserOutlined, SmileOutlined } from '@ant-design/icons';
- import ProLayout, { PageContainer } from '@ant-design/pro-layout';
- import { getPlatformMenu, getSpecifyMenuDetail } from '@/service/menu';
- import './index.less';
- import { TreeItemType } from '@/utils';
- import { SpacicalPageParamsType } from '@/typings';
- import { Key, useEffect, useRef, useState } from 'react';
- import Icon, { FileOutlined, FolderOutlined, createFromIconfontCN } from '@ant-design/icons';
- import { getAllParams } from '@/service';
- import '../../../public/zhongtaiA';
- import ResizableContainer from '@/components/ResizableContainer';
- import { Menu } from 'antd';
- import EmptyPage from '@/components/emptyPage';
- const IconFont = createFromIconfontCN({
- scriptUrl: '',
- });
- interface TransformResult {
- newTree: any[];
- firstLeafNode: any | null;
- firstLeafNodePath: any[];
- }
- function transformTree(tree: any[]): TransformResult {
- let firstLeafNode: any | null = null;
- let firstLeafNodePath: any[] = [];
- function traverse(node: any, path: any[]): any {
- const newNode: any = {
- ...node,
- label: node.name,
- };
- const newPath = [...path, newNode];
- if (node.children && node.children.length > 0) {
- newNode.children = node.children.map((child: any) => traverse(child, newPath));
- } else {
- if (!firstLeafNode) {
- firstLeafNode = newNode;
- firstLeafNodePath = newPath;
- }
- }
- // Remove children property if it is an empty array
- if (node.children && node.children.length === 0) {
- newNode.children = null;
- }
- return newNode;
- }
- const newTree = tree.map((node) => traverse(node, []));
- return { newTree, firstLeafNode, firstLeafNodePath };
- }
- const findItemByKey: any = (tree: any[], key: string, keyName: string) => {
- for (const node of tree) {
- if (node[`${keyName}`] === key) {
- return node;
- }
- if (node.children) {
- const result = findItemByKey(node.children, key, keyName);
- if (result) {
- return result;
- }
- }
- }
- return null;
- };
- // 权限检查函数
- function checkAccess(menu: any[], pathname: string) {
- const matchPath = (path: any, target: string) => {
- // 如果路径以 /platform 开头,则需要完整匹配
- if (target.startsWith('/platform')) {
- return path === target; // 完整匹配
- }
- // 否则,执行前缀匹配逻辑
- return target.startsWith(path);
- };
- for (const item of menu) {
- // 如果匹配成功,则立即返回 true
- if (matchPath(item.path, pathname)) {
- return true;
- }
- // 递归检查 item.child 的情况
- if (item.child) {
- const hasAccess = checkAccess(item.child, pathname);
- if (hasAccess) {
- return true;
- }
- }
- // 递归检查 item.children 的情况
- if (item.children) {
- const hasAccess = checkAccess(item.children, pathname);
- if (hasAccess) {
- return true;
- }
- }
- }
- // 如果所有匹配都失败,返回 false
- return false;
- }
- export default function Layout({ children, location, route, history, match, ...rest }: IRouteComponentProps) {
- const { initialState, setInitialState } = useModel('@@initialState');
- const [openKeys, set_openKeys] = useState<string[]>([]);
- const [selectedKeys, set_selectedKeys] = useState<string[]>([]);
- const [emptyPageContent, set_emptyPageContent] = useState('');
- const [isShowPageMenu, set_isShowPageMenu] = useState(true);
- const [isEmpty, set_isEmpty] = useState(false);
- const [isThirdPartySystem, setIsThirdPartySystem] = useState(false);
- const [collapsed, set_collapsed] = useState(false);
- const [pageUrl, set_pageUrl] = useState<string | undefined>(undefined);
- const queryParams = new URLSearchParams(location.search);
- const noMenu = queryParams.get('noMenu');
- const noTopBar = queryParams.get('noTopbar');
- const moreConfig: { menuRender?: any } = {};
- const { pathname } = location;
- const isMenuClickRef = useRef(false);
- const [loading, setLoading] = useState(true);
- const [dataLoaded, setDataLoaded] = useState(false);
- // 用于记录上一次 isThirdPartySystem 状态
- const prevIsThirdPartySystemRef = useRef(isThirdPartySystem);
- const setEmptyPageContent = async (menuId: Key) => {
- const menuItem = await getSpecifyMenuDetail(menuId);
- if (menuItem.isSetupMenu) {
- set_isShowPageMenu(false);
- }
- set_emptyPageContent(menuItem.description);
- };
- const currentHospName = localStorage.getItem('currentHospName');
- const checkPermission = (path: any) => {
- const { navData = [], menuData = [] } = initialState || {};
- // 检查访问权限
- const hasAccess = checkAccess([...navData, ...menuData], path);
- return hasAccess;
- };
- useEffect(() => {
- const isShowMenu = localStorage.getItem('isChildShowMenu');
- if (isShowMenu) {
- set_isShowPageMenu(isShowMenu == 'true');
- } else {
- set_isShowPageMenu(true);
- }
- });
- useEffect(() => {
- if (location.query.menuId) {
- setEmptyPageContent(location.query.menuId as string);
- }
- set_isEmpty(location.query.isEmpty == 'true');
- }, [location]);
- useEffect(() => {
- const handleResize = () => {
- if (window.innerWidth <= 1280) {
- // 自定义触发宽度为 800px
- set_collapsed(true);
- } else {
- set_collapsed(false);
- }
- };
- // 初始化
- handleResize();
- // 监听窗口大小变化
- window.addEventListener('resize', handleResize);
- // 清除监听器
- return () => {
- window.removeEventListener('resize', handleResize);
- };
- }, []);
- const adjustIframe = () => {
- // var ifm:any = document.getElementById("bi_iframe");
- // if(ifm){
- // ifm.height=document.documentElement.clientHeight;
- // ifm.width=document.documentElement.clientWidth;
- // }
- };
- const addTokenToUrl = (url: string, token = '') => {
- // 检查 URL 中是否有查询字符串
- url = url.trim();
- if (url.includes('?')) {
- // 检查是否已经有 token 参数
- if (!url.includes('token=')) {
- // 添加 &token=,因为 URL 中已经有其他查询参数
- url += `&token=${token}`;
- }
- } else {
- // URL 中没有查询参数,所以添加 ?token=
- url += `?token=${token}`;
- }
- return url;
- };
- const { type, url, contentType } = initialState?.currentSelectedSys ?? {};
- const userData = localStorage.getItem('userData');
- const { token } = JSON.parse(userData as string);
- // if (initialState?.currentSelectedSys) {
- // const { type, url, contentType } = initialState.currentSelectedSys;
- // if (type == 1 && contentType == 6) {
- // const userData = localStorage.getItem('userData');
- // const { token } = JSON.parse(userData as string);
- // return <iframe id={'bi_iframe'} style={{ width: '100%', height: '100%', border: 'none' }} src={addTokenToUrl(url as string, token)}
- // onLoad={() => adjustIframe()}
- // ></iframe>;
- // }
- // }
- //临时演示处理
- if (location.pathname == '/platform/costMana') {
- //临时解决未嵌入成本核算,而实现访问的效果
- const getToken = async () => {
- const resp = await getAllParams();
- if (resp) {
- const needItem = resp.filter((a: any) => a.code == '1647777324889935872');
- if (needItem.length > 0) {
- set_pageUrl(`http://47.96.149.190:8000/platformMana/roleManage?hospSign=dOBHdoPmJgPGnMSH&token=${needItem[0].value}`);
- }
- }
- };
- getToken();
- return <>{pageUrl && <iframe id={'bi_iframe'} style={{ width: '100%', height: '100%', border: 'none' }} src={pageUrl} onLoad={() => adjustIframe()}></iframe>};</>;
- }
- if (location.pathname == '/platform/costMana2') {
- //临时解决未嵌入成本核算,而实现访问的效果
- const getToken = async () => {
- const resp = await getAllParams();
- if (resp) {
- const needItem = resp.filter((a: any) => a.code == '1733034722981974016');
- if (needItem.length > 0) {
- set_pageUrl(`http://47.96.149.190:8000/platformMana/roleManage?hospSign=QgqzJxUR5reLh5ER&token=${needItem[0].value}`);
- }
- }
- };
- getToken();
- return <>{pageUrl && <iframe id={'bi_iframe'} style={{ width: '100%', height: '100%', border: 'none' }} src={pageUrl} onLoad={() => adjustIframe()}></iframe>};</>;
- }
- if (location.pathname == '/platform/Budget') {
- const pageUrl = `https://test.baokangyiguan.com/index/apiLogin?username=admin&url=budget/index`;
- return <>{pageUrl && <iframe id={'bi_iframe'} style={{ width: '100%', height: '100%', border: 'none' }} src={pageUrl} onLoad={() => adjustIframe()}></iframe>};</>;
- }
- if (location.pathname == '/platform/DRG') {
- const pageUrl = `https://test.baokangyiguan.com/index/apiLogin?username=admin&url=drgs/index`;
- return <>{pageUrl && <iframe id={'bi_iframe'} style={{ width: '100%', height: '100%', border: 'none' }} src={pageUrl} onLoad={() => adjustIframe()}></iframe>};</>;
- }
- if (location.pathname == '/platform/DIP') {
- const pageUrl = `https://test.baokangyiguan.com/index/apiLogin?username=admin&url=dips/index`;
- return <>{pageUrl && <iframe id={'bi_iframe'} style={{ width: '100%', height: '100%', border: 'none' }} src={pageUrl} onLoad={() => adjustIframe()}></iframe>};</>;
- }
- if (location.pathname == '/platform/baokangCostApp') {
- const pageUrl = `https://test.baokangyiguan.com/index/apiLogin?username=admin&url=cost/index `;
- return <>{pageUrl && <iframe id={'bi_iframe'} style={{ width: '100%', height: '100%', border: 'none' }} src={pageUrl} onLoad={() => adjustIframe()}></iframe>};</>;
- }
- // useEffect(() => {
- // if (!dataLoaded && initialState) {
- // const navData = initialState.navData || [];
- // const menuData = initialState.menuData || [];
- // if (navData.length > 0 || menuData.length > 0) {
- // setDataLoaded(true);
- // const { pathname } = history.location;
- // const hasAccess = checkPermission(pathname);
- // if (!hasAccess) {
- // if (!pathname.includes('/platform')) {
- // history.push('/noAccess');
- // }
- // }
- // setLoading(false);
- // }
- // }
- // }, [initialState, dataLoaded]);
- useEffect(() => {
- return history.listen((location) => {
- if (!isMenuClickRef.current && dataLoaded) {
- const hasPermission = checkPermission(location.pathname);
- if (!hasPermission) {
- history.push('/noAccess');
- }
- }
- isMenuClickRef.current = false; // 重置状态
- });
- }, [dataLoaded, initialState]);
- useEffect(() => {
- if (initialState?.currentSelectedSys) {
- const { type, contentType } = initialState.currentSelectedSys;
- setIsThirdPartySystem(type === 1 && contentType === 6);
- }
- }, [initialState?.currentSelectedSys]);
- useEffect(() => {
- // 只有从第三方系统切回中台时才处理
- if (prevIsThirdPartySystemRef.current && !isThirdPartySystem) {
- // 取当前选中的菜单 key
- if (selectedKeys && selectedKeys.length > 0 && initialState?.menuData) {
- // 递归查找菜单项
- const findItemByKey = (tree: any[], key: string, keyName: string): any => {
- for (const node of tree) {
- if (node[`${keyName}`] === key) {
- return node;
- }
- if (node.children) {
- const result = findItemByKey(node.children, key, keyName);
- if (result) {
- return result;
- }
- }
- }
- return null;
- };
- const selectedMenu = findItemByKey(initialState.menuData, selectedKeys[0], 'key');
- if (selectedMenu && selectedMenu.path && history.location.pathname !== selectedMenu.path) {
- history.push(selectedMenu.path);
- }
- }
- }
- prevIsThirdPartySystemRef.current = isThirdPartySystem;
- }, [isThirdPartySystem]);
-
- return (
- <ProLayout
- style={{
- height:noTopBar?'100%': 'calc(100vh - 50px)',
- }}
- //iconfontUrl="//at.alicdn.com/t/font_8d5l8fzk5b87iudi.js"
- logoStyle={{
- display: 'none',
- }}
- className="platFormLayout"
- contentStyle={{
- margin: 0,
- }}
- location={{}}
- headerContentRender={false}
- headerRender={false}
- siderWidth={isShowPageMenu && noMenu != 'true' ? 200 : 0}
- breakpoint={false}
- pageTitleRender={false}
- disableContentMargin
- collapsed={collapsed}
- onCollapse={(collapsed) => set_collapsed(collapsed)}
- collapsedButtonRender={false}
- // collapsedButtonRender={() => {
- // return (
- // <div
- // className="collapsedBtn"
- // onClick={() => {
- // set_collapsed(collapsed ? false : true);
- // }}
- // >
- // <IconFont style={{ display: 'inline-block' }} className="menuCollapseIcon" type={collapsed ? 'icon-celanzhankai' : 'icon-celanshouqi'} />
- // </div>
- // );
- // }}
- menuItemRender={(item, dom) => {
- return (
- <a
- onClick={() => {
- isMenuClickRef.current = true; // 标记为菜单点击
- history.push(`${item.path}${item.contentType == '4' ? `?isEmpty=true&menuId=${item.key}` : ''}` || '/');
- }}
- >
- {dom}
- </a>
- );
- }}
- menuProps={{
- openKeys: [...openKeys],
- selectedKeys: [...selectedKeys],
- onSelect: ({ key, keyPath, selectedKeys, domEvent }) => {
- set_selectedKeys(selectedKeys);
- localStorage.setItem('selectedKeys', JSON.stringify(selectedKeys));
- },
- onOpenChange: (keys: string[]) => {
- set_openKeys([...keys]);
- localStorage.setItem('openKeys', JSON.stringify(keys));
- },
- }}
- menu={isShowPageMenu && !noMenu ? {
- autoClose: false,
- params:initialState?.currentSelectedSys,
- request: async () => {
- if (initialState && initialState.currentSelectedSys) {
- const { systemId, menuId, path, type, contentType } = initialState.currentSelectedSys;
- if (systemId || (menuId && type != 1 && contentType != 6)) {
- //只有当存在systemId
- const menuData = await getPlatformMenu(systemId || menuId);
- let homePage: TreeItemType | undefined;
- const getVFromTree = (data: TreeItemType[], key: string) => {
- let result: SpacicalPageParamsType[] = [];
- function looper(data: TreeItemType[], key: string) {
- data.forEach((t) => {
- if (t.isHomepage) {
- homePage = t;
- }
- if (t[key] == 1 || t[key] == 2 || t[key] == 3) {
- //网易有数页面
- result.push({
- contentType: t[key],
- path: t['path'],
- reportId: t['reportId'],
- url: t['youshuUrl'],
- });
- }
- if (t[key] == 5) {
- //蓝湖静态展示页面
- result.push({
- contentType: t[key],
- path: t['path'],
- reportId: t['reportId'],
- url: t['softUrl'],
- });
- }
- if (t.children && t.children.length > 0) {
- looper(t.children, key);
- }
- });
- }
- looper(data, key);
- return result;
- };
- const _menu = getVFromTree(menuData, 'contentType');
- setInitialState((t) => ({ ...t, spacicalPageParamsType: _menu, menuData } as any));
- if (homePage) {
- // console.log({homePage});
- set_openKeys([homePage.key]);
- set_selectedKeys([homePage.key]);
- history.push(homePage.path);
- } else {
- if (path == '/platform') {
- const selectedKeys = localStorage.getItem('selectedKeys');
- const openKeys = localStorage.getItem('openKeys');
- if (selectedKeys && openKeys) {
- const _selectedKeys = JSON.parse(selectedKeys);
- const _openKeys = JSON.parse(openKeys);
- set_openKeys(_openKeys);
- set_selectedKeys(_selectedKeys);
- } else {
- if (menuData[0].children && menuData[0].children.length > 0) {
- const childs = menuData[0].children;
- set_openKeys([menuData[0].key]);
- set_selectedKeys([childs[0].key]);
- localStorage.setItem('openKeys', JSON.stringify([menuData[0].key]));
- localStorage.setItem('selectedKeys', JSON.stringify([childs[0].key]));
- history.push(`${childs[0].path}`);
- } else {
- if (menuData[0]) {
- set_openKeys([menuData[0].key]);
- set_selectedKeys([menuData[0].key]);
- localStorage.setItem('openKeys', JSON.stringify([menuData[0].key]));
- localStorage.setItem('selectedKeys', JSON.stringify([menuData[0].key]));
- history.push(`${menuData[0].path}`);
- }
- }
- }
- }
- }
- const addIcon = (arr: any) =>
- arr.map((item: any) =>
- item.children
- ? {
- ...item,
- icon: <FolderOutlined />,
- children: addIcon(item.children),
- }
- : {
- ...item,
- icon: <FileOutlined />,
- },
- );
- const imgNode = (props: any) => {
- return <IconFont type="icon-pingtaiguanli" />;
- };
- const systemSet = (props: any) => {
- return <IconFont type="icon-xitongshezhi" />;
- };
- function addIconToPath(node: any) {
- if (node.name == '超管设置') {
- node.icon = <Icon component={imgNode} />;
- }
- if (node.name == '系统设置') {
- node.icon = <Icon component={systemSet} />;
- }
- if (node.children) {
- node.children.forEach((child: any) => addIconToPath(child));
- }
- }
- const result = addIcon(menuData);
- result.forEach((item: any) => {
- addIconToPath(item);
- });
- return [...result];
- }
- return [];
- }
- return [];
- },
- } : undefined}
- menuRender={(props: any, defaultDom) => {
- return (
- <div style={isShowPageMenu && noMenu != 'true' ? {} : { display: 'inline-block', width: 0, overflow: 'hidden' }}>
- <ResizableContainer width={collapsed ? 64 : 200} minWidth={0} maxWidth={600} height={'calc(100vh - 48px)'}>
- <div style={{ background: '#fff', height: '100%' }}>
- <div className="menuWrapper" style={{ height: 'calc(100% - 40px)', overflowY: 'scroll', overflowX: 'hidden', background: '#fff' }}>
- {defaultDom}
- </div>
- <div
- style={{
- position: 'absolute',
- zIndex: 10,
- right: 17,
- bottom: 9,
- display: 'flex',
- justifyContent: 'center',
- alignItems: 'center',
- cursor: 'pointer',
- width: 24,
- height: 24,
- background: '#fff',
- }}
- onClick={() => {
- set_collapsed(collapsed ? false : true);
- }}
- >
- <IconFont style={{ display: 'inline-block', fontSize: 24 }} className="menuCollapseIcon" type={collapsed ? 'icon-celanzhankai' : 'icon-celanshouqi'} />
- </div>
- </div>
- </ResizableContainer>
- </div>
- );
- }}
- onPageChange={(location) => {}}
- layout="side"
- navTheme="light"
- {...moreConfig}
- >
- {isEmpty && <EmptyPage textContent={emptyPageContent} />}
- {!isEmpty && !isThirdPartySystem && (
- <PageContainer
- className="kcmpPageContainer"
- header={{
- title: false,
- }}
- style={{
- margin: 16,
- marginRight: 8,
- }}
- >
- <Helmet>
- <title>{initialState?.customerType == '2' ? currentHospName : '精益管理中台'}</title>
- </Helmet>
- <div className="page" style={noTopBar?{height:'100%',overflowY: 'scroll'}:{ height: 'calc(100vh - 80px)', overflowY: 'scroll' }}>
- {children}
- </div>
- </PageContainer>
- )}
- {isThirdPartySystem && (
- <iframe
- id={'bi_iframe'}
- style={{ width: '100%', height: 'calc(100vh - 48px)', border: 'none' }}
- src={addTokenToUrl(url as string, token)}
- onLoad={() => adjustIframe()}
- />
- )}
- </ProLayout>
- );
- }
|