diff --git a/config/config.js b/config/config.js index 226d448ea8821b30b8a04f5389232383e91feda6..d0eef764477aebdd9210d0b43a3683859d8e6f7f 100644 --- a/config/config.js +++ b/config/config.js @@ -1,6 +1,5 @@ // https://umijs.org/config/ import os from 'os'; -import pageRoutes from './router.config'; import webpackPlugin from './plugin.config'; import defaultSettings from '../src/defaultSettings'; import slash from 'slash2'; @@ -21,6 +20,11 @@ const plugins = [ default: 'zh-CN', // default zh-CN baseNavigator: true, // default true, when it is true, will use `navigator.language` overwrite default }, + routes: { + update(routes) { + return [...require('../src/pages/_routes'), ...routes]; + }, + }, dynamicImport: { loadingComponent: './components/PageLoading/index', webpackChunkName: true, @@ -45,6 +49,18 @@ const plugins = [ : {}), }, ], + [ + 'umi-plugin-authorize', + { + authorize: [ + { + guard: ['src/pages/Auth'], + include: /\//, + exclude: /\/user/i, + }, + ], + }, + ], ]; // 针对 preview.pro.ant.design 的 GA 统计代码 @@ -69,7 +85,7 @@ export default { ie: 11, }, // 路由配置 - routes: pageRoutes, + // routes: pageRoutes, // Theme for antd // https://ant.design/docs/react/customize-theme-cn theme: { diff --git a/mock/route.js b/mock/route.js index 418d10f1ab333d66dfed05220d8da9a11110a9e8..17a00bce3690803325340419d4be549f88d7993c 100644 --- a/mock/route.js +++ b/mock/route.js @@ -2,4 +2,196 @@ export default { '/api/auth_routes': { '/form/advanced-form': { authority: ['admin', 'user'] }, }, + '/api/menus': { + routes: [ + // dashboard + { + path: '/dashboard', + name: 'dashboard', + icon: 'dashboard', + routes: [ + { + path: '/dashboard/analysis', + name: 'analysis', + }, + { + path: '/dashboard/monitor', + name: 'monitor', + }, + { + path: '/dashboard/workplace', + name: 'workplace', + }, + ], + }, + // forms + { + path: '/forms', + icon: 'form', + name: 'form', + routes: [ + { + path: '/forms/basicform', + name: 'basicform', + }, + { + path: '/forms/stepform', + name: 'stepform', + hideChildrenInMenu: true, + routes: [ + { + path: '/forms/stepform/info', + name: 'info', + }, + { + path: '/forms/stepform/confirm', + name: 'confirm', + }, + { + path: '/forms/stepform/result', + name: 'result', + }, + ], + }, + { + path: '/forms/advancedform', + name: 'advancedform', + authority: ['admin'], + }, + ], + }, + // list + { + path: '/list', + icon: 'table', + name: 'list', + routes: [ + { + path: '/list/tablelist', + name: 'searchtable', + }, + { + path: '/list/basiclist', + name: 'basiclist', + }, + { + path: '/list/cardlist', + name: 'cardlist', + }, + { + path: '/list/search', + name: 'searchlist', + routes: [ + { + path: '/list/search/articles', + name: 'articles', + }, + { + path: '/list/search/projects', + name: 'projects', + }, + { + path: '/list/search/applications', + name: 'applications', + }, + ], + }, + ], + }, + { + path: '/profile', + name: 'profile', + icon: 'profile', + routes: [ + // profile + { + path: '/profile/basicprofile', + name: 'basic', + }, + { + path: '/profile/advancedprofile', + name: 'advanced', + }, + ], + }, + { + name: 'result', + icon: 'check-circle-o', + path: '/result', + routes: [ + // result + { + path: '/result/success', + name: 'success', + }, + { path: '/result/fail', name: 'fail' }, + ], + }, + { + name: 'exception', + icon: 'warning', + path: '/exception', + routes: [ + // exception + { + path: '/exception/403', + name: 'not-permission', + }, + { + path: '/exception/404', + name: 'not-find', + }, + { + path: '/exception/500', + name: 'server-error', + }, + { + path: '/exception/trigger', + name: 'trigger', + hideInMenu: true, + }, + ], + }, + { + name: 'account', + icon: 'user', + path: '/account', + routes: [ + { + path: '/account/center', + name: 'center', + routes: [ + { + path: '/account/center/articles', + }, + { + path: '/account/center/applications', + }, + { + path: '/account/center/projects', + }, + ], + }, + { + path: '/account/settings', + name: 'settings', + routes: [ + { + path: '/account/settings/baseview', + }, + { + path: '/account/settings/security', + }, + { + path: '/account/settings/binding', + }, + { + path: '/account/settings/notification', + }, + ], + }, + ], + }, + ], + }, }; diff --git a/package.json b/package.json index b75d691092f66e5f208c3b6da27e2b3510b30c6d..da3053f08f0f40598458373ee47d04be352d59c3 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,8 @@ "react-dom": "^16.7.0", "react-fittext": "^1.0.0", "react-media": "^1.9.2", - "react-router-dom": "^4.3.1" + "react-router-dom": "^4.3.1", + "umi-plugin-authorize": "^1.0.0" }, "devDependencies": { "@types/react": "^16.8.1", diff --git a/src/layouts/index.js b/src/layouts/index.js new file mode 100644 index 0000000000000000000000000000000000000000..eefda48e9c6d1271baa5947b55836cc09b237b75 --- /dev/null +++ b/src/layouts/index.js @@ -0,0 +1,12 @@ +import React from 'react'; +import BasicLayout from './BasicLayout'; +import UserLayout from './UserLayout'; + +export default props => { + const { location } = props; + const { pathname } = location; + if (/\/user/i.test(pathname)) { + return ; + } + return ; +}; diff --git a/src/models/menu.js b/src/models/menu.js index 218c706513ea54fb2eb97ef0e2baf7195a8608b3..d87072a594e46fb9e21be53d5de47c49da31f73d 100644 --- a/src/models/menu.js +++ b/src/models/menu.js @@ -3,6 +3,7 @@ import isEqual from 'lodash/isEqual'; import { formatMessage } from 'umi/locale'; import Authorized from '@/utils/Authorized'; import { menu } from '../defaultSettings'; +import { queryMenu } from '@/services/user'; const { check } = Authorized; @@ -97,17 +98,18 @@ export default { state: { menuData: [], + routerData: [], breadcrumbNameMap: {}, }, effects: { - *getMenuData({ payload }, { put }) { - const { routes, authority } = payload; + *getMenuData(_, { put, call }) { + const { routes, authority } = yield call(queryMenu); const menuData = filterMenuData(memoizeOneFormatter(routes, authority)); const breadcrumbNameMap = memoizeOneGetBreadcrumbNameMap(menuData); yield put({ type: 'save', - payload: { menuData, breadcrumbNameMap }, + payload: { menuData, breadcrumbNameMap, routerData: routes }, }); }, }, diff --git a/src/pages/Account/Center/Applications.js b/src/pages/Account/Center/Applications.js index 031686cd1148c48d8444eec9573776d5185950d3..b06bb6582cc27d36996d924a29f559209bb460db 100644 --- a/src/pages/Account/Center/Applications.js +++ b/src/pages/Account/Center/Applications.js @@ -3,7 +3,7 @@ import { List, Card, Icon, Dropdown, Menu, Avatar, Tooltip } from 'antd'; import numeral from 'numeral'; import { connect } from 'dva'; import { formatWan } from '@/utils/utils'; -import stylesApplications from '../../List/Applications.less'; +import stylesApplications from '../../List/Search/Applications.less'; @connect(({ list }) => ({ list, diff --git a/src/pages/Account/Center/Projects.js b/src/pages/Account/Center/Projects.js index ac749fdb58a75ab9003660444bcc191a1f83fcda..3526bb4ec3803f858d96fd6f9c1834188032ac43 100644 --- a/src/pages/Account/Center/Projects.js +++ b/src/pages/Account/Center/Projects.js @@ -3,7 +3,7 @@ import { List, Card } from 'antd'; import moment from 'moment'; import { connect } from 'dva'; import AvatarList from '@/components/AvatarList'; -import stylesProjects from '../../List/Projects.less'; +import stylesProjects from '../../List/Search/Projects.less'; @connect(({ list }) => ({ list, diff --git a/src/pages/Account/Center/Center.js b/src/pages/Account/Center/_layout.js similarity index 100% rename from src/pages/Account/Center/Center.js rename to src/pages/Account/Center/_layout.js diff --git a/src/pages/Account/Settings/Info.js b/src/pages/Account/Settings/_layout.js similarity index 94% rename from src/pages/Account/Settings/Info.js rename to src/pages/Account/Settings/_layout.js index ceee506b8bc5c5569d838f95f1d9cb051dbd2f26..5defae7335734b7ac47cb130602eda59d361fce7 100644 --- a/src/pages/Account/Settings/Info.js +++ b/src/pages/Account/Settings/_layout.js @@ -16,14 +16,16 @@ class Info extends Component { super(props); const { match, location } = props; const menuMap = { - base: , - security: ( + baseview: ( + + ), + securityview: ( ), - binding: ( + bindingview: ( ), - notification: ( + notificationview: ( { + /* eslint-disable no-underscore-dangle */ + const { routerData } = window.g_app._store.getState().menu; + const getRouteAuthority = (pathname, routeData) => { + const routes = routeData.slice(); // clone + + const getAuthority = (routeDatas, path) => { + let authorities; + routeDatas.forEach(route => { + // check partial route + if (pathToRegexp(`${route.path}(.*)`).test(path)) { + if (route.authority) { + authorities = route.authority; + } + // is exact route? + if (!pathToRegexp(route.path).test(path) && route.routes) { + authorities = getAuthority(route.routes, path); + } + } + }); + return authorities; + }; + + return getAuthority(routes, pathname); + }; + + return ( + } + > + {children} + + ); +}; diff --git a/src/pages/Forms/StepForm/Step2.js b/src/pages/Forms/StepForm/Confirm.js similarity index 98% rename from src/pages/Forms/StepForm/Step2.js rename to src/pages/Forms/StepForm/Confirm.js index 3e3b05bf2fe769c3994829ffff059844cb0f7146..962297d2be55261a7d57fd91acbd703939da1078 100644 --- a/src/pages/Forms/StepForm/Step2.js +++ b/src/pages/Forms/StepForm/Confirm.js @@ -24,7 +24,7 @@ class Step2 extends React.PureComponent { const { form, data, dispatch, submitting } = this.props; const { getFieldDecorator, validateFields } = form; const onPrev = () => { - router.push('/form/step-form/info'); + router.push('/forms/stepform/info'); }; const onValidateForm = e => { e.preventDefault(); diff --git a/src/pages/Forms/StepForm/Step1.js b/src/pages/Forms/StepForm/Info.js similarity index 98% rename from src/pages/Forms/StepForm/Step1.js rename to src/pages/Forms/StepForm/Info.js index a62e294192b1cfcc74ef3ee5f817d005d05f22a2..7b3bfa28bb44b4dc373c18840789ab4596f0a2a5 100644 --- a/src/pages/Forms/StepForm/Step1.js +++ b/src/pages/Forms/StepForm/Info.js @@ -30,7 +30,7 @@ class Step1 extends React.PureComponent { type: 'form/saveStepFormData', payload: values, }); - router.push('/form/step-form/confirm'); + router.push('/forms/stepform/confirm'); } }); }; diff --git a/src/pages/Forms/StepForm/Step3.js b/src/pages/Forms/StepForm/Result.js similarity index 97% rename from src/pages/Forms/StepForm/Step3.js rename to src/pages/Forms/StepForm/Result.js index 74e1a6b8add060d063a141f905976c80effbb2ab..fa3ac49422c92a2bab92406c1a4c670e096d7db8 100644 --- a/src/pages/Forms/StepForm/Step3.js +++ b/src/pages/Forms/StepForm/Result.js @@ -12,7 +12,7 @@ class Step3 extends React.PureComponent { render() { const { data } = this.props; const onFinish = () => { - router.push('/form/step-form/info'); + router.push('/forms/stepform/info'); }; const information = (
diff --git a/src/pages/Forms/StepForm/index.js b/src/pages/Forms/StepForm/_layout.js similarity index 100% rename from src/pages/Forms/StepForm/index.js rename to src/pages/Forms/StepForm/_layout.js diff --git a/src/pages/Forms/models/form.js b/src/pages/Forms/models/form.js index 0b241b133d5fb8c0147f8bf81f8400df1a97ffd7..e2dd2076c9636fc5795c42f8b0993b6fb7e65668 100644 --- a/src/pages/Forms/models/form.js +++ b/src/pages/Forms/models/form.js @@ -25,7 +25,7 @@ export default { type: 'saveStepFormData', payload, }); - yield put(routerRedux.push('/form/step-form/result')); + yield put(routerRedux.push('/forms/stepform/result')); }, *submitAdvancedForm({ payload }, { call }) { yield call(fakeSubmitForm, payload); diff --git a/src/pages/List/Applications.js b/src/pages/List/Search/Applications.js similarity index 100% rename from src/pages/List/Applications.js rename to src/pages/List/Search/Applications.js diff --git a/src/pages/List/Applications.less b/src/pages/List/Search/Applications.less similarity index 100% rename from src/pages/List/Applications.less rename to src/pages/List/Search/Applications.less diff --git a/src/pages/List/Articles.js b/src/pages/List/Search/Articles.js similarity index 100% rename from src/pages/List/Articles.js rename to src/pages/List/Search/Articles.js diff --git a/src/pages/List/Articles.less b/src/pages/List/Search/Articles.less similarity index 100% rename from src/pages/List/Articles.less rename to src/pages/List/Search/Articles.less diff --git a/src/pages/List/Projects.js b/src/pages/List/Search/Projects.js similarity index 100% rename from src/pages/List/Projects.js rename to src/pages/List/Search/Projects.js diff --git a/src/pages/List/Projects.less b/src/pages/List/Search/Projects.less similarity index 100% rename from src/pages/List/Projects.less rename to src/pages/List/Search/Projects.less diff --git a/src/pages/List/List.js b/src/pages/List/Search/_layout.js similarity index 100% rename from src/pages/List/List.js rename to src/pages/List/Search/_layout.js diff --git a/src/pages/_routes.json b/src/pages/_routes.json new file mode 100644 index 0000000000000000000000000000000000000000..81b4b64126973c4197eaccf12dfb2783924e3480 --- /dev/null +++ b/src/pages/_routes.json @@ -0,0 +1,57 @@ +[ + { + "path": "/", + "exact": true, + "redirect": "/dashboard/analysis" + }, + { + "path": "/dashboard", + "exact": true, + "redirect": "/dashboard/analysis" + }, + { + "path": "/forms", + "exact": true, + "redirect": "/forms/basicform" + }, + { + "path": "/forms/stepform", + "exact": true, + "redirect": "/forms/stepform/info" + }, + { + "path": "/list", + "exact": true, + "redirect": "/list/tableList" + }, + { + "path": "/list/search", + "exact": true, + "redirect": "/list/search/articles" + }, + { + "path": "/profile", + "exact": true, + "redirect": "/profile/basicprofile" + }, + { + "path": "/result", + "exact": true, + "redirect": "/result/success" + }, + { + "path": "/exception", + "exact": true, + "redirect": "/exception/403" + }, + { + "path": "/account/center", + "exact": true, + "redirect": "/account/center/articles" + }, + { + "path": "/account/settings", + "exact": true, + "redirect": "/account/settings/baseview" + } +] diff --git a/src/services/user.js b/src/services/user.js index 89e03c6f67b2ba505e429b2c9afbcb40142508aa..64a4f7a49d25671bc825e0a733c9ca0240f37eb5 100644 --- a/src/services/user.js +++ b/src/services/user.js @@ -7,3 +7,7 @@ export async function query() { export async function queryCurrent() { return request('/api/currentUser'); } + +export async function queryMenu() { + return request('/api/menus'); +}