From 314e7b8cb2f7f18e3881e6d65cf7724ce3accb13 Mon Sep 17 00:00:00 2001 From: LoadChange Date: Tue, 7 Jan 2020 16:45:18 +0800 Subject: [PATCH] feat: user management i18n --- .../static/console-fe/src/constants.js | 2 + .../static/console-fe/src/locales/en-US.js | 26 +++++ .../static/console-fe/src/locales/zh-CN.js | 26 +++++ .../PermissionsManagement/NewPermissions.js | 90 +++++++++++++++ .../PermissionsManagement.js | 107 +++++++++++++++--- .../RolesManagement/RolesManagement.js | 6 +- .../UserManagement/NewUser.js | 22 ++-- .../UserManagement/PasswordReset.js | 18 +-- .../UserManagement/UserManagement.js | 26 ++--- .../console-fe/src/pages/Login/Login.jsx | 31 ++--- .../console-fe/src/reducers/authority.js | 53 ++++++++- .../static/console-fe/src/reducers/base.js | 8 +- .../static/console-fe/src/utils/request.js | 20 ++-- 13 files changed, 351 insertions(+), 84 deletions(-) create mode 100644 console/src/main/resources/static/console-fe/src/pages/AuthorityControl/PermissionsManagement/NewPermissions.js diff --git a/console/src/main/resources/static/console-fe/src/constants.js b/console/src/main/resources/static/console-fe/src/constants.js index e4ad885c1..91c00d365 100644 --- a/console/src/main/resources/static/console-fe/src/constants.js +++ b/console/src/main/resources/static/console-fe/src/constants.js @@ -29,3 +29,5 @@ export const SIGN_IN = 'SIGN_IN'; export const USER_LIST = 'USER_LIST'; export const ROLE_LIST = 'ROLE_LIST'; + +export const PERMISSIONS_LIST = 'PERMISSIONS_LIST'; diff --git a/console/src/main/resources/static/console-fe/src/locales/en-US.js b/console/src/main/resources/static/console-fe/src/locales/en-US.js index 63e96c6b1..a56b4a824 100644 --- a/console/src/main/resources/static/console-fe/src/locales/en-US.js +++ b/console/src/main/resources/static/console-fe/src/locales/en-US.js @@ -508,6 +508,32 @@ const I18N_CONF = { update: 'Update', insert: 'Insert', }, + UserManagement: { + userManagement: 'User Management', + createUser: 'Create user', + resetPassword: 'Edit', + deleteUser: 'Delete', + deleteUserTip: 'Do you want to delete this user?', + username: 'Username', + password: 'Password', + operation: 'Operation', + }, + NewUser: { + createUser: 'Create user', + username: 'Username', + password: 'Password', + usernamePlaceholder: 'Please Enter Username', + passwordPlaceholder: 'Please Enter Password', + usernameError: 'User name cannot be empty!', + passwordError: 'Password cannot be empty!', + }, + PasswordReset: { + resetPassword: 'Password Reset', + username: 'Username', + password: 'Password', + passwordPlaceholder: 'Please Enter Password', + passwordError: 'Password cannot be empty!', + }, }; export default I18N_CONF; diff --git a/console/src/main/resources/static/console-fe/src/locales/zh-CN.js b/console/src/main/resources/static/console-fe/src/locales/zh-CN.js index d22e60f81..e8c75997c 100644 --- a/console/src/main/resources/static/console-fe/src/locales/zh-CN.js +++ b/console/src/main/resources/static/console-fe/src/locales/zh-CN.js @@ -505,6 +505,32 @@ const I18N_CONF = { update: '更新', insert: '插入', }, + UserManagement: { + userManagement: '用户管理', + createUser: '创建用户', + resetPassword: '修改', + deleteUser: '删除', + deleteUserTip: '是否要删除该用户?', + username: '用户名', + password: '密码', + operation: '操作', + }, + NewUser: { + createUser: '创建用户', + username: '用户名', + password: '密码', + usernamePlaceholder: '请输入用户名', + passwordPlaceholder: '请输入密码', + usernameError: '用户名不能为空!', + passwordError: '密码不能为空!', + }, + PasswordReset: { + resetPassword: '密码重置', + username: '用户名', + password: '密码', + passwordError: '密码不能为空!', + passwordPlaceholder: '请输入密码', + }, }; export default I18N_CONF; diff --git a/console/src/main/resources/static/console-fe/src/pages/AuthorityControl/PermissionsManagement/NewPermissions.js b/console/src/main/resources/static/console-fe/src/pages/AuthorityControl/PermissionsManagement/NewPermissions.js new file mode 100644 index 000000000..22ad2a759 --- /dev/null +++ b/console/src/main/resources/static/console-fe/src/pages/AuthorityControl/PermissionsManagement/NewPermissions.js @@ -0,0 +1,90 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import PropTypes from 'prop-types'; +import { Field, Form, Input, Dialog, ConfigProvider } from '@alifd/next'; + +const FormItem = Form.Item; + +const formItemLayout = { + labelCol: { fixedSpan: 3 }, + wrapperCol: { span: 20 }, +}; + +@ConfigProvider.config +class NewPermissions extends React.Component { + static displayName = 'NewPermissions'; + + field = new Field(this); + + static propTypes = { + locale: PropTypes.object, + visible: PropTypes.bool, + }; + + check() { + const errors = { + role: '角色不能为空!', + resource: '资源不能为空!', + action: '动作不能为空!', + }; + const vals = Object.keys(errors).map(key => { + const val = this.field.getValue(key); + if (!val) { + this.field.setError(key, errors[key]); + } + return val; + }); + if (vals.filter(v => v).length === 3) { + return vals; + } + return null; + } + + render() { + const { getError } = this.field; + const { visible, onOk, onCancel } = this.props; + return ( + <> + { + const vals = this.check(); + if (vals) { + onOk(vals).then(() => onCancel()); + } + }} + onClose={onCancel} + onCancel={onCancel} + afterClose={() => this.field.reset()} + > +
+ + + + + + + + + +
+
+ + ); + } +} + +export default NewPermissions; diff --git a/console/src/main/resources/static/console-fe/src/pages/AuthorityControl/PermissionsManagement/PermissionsManagement.js b/console/src/main/resources/static/console-fe/src/pages/AuthorityControl/PermissionsManagement/PermissionsManagement.js index eb54bfeb5..69d8fbbfd 100644 --- a/console/src/main/resources/static/console-fe/src/pages/AuthorityControl/PermissionsManagement/PermissionsManagement.js +++ b/console/src/main/resources/static/console-fe/src/pages/AuthorityControl/PermissionsManagement/PermissionsManagement.js @@ -13,32 +13,113 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { - Button, - Field, - Form, - Grid, - Input, - Loading, - Pagination, - Table, - ConfigProvider, -} from '@alifd/next'; +import { Button, Dialog, Pagination, Table, ConfigProvider } from '@alifd/next'; +import { connect } from 'react-redux'; +import { getPermissions, createPermission, deletePermission } from '../../../reducers/authority'; +import RegionGroup from '../../../components/RegionGroup'; +import NewPermissions from './NewPermissions'; import './PermissionsManagement.scss'; +@connect(state => ({ permissions: state.authority.permissions }), { getPermissions }) @ConfigProvider.config class PermissionsManagement extends React.Component { - static displayName = 'UserManagement'; + static displayName = 'PermissionsManagement'; static propTypes = { locale: PropTypes.object, + permissions: PropTypes.object, + getPermissions: PropTypes.func, }; + constructor(props) { + super(props); + this.state = { + loading: true, + pageNo: 1, + pageSize: 9, + createPermission: false, + }; + } + + componentDidMount() { + this.getPermissions(); + } + + getPermissions() { + const { pageNo, pageSize } = this.state; + this.props + .getPermissions({ pageNo, pageSize }) + .then(() => { + if (this.state.loading) { + this.setState({ loading: false }); + } + }) + .catch(() => this.setState({ loading: false })); + } + + colseCreatePermission() { + this.setState({ createPermissionVisible: false }); + } + render() { + const { permissions } = this.props; + const { loading, pageSize, pageNo, createPermissionVisible } = this.state; return ( <> -

PermissionsManagement

+ +
+ +
+ + + + + ( + <> + + + )} + /> +
+ {permissions.totalCount > pageSize && ( + this.setState({ pageNo }, () => this.getPermissions())} + /> + )} + + createPermission(permission).then(res => { + this.setState({ pageNo: 1 }, () => this.getPermissions()); + return res; + }) + } + onCancel={() => this.colseCreatePermission()} + /> ); } diff --git a/console/src/main/resources/static/console-fe/src/pages/AuthorityControl/RolesManagement/RolesManagement.js b/console/src/main/resources/static/console-fe/src/pages/AuthorityControl/RolesManagement/RolesManagement.js index 484dcf932..a8cf9edf5 100644 --- a/console/src/main/resources/static/console-fe/src/pages/AuthorityControl/RolesManagement/RolesManagement.js +++ b/console/src/main/resources/static/console-fe/src/pages/AuthorityControl/RolesManagement/RolesManagement.js @@ -68,11 +68,7 @@ class RolesManagement extends React.Component { <>
-
diff --git a/console/src/main/resources/static/console-fe/src/pages/AuthorityControl/UserManagement/NewUser.js b/console/src/main/resources/static/console-fe/src/pages/AuthorityControl/UserManagement/NewUser.js index cb47cd9b7..896f4e1bb 100644 --- a/console/src/main/resources/static/console-fe/src/pages/AuthorityControl/UserManagement/NewUser.js +++ b/console/src/main/resources/static/console-fe/src/pages/AuthorityControl/UserManagement/NewUser.js @@ -19,8 +19,8 @@ import './UserManagement.scss'; const FormItem = Form.Item; const formItemLayout = { - labelCol: { fixedSpan: 3 }, - wrapperCol: { span: 20 }, + labelCol: { fixedSpan: 4 }, + wrapperCol: { span: 19 }, }; @ConfigProvider.config @@ -35,11 +35,12 @@ class NewUser extends React.Component { }; check() { + const { locale } = this.props; const errors = { - username: '用户名不能为空!', - password: '密码不能为空!', + username: locale.usernameError, + password: locale.passwordError, }; - const vals = ['username', 'password'].map(key => { + const vals = Object.keys(errors).map(key => { const val = this.field.getValue(key); if (!val) { this.field.setError(key, errors[key]); @@ -53,12 +54,13 @@ class NewUser extends React.Component { } render() { + const { locale } = this.props; const { getError } = this.field; const { visible, onOk, onCancel } = this.props; return ( <> { const vals = this.check(); @@ -71,11 +73,11 @@ class NewUser extends React.Component { afterClose={() => this.field.reset()} >
- - + + - - + +
diff --git a/console/src/main/resources/static/console-fe/src/pages/AuthorityControl/UserManagement/PasswordReset.js b/console/src/main/resources/static/console-fe/src/pages/AuthorityControl/UserManagement/PasswordReset.js index 9d2e96fd8..f8b8070aa 100644 --- a/console/src/main/resources/static/console-fe/src/pages/AuthorityControl/UserManagement/PasswordReset.js +++ b/console/src/main/resources/static/console-fe/src/pages/AuthorityControl/UserManagement/PasswordReset.js @@ -19,8 +19,8 @@ import './UserManagement.scss'; const FormItem = Form.Item; const formItemLayout = { - labelCol: { fixedSpan: 3 }, - wrapperCol: { span: 20 }, + labelCol: { fixedSpan: 4 }, + wrapperCol: { span: 19 }, }; @ConfigProvider.config @@ -35,8 +35,9 @@ class PasswordReset extends React.Component { }; check() { - const errors = { password: '密码不能为空!' }; - const vals = ['password'].map(key => { + const { locale } = this.props; + const errors = { password: locale.passwordError }; + const vals = Object.keys(errors).map(key => { const val = this.field.getValue(key); if (!val) { this.field.setError(key, errors[key]); @@ -50,12 +51,13 @@ class PasswordReset extends React.Component { } render() { + const { locale } = this.props; const { getError } = this.field; const { username, onOk, onCancel } = this.props; return ( <> { const vals = this.check(); @@ -68,11 +70,11 @@ class PasswordReset extends React.Component { afterClose={() => this.field.reset()} >
- +

{username}

- - + +
diff --git a/console/src/main/resources/static/console-fe/src/pages/AuthorityControl/UserManagement/UserManagement.js b/console/src/main/resources/static/console-fe/src/pages/AuthorityControl/UserManagement/UserManagement.js index 202275f72..12e4e964d 100644 --- a/console/src/main/resources/static/console-fe/src/pages/AuthorityControl/UserManagement/UserManagement.js +++ b/console/src/main/resources/static/console-fe/src/pages/AuthorityControl/UserManagement/UserManagement.js @@ -64,29 +64,25 @@ class UserManagement extends React.Component { } render() { - const { users } = this.props; + const { users, locale } = this.props; const { loading, pageSize, pageNo, createUserVisible, passwordResetUser } = this.state; return ( <> - +
-
- + value.replace(/\S/g, '*')} /> ( <> @@ -94,7 +90,7 @@ class UserManagement extends React.Component { type="primary" onClick={() => this.setState({ passwordResetUser: username })} > - 修改 + {locale.resetPassword}     )} diff --git a/console/src/main/resources/static/console-fe/src/pages/Login/Login.jsx b/console/src/main/resources/static/console-fe/src/pages/Login/Login.jsx index 307a558ec..5da21b894 100644 --- a/console/src/main/resources/static/console-fe/src/pages/Login/Login.jsx +++ b/console/src/main/resources/static/console-fe/src/pages/Login/Login.jsx @@ -4,8 +4,8 @@ import { withRouter } from 'react-router-dom'; import './index.scss'; import Header from '../../layouts/Header'; -import { request } from '../../globalLib'; import PropTypes from 'prop-types'; +import { login } from '../../reducers/base'; const FormItem = Form.Item; @@ -30,29 +30,16 @@ class Login extends React.Component { if (errors) { return; } - request({ - type: 'post', - url: 'v1/auth/login', - data: values, - success: ({ code, data }) => { - if (code === 200) { - // TODO: 封装一个方法存储、读取token - localStorage.setItem('token', data); - // TODO: 使用react router - this.props.history.push('/'); - } - if (code === 401) { - Message.error({ - content: locale.invalidUsernameOrPassword, - }); - } - }, - error: () => { + login(values) + .then(res => { + localStorage.setItem('token', JSON.stringify(res)); + this.props.history.push('/'); + }) + .catch(() => Message.error({ content: locale.invalidUsernameOrPassword, - }); - }, - }); + }) + ); }); }; diff --git a/console/src/main/resources/static/console-fe/src/reducers/authority.js b/console/src/main/resources/static/console-fe/src/reducers/authority.js index 770f9af5f..0ee7ef288 100644 --- a/console/src/main/resources/static/console-fe/src/reducers/authority.js +++ b/console/src/main/resources/static/console-fe/src/reducers/authority.js @@ -13,7 +13,7 @@ import { Message } from '@alifd/next'; import request from '../utils/request'; -import { UPDATE_USER, SIGN_IN, USER_LIST, ROLE_LIST } from '../constants'; +import { UPDATE_USER, SIGN_IN, USER_LIST, ROLE_LIST, PERMISSIONS_LIST } from '../constants'; const initialState = { users: { @@ -22,7 +22,18 @@ const initialState = { pagesAvailable: 1, pageItems: [], }, - roles: {}, + roles: { + totalCount: 0, + pageNumber: 1, + pagesAvailable: 1, + pageItems: [], + }, + permissions: { + totalCount: 0, + pageNumber: 1, + pagesAvailable: 1, + pageItems: [], + }, }; const successMsg = res => { @@ -82,15 +93,51 @@ const createRole = ([role, username]) => const deleteRole = role => request.delete('v1/auth/roles', { params: role }).then(res => successMsg(res)); +/** + * 权限列表 + * @param {*} params + */ +const getPermissions = params => dispatch => + request + .get('v1/auth/permissions', { params }) + .then(data => dispatch({ type: PERMISSIONS_LIST, data })); + +/** + * 给角色添加权限 + * @param {*} param0 + */ +const createPermission = ([role, resource, action]) => + request.post('v1/auth/permissions', { role, resource, action }).then(res => successMsg(res)); + +/** + * 删除权限 + * @param {*} param0 + */ +const deletePermission = permission => + request.delete('v1/auth/permissions', { params: permission }).then(res => successMsg(res)); + export default (state = initialState, action) => { switch (action.type) { case USER_LIST: return { ...state, users: { ...action.data } }; case ROLE_LIST: return { ...state, roles: { ...action.data } }; + case PERMISSIONS_LIST: + return { ...state, permissions: { ...action.data } }; default: return state; } }; -export { getUsers, createUser, deleteUser, passwordReset, getRoles, createRole, deleteRole }; +export { + getUsers, + createUser, + deleteUser, + passwordReset, + getRoles, + createRole, + deleteRole, + getPermissions, + createPermission, + deletePermission, +}; diff --git a/console/src/main/resources/static/console-fe/src/reducers/base.js b/console/src/main/resources/static/console-fe/src/reducers/base.js index 78c3b6d27..7bab4dc57 100644 --- a/console/src/main/resources/static/console-fe/src/reducers/base.js +++ b/console/src/main/resources/static/console-fe/src/reducers/base.js @@ -20,6 +20,12 @@ const initialState = { functionMode: '', }; +/** + * 用户登录 + * @param {*} param0 + */ +const login = user => request.post('v1/auth/users/login', user); + const getState = () => dispatch => request .get('v1/console/server/state') @@ -52,4 +58,4 @@ export default (state = initialState, action) => { } }; -export { getState }; +export { getState, login }; diff --git a/console/src/main/resources/static/console-fe/src/utils/request.js b/console/src/main/resources/static/console-fe/src/utils/request.js index 736fd8d56..7ba66e009 100644 --- a/console/src/main/resources/static/console-fe/src/utils/request.js +++ b/console/src/main/resources/static/console-fe/src/utils/request.js @@ -9,18 +9,24 @@ const request = () => { const instance = axios.create(); instance.interceptors.request.use( - function(config) { + config => { + if (!config.params) { + config.params = {}; + } + if (!config.url.includes('auth/users/login')) { + const { accessToken = '' } = JSON.parse(localStorage.token || '{}'); + config.params.accessToken = accessToken; + } if (['post', 'put'].includes(config.method)) { config.data = qs.stringify(config.data); - config.headers = { - 'Content-Type': 'application/x-www-form-urlencoded', - }; + if (!config.headers) { + config.headers = {}; + } + config.headers['Content-Type'] = 'application/x-www-form-urlencoded'; } return config; }, - function(error) { - return Promise.reject(error); - } + error => Promise.reject(error) ); instance.interceptors.response.use(