Explorar o código

change to upcales

陈帅 %!s(int64=6) %!d(string=hai) anos
pai
achega
aa7e9bd46f

+ 135 - 0
src/components/PageHeaderWrapper/Breadcrumb.tsx

@@ -0,0 +1,135 @@
+import React from 'react';
+import pathToRegexp from 'path-to-regexp';
+import Link from 'umi/link';
+import { FormattedMessage } from 'umi-plugin-react/locale';
+import { urlToList } from '../_utils/pathTools';
+import { PageHeaderWrapperProps } from '.';
+import { MenuDataItem } from '../SiderMenu';
+import { BreadcrumbProps as AntdBreadcrumbProps } from 'antd/lib/breadcrumb';
+
+type BreadcrumbProps = PageHeaderWrapperProps;
+
+// 渲染Breadcrumb 子节点
+// Render the Breadcrumb child node
+const itemRender: AntdBreadcrumbProps['itemRender'] = (route, params, routes, paths) => {
+  const last = routes.indexOf(route) === routes.length - 1;
+  return last || !route.component ? (
+    <span>{route.breadcrumbName}</span>
+  ) : (
+    <Link to={paths.join('/')}>{route.breadcrumbName}</Link>
+  );
+};
+
+const renderItemLocal = (item: MenuDataItem): React.ReactNode => {
+  if (item.locale) {
+    return <FormattedMessage id={item.locale} defaultMessage={item.name} />;
+  }
+  return item.name;
+};
+
+export const getBreadcrumb = (
+  breadcrumbNameMap: PageHeaderWrapperProps['breadcrumbNameMap'],
+  url: string,
+): MenuDataItem => {
+  if (!breadcrumbNameMap) {
+    return {
+      path: '',
+    };
+  }
+  let breadcrumb = breadcrumbNameMap[url];
+  if (!breadcrumb) {
+    Object.keys(breadcrumbNameMap).forEach(item => {
+      if (pathToRegexp(item).test(url)) {
+        breadcrumb = breadcrumbNameMap[item];
+      }
+    });
+  }
+  return breadcrumb || { path: '' };
+};
+
+export const getBreadcrumbProps = (props: BreadcrumbProps): PageHeaderWrapperProps => {
+  const { location, breadcrumbNameMap } = props;
+  return {
+    location,
+    breadcrumbNameMap,
+  };
+};
+
+// Generated according to props
+const conversionFromProps = (props: BreadcrumbProps): AntdBreadcrumbProps['routes'] => {
+  const { breadcrumbList = [] } = props;
+  return breadcrumbList
+    .map(item => {
+      const { title, href } = item;
+      return {
+        path: href,
+        breadcrumbName: title,
+      };
+    })
+    .filter(item => item.path);
+};
+
+const conversionFromLocation = (
+  routerLocation: PageHeaderWrapperProps['location'],
+  breadcrumbNameMap: PageHeaderWrapperProps['breadcrumbNameMap'],
+  props: BreadcrumbProps,
+): AntdBreadcrumbProps['routes'] => {
+  if (!routerLocation) {
+    return [];
+  }
+  const { home } = props;
+  // Convert the url to an array
+  const pathSnippets = urlToList(routerLocation.pathname);
+  // Loop data mosaic routing
+  const extraBreadcrumbItems: AntdBreadcrumbProps['routes'] = pathSnippets
+    .map(url => {
+      const currentBreadcrumb = getBreadcrumb(breadcrumbNameMap, url);
+      if (currentBreadcrumb.inherited) {
+        return { path: '', breadcrumbName: '' };
+      }
+      const name = renderItemLocal(currentBreadcrumb);
+      const { hideInBreadcrumb } = currentBreadcrumb;
+      return name && !hideInBreadcrumb
+        ? {
+            path: url,
+            breadcrumbName: name,
+          }
+        : { path: '', breadcrumbName: '' };
+    })
+    .filter(item => item && item.path);
+  // Add home breadcrumbs to your head if defined
+  if (home) {
+    extraBreadcrumbItems.unshift({
+      path: '/',
+      breadcrumbName: home,
+    });
+  }
+  return extraBreadcrumbItems;
+};
+
+/**
+ * 将参数转化为面包屑
+ * Convert parameters into breadcrumbs
+ */
+export const conversionBreadcrumbList = (props: BreadcrumbProps): AntdBreadcrumbProps => {
+  const { breadcrumbList } = props;
+  const { location, breadcrumbNameMap } = getBreadcrumbProps(props);
+  if (breadcrumbList && breadcrumbList.length) {
+    return {
+      routes: conversionFromProps(props),
+      itemRender,
+    };
+  }
+
+  // 根据 location 生成 面包屑
+  // Generate breadcrumbs based on location
+  if (location && location.pathname) {
+    return {
+      routes: conversionFromLocation(location, breadcrumbNameMap, props),
+      itemRender,
+    };
+  }
+  return {
+    routes: [],
+  };
+};

+ 1 - 1
src/components/PageHeaderWrapper/breadcrumb.tsx

@@ -3,7 +3,7 @@ import pathToRegexp from 'path-to-regexp';
 import Link from 'umi/link';
 import { FormattedMessage } from 'umi-plugin-react/locale';
 import { urlToList } from '../_utils/pathTools';
-import { PageHeaderWrapperProps } from './';
+import { PageHeaderWrapperProps } from '.';
 import { MenuDataItem } from '../SiderMenu';
 import { BreadcrumbProps as AntdBreadcrumbProps } from 'antd/lib/breadcrumb';
 

+ 16 - 9
src/components/PageHeaderWrapper/index.tsx

@@ -7,7 +7,7 @@ import GridContent from './GridContent';
 import ConnectState from '@/models/connect';
 import { ContentWidth } from 'config/defaultSettings';
 import styles from './index.less';
-import { conversionBreadcrumbList } from './breadcrumb';
+import { conversionBreadcrumbList } from './Breadcrumb';
 import { MenuDataItem } from '../SiderMenu';
 import * as H from 'history';
 
@@ -81,7 +81,18 @@ class PageHeaderWrapper extends React.Component<PageHeaderWrapperProps> {
       extraContent,
       ...restProps
     } = this.mergePropsAndChildren();
-    if (!title && !content) {
+    let pageTitle = title;
+    const breadcrumb = conversionBreadcrumbList({
+      ...restProps,
+      home: <FormattedMessage id="menu.home" defaultMessage="Home" />,
+    });
+    if (!title && breadcrumb.routes) {
+      const router = breadcrumb.routes[breadcrumb.routes.length - 1];
+      if (router) {
+        pageTitle = router.breadcrumbName;
+      }
+    }
+    if (!pageTitle && !content) {
       return;
     }
     return (
@@ -93,14 +104,11 @@ class PageHeaderWrapper extends React.Component<PageHeaderWrapperProps> {
               marginBottom: 0,
             }}
           >
-            {title}
+            {pageTitle}
           </Title>
         }
         {...restProps}
-        breadcrumb={conversionBreadcrumbList({
-          ...restProps,
-          home: <FormattedMessage id="menu.home" defaultMessage="Home" />,
-        })}
+        breadcrumb={breadcrumb}
         className={styles.pageHeader}
         footer={renderFooter(restProps)}
       >
@@ -117,10 +125,9 @@ class PageHeaderWrapper extends React.Component<PageHeaderWrapperProps> {
     );
   };
   render() {
-    const { children, top } = this.mergePropsAndChildren();
+    const { children } = this.mergePropsAndChildren();
     return (
       <div style={{ margin: '-24px -24px 0' }} className={classNames(classNames, styles.main)}>
-        {top}
         {this.renderPageHeader()}
         {children ? (
           <div className={styles['children-content']}>