项目实战二:共享单车后台3

权限设计:http://www.imooc.com/article/40553

import ....
const Option= Select.Option;
const FormItem =Form.Item;
const TreeNode =Tree.TreeNode;

  state={}
  
    componentWillMount(){
        axios.requestList(this,'/role/list',{})
        //已经封装好的axios里面的requestList this指的是指向本元素this
    }
    
//封装好的函数如下
    requestList = ()=>{
        axios.ajax({
            url:'/role/list',
            data:{
                params:{}
            }
        }).then((res)=>{
            if(res.code == 0){
                let list  = res.result.item_list.map((item,i)=>{
                    item.key = i;
                    return item;
                })
                this.setState({
                    list
                })
            }
        })
    }
    
     // 角色创建
    handleRole = ()=>{
        this.setState({
            isRoleVisible:true
        })
    }

 // 角色提交
    handleRoleSubmit = ()=>{
        let data = this.roleForm.props.form.getFieldsValue();
        axios.ajax({
            url:'role/create',
            data:{
                params:{
                    ...data
                }
            }
        }).then((res)=>{
            if(res.code ==0){
                this.setState({
                    isRoleVisible:false
                })
                this.roleForm.props.form.resetFields();//清空角色创建弹框表单
                axios.requestList(this,'role/list',{});
            }
        })
    }
    
    handlePermission = ()=>{
    	let item =this.state.selectedItem;//检查是否选中了项
        if (!item) {
            Modal.info({
                text: '请选择一个角色'
            })
            return;
        }
        this.setState({
            isPermVisible: true,
            detailInfo: item,
            menuInfo:item.menus
        });
        let menuList = this.state.selectedItem.menus;
        this.setState({
            menuInfo:menuList
        })
    }

 handlePermEditSubmit = ()=>{
        let data = this.permForm.props.form.getFieldsValue();
        data.role_id = this.state.selectedItem.id;//被选中项的id获取到
        data.menus = this.state.menuInfo;//选中的key值
        axios.ajax({
            url:'/permission/edit',
            data:{
                params:{
                    ...data
                }
            }
        }).then((res)=>{
            if(res){
                this.setState({
                    isPermVisible:false
                })
               axios.requestList(this,'role/list',{});
            }
        })
    }
    
// 用户授权提交
    handleUserSubmit = ()=>{
        let data = {};
        data.user_ids = this.state.targetKeys || [];
        data.role_id = this.state.selectedItem.id;//大列表里面那一行的id(不是modal里的表单
        axios.ajax({
            url:'/role/user_role_edit',
            data:{
                params:{
                    ...data
                }
            }
        }).then((res)=>{
            if(res){
                this.setState({
                    isUserVisible:false
                })
                axios.requestList(this,'/role/list',{});
            }
        })
    }
 render(){
        const columns = [
            {
                title: '角色ID',
                dataIndex: 'id'
            }, {
                title: '角色名称',
                dataIndex: 'role_name'
            },{
                title: '创建时间',
                dataIndex: 'create_time',
                render: Utils.formatTime //引用封装好的时间格式转换函数
            }, {
                title: '使用状态',
                dataIndex: 'status',
                render(status){
                   return status ==1?'启用':'停用'
                }
            }, {
                title: '授权时间',
                dataIndex: 'authorize_time',
                render: Utils.formatTime
            }, {
                title: '授权人',
                dataIndex: 'authorize_user_name'
            }
        ];
   
    return (
            <div>
                <Card>
                    <Button type="primary" onClick={this.handleRole}>创建角色</Button>
                    <Button type="primary" onClick={this.handlePermission}>设置权限</Button>
                    <Button type="primary" onClick={this.handleUserAuth}>用户授权</Button>
                </Card>           
                <div className="content-wrap">
                    <ETable
                        updateSelectedItem={Utils.updateSelectedItem.bind(this)}
                        selectedRowKeys={this.state.selectedRowKeys}
                        dataSource={this.state.list}
                        columns={columns}
                    />
                </div>
                <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 }/>//wrappedComponentRef获取该元素的值为inst 然后赋给this.roleForm 
                </Modal>
                <Modal
                       title="权限设置"
                       visible={this.state.isPermVisible}
                       width={600}
                       onOk={this.handlePermEditSubmit}
                       onCancel={()=>{
                           this.setState({
                               isPermVisible:false
                           })
                       }}>
                        <PermEditForm
                            wrappedComponentRef={(inst) => this.permForm = inst }
                            detailInfo={this.state.detailInfo}
                            menuInfo={this.state.menuInfo||[]}
                            patchMenuInfo={(checkedKeys)=>{
                                this.setState({
                                    menuInfo: checkedKeys
                                });
                            }}
                        />
                </Modal>
                <Modal
                       title="用户授权"
                       visible={this.state.isUserVisible}
                       width={800}
                       onOk={this.handleUserSubmit}
                       onCancel={()=>{
                           this.setState({
                               isUserVisible:false
                           })
                       }}>
                        <RoleAuthForm
                            wrappedComponentRef={(inst) => this.userAuthForm = inst }
                            isClosed={this.state.isAuthClosed}
                            detailInfo={this.state.detailInfo}
                            targetKeys={this.state.targetKeys}
                            mockData={this.state.mockData}
                            patchUserInfo={(targetKeys)=>{
								this.setState({ targetKeys})
							}}
                            
                        />
                </Modal>
            </div>
        );
    }
}

// 角色创建
class RoleForm extends React.Component{

    render(){
        const { getFieldDecorator } = this.props.form;
        const formItemLayout = {
            labelCol: {span: 5},
            wrapperCol: {span: 19}
        };
        return (
            <Form layout="horizontal">
                <FormItem label="角色名称" {...formItemLayout}>
                    {
                        getFieldDecorator('role_name',)(
                            <Input type="text" placeholder="请输入角色名称"/>
                        )
                    }
                </FormItem>
                <FormItem label="状态" {...formItemLayout}>
                    {
                        getFieldDecorator('state')(
                        <Select>
                            <Option value={1}>开启</Option>
                            <Option value={0}>关闭</Option>
                        </Select>
                    )}
                </FormItem>
            </Form>
        );
    }
}
RoleForm = Form.create({})(RoleForm);

// 设置权限
class PermEditForm extends React.Component {
    state = {};
    
    // 设置选中的节点,通过父组件方法再传递回来
    onCheck = (checkedKeys) => {
        this.props.patchMenuInfo(checkedKeys);//批量传回
    };
    
    //递归权限树
    renderTreeNodes = (data) => {
        return data.map((item) => {
        //要分是否有子节点 如果有子节点继续递归
    
            if (item.children) {
                return (
                    <TreeNode title={item.title} key={parentKey} >
                        {this.renderTreeNodes(item.children)}
                    </TreeNode>
                )
            } else  {
                return 
                    <TreeNode title={item.title} key={item.Key} />
                 //方法二:return 
                 }
        })
    }

    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;
    }

    render() {
        const { getFieldDecorator } = this.props.form;
        const formItemLayout = {
            labelCol: {span: 5},
            wrapperCol: {span: 18}
        };
        const detail_info = this.props.detailInfo;
        const menuInfo = this.props.menuInfo;
        return (
            <Form layout="horizontal">
                <FormItem label="角色名称:" {...formItemLayout}>
                    <Input disabled  placeholder={detail_info.role_name}/>
                </FormItem>
                <FormItem label="状态:" {...formItemLayout}>
                    {getFieldDecorator('status',{
                        initialValue: '1'
                    })(
                        <Select style={{ width: 80}}
                                placeholder="启用"
                        >
                            <Option value="1">启用</Option>
                            <Option value="0">停用</Option>
                        </Select>
                    )}
                </FormItem>
                <Tree
                    checkable
                    defaultExpandAll //默认展开
                    //勾选时
                    onCheck={(checkedKeys)=>this.onCheck(checkedKeys)}
                    checkedKeys={menuInfo}//默认选择
                >
                    <TreeNode title="平台权限" key="platform_all">
                        {this.renderTreeNodes(menuConfig)}
                    </TreeNode>
                </Tree>
            </Form>
        )
    }
}

PermEditForm = Form.create({})(PermEditForm);

menuConfig.js //权限树
const menuList =[
{
	title:'首页',
	key:'/home'
},
{
	title:'UI',
	key:'/ui',
	children:[
		{
			title:'按钮',
			key:'/admin/ui/buttons',
		},
		...
	]
},
...
];


注意关于路由匹配一块
在router.js的设置上
先放/
再放/common 会使我们想进入/common时进入了/的页面 因为/common 拆解为/ common

我们可以把/common放在/前面 并且在/common里加上extract 精准匹配 
依然还会出现两个页面都加载的问题
那可以借助swicth把两个 / /common的外面整个包起来 
switch的意思即匹配了一个之后就返回 不会再往后面走的意思

用穿梭框来做这个用户授权

// 用户授权
    handleUserAuth = ()=>{
        if (!this.state.selectedItem) {
            Modal.info({
                title: '信息',
                content: '未选中任何项目'
            })
            return;
        }
       
        this.setState({
            isUserVisible: true,
            isAuthClosed: false,
            detailInfo: this.state.selectedItem
        });
         this.getRoleUserList(this.state.selectedItem.id);
    }
    
getRoleUserList = (id)=>{//角色id
        axios.ajax({
            url:'/role/user_list',
            data:{
                params:{
                    id:id//即id
                }
            }
        }).then((res)=>{
            if(res){
                this.getAuthUserList(res.result);//对用户进行筛选 已授权和未授权
            }
        })
    }

 // 筛选目标用户
    getAuthUserList = (dataSource) => {
        const mockData = [];//就是数据源 datasource
        const targetKeys = [];
        if (dataSource && dataSource.length > 0) {
            for (let i = 0; i < dataSource.length; i++) {
                const data = {
                    key: dataSource[i].user_id,
                    title: dataSource[i].user_name,
                    status: dataSource[i].status,
                };
                if (data.status == 1) {//1为目标用户
                    targetKeys.push(data.key);//从左侧挑出来同样key的放在右边
                }
                	mockData.push(data);//全部的数据
                
            }
        }
        this.setState({mockData, targetKeys});
    };

// 用户授权
class RoleAuthForm extends React.Component {

    filterOption = (inputValue, option) => {
        return option.title.indexOf(inputValue) > -1;
    };
    handleChange = (targetKeys) => {
        this.props.patchUserInfo(targetKeys);
    };

    render() {
        const formItemLayout = {
            labelCol: {span: 5},
            wrapperCol: {span: 18}
        };
        const detail_info = this.props.detailInfo;
        return (
            <Form layout="horizontal">
                <FormItem label="角色名称:" {...formItemLayout}>
                    <Input disabled maxLength={8} placeholder={detail_info.role_name}/>
                </FormItem>
                <FormItem label="选择用户:" {...formItemLayout}>
                    <Transfer
                        listStyle={{width: 200,height: 400}}//style
                        dataSource={this.props.mockData}
                        showSearch
                        titles={['待选用户', '已选用户']}
                        searchPlaceholder='输入用户名'
                        filterOption={this.filterOption}
                        targetKeys={this.props.targetKeys}
                        onChange={this.handleChange}
                        render={item => item.title}//渲染每一行 放在自己的类里 放在外面表单里不起作用
                    />
                </FormItem>
            </Form>
        )
    }
}
RoleAuthForm = Form.create({})(RoleAuthForm);


handleClick=({item})=>{	
	const {dispatch }=this.props;
	dispatch(switchMenu(item.props.title)); //引入Action里面的方法
	this.setState({
		currentKey:key//实际上是item.key 因为上面解构了
	})
}

想要这个后台的左边栏有一个选中的栏,
首先我们要设置这个默认的选中栏
key取menuConfig.js里面的key =/order',或者等等
<Menu 
	onClick={this.handleClick}
	selectedKeys={this.state.currentKey}
	theme="dark"
	>
想要实现进入某一个子页面 然后左边栏就会出现选中哪个子页面栏的标志,
关于这个Redux里面的设置见redux入门最前面


Navleft/index.js
state={ currentKey:''}

componentWillMount(){
//从路由里取key
//当页面里面只有子页面路由和#时 可以选择把#替换掉
	let currentKey = window.location.hash.replace('#','');
	//或者(/#|\?.*$/g,'')把#号或者是?后面还有任意字符结尾的替换掉	
	this.setState({
		currentKey	
	})
}

显示选中那一页面的header/index.js
取这个name: {this.props.menuName}
const mapStateToPros =state =>{
	return {
		menuName:state.menuName
}	
}
export default connect(mapStateToPros)(header);

你可能感兴趣的:(项目实战二:共享单车后台3)