ICEWorks 权限Demo

Auth.js


import {session, stoage} from './util'

const NotLoginAuth = [
    '/login',
    '/register',
    '/register/complete',
    '/register/fail',
    '/forgetpassword'
]
/**
 * 分角色控制权限和菜单
 */
const RoleAssentPath = {
    GUEST : [
        ...NotLoginAuth,
    ],
    USER : [
        ...NotLoginAuth,
        '/',
        '/user',
    ],
    COMPANY : [
        ...NotLoginAuth,
        '/',
        '/company',
        '/user',
        '/user/list',
        '/user/add',
        '/user/edit',
    ],
    ADMIN : [
        ...NotLoginAuth,
        '/',
        '/channel',
        '/channel/add',
        '/channel/list',
        '/company',
        '/company/add',
        '/company/list',
        '/company/edit',
    ],
}

export const getRoute = () => { return RoleAssentPath[LoginInfo.role] }

let LoginInfo = {
    logined : false,
    username : null,
    role : 'GUEST', // ADMIN | COMPANY | USER | GUEST
}

export const Login = (userInfo, remember) =>{
    LoginInfo = {
        ...userInfo,
        logined : true,
        lastime : new Date().getTime(),
    }
    if(remember){
        stoage.setStore('UserInfo', LoginInfo)
    }
    session.setStore('UserInfo', LoginInfo)
}

export const LoginOut = () =>{
    LoginInfo = {
        logined : false,
        role : 'GUEST',
    }
    session.removeStore('UserInfo')
    stoage.removeStore('UserInfo')
}

export const getUser = () =>{
    if(LoginInfo.logined === false){
        let storeUser = stoage.getStore('UserInfo')
        if(storeUser && storeUser.logined){ Login(storeUser) }
    }
    return LoginInfo
}

export default (nextState, replace) => {
    let path = nextState.location.pathname.toLocaleLowerCase()
    if(path == '/loginout'){
        LoginOut()
        replace('/login')
    }else if(NotLoginAuth.indexOf(path) == -1 && getUser().logined == false){
        replace('/login')
    }else if(getRoute().indexOf(path)==-1){
        console.log('没有权限')
        replace('/error/401')
    }
}

route.js


/**
 * 定义应用路由
 */
import React from 'react';
import { Router, hashHistory, } from 'react-router';
import auth from './auth';
// 路由配置规则参考: https://github.com/ReactTraining/react-router/blob/v3/docs/guides/RouteConfiguration.md#configuration-with-plain-routes
// 一下部分是由 ICE 相关工具自动生成的路由,请勿随意改变,否则可能会出现一些异常情况
// <!-- auto generated routes start -->
import ForgetPassword from "./pages/ForgetPassword";
import Login from "./pages/Login";
import HeaderAsideFooterResponsiveLayout from './layouts/HeaderAsideFooterResponsiveLayout';
import BlankLayout from './layouts/BlankLayout';
import Home from './pages/Home';
import HeaderFooterLayout from './layouts/HeaderFooterLayout';
import { NotFound, BasicException, NotPermission, EmptyContent } from './pages/ErrorPage';
import { Register, RegisterComplete, RegisterFail } from "./pages/Register";
import { Channel, AddChannel, EditChannel } from "./pages/Channel";
import { Company, AddCompany, EditCompany } from "./pages/Company";
import { User, AddUser } from "./pages/User";
const autoGeneratedRoutes = [{
  path: "/company",
  childRoutes: [{
    path: "list",
    component: Company,
    onEnter: auth
  }, {
    path: "add",
    component: AddCompany,
    onEnter: auth
  }, {
    path: "edit/:id",
    component: EditCompany,
    onEnter: auth
  }],
  component: HeaderAsideFooterResponsiveLayout,
  onEnter: auth
}, {
  path: "/channel",
  childRoutes: [{
    path: "list",
    component: Channel,
    onEnter: auth
  }, {
    path: "add",
    component: AddChannel,
    onEnter: auth
  }, {
    path: "edit/:id",
    component: EditChannel,
    onEnter: auth
  }],
  component: HeaderAsideFooterResponsiveLayout,
  onEnter: auth
}, {
  path: "/user",
  childRoutes: [{
    path: "list",
    component: User,
    onEnter: auth
  }, {
    path: "add",
    component: AddUser,
    onEnter: auth
  }],
  component: HeaderAsideFooterResponsiveLayout,
  onEnter: auth
}, {
  path: "/error",
  childRoutes: [{
    path: "401",
    component: NotPermission
  }, {
    path: "404",
    component: NotFound
  }, {
    path: "500",
    component: BasicException
  }, {
    path: "empty",
    component: EmptyContent
  }],
  component: BlankLayout,
  indexRoute: {
    component: NotFound
  }
}, {
  path: "/forgetPassword",
  childRoutes: [],
  component: BlankLayout,
  indexRoute: {
    component: ForgetPassword
  },
  onEnter: auth
}, {
  path: "/register",
  childRoutes: [
    {
      path: "complete",
      component: RegisterComplete
    }, {
      path: "fail",
      component: RegisterFail
    }
  ],
  component: BlankLayout,
  indexRoute: {
    component: Register
  },
  onEnter: auth
}, {
  path: "/login",
  childRoutes: [],
  component: BlankLayout,
  indexRoute: {
    component: Login
  },
  onEnter: auth
}, {
  path: "/loginout",
  childRoutes: [],
  component: BlankLayout,
  indexRoute: {
    component: Login
  },
  onEnter: auth
}, {
  path: '/',
  childRoutes: [{
    path: '*',
    childRoutes: [],
    component: NotFound
  }],
  component: HeaderAsideFooterResponsiveLayout,
  indexRoute: {
    component: Home
  },
  onEnter: auth
}];
// <!-- auto generated routes end -->

// 自定义路由,如果 path 相同则会覆盖自动生成部分的路由配置
const customRoutes = [];

export default (
  <Router history={hashHistory} routes={[...autoGeneratedRoutes, ...customRoutes]} />
);


HeaderAsideFooterResponsiveLayout/Layout.js

/* eslint no-undef:0, no-unused-expressions:0, array-callback-return:0 */
import React, { Component } from 'react';
import cx from 'classnames';
import Layout from '@icedesign/layout';
import { Icon } from '@icedesign/base';
import Menu, { SubMenu, Item as MenuItem } from '@icedesign/menu';
import { Link } from 'react-router';
import FoundationSymbol from 'foundation-symbol';
import { enquire } from 'enquire-js';
import Header from './../../components/Header';
import Footer from './../../components/Footer';
import Logo from './../../components/Logo';
import { asideNavs } from './../../navs';
import './scss/light.scss';
import './scss/dark.scss';
import { getRoute } from '../../auth'

// 设置默认的皮肤配置,支持 dark 和 light 两套皮肤配置
const theme = typeof THEME === 'undefined' ? 'light' : THEME;

export default class HeaderAsideFooterResponsiveLayout extends Component {
  static propTypes = {};

  static defaultProps = {};

  constructor(props) {
    super(props);

    const openKeys = this.getOpenKeys();
    this.state = {
      collapse: false,
      openDrawer: false,
      isScreen: undefined,
      openKeys,
    };
    this.openKeysCache = openKeys;
  }

  getAsideNavs = () =>{
      if(this.asideNavs == null){
        let routes = getRoute()
        let allMenu = asideNavs.filter(m=> routes.indexOf(m.to) != -1 )
        allMenu.forEach(m=>{
          if(m.children){
            m.children = m.children.filter(m=> routes.indexOf(m.to) != -1)
          }
        })
        this.asideNavs = allMenu
      }
      return this.asideNavs
  }

  componentDidMount() {
    this.enquireScreenRegister();
  }

  /**
   * 注册监听屏幕的变化,可根据不同分辨率做对应的处理
   */
  enquireScreenRegister = () => {
    const isMobile = 'screen and (max-width: 720px)';
    const isTablet = 'screen and (min-width: 721px) and (max-width: 1199px)';
    const isDesktop = 'screen and (min-width: 1200px)';

    enquire.register(isMobile, this.enquireScreenHandle('isMobile'));
    enquire.register(isTablet, this.enquireScreenHandle('isTablet'));
    enquire.register(isDesktop, this.enquireScreenHandle('isDesktop'));
  };

  enquireScreenHandle = (type) => {
    let collapse;
    if (type === 'isMobile') {
      collapse = false;
    } else if (type === 'isTablet') {
      collapse = true;
    } else {
      collapse = this.state.collapse;
    }

    const handler = {
      match: () => {
        this.setState({
          isScreen: type,
          collapse,
        });
      },
      unmatch: () => {
        // handler unmatched
      },
    };

    return handler;
  };

  /**
   * 左侧菜单收缩切换
   */
  toggleCollapse = () => {
    const { collapse } = this.state;
    const openKeys = !collapse ? [] : this.openKeysCache;

    this.setState({
      collapse: !collapse,
      openKeys,
    });
  };

  /**
   * 响应式通过抽屉形式切换菜单
   */
  toggleMenu = () => {
    const { openDrawer } = this.state;
    this.setState({
      openDrawer: !openDrawer,
    });
  };

  /**
   * 当前展开的菜单项
   */
  onOpenChange = (openKeys) => {
    this.setState({
      openKeys,
    });
    this.openKeysCache = openKeys;
  };

  /**
   * 响应式时点击菜单进行切换
   */
  onMenuClick = () => {
    this.toggleMenu();
  };

  /**
   * 获取当前展开的菜单项
   */
  getOpenKeys = () => {
    const { routes } = this.props;
    const matched = routes[0].path;
    const asideNavs = this.getAsideNavs()
    let openKeys = [];

    asideNavs &&
      asideNavs.length > 0 &&
      asideNavs.map((item, index) => {
        if (item.to === matched) {
          openKeys = [`${index}`];
        }
      });

    return openKeys;
  };

  render() {
    const { location = {} } = this.props;
    const { pathname } = location;
    const asideNavs = this.getAsideNavs()

    return (
      <Layout
        style={{ minHeight: '100vh' }}
        className={cx(
          `ice-design-header-aside-footer-responsive-layout-${theme}`,
          {
            'ice-design-layout': true,
          }
        )}
      >
        <Header
          theme={theme}
          isMobile={this.state.isScreen !== 'isDesktop' ? true : undefined}
        />
        <Layout.Section>
          {this.state.isScreen === 'isMobile' && (
            <a className="menu-btn" onClick={this.toggleMenu}>
              <Icon type="category" size="small" />
            </a>
          )}
          {this.state.openDrawer && (
            <div className="open-drawer-bg" onClick={this.toggleMenu} />
          )}
          <Layout.Aside
            width="auto"
            theme={theme}
            className={cx('ice-design-layout-aside', {
              'open-drawer': this.state.openDrawer,
            })}
          >
            {/* 侧边菜单项 begin */}
            {this.state.isScreen !== 'isMobile' && (
              <a className="collapse-btn" onClick={this.toggleCollapse}>
                <Icon
                  type={this.state.collapse ? 'arrow-right' : 'arrow-left'}
                  size="small"
                />
              </a>
            )}
            {this.state.isScreen === 'isMobile' && <Logo />}
            <Menu
              style={{ width: this.state.collapse ? 60 : 200 }}
              inlineCollapsed={this.state.collapse}
              mode="inline"
              selectedKeys={[pathname]}
              openKeys={this.state.openKeys}
              defaultSelectedKeys={[pathname]}
              onOpenChange={this.onOpenChange}
              onClick={this.onMenuClick}
            >
              {asideNavs &&
                asideNavs.length > 0 &&
                asideNavs.map((nav, index) => {
                  if (nav.children && nav.children.length > 0) {
                    return (
                      <SubMenu
                        key={index}
                        title={
                          <span>
                            {nav.icon ? (
                              <FoundationSymbol size="small" type={nav.icon} />
                            ) : null}
                            <span className="ice-menu-collapse-hide">
                              {nav.text}
                            </span>
                          </span>
                        }
                      >
                        {nav.children.map((item) => {
                          const linkProps = {};
                          if (item.newWindow) {
                            linkProps.href = item.to;
                            linkProps.target = '_blank';
                          } else if (item.external) {
                            linkProps.href = item.to;
                          } else {
                            linkProps.to = item.to;
                          }
                          return (
                            <MenuItem key={item.to}>
                              <Link {...linkProps}>{item.text}</Link>
                            </MenuItem>
                          );
                        })}
                      </SubMenu>
                    );
                  }
                  const linkProps = {};
                  if (nav.newWindow) {
                    linkProps.href = nav.to;
                    linkProps.target = '_blank';
                  } else if (nav.external) {
                    linkProps.href = nav.to;
                  } else {
                    linkProps.to = nav.to;
                  }
                  return (
                    <MenuItem key={nav.to}>
                      <Link {...linkProps}>
                        <span>
                          {nav.icon ? (
                            <FoundationSymbol size="small" type={nav.icon} />
                          ) : null}
                          <span className="ice-menu-collapse-hide">
                            {nav.text}
                          </span>
                        </span>
                      </Link>
                    </MenuItem>
                  );
                })}
            </Menu>
            {/* 侧边菜单项 end */}
          </Layout.Aside>
          {/* 主体内容 */}
          <Layout.Main>{this.props.children}</Layout.Main>
        </Layout.Section>
        <Footer />
      </Layout>
    );
  }
}


转载于:https://my.oschina.net/u/147708/blog/1789351

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值