Permissions Simple Version

This commit is contained in:
zuiidea
2017-07-04 23:41:13 +08:00
parent 6df97916fa
commit 3a01626df9
9 changed files with 236 additions and 22 deletions
+5 -1
View File
@@ -25,7 +25,11 @@ const Bread = ({ menu }) => {
}
if (!current) {
pathArray.push(menu[0])
pathArray.push(menu[0] || {
id: 1,
icon: 'laptop',
name: 'Dashboard',
})
pathArray.push({
id: 404,
name: 'Not Found',
+5 -5
View File
@@ -7,7 +7,7 @@ import pathToRegexp from 'path-to-regexp'
const Menus = ({ siderFold, darkTheme, location, handleClickNavMenu, navOpenKeys, changeOpenKeys, menu }) => {
// 生成树状
const menuTree = arrayToTree(menu.filter(_ => _.mpid !== -1), 'id', 'mpid')
const menuTree = arrayToTree(menu.filter(_ => _.mpid !== '-1'), 'id', 'mpid')
const levelMap = {}
// 递归生成菜单
@@ -22,7 +22,7 @@ const Menus = ({ siderFold, darkTheme, location, handleClickNavMenu, navOpenKeys
key={item.id}
title={<span>
{item.icon && <Icon type={item.icon} />}
{(!siderFoldN || menuTree.indexOf(item) < 0) && item.name}
{(!siderFoldN || !menuTree.includes(item)) && item.name}
</span>}
>
{getMenus(item.children, siderFoldN)}
@@ -33,7 +33,7 @@ const Menus = ({ siderFold, darkTheme, location, handleClickNavMenu, navOpenKeys
<Menu.Item key={item.id}>
<Link to={item.router}>
{item.icon && <Icon type={item.icon} />}
{(!siderFoldN || menuTree.indexOf(item) < 0) && item.name}
{(!siderFoldN || !menuTree.includes(item)) && item.name}
</Link>
</Menu.Item>
)
@@ -60,8 +60,8 @@ const Menus = ({ siderFold, darkTheme, location, handleClickNavMenu, navOpenKeys
}
const onOpenChange = (openKeys) => {
const latestOpenKey = openKeys.find(key => !(navOpenKeys.indexOf(key) > -1))
const latestCloseKey = navOpenKeys.find(key => !(openKeys.indexOf(key) > -1))
const latestOpenKey = openKeys.find(key => !navOpenKeys.includes(key))
const latestCloseKey = navOpenKeys.find(key => !openKeys.includes(key))
let nextOpenKeys = []
if (latestOpenKey) {
nextOpenKeys = getAncestorKeys(latestOpenKey).concat(latestOpenKey)
+164
View File
@@ -0,0 +1,164 @@
const { config, posts } = require('./common')
const { apiPrefix } = config
let database = [
{
id: '1',
icon: 'laptop',
name: 'Dashboard',
router: '/dashboard',
},
{
id: '2',
bpid: '1',
name: 'Users',
icon: 'user',
router: '/user',
},
{
id: '7',
bpid: '1',
name: 'Posts',
icon: 'shopping-cart',
router: '/post',
},
{
id: '21',
mpid: '-1',
bpid: '2',
name: 'User Detail',
router: '/user/:id',
},
{
id: '3',
bpid: '1',
name: 'Request',
icon: 'api',
router: '/request',
},
{
id: '4',
bpid: '1',
name: 'UI Element',
icon: 'camera-o',
},
{
id: '41',
bpid: '4',
mpid: '4',
name: 'IconFont',
icon: 'heart-o',
router: '/UIElement/iconfont',
},
{
id: '42',
bpid: '4',
mpid: '4',
name: 'DataTable',
icon: 'database',
router: '/UIElement/dataTable',
},
{
id: '43',
bpid: '4',
mpid: '4',
name: 'DropOption',
icon: 'bars',
router: '/UIElement/dropOption',
},
{
id: '44',
bpid: '4',
mpid: '4',
name: 'Search',
icon: 'search',
router: '/UIElement/search',
},
{
id: '45',
bpid: '4',
mpid: '4',
name: 'Editor',
icon: 'edit',
router: '/UIElement/editor',
},
{
id: '46',
bpid: '4',
mpid: '4',
name: 'layer (Function)',
icon: 'credit-card',
router: '/UIElement/layer',
},
{
id: '5',
bpid: '1',
name: 'Recharts',
icon: 'code-o',
},
{
id: '51',
bpid: '5',
mpid: '5',
name: 'LineChart',
icon: 'line-chart',
router: '/chart/lineChart',
},
{
id: '52',
bpid: '5',
mpid: '5',
name: 'BarChart',
icon: 'bar-chart',
router: '/chart/barChart',
},
{
id: '53',
bpid: '5',
mpid: '5',
name: 'AreaChart',
icon: 'area-chart',
router: '/chart/areaChart',
},
{
id: '6',
bpid: '1',
name: 'Test Navigation',
icon: 'setting',
},
{
id: '61',
bpid: '6',
mpid: '6',
name: 'Test Navigation1',
router: '/navigation/navigation1',
},
{
id: '62',
bpid: '6',
mpid: '6',
name: 'Test Navigation2',
router: '/navigation/navigation2',
},
{
id: '621',
bpid: '62',
mpid: '62',
name: 'Test Navigation21',
router: '/navigation/navigation2/navigation1',
},
{
id: '622',
bpid: '62',
mpid: '62',
name: 'Test Navigation22',
router: '/navigation/navigation2/navigation2',
},
]
module.exports = {
[`GET ${apiPrefix}/menus`] (req, res) {
res.status(200).json(database)
},
}
+9 -7
View File
@@ -26,13 +26,15 @@ let usersListData = Mock.mock({
let database = usersListData.data
const userPermission = {
DEFAULT: [
'dashboard', 'chart',
],
ADMIN: [
'dashboard', 'users', 'UIElement', 'UIElementIconfont', 'chart',
],
DEVELOPER: ['dashboard', 'users', 'UIElement', 'UIElementIconfont', 'chart'],
DEFAULT: {
visit: ['1', '2', '21', '7', '5', '51', '52', '53'],
},
ADMIN: {
visit: ['1', '2', '7', '21', '3', '4', '41', '42', '43', '44', '45', '46', '5', '51', '52', '53', '6', '61', '62', '621', '622'],
},
DEVELOPER: {
visit: ['1', '2', '7', '21', '3', '4', '41', '42', '43', '44', '45', '46', '5', '51', '52', '53', '6', '61', '62', '621', '622'],
},
}
const adminUsers = [
+32 -6
View File
@@ -1,4 +1,5 @@
import { query, logout } from '../services/app'
import * as menusService from '../services/menus'
import { routerRedux } from 'dva/router'
import { parse } from 'qs'
import { config } from 'utils'
@@ -8,6 +9,17 @@ export default {
namespace: 'app',
state: {
user: {},
permissions: {
visit: [],
},
menu: [
{
id: 1,
icon: 'laptop',
name: 'Dashboard',
router: '/dashboard',
},
],
menuPopoverVisible: false,
siderFold: localStorage.getItem(`${prefix}siderFold`) === 'true',
darkTheme: localStorage.getItem(`${prefix}darkTheme`) === 'true',
@@ -33,11 +45,25 @@ export default {
*query ({
payload,
}, { call, put }) {
const data = yield call(query, parse(payload))
if (data.success && data.user) {
const { success, user } = yield call(query, payload)
const { list } = yield call(menusService.query)
if (success && user) {
const { permissions } = user
yield put({
type: 'querySuccess',
payload: data.user,
type: 'updateState',
payload: {
user,
permissions,
menu: list.filter(item => {
const cases = [
permissions.visit.includes(item.id),
item.mpid ? permissions.visit.includes(item.mpid) || item.mpid === '-1' : true,
item.bpid ? permissions.visit.includes(item.bpid) : true,
]
return cases.every(_ => _)
}
),
},
})
if (location.pathname === '/login') {
yield put(routerRedux.push('/dashboard'))
@@ -76,10 +102,10 @@ export default {
},
reducers: {
querySuccess (state, { payload: user }) {
updateState (state, { payload }) {
return {
...state,
user,
...payload,
}
},
+2 -2
View File
@@ -2,7 +2,7 @@ import React from 'react'
import PropTypes from 'prop-types'
import { connect } from 'dva'
import { Layout } from 'components'
import { classnames, config, menu } from 'utils'
import { classnames, config } from 'utils'
import { Helmet } from 'react-helmet'
import '../themes/index.less'
import './app.less'
@@ -13,7 +13,7 @@ const { Header, Bread, Footer, Sider, styles } = Layout
let lastHref
const App = ({ children, location, dispatch, app, loading }) => {
const { user, siderFold, darkTheme, isNavbar, menuPopoverVisible, navOpenKeys } = app
const { user, siderFold, darkTheme, isNavbar, menuPopoverVisible, navOpenKeys, menu } = app
const href = window.location.href
if (lastHref !== href) {
+11
View File
@@ -0,0 +1,11 @@
import { request, config } from 'utils'
const { api } = config
const { menus } = api
export async function query (params) {
return request({
url: menus,
method: 'get',
data: params,
})
}
+2 -1
View File
@@ -9,7 +9,7 @@ module.exports = {
iconFontCSS: '/iconfont.css',
iconFontJS: '/iconfont.js',
YQL: ['http://www.zuimeitianqi.com'],
CORS: ['http://localhost:7000'],
CORS: [],
openPages: ['/login'],
apiPrefix: '/api/v1',
api: {
@@ -20,6 +20,7 @@ module.exports = {
posts: `${APIV1}/posts`,
user: `${APIV1}/user/:id`,
dashboard: `${APIV1}/dashboard`,
menus: `${APIV1}/menus`,
v1test: `${APIV1}/test`,
v2test: `${APIV2}/test`,
},
+6
View File
@@ -89,6 +89,12 @@ export default function request (options) {
return fetch(options).then((response) => {
const { statusText, status } = response
let data = options.fetchType === 'YQL' ? response.data.query.results.json : response.data
if (data instanceof Array) {
data = {
list: data,
}
}
return {
success: true,
message: statusText,