laravel-react实战打造企业级高并发分布式电商小程序(三)--权限管理的前端

laravel-react实战打造企业级高并发分布式电商小程序(三)–权限管理的前端

react

我们前端使用react来做,我们这个后台基于antd pro。使用npm创建它。

npm create umi

选择 ant-design-pro


Select the boilerplate type (Use arrow keys)
❯ ant-design-pro - Create project with an layout-only ant-design-pro boilerplate, use together with umi block.
app - Create project with a simple boilerplate, support typescript.
block - Create a umi block.
library - Create a library with umi.
plugin - Create a umi plugin.


Ant Design Pro 脚手架将会自动安装。

本地开发

npm installnpm start

启动完成后会自动打开浏览器访问 http://localhost:8000,你看到下面的页面就代表成功了。

用户管理

添加用户管理的增删改查,因为后台都需要一个表格展示数据,所以把表格抽出来一个组件。

src/components/下面添加Table文件夹,在src/components/Table/下面创建CommonTable.jsx.

src/components/Table/CommonTable.jsx文件内容如下:

import { Table } from 'antd';
import { PureComponent } from 'react';

class CommonTable extends PureComponent{
  constructor(props) {
    super(props);
  }

  render() {
    const {
      datas: { data, page },
      loading,
      columns,
      size,
    } = this.props;
    const paginationProps = {
      showSizeChanger: true,
      showQuickJumper: true,
      ...page
    }
    const scroll = {
      x:true,
      y:500,
      scrollToFirstRowOnChange:true
    }
    console.log(data)
    return <Table
            dataSource={data}
            columns={columns}
            pagination={paginationProps}
            bordered
            loading={loading}
            scroll={scroll}
            rowKey="id"
            size={size}
            />;
  }
}
export default CommonTable;

接下来在src/pages/下面新建auth文件夹和src/pages/auth/users.js



import { PageHeaderWrapper } from '@ant-design/pro-layout';
import CommonTable from '@/components/Table/CommonTable'
import { connect } from 'dva';
import { Popconfirm, Button, message, Card, Row, Col, Form, Modal, Input, Select } from 'antd'

const ButtonGroup = Button.Group;
const { Option } = Select;

const CreateForm = Form.create()(props => {
  const { modalVisible, form, handleAdd, handleModalVisible, handleChange, roleList: { data } } = props

  const okHandle = () => {
    form.validateFields((err, fieldsValue) => {
      if (err) return
      form.resetFields()
      handleAdd(fieldsValue)
    })
  }
  return (
    <Modal
      destroyOnClose
      title="创建用户"
      visible={modalVisible}
      onOk={okHandle}
      onCancel={() => handleModalVisible()}
    >
      <Form.Item labelCol={{ span: 6 }} wrapperCol={{ span: 15 }} label="用户名称">
        {form.getFieldDecorator('name', {
          rules: [{ required: true, message: '请输入用户名称' }],
        })(<Input placeholder="请输入用户名称" />)}
      </Form.Item>
      <Form.Item labelCol={{ span: 6 }} wrapperCol={{ span: 15 }} label="用户邮箱">
        {form.getFieldDecorator('email', {
          rules: [{ required: true, message: '请输入用户邮箱' }],
        })(<Input placeholder="请输入用户邮箱" />)}
      </Form.Item>
      <Form.Item labelCol={{ span: 6 }} wrapperCol={{ span: 15 }} label="用户密码">
        {form.getFieldDecorator('password', {
          rules: [{ required: true, message: '请输入用户密码' }],
        })(<Input placeholder="请输入用户密码" />)}
      </Form.Item>
      <Form.Item labelCol={{ span: 6 }} wrapperCol={{ span: 15 }} label="角色">
        {form.getFieldDecorator('roleIds', {
          rules: [{ required: true, message: '请选择角色' }],
        })(<Select
          mode="multiple"
          style={{ width: '100%' }}
          placeholder="请选择角色"
          // defaultValue={['a10', 'c12']}
          onChange={handleChange}
        >
          {data.map(t => <Option key={t.id} value={t.id} >{t.name}</Option>)}
        </Select>)}
      </Form.Item>
    </Modal>
  )
})

const EditForm = Form.create()(props => {
  const { editModalVisible, form, handleSave, handleModalVisible, values: { name, email, roleIds }, handleChange, roleList: { data } } = props

  const okHandle = () => {
    form.validateFields((err, fieldsValue) => {
      if (err) return
      form.resetFields()
      handleSave(fieldsValue)
    })
  }
  console.log('默认值', name, email, roleIds)
  return (
    <Modal
      destroyOnClose
      title="修改用户"
      visible={editModalVisible}
      onOk={okHandle}
      onCancel={() => handleModalVisible()}
    >
      <Form.Item labelCol={{ span: 6 }} wrapperCol={{ span: 15 }} label="用户名称">
        {form.getFieldDecorator('name', {
          rules: [{ required: true, message: '请输入用户名称' }],
          initialValue: name,
        })(<Input placeholder="请输入用户名称" />)}
      </Form.Item>
      <Form.Item labelCol={{ span: 6 }} wrapperCol={{ span: 15 }} label="用户邮箱">
        {form.getFieldDecorator('email', {
          rules: [{ required: true, message: '请输入用户邮箱' }],
          initialValue: email,
        })(<Input placeholder="请输入用户邮箱" />)}
      </Form.Item>
      <Form.Item labelCol={{ span: 6 }} wrapperCol={{ span: 15 }} label="角色">
        {form.getFieldDecorator('roleIds', {
          rules: [{ required: true, message: '请选择角色' }],
          initialValue: roleIds,
        })(<Select
          mode="multiple"
          style={{ width: '100%' }}
          placeholder="请选择角色"
          // defaultValue={['a10', 'c12']}
          onChange={handleChange}
        >
          {data.map(t => <Option key={t.id} value={t.id} >{t.name}</Option>)}
        </Select>)}
      </Form.Item>
    </Modal>
  )
})

@connect(({ userList, loading, roleModel }) => ({
  userList,
  loading: loading.models.userList,
  roleModel,
  roleLoading: loading.models.roleModel,
}))
export default class Users extends React.PureComponent {
  constructor(props) {
    super(props)
    this.state = {
      pageIndex: 1,
      pageSize: 10,
      modalVisible: false,
      editModalVisible: false,
      values: {},
    }
  }

  componentDidMount() {
    this.handleSearch(this.state.pageIndex, this.state.pageSize)
  }

  // 获取列
  getColumns = () => [
      {
        title: '用户名',
        dataIndex: 'name',
        key: 'name',
        align: 'center',
        width: 200,
      },
      {
        title: '邮箱',
        dataIndex: 'email',
        key: 'email',
        align: 'center',
        width: 300,
      },
      {
        title: '创建时间',
        dataIndex: 'created_at',
        key: 'created_at',
        align: 'center',
        width: 600,
      },
      {
        title: '操作',
        render: (text, record) => (
              <ButtonGroup>
              <Button type="primary" onClick={() => this.edit(record)}>修改</Button>
              <Popconfirm title="确定要删除嘛?" onConfirm={() => this.handleDelete(record.id)}>
                <Button type="danger">删除</Button>
              </Popconfirm>
              </ButtonGroup>
          ),
        align: 'center',
      },
    ]

  // 搜索操作
  handleSearch = (pageIndex, pageSize) => {
    const { dispatch } = this.props
    dispatch({
      type: 'userList/getUserList',
      params: {
        pageIndex,
        pageSize,
      },
    })
  }

  // 获取角色列表
  getRoles = () => {
    const { dispatch } = this.props
    dispatch({
      type: 'roleModel/getRoleList',
      params: {
        pageIndex: 1,
        pageSize: 10000,
      },
    })
  }

  edit = values => {
    console.log('value:', values)
    this.setState({
      values,
    })
    this.editVisible(true)
  }

  // 显示创建弹窗
  createVisible = flag => {
    // 获取角色列表
    this.getRoles()
    this.setState({
      modalVisible: !!flag,
    })
  }

  // 显示修改弹窗
  editVisible = flag => {
    this.setState({
      editModalVisible: !!flag,
    })
  }

  // 删除操作
  handleDelete = id => {
    const { dispatch } = this.props
    dispatch({
      type: 'userList/delete',
      params: id,
      callback: () => {
        message.success('删除用户成功!')
        this.handleSearch(this.state.pageIndex, this.state.pageSize)
      },
    });
  }

  // 创建操作
  handleAdd = fields => {
    const { dispatch } = this.props
    const newFieldsValue = {
      name: fields.name,
      email: fields.email,
      password: fields.password,
      roleIds: fields.roleIds,
    }
    // 跳到第一页
    this.setState({
      pageIndex: 1,
    })

    dispatch({
      type: 'userList/create',
      params: newFieldsValue,
      callback: () => {
        message.success('新建用户成功!')
        this.handleSearch(this.state.pageIndex, this.state.pageSize)
      },
    })
    this.createVisible()
  }

  handleSave= fields => {
    const { dispatch } = this.props
    console.log('表单', this.state.values)
    const newFieldsValue = {
      name: fields.name,
      email: fields.email,
      roleIds: fields.roleIds,
    }
    // 跳到第一页
    this.setState({
      pageIndex: 1,
    })

    dispatch({
      type: 'userList/save',
      id: this.state.values.id,
      params: newFieldsValue,
      callback: () => {
        message.success('修改用户成功!')
        this.handleSearch(this.state.pageIndex, this.state.pageSize)
      },
    })

    this.editVisible()
  }

  handleChange = value => {
    console.log(`selected ${value}`);
  }


  render() {
    const { userList: { userList }, loading, roleModel: { roleList } } = this.props
    console.log('props:', this.props)
    console.log('load', loading)
    console.log('roles', roleList)

    return (
    <PageHeaderWrapper>
      <Card bordered={false}>
        <Row>
          <Col style={{ paddingBottom: 20 }}>
            <Button icon="plus" type="primary" onClick={() => this.createVisible(true)}>新建用户</Button>
          </Col>
        </Row>
        <CommonTable
            datas={userList}
            loading={loading}
            columns={this.getColumns()}
            size="middle"
        />
      </Card>
      <CreateForm
          handleAdd={this.handleAdd}
          handleModalVisible={this.createVisible}
          modalVisible={this.state.modalVisible}
          roleList={roleList}
          handleChange={this.handleChange}
        />
        <EditForm
          handleSave={this.handleSave}
          handleModalVisible={this.editVisible}
          editModalVisible={this.state.editModalVisible}
          values={this.state.values}
          roleList={roleList}
          handleChange={this.handleChange}
        />
    </PageHeaderWrapper>
    )
  }
}

在这个页面中还用到了model,所以我们创建model,在src/models下面创建auth文件夹和src/models/auth/userList.js文件


import {getUsers, deleteUser, createUser, saveUser} from '@/services/auth/users'

export default {
  namespace: 'userList',
  state: {
    userList:{
      data: [],
      page: {},
    }
  },
  effects: {
    *getUserList({params},{call, put}) {
      // console.log(params)
      const res = yield call(getUsers, params);

      // console.log(res)
      yield put({
        type: 'get_user_list',
        payload: res
      })
    },
    *delete({params, callback},{call}) {
      const res = yield call(deleteUser, params);
      if (res !== false) {
        callback()
      }

    },
    *create({params, callback },{call}) {
      const res = yield call(createUser, params);
      if (res !== false) {
        callback()
      }
    },
    *save({id ,params, callback },{call}) {
      const res = yield call(saveUser, id, params);
      if (res !== false) {
        callback()
      }
    }
  },
  reducers: {
    get_user_list(state, action) {
        return  {
          ...state,
          userList:{...state.userList,...action.payload},
        }
    }
  },
};

这里面使用了service来给后端发送请求,model里面主要effects里面封装了一些给page使用的方法来操作数据,state里面存放了page需要使用的数据。

我们创建service,在src/services下面创建auth文件夹和src/services/auth/users.js文件。


import request from '@/utils/request';

export async function getUsers(params) {
  return request('/api/auth/users', {
    method: 'get',
    params,
  });
}

export async function deleteUser(id) {
  return request(`/api/auth/user/${id}`, {
    method: 'delete',
  });
}

export async function createUser(params) {
  return request('/api/auth/user', {
    method: 'post',
    data: params,
  });
}

export async function saveUser(id, params) {
  return request(`/api/auth/user/${id}`, {
    method: 'put',
    data: params,
  });
}

好了,接下来就完成了,可以看到service调用了后端刚刚的几个用户的增删改查接口。而model调用了service封装的接口来改变model中的数据。page通过调用model的数据进行渲染,调用函数进行操作数据。

我们还需要对request进行一个拦截器的封装,因为我们使用到了token机制。

src/utils/request.js文件下面添加如下内容:


// request拦截器, 改变url 或 options.
request.interceptors.request.use(async (url, options) => {
  // console.log(url)
  let token = localStorage.getItem('token');
  if (!token) {
    // 请求token
    const res = await fetch('http://www.laraadmin.com/api/require_token', {
      method: 'post',
      headers: {
        Accept: 'application/json',
        'Content-Type': 'application/json; charset=utf-8' },
      })
      const body = await res.json()
    token = body.data
    localStorage.setItem('token', token)
  }
  const headers = {
    Authorization: token,
  };
  return (
    {
      url: `http://www.laraadmin.com${url}`,
      options: { ...options, headers },
    }
  );
})

// response拦截器, 处理response
request.interceptors.response.use(async (response, options) => {
  const res = await response.json()
  // eslint-disable-next-line eqeqeq
  if (res.code != 0) {
    // eslint-disable-next-line eqeqeq
    if (res.code == '400003') {
      // 令牌过期
      // console.log(response, options)
      localStorage.removeItem('token')
      // 重新请求
      request(response.url, options)
    } else {
      message.error(res.msg)
      return false
    }
  }
  return res.data;
});

注意,这些内容放在最后一行上面,也就是下面这句的上面。

export default request;

接下来运行

npm run start

打开浏览器

localhost:8000

就可以看到结果了。

角色管理

接下来角色管理,也差不多,就不再写那么多目录结构了。

src/pages/auth/role.js



import { PageHeaderWrapper } from '@ant-design/pro-layout';
import CommonTable from '@/components/Table/CommonTable'
import { connect } from 'dva';
import {Popconfirm, Button, message, Card, Row, Col, Form, Modal, Input } from 'antd'

const ButtonGroup = Button.Group;

const CreateForm = Form.create()(props => {
  const { modalVisible, form, handleAdd, handleModalVisible } = props

  const okHandle = () => {
    form.validateFields((err, fieldsValue) => {
      if (err) return
      form.resetFields()
      handleAdd(fieldsValue)
    })
  }
  return (
    <Modal
      destroyOnClose
      title="创建角色"
      visible={modalVisible}
      onOk={okHandle}
      onCancel={() => handleModalVisible()}
    >
      <Form.Item labelCol={{ span: 6 }} wrapperCol={{ span: 15 }} label="角色名称">
        {form.getFieldDecorator('name', {
          rules: [{ required: true, message: '请输入角色名称'  }],
        })(<Input placeholder="请输入角色名称" />)}
      </Form.Item>
    </Modal>
  )
})

const EditForm = Form.create()(props => {
  const { editModalVisible, form, handleSave, handleModalVisible, values:{name} } = props

  const okHandle = () => {
    form.validateFields((err, fieldsValue) => {
      if (err) return
      form.resetFields()
      handleSave(fieldsValue)
    })
  }
  return (
    <Modal
      destroyOnClose
      title="修改角色"
      visible={editModalVisible}
      onOk={okHandle}
      onCancel={() => handleModalVisible()}
    >
      <Form.Item labelCol={{ span: 6 }} wrapperCol={{ span: 15 }} label="角色名称">
        {form.getFieldDecorator('name', {
          rules: [{ required: true, message: '请输入角色名称'  }],
          initialValue:name
        })(<Input placeholder="请输入角色名称" />)}
      </Form.Item>
    </Modal>
  )
})

@connect(({ roleModel,loading }) => ({
  roleModel,
  loading: loading.models.roleModel,
}))
export default class Roles extends React.PureComponent{
  constructor(props) {
    super(props)
    this.state = {
      pageIndex: 1,
      pageSize: 10,
      modalVisible: false,
      editModalVisible: false,
      values: {},
    }
  }

  componentDidMount() {
    this.handleSearch(this.state.pageIndex, this.state.pageSize)
  }

  //获取列
  getColumns = () => {
    return [
      {
        title: '角色名',
        dataIndex: 'name',
        key:'name',
        align:'center',
        width: 400,
      },
      {
        title: '创建时间',
        dataIndex: 'created_at',
        key:'created_at',
        align:'center',
        width: 600,
      },
      {
        title: '操作',
        render: (text, record) => {
          return (
              <ButtonGroup>
              <Button type="primary" onClick={() => this.edit(record)}>修改</Button>
              <Popconfirm title="确定要删除嘛?" onConfirm={() => this.handleDelete(record.id)}>
                <Button type="danger">删除</Button>
              </Popconfirm>
              </ButtonGroup>
          );
        },
        align:'center'
      },
    ];
  }

  //搜索操作
  handleSearch = (pageIndex, pageSize) => {
    const { dispatch } = this.props
    dispatch({
      type: 'roleModel/getRoleList',
      params: {
        pageIndex,
        pageSize,
      },
    })
  }

  edit = (values) => {
    this.setState({
      values: values
    })
    this.editVisible(true)
  }

  //显示创建弹窗
  createVisible = flag => {
    this.setState({
      modalVisible: !!flag,
    })
  }

  //显示修改弹窗
  editVisible = (flag) => {
    this.setState({
      editModalVisible: !!flag,
    })
  }

  //删除操作
  handleDelete = (id) => {
    const { dispatch } = this.props
    dispatch({
      type: 'roleModel/delete',
      params: id,
      callback: () =>{
        message.success('删除角色成功!')
        this.handleSearch(this.state.pageIndex, this.state.pageSize)
      }
    });
  }

  //创建操作
  handleAdd = (fields) => {
    const { dispatch } = this.props

    //跳到第一页
    this.setState({
      pageIndex: 1,
    })

    dispatch({
      type: 'roleModel/create',
      params: fields,
      callback: () => {
        message.success('新建角色成功!')
        this.handleSearch(this.state.pageIndex, this.state.pageSize)
      },
    })
    this.createVisible()
  }

  handleSave= (fields) => {
    const { dispatch } = this.props

    //跳到第一页
    this.setState({
      pageIndex: 1,
    })

    dispatch({
      type: 'roleModel/save',
      id: this.state.values.id,
      params: fields,
      callback: () => {
        message.success('修改角色成功!')
        this.handleSearch(this.state.pageIndex, this.state.pageSize)
      },
    })

    this.editVisible()

  }


  render(){
    const { roleModel:{roleList}, loading } = this.props
    return (
    <PageHeaderWrapper>
      <Card bordered={false}>
        <Row>
          <Col style={{ paddingBottom: 20 }}>
            <Button icon="plus" type="primary" onClick={() => this.createVisible(true)}>新建角色</Button>
          </Col>
        </Row>
        <CommonTable
            datas={roleList}
            loading={loading}
            columns={this.getColumns()}
            size='middle'
        />
      </Card>
      <CreateForm
          handleAdd={this.handleAdd}
          handleModalVisible={this.createVisible}
          modalVisible={this.state.modalVisible}
        />
        <EditForm
          handleSave={this.handleSave}
          handleModalVisible={this.editVisible}
          editModalVisible={this.state.editModalVisible}
          values={this.state.values}
        />
    </PageHeaderWrapper>
    )
  }
}

model

src/models/auth/roleModel.js


import { getRoles, deleteRole, createRole, saveRole } from '@/services/auth/roleService'

export default {
  namespace: 'roleModel',
  state: {
    roleList:{
      data: [],
      page: {},
    }
  },
  effects: {
    *getRoleList({params},{call, put}) {
      // console.log(params)
      const res = yield call(getRoles, params);

      // console.log(res)
      yield put({
        type: 'get_role_list',
        payload: res
      })
    },
    *delete({params, callback},{call}) {
      const res = yield call(deleteRole, params);
      if (res !== false) {
        callback()
      }

    },
    *create({params, callback },{call}) {
      const res = yield call(createRole, params);
      if (res !== false) {
        callback()
      }
    },
    *save({id ,params, callback },{call}) {
      const res = yield call(saveRole, id, params);
      if (res !== false) {
        callback()
      }
    }
  },
  reducers: {
    get_role_list(state, action) {
        return  {
          ...state,
          roleList:{...state.roleList,...action.payload},
        }
    }
  },
};

service

src/services/auth/roleService.js


import request from '@/utils/request';

export async function getRoles(params) {
  return request('/api/auth/roles', {
    method: 'get',
    params,
  });
}

export async function deleteRole(id) {
  return request(`/api/auth/role/${id}`, {
    method: 'delete',
  });
}

export async function createRole(params) {
  return request('/api/auth/role', {
    method: 'post',
    data: params,
  });
}

export async function saveRole(id, params) {
  return request(`/api/auth/role/${id}`, {
    method: 'put',
    data: params,
  });
}

权限管理

page

src/pages/auth/permission.js


import { PageHeaderWrapper } from '@ant-design/pro-layout';
import CommonTable from '@/components/Table/CommonTable'
import { connect } from 'dva';
import {Popconfirm, Button, message, Card, Row, Col, Form, Modal, Input, Select, TreeSelect  } from 'antd'

const ButtonGroup = Button.Group;

const CreateForm = Form.create()(props => {
  const { modalVisible, form, handleAdd, handleModalVisible, treeValue, treeData, treeOnChange } = props

  const okHandle = () => {
    form.validateFields((err, fieldsValue) => {
      if (err) return
      form.resetFields()
      handleAdd(fieldsValue)
    })
  }
  return (
    <Modal
      destroyOnClose
      title="创建菜单"
      visible={modalVisible}
      onOk={okHandle}
      onCancel={() => handleModalVisible()}
    >
      <Form.Item labelCol={{ span: 6 }} wrapperCol={{ span: 15 }} label="菜单名称">
        {form.getFieldDecorator('name', {
          rules: [{ required: true, message: '请输入菜单名称'  }],
        })(<Input placeholder="请输入菜单名称" />)}
      </Form.Item>
      <Form.Item labelCol={{ span: 6 }} wrapperCol={{ span: 15 }} label="菜单类型">
        {form.getFieldDecorator('type', {
          rules: [{ required: true, message: '请输入菜单类型'  }],
          initialValue:"menu"
        })(<Select style={{ width: 120 }}>
          <Select.Option value="menu">菜单</Select.Option>
          <Select.Option value="action">功能</Select.Option>
        </Select>)}
      </Form.Item>
      <Form.Item labelCol={{ span: 6 }} wrapperCol={{ span: 15 }} label="上级菜单">
        {form.getFieldDecorator('parentId', {
          setFieldsValue:treeValue
        })(<TreeSelect
          treeDataSimpleMode
          treeDefaultExpandAll="false"
          style={{ width: '100%' }}
          dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
          treeData={treeData}
          placeholder="Please select"
          treeDefaultExpandAll
          onChange={treeOnChange}
        />)}
      </Form.Item>
    </Modal>
  )
})

const EditForm = Form.create()(props => {
  const { editModalVisible, form, handleSave, handleModalVisible, treeValue, treeData, treeOnChange, values:{name,type,parent_id} } = props

  const okHandle = () => {
    form.validateFields((err, fieldsValue) => {
      if (err) return
      form.resetFields()
      handleSave(fieldsValue)
    })
  }
  console.log('tree',treeValue,parent_id,type)
  return (
    <Modal
      destroyOnClose
      title="修改菜单"
      visible={editModalVisible}
      onOk={okHandle}
      onCancel={() => handleModalVisible()}
    >
      <Form.Item labelCol={{ span: 6 }} wrapperCol={{ span: 15 }} label="菜单名称">
        {form.getFieldDecorator('name', {
          rules: [{ required: true, message: '请输入菜单名称'  }],
          initialValue:name,
        })(<Input placeholder="请输入菜单名称" />)}
      </Form.Item>
      <Form.Item labelCol={{ span: 6 }} wrapperCol={{ span: 15 }} label="菜单类型">
        {form.getFieldDecorator('type', {
          rules: [{ required: true, message: '请输入菜单类型'  }],
          initialValue:type,
        })(<Select style={{ width: 120 }}>
          <Select.Option value="menu">菜单</Select.Option>
          <Select.Option value="action">功能</Select.Option>
        </Select>)}
      </Form.Item>
      <Form.Item labelCol={{ span: 6 }} wrapperCol={{ span: 15 }} label="上级菜单">
        {form.getFieldDecorator('parentId', {
          setFieldsValue:treeValue,
          initialValue:parent_id,
        })(<TreeSelect
          treeDataSimpleMode
          treeDefaultExpandAll="false"
          style={{ width: '100%' }}
          dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
          treeData={treeData}
          placeholder="Please select"
          treeDefaultExpandAll
          onChange={treeOnChange}
        />)}
      </Form.Item>
    </Modal>
  )
})

@connect(({ permissionModel,loading }) => ({
  permissionModel,
  loading: loading.models.permissionModel,
}))
export default class Permission extends React.PureComponent{
  constructor(props) {
    super(props)
    this.state = {
      pageIndex: 1,
      pageSize: 10,
      modalVisible: false,
      editModalVisible: false,
      values: {},
      treeValue:undefined,
    }
  }

  //选择上级菜单
  treeOnChange = value => {

    this.setState({ treeValue:value });
  };

  componentDidMount() {
    this.handleSearch(this.state.pageIndex, this.state.pageSize)
  }

  //获取列
  getColumns = () => {
    return [
      {
        title: '菜单名',
        dataIndex: 'name',
        key:'name',
        align:'left',
      },
      {
        title: '菜单类型',
        dataIndex: 'type.name',
        key:'type.name',
        align:'center',
      },
      {
        title: '创建时间',
        dataIndex: 'created_at',
        key:'created_at',
        align:'center',
      },
      {
        title: '操作',
        render: (text, record) => {
          return (
              <ButtonGroup>
              <Button type="primary" onClick={() => this.edit(record)}>修改</Button>
              <Popconfirm title="确定要删除嘛?" onConfirm={() => this.handleDelete(record.id)}>
                <Button type="danger">删除</Button>
              </Popconfirm>
              </ButtonGroup>
          );
        },
        align:'center'
      },
    ];
  }

  //搜索操作
  handleSearch = (pageIndex, pageSize) => {
    const { dispatch } = this.props
    dispatch({
      type: 'permissionModel/getPermissionList',
      params: {
        pageIndex,
        pageSize,
      },
    })
  }

  edit = (values) => {
    console.log('菜单',values)
    this.getTreeList()
    this.setState({
      values: {...values,type:values.type.code}
    })
    this.editVisible(true)
  }

  //显示创建弹窗
  createVisible = flag => {
    this.getTreeList()
    this.setState({
      modalVisible: !!flag,
    })
  }

  //显示修改弹窗
  editVisible = (flag) => {
    this.setState({
      editModalVisible: !!flag,
    })
  }

  //删除操作
  handleDelete = (id) => {
    const { dispatch } = this.props
    dispatch({
      type: 'permissionModel/delete',
      params: id,
      callback: () =>{
        message.success('删除菜单成功!')
        this.handleSearch(this.state.pageIndex, this.state.pageSize)
      }
    });
  }

  //创建操作
  handleAdd = (fields) => {
    const { dispatch } = this.props

    //跳到第一页
    this.setState({
      pageIndex: 1,
    })

    dispatch({
      type: 'permissionModel/create',
      params: fields,
      callback: () => {
        message.success('新建菜单成功!')
        this.handleSearch(this.state.pageIndex, this.state.pageSize)
      },
    })
    this.createVisible()
  }

  handleSave= (fields) => {
    const { dispatch } = this.props

    //跳到第一页
    this.setState({
      pageIndex: 1,
    })

    dispatch({
      type: 'permissionModel/save',
      id: this.state.values.id,
      params: fields,
      callback: () => {
        message.success('修改菜单成功!')
        this.handleSearch(this.state.pageIndex, this.state.pageSize)
      },
    })

    this.editVisible()

  }

  //获取树形列表
  getTreeList = () => {
    const {dispatch} = this.props
    dispatch({
      type: 'permissionModel/getTree',
    })

  }

  render(){
    const { permissionModel:{permissionList,permissionTrees  }, loading } = this.props

    const treeData = permissionTrees
    console.log('list',permissionList)
    return (
    <PageHeaderWrapper>
      <Card bordered={false}>
        <Row>
          <Col style={{ paddingBottom: 20 }}>
            <Button icon="plus" type="primary" onClick={() => this.createVisible(true)}>新建菜单</Button>
          </Col>
        </Row>
        <CommonTable
            datas={permissionList}
            loading={loading}
            columns={this.getColumns()}
            size='middle'
        />
      </Card>
      <CreateForm
          handleAdd={this.handleAdd}
          handleModalVisible={this.createVisible}
          modalVisible={this.state.modalVisible}
          treeData={treeData}
          treeValue={this.state.treeValue}
          treeOnChange={this.treeOnChange}
        />
        <EditForm
          handleSave={this.handleSave}
          handleModalVisible={this.editVisible}
          editModalVisible={this.state.editModalVisible}
          treeData={treeData}
          treeValue={this.state.treeValue}
          treeOnChange={this.treeOnChange}
          values={this.state.values}
        />
    </PageHeaderWrapper>
    )
  }
}

model

src/models/auth/permissionModel.js

import { getPermissions, deletePermission, createPermission, savePermission, getPermissionTree } from '@/services/auth/permissionService'

export default {
  namespace: 'permissionModel',
  state: {
    permissionList:{
      data: [],
      page: {},
    },
    permissionTrees:[]
  },
  effects: {
    *getPermissionList({params},{call, put}) {
      // console.log(params)
      const res = yield call(getPermissions, params);

      // console.log(res)
      yield put({
        type: 'get_list',
        payload: res
      })
    },
    *delete({params, callback},{call}) {
      const res = yield call(deletePermission, params);
      if (res !== false) {
        callback()
      }

    },
    *create({params, callback },{call}) {
      const res = yield call(createPermission, params);
      if (res !== false) {
        callback()
      }
    },
    *save({id ,params, callback },{call}) {
      const res = yield call(savePermission, id, params);
      if (res !== false) {
        callback()
      }
    },
    *getTree({params},{call, put}) {
      const res = yield call(getPermissionTree, params);
      yield put({
        type: 'get_tree_list',
        payload: res
      })
    }
  },
  reducers: {
    get_list(state, action) {
        return  {
          ...state,
          permissionList:{...state.permissionList,...action.payload},
        }
    },
    get_tree_list(state, action) {
      return  {
        ...state,
        permissionTrees:action.payload,
      }
  }
  },
};

service

src/services/auth/permisiionService.js

import request from '@/utils/request';

export async function getPermissions(params) {
  return request('/api/auth/permissions', {
    method: 'get',
    params,
  });
}

export async function deletePermission(id) {
  return request(`/api/auth/permission/${id}`, {
    method: 'delete',
  });
}

export async function createPermission(params) {
  return request('/api/auth/permission', {
    method: 'post',
    data: params,
  });
}

export async function savePermission(id, params) {
  return request(`/api/auth/permission/${id}`, {
    method: 'put',
    data: params,
  });
}

export async function getPermissionTree(params) {
  return request('/api/auth/permission/tree', {
    method: 'get',
    params,
  })
}

好了,权限管理完成了,可以自己试一下。因为本系列主要讲的是后端和高并发的应用而不是前端,所以前端这里会略过。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值