【共享单车】—— React后台管理系统开发手记:权限设置和菜单调整(未完)
前言:以下内容基于React全家桶+AntD实战课程的学习实践过程记录。最终成果github地址:https://github.com/66Web/react-antd-manager,欢迎star。
一、创建角色
- 权限菜单设计:RBAC权限模型(详解链接)
- RBAC,即基于角色的访问控制(Role-Based Access Control),是优秀的权限控制模型
- 主要通过角色和权限建立管理,再赋予用户不同的角色,来实现权限控制的目标
- 角色列表展示:对应Easy Mock数据接口/role/list
123456789101112131415161718
{
"code"
: 0,
"list"
: {
"item_list|7"
: [{
"id|+1"
: 1,
"role_name"
: /(管理人员)|(客服专员)|(财务专员)|(市场专员)|(人力专员)|(研发)|(测试)|(系统管理员)/,
"status|0-1"
: 1,
"authorize_user_name"
:
"@cname"
,
"authorize_time"
: 1521270166000,
"create_time"
: 1499305790000,
"menus"
: [
"/home"
,
"/ui/buttons"
,
"/ui/modals"
,
"/ui/loadings"
,
"/ui/notification"
,
"/ui/messages"
,
"/ui/tabs"
,
"/ui/gallery"
,
"/ui/carousel"
,
"/ui"
]
}]
},
"page"
: 1,
"page_size"
: 10,
"total_count"
: 25,
"page_count"
: 3
}
-
调用封装好的axios.requestList()获取角色数据
1234567componentWillMount(){
this
.requestList();
}
requestList = ()=>{
axios.requestList(
this
,
'/role/list'
, {})
}
-
使用封装好的ETable组件实现角色列表的展示
12345678<div className=
"content-wrap"
>
<ETable
updateSelectedItem={Utils.updateSelectedItem.bind(
this
)}
selectedRowKeys={
this
.state.selectedRowKeys}
dataSource={
this
.state.list}
columns={columns}
/>
</div>
-
创建角色:Modal弹框中嵌入表单子组件
-
表单组件:RoleForm = Form.create({})(RoleForm)实现表单数据的双向绑定
123456789101112131415161718192021222324252627282930313233343536// 角色创建
class
RoleForm
extends
React.Component{
render(){
const { getFieldDecorator } =
this
.props.form;
const formItemLayout = {
labelCol: {span: 5},
wrapperCol: {span: 16}
};
return
(
<Form layout=
"horizontal"
>
<FormItem label=
"角色名称"
{...formItemLayout}>
{
getFieldDecorator(
'role_name'
,{
initialValue:
''
})(
<Input type=
"text"
placeholder=
"请输入角色名称"
/>
)
}
</FormItem>
<FormItem label=
"状态"
{...formItemLayout}>
{
getFieldDecorator(
'state'
,{
initialValue:1
})(
<Select>
<Option value={1}>开启</Option>
<Option value={0}>关闭</Option>
</Select>
)}
</FormItem>
</Form>
);
}
}
RoleForm = Form.create({})(RoleForm);
-
Modal弹框中应用表单组件:通过wrappedComponentRef={(inst) => this.roleForm = inst }获取表单元素的数据对象
12345678910111213<Modal
title=
"创建角色"
visible={
this
.state.isRoleVisible}
onOk={
this
.handleRoleSubmit}
onCancel={()=>{
this
.roleForm.props.form.resetFields();
//表单重置
this
.setState({
isRoleVisible:
false
})
}}
>
<RoleForm wrappedComponentRef={(inst) =>
this
.roleForm = inst }/>
</Modal>
-
点击【创建角色】按钮弹出弹框:给onClick事件绑定this.handleRole(),设置this.state.isRoleVisible为true
-
点击【OK】提交创建角色:给onOk事件绑定this.handleRoleSubmit()。①通过this.roleForm.props.form.getFieldsValue()获取表单的值,赋给params;②接口访问成功后,关闭弹框,刷新列表数据。
12345678910111213141516171819// 角色提交
handleRoleSubmit = ()=>{
let
data =
this
.roleForm.props.form.getFieldsValue();
//获取表单的值
axios.ajax({
url:
'role/create'
,
//Easy Mock中只有{"code": 0}
data:{
params:{
...data
}
}
}).then((res)=>{
if
(res.code === 0){
this
.setState({
isRoleVisible:
false
//关闭弹框
})
this
.requestList();
//刷新列表数据
}
})
}
二、设置权限
- 设置权限表单组件 :AntD Tree树形结构组件的使用
- TreeNode树形节点:const TreeNode = Tree.TreeNode;
- 加载完整的权限列表:本地定义menuConfig.js权限列表文件,通过递归方法渲染TreeNode
123456789101112131415161718192021222324252627282930313233343536373839
import
menuConfig from
'../../config/menuConfig'
renderTreeNodes = (data,key=
''
) => {
return
data.map((item) => {
let
parentKey = key+item.key;
if
(item.children) {
return
(
<TreeNode title={item.title} key={parentKey} dataRef={item} className=
"op-role-tree"
>
{
this
.renderTreeNodes(item.children,parentKey)}
</TreeNode>
);
}
else
if
(item.btnList) {
return
(
<TreeNode title={item.title} key={parentKey} dataRef={item} className=
"op-role-tree"
>
{
this
.renderBtnTreedNode(item,parentKey) }
</TreeNode>
);
}
return
<TreeNode {...item} />;
});
};
renderBtnTreedNode = (menu,parentKey=
''
)=> {
const btnTreeNode = []
menu.btnList.forEach((item)=> {
// console.log(parentKey+'-btn-'+item.key);
btnTreeNode.push(<TreeNode title={item.title} key={parentKey+
'-btn-'
+item.key} className=
"op-role-tree"
/>);
})
return
btnTreeNode;
}
<Tree
checkable
defaultExpandAll
>
<TreeNode title=
"平台权限"
key=
"platform_all"
>
{
this
.renderTreeNodes(menuConfig)}
</TreeNode>
</Tree>
- Modal弹框中应用表单组件:
- 点击【设置权限】按钮弹出弹框:判断若没有this.state.selectedItem,提示需“选择”
123456789101112131415161718
//权限设置
handlePermission = ()=>{
if
(!
this
.state.selectedItem) {
Modal.info({
title:
'信息'
,
content:
'请选择一个角色'
})
return
;
}
this
.setState({
isPermVisible:
true
,
detailInfo:
this
.state.selectedItem
//角色详细信息
});
let
menuList =
this
.state.selectedItem.menus;
//角色权限
this
.setState({
menuInfo:menuList
})
}
- 点击【OK】提交权限:给onOk事件绑定this.handlePermEditSubmit()
三、菜单调整
四、用户授权
注:项目来自慕课网
越是迷茫、浮躁的时候,保持冷静和耐心,尤为重要
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?