ant-design-pro 实现二级权限表格

2019-08-14  本文已影响0人  吃瓜群众666

场景:需要实现一个可折叠的二级权限表格,勾选全部时,下面的子权限自动勾选;去除子权限的勾选时,父权限的勾选也自动取消。
如图:


permission.png
解决方案:

1.主页面

import BaseComponent from '../../../base/BaseComponent';
import { connect } from 'dva';
import LogUtil from '../../../../../utils/erp/LogUtil';
import MsgUtil from '../../../../../utils/erp/MsgUtil';
import MyConstants from '../../../../../utils/erp/MyConstants';
import { Table, Checkbox, Button, message } from 'antd';
import HttpCode from '../../../../../utils/erp/HttpCode';
import PmsOperateCode from '../../../../../utils/erp/PmsOperateCode';
import router from 'umi/router';

@connect(({ system, loading }) => ({
  system,
  loading: loading.models.system,
}))
class OperatorPermission extends BaseComponent {
  positionId = MyConstants.DefaultNumValue;
  columns = [
    {
      title: '权限名称',
      dataIndex: 'name',
      key: 'name',
      width: '20%',
    },
    {
      title: '功能权限',
      dataIndex: 'view',
      key: 'view',
      width: '40%',
      render: (text, record) => (
        <div style={{ width: 300 }}>
          {this.renderCheckBoxLine(record)}
        </div>
      ),
    },
    {
      title: '说明',
      dataIndex: 'remarks',
      width: '40%',
      key: 'remarks',
    },
  ];
  list = [];
  tableKey = 0;

  constructor(props) {
    super(props);
    const getParams = this.props.location.state;
    if (getParams != null && getParams.positionId != null) {
      this.positionId = getParams.positionId;
      LogUtil.debugTag('this.positionId=', this.positionId);
    } else {
      MsgUtil.transParamsIsNull('订单 ID');
    }
  }

  componentDidMount() {
    this.getBasicPermissionList();
  }

  render() {
    const { loading } = this.props;
    return (
      <div>
        权限设置
        <Table key={this.tableKey} loading={loading} defaultExpandAllRows={true} columns={this.columns}
               dataSource={this.list}/>
        <div>
          <Button type="primary" style={{ marginLeft: 20 }} onClick={this.saveInfo.bind(this)}> 保存</Button>
          <Button type="primary" ghost style={{ marginLeft: 20 }} onClick={this.goBack.bind(this)}> 取消</Button>
        </div>
      </div>
    );
  }

  /**
   * 加载权限勾选行
   */
  renderCheckBoxLine(record) {
    if (!record.isFather) {
      return (
        <div style={{ marginLeft: 30 }}>
          {record.operationList.map((item) => {
            return this.renderCheckbox(item, record.fatherCode, record.code);
          })}
        </div>
      );
    } else {
      return <Checkbox id={record.code} key={record.code} onChange={this.onFatherCheckboxChange}
                       checked={record.allChecked}>打开所有</Checkbox>;
    }
  }

  /**
   * 加载权限勾选框
   */
  renderCheckbox(operation, levelOneCode, levelTwoCode) {
    let text = '';
    let key = levelOneCode + '#' + levelTwoCode + '#' + operation.code;
    switch (operation.code) {
      case PmsOperateCode.READ:
        text = '打开';
        break;
      case PmsOperateCode.WRITE:
        text = '编辑';
        break;
      case PmsOperateCode.VERIFY:
        text = '审核';
        break;
    }
    return (
      <Checkbox id={key} key={key} onChange={this.onCheckboxChange} checked={operation.checked}>
        {text}
      </Checkbox>
    );
  }

  //================================== 控件回调 =====================================

  /**
   * 父节点勾选框回调
   */
  onFatherCheckboxChange = (e) => {
    let id = e.target.id;
    for (let i = 0; i < this.list.length; i++) {
      if (this.list[i].code === id) {
        this.list[i].allChecked = e.target.checked;
        //勾选所有子节点
        if (this.list[i].children !== undefined) {
          for (let j = 0; j < this.list[i].children.length; j++) {
            for (let k = 0; k < this.list[i].children[j].operationList.length; k++) {
              this.list[i].children[j].operationList[k].checked = e.target.checked;
            }
          }
        }
      }
    }
    this.setState({});
  };

  /**
   * 子节点勾选框回调
   */
  onCheckboxChange = e => {
    let id = e.target.id;
    let keyArr = id.split('#');
    for (let i = 0; i < this.list.length; i++) {
      //父模块编号匹配
      if ((this.list[i].code + '').trim() === keyArr[0].trim()) {
        for (let j = 0; j < this.list[i].children.length; j++) {
          //子模块编号匹配
          if ((this.list[i].children[j].code + '').trim() === keyArr[1].trim()) {
            for (let k = 0; k < this.list[i].children[j].operationList.length; k++) {
              //勾选框匹配
              if ((this.list[i].children[j].operationList[k].code + '').trim() === keyArr[2].trim()) {
                this.list[i].children[j].operationList[k].checked = e.target.checked;
                if (!this.list[i].children[j].operationList[k].checked) {
                  this.list[i].allChecked = false;
                }
                this.setState({});
                return;
              }
            }
          }
        }
      }
    }
  };

  //============================ 数据转化  ===================================
  /**
   * 初始化空的权限表
   */
  initBasicPermissionList(list) {
    LogUtil.debugTag('list', list);
    this.list = list;
    this.tableKey++;
    this.setState({});
  }

  /**
   * 将某个职位的权限加到权限表上面去
   */
  addPosPmsToBasicList(posPmsList) {
    LogUtil.debugTag('posPmsList', posPmsList);
    //循环需要加入表格的权限列表
    for (let m = 0; m < posPmsList.length; m++) {
      //循环权限表
      for (let i = 0; i < this.list.length; i++) {
        if (this.list[i].children === undefined) {
          //没有子节点的父节点
          if (this.list[i].code === posPmsList[m].module) {
            if (posPmsList[m].operations.length > 0) {
              let operation = posPmsList[m].operations[0];
              if (operation === PmsOperateCode.READ) {
                this.list[i].allChecked = true;
              } else {
                this.list[i].allChecked = false;
              }
            }
          } else {
            //有子节点的父节点,不做操作
          }
        } else {
          //子节点
          for (let j = 0; j < this.list[i].children.length; j++) {
            if (this.list[i].children[j].code === posPmsList[m].module) {
              for (let k = 0; k < this.list[i].children[j].operationList.length; k++) {
                //判断某一个权限checkBox是否需要被选中
                for (let n = 0; n < posPmsList[m].operations.length; n++) {
                  if (posPmsList[m].operations[n] === this.list[i].children[j].operationList[k].code) {
                    this.list[i].children[j].operationList[k].checked = true;
                    break;
                  }
                }
              }
            }
          }
        }
      }
    }
    this.setState({});
  }
  /**
   * 将UI数据转化为网络上传所需要的形式
   */
  transLocalDataToNet(){
    let netList = [];
    for (let i = 0; i < this.list.length; i++) {
      if (this.list[i].children === undefined) {
        //没有子节点的模块,必传
        let temp = {};
        temp.name = this.list[i].name;
        temp.module = this.list[i].code;
        temp.operations = [];
        if (this.list[i].allChecked) {
          temp.operations.push(PmsOperateCode.READ);
        } else {
          temp.operations.push(PmsOperateCode.UNKNOWN);
        }
        netList.push(temp);
      } else {
        //有子节点的模块
        for (let j = 0; j < this.list[i].children.length; j++) {
          let temp = {};
          temp.name = this.list[i].children[j].name;
          temp.module = this.list[i].children[j].code;
          temp.operations = [];
          for (let k = 0; k < this.list[i].children[j].operationList.length; k++) {
            if (this.list[i].children[j].operationList[k].checked) {
              temp.operations.push(this.list[i].children[j].operationList[k].code);
            }
          }
          //有勾选的的才传,否则默认为未勾选
          if (temp.operations.length !== 0) {
            netList.push(temp);
          }
        }
      }
    }
    LogUtil.debugTag('netList', netList);
    LogUtil.debugTag('netList', JSON.stringify(netList));
    return netList;
  }

  //======================= 网络数据相关 ================================

  /**
   * 获取空的权限表格数据
   */
  getBasicPermissionList() {
    const { dispatch } = this.props;
    dispatch({
      type: 'system/getBasicPermissionList',
      payload: {},
      callback: response => {
        LogUtil.debugTag('response', response);
        if (response.code === HttpCode.OK) {
          this.initBasicPermissionList(response.data);
          this.getPositionPermission(this.positionId);
        }
      },
    });
  }

  getPositionPermission(id) {
    LogUtil.debugTag('getPositionPermission id', id);
    const { dispatch } = this.props;
    dispatch({
      type: 'system/getPositionPermission',
      payload: {
        id: id,
      },
      callback: response => {
        if (response.code === HttpCode.OK) {
          this.addPosPmsToBasicList(response.data);
        } else {
          MsgUtil.netCodeIsNotOk(response);
        }
      },
    });
  }



  saveInfo = () => {
    let netList = this.transLocalDataToNet();
    const { dispatch } = this.props;
    dispatch({
      type: 'system/modifyPosPermission',
      payload: {
        id: this.positionId,
        body: netList,
      },
      callback: response => {
        if (response.code === HttpCode.OK) {
          message.success('保存成功!');
          this.goBack();
        } else {
          MsgUtil.netCodeIsNotOk(response);
        }
      },
    });

  };

  goBack = () => {
    router.goBack();
  };
}

export default OperatorPermission;

2.权限表格数据模型

import PmsOperateCode from '../../src/utils/erp/PmsOperateCode';
import PmsMdlCode from '../../src/utils/erp/PmsMdlCode';

export default {
  // 空的权限表
  'GET /system/basicPermissionList': {
    code: 0,
    data: [
      {
        //商品模块
        code: PmsMdlCode.GOODS,
        allChecked: false,
        name: '火影忍者',
        remarks: '只要有树叶飞舞的地方,火就会燃烧。火的影子会照耀着村子,并且,让新的树叶发芽。',
        isFather: true,
        children: [
          {
            code: PmsMdlCode.GOODS_MNG,
            fatherCode: PmsMdlCode.GOODS,
            isFather: false,
            name: '漩涡鸣人',
            remarks: '只要有树叶飞舞的地方,火就会燃烧。火的影子会照耀着村子,并且,让新的树叶发芽。',
            operationList: [
              {
                code: PmsOperateCode.READ,
                checked: false,
              },
              {
                code: PmsOperateCode.WRITE,
                checked: false,
              },
            ],
          },
          {
            code: PmsMdlCode.GOODS_SUPPLIER_MNG,
            fatherCode: PmsMdlCode.GOODS,
            isFather: false,
            name: '宇智波佐助',
            remarks: '只要有树叶飞舞的地方,火就会燃烧。火的影子会照耀着村子,并且,让新的树叶发芽。',
            operationList: [
              {
                code: PmsOperateCode.READ,
                checked: false,
              },
              {
                code: PmsOperateCode.WRITE,
                checked: false,
              },
            ],
          },
        ],
      },
      {
        code: PmsMdlCode.STORE,
        allChecked: false,
        name: '波风水门',
        remarks: '只要有树叶飞舞的地方,火就会燃烧。火的影子会照耀着村子,并且,让新的树叶发芽。',
        isFather: true,
        children: [
          {
            code: PmsMdlCode.STORE_GOODS_MNG,
            fatherCode: PmsMdlCode.STORE,
            isFather: false,
            name: '猿飞日斩',
            remarks: '只要有树叶飞舞的地方,火就会燃烧。火的影子会照耀着村子,并且,让新的树叶发芽。',
            operationList: [
              {
                code: PmsOperateCode.READ,
                checked: false,
              },
              {
                code: PmsOperateCode.WRITE,
                checked: false,
              },
            ],
          },
          {
            code: PmsMdlCode.STORE_FREE_SHIP_SCHEME,
            fatherCode: PmsMdlCode.STORE,
            isFather: false,
            name: '包邮方案',
            remarks: '只要有树叶飞舞的地方,火就会燃烧。火的影子会照耀着村子,并且,让新的树叶发芽。',
            operationList: [
              {
                code: PmsOperateCode.READ,
                checked: false,
              },
              {
                code: PmsOperateCode.WRITE,
                checked: false,
              },
            ],
          },
          {
            code: PmsMdlCode.STORE_BANNER_MNG,
            fatherCode: PmsMdlCode.STORE,
            isFather: false,
            name: ' 雷影',
            remarks: '只要有树叶飞舞的地方,火就会燃烧。火的影子会照耀着村子,并且,让新的树叶发芽。',
            operationList: [
              {
                code: PmsOperateCode.READ,
                checked: false,
              },
            ],
          },
          {
            code: PmsMdlCode.STORE_FEEDBACK_MNG,
            fatherCode: PmsMdlCode.STORE,
            isFather: false,
            name: '自来也',
            remarks: '只要有树叶飞舞的地方,火就会燃烧。火的影子会照耀着村子,并且,让新的树叶发芽。',
            operationList: [
              {
                code: PmsOperateCode.READ,
                checked: false,
              },
            ],
          },
        ],
      },
      {
        code: PmsMdlCode.STOCK,
        allChecked: false,
        name: '我爱罗',
        remarks: '库存模块下所有页面的所有权限;',
        isFather: true,
        children: [
          {
            code: PmsMdlCode.STOCK_SEARCH,
            fatherCode: PmsMdlCode.STOCK,
            isFather: false,
            name: '卡卡西',
            remarks: '只要有树叶飞舞的地方,火就会燃烧。火的影子会照耀着村子,并且,让新的树叶发芽。',
            operationList: [
              {
                code: PmsOperateCode.READ,
                checked: false,
              },
            ],
          },
          {
            code: PmsMdlCode.STOCK_RETURN_GOODS_TO_STOCK,
            fatherCode: PmsMdlCode.STOCK,
            isFather: false,
            name: ' 小李',
            remarks: '只要有树叶飞舞的地方,火就会燃烧。火的影子会照耀着村子,并且,让新的树叶发芽。',
            operationList: [
              {
                code: PmsOperateCode.READ,
                checked: false,
              },
              {
                code: PmsOperateCode.WRITE,
                checked: false,
              },
              {
                code: PmsOperateCode.VERIFY,
                checked: false,
              },
            ],
          },
          {
            code: PmsMdlCode.STOCK_GOODS_OUT_STOCK,
            fatherCode: PmsMdlCode.STOCK,
            isFather: false,
            name: ' 照美冥',
            remarks: '只要有树叶飞舞的地方,火就会燃烧。火的影子会照耀着村子,并且,让新的树叶发芽。',
            operationList: [
              {
                code: PmsOperateCode.READ,
                checked: false,
              },
              {
                code: PmsOperateCode.WRITE,
                checked: false,
              },
              {
                code: PmsOperateCode.VERIFY,
                checked: false,
              },
            ],
          },
          {
            code: PmsMdlCode.STOCK_CHECK,
            fatherCode: PmsMdlCode.STOCK,
            isFather: false,
            name: ' 纲手大奶',
            remarks: '只要有树叶飞舞的地方,火就会燃烧。火的影子会照耀着村子,并且,让新的树叶发芽。',
            operationList: [
              {
                code: PmsOperateCode.READ,
                checked: false,
              },
              {
                code: PmsOperateCode.WRITE,
                checked: false,
              },
            ],
          },
          {
            code: PmsMdlCode.STOCK_ALLOCATE,
            fatherCode: PmsMdlCode.STOCK,
            isFather: false,
            name: ' 佩恩',
            remarks: ' 只要有树叶飞舞的地方,火就会燃烧。火的影子会照耀着村子,并且,让新的树叶发芽。',
            operationList: [
              {
                code: PmsOperateCode.READ,
                checked: false,
              },
              {
                code: PmsOperateCode.WRITE,
                checked: false,
              },
            ],
          },
          {
            code: PmsMdlCode.STOCK_STREAM,
            fatherCode: PmsMdlCode.STOCK,
            isFather: false,
            name: ' 九尾妖狐',
            remarks: ' 哈哈哈...',
            operationList: [
              {
                code: PmsOperateCode.READ,
                checked: false,
              },
            ],
          },
        ],
      },
      {
        code: PmsMdlCode.PURCHASE,
        allChecked: false,
        name: '春野樱',
        remarks: '只要有树叶飞舞的地方,火就会燃烧。火的影子会照耀着村子,并且,让新的树叶发芽。',
        isFather: true,
        children: [
          {
            code: PmsMdlCode.PURCHASE_FAST,
            fatherCode: PmsMdlCode.PURCHASE,
            isFather: false,
            name: '井野',
            remarks: '只要有树叶飞舞的地方,火就会燃烧。火的影子会照耀着村子,并且,让新的树叶发芽。',
            operationList: [
              {
                code: PmsOperateCode.READ,
                checked: false,
              },
              {
                code: PmsOperateCode.WRITE,
                checked: false,
              },
              {
                code: PmsOperateCode.VERIFY,
                checked: false,
              },
            ],
          },
          {
            code: PmsMdlCode.PURCHASE_TO_STOCK,
            fatherCode: PmsMdlCode.PURCHASE,
            isFather: false,
            name: '犬夜叉',
            remarks: '只要有树叶飞舞的地方,火就会燃烧。火的影子会照耀着村子,并且,让新的树叶发芽。',
            operationList: [
              {
                code: PmsOperateCode.READ,
                checked: false,
              },
              {
                code: PmsOperateCode.WRITE,
                checked: false,
              },
              {
                code: PmsOperateCode.VERIFY,
                checked: false,
              },
            ],
          },
          {
            code: PmsMdlCode.PURCHASE_OUT_STOCK,
            fatherCode: PmsMdlCode.PURCHASE,
            isFather: false,
            name: '母夜叉',
            remarks: '只要有树叶飞舞的地方,火就会燃烧。火的影子会照耀着村子,并且,让新的树叶发芽。',
            operationList: [
              {
                code: PmsOperateCode.READ,
                checked: false,
              },
              {
                code: PmsOperateCode.WRITE,
                checked: false,
              },
              {
                code: PmsOperateCode.VERIFY,
                checked: false,
              },
            ],
          },
        ],
      },
      {
        code: PmsMdlCode.SHOP,
        allChecked: false,
        name: '牛叉',
        remarks: '哈哈哈...',
        isFather: true,
      },
      {
        code: PmsMdlCode.ORDER,
        allChecked: false,
        name: '我擦',
        remarks: '只要有树叶飞舞的地方,火就会燃烧。火的影子会照耀着村子,并且,让新的树叶发芽。',
        isFather: true,
        children: [
          {
            code: PmsMdlCode.ORDER_ONLINE,
            fatherCode: PmsMdlCode.ORDER,
            isFather: false,
            name: '照美冥',
            remarks: ' 只要有树叶飞舞的地方,火就会燃烧。火的影子会照耀着村子,并且,让新的树叶发芽。',
            operationList: [
              {
                code: PmsOperateCode.READ,
                checked: false,
              },
              {
                code: PmsOperateCode.WRITE,
                checked: false,
              },
            ],
          },
          {
            code: PmsMdlCode.ORDER_OFFLINE,
            fatherCode: PmsMdlCode.ORDER,
            isFather: false,
            name: '照美冥',
            remarks: '只要有树叶飞舞的地方,火就会燃烧。火的影子会照耀着村子,并且,让新的树叶发芽。',
            operationList: [
              {
                code: PmsOperateCode.READ,
                checked: false,
              },
            ],
          },
        ],
      },
      {
        code: PmsMdlCode.MEMBER,
        allChecked: false,
        name: '照美冥',
        remarks: '会员模块下所有页面的所有权限;',
        isFather: true,
      },
      {
        code: PmsMdlCode.DATA,
        allChecked: false,
        name: '数据',
        remarks: '数据模块下所有页面的所有权限;',
        isFather: true,
      },
      {
        code: PmsMdlCode.MARKETING,
        allChecked: false,
        name: '照美冥',
        remarks: '只要有树叶飞舞的地方,火就会燃烧。火的影子会照耀着村子,并且,让新的树叶发芽。',
        isFather: true,
        children: [
          {
            code: PmsMdlCode.MARKETING_MNG,
            fatherCode: PmsMdlCode.MARKETING,
            isFather: false,
            name: ' 营销管理',
            remarks: ' 只要有树叶飞舞的地方,火就会燃烧。火的影子会照耀着村子,并且,让新的树叶发芽。',
            operationList: [
              {
                code: PmsOperateCode.READ,
                checked: false,
              },
              {
                code: PmsOperateCode.WRITE,
                checked: false,
              },
            ],
          },
          {
            code: PmsMdlCode.MARKETING_PROMO_CODE,
            fatherCode: PmsMdlCode.MARKETING,
            isFather: false,
            name: '照美冥',
            remarks: '只要有树叶飞舞的地方,火就会燃烧。火的影子会照耀着村子,并且,让新的树叶发芽。',
            operationList: [
              {
                code: PmsOperateCode.READ,
                checked: false,
              },
              {
                code: PmsOperateCode.WRITE,
                checked: false,
              },
            ],
          },
        ],
      },
      {
        code: PmsMdlCode.SYSTEM,
        allChecked: false,
        name: '照美冥',
        remarks: '只要有树叶飞舞的地方,火就会燃烧。火的影子会照耀着村子,并且,让新的树叶发芽。',
        isFather: true,
        children: [
          {
            code: PmsMdlCode.SYSTEM_PERMISSION_MNG,
            fatherCode: PmsMdlCode.SYSTEM,
            isFather: false,
            name: ' 权限管理',
            remarks: ' 只要有树叶飞舞的地方,火就会燃烧。火的影子会照耀着村子,并且,让新的树叶发芽。',
            operationList: [
              {
                code: PmsOperateCode.READ,
                checked: false,
              },
              {
                code: PmsOperateCode.WRITE,
                checked: false,
              },
            ],
          },
          {
            code: PmsMdlCode.SYSTEM_OPERATE_LOG,
            fatherCode: PmsMdlCode.SYSTEM,
            isFather: false,
            name: ' 照美冥',
            remarks: ' 只要有树叶飞舞的地方,火就会燃烧。火的影子会照耀着村子,并且,让新的树叶发芽。',
            operationList: [
              {
                code: PmsOperateCode.READ,
                checked: false,
              },
            ],
          },
          {
            code: PmsMdlCode.SYSTEM_VERIFY_OPPOSITE,
            fatherCode: PmsMdlCode.SYSTEM,
            isFather: false,
            name: ' 照美冥',
            remarks: ' 只要有树叶飞舞的地方,火就会燃烧。火的影子会照耀着村子,并且,让新的树叶发芽。',
            operationList: [
              {
                code: PmsOperateCode.READ,
                checked: false,
              },
              {
                code: PmsOperateCode.WRITE,
                checked: false,
              },
              {
                code: PmsOperateCode.VERIFY,
                checked: false,
              },
            ],
          },
        ],
      },
    ],
  },
  //测试数据
  'GET /system/getPositionPermission': {
    code: 0,
    data: [
      { name: '漩涡鸣人', module: 10100, operation: [100, 101] },
      {
        name: '宇智波佐助',
        module: 10101,
        operation: [100, 101],
      }
      , { name: '波风水门', module: 1, operation: [100] }, {
        name: '大蛇丸',
        module: 10201,
        operation: [101],
      }, { name: '卡卡西', module: 10300, operation: [100, 101, 102] }, {
        name: '照美冥',
        module: 10301,
        operation: [100, 101, 102],
      }, { name: '雷影', module: 10302, operation: [100, 101, 102] }, {
        name: '自来也',
        module: 10400,
        operation: [100],
      }, { name: '小李', module: 10600, operation: [0] },
      { name: '宇智波斑', module: 10700, operation: [0] }],
  },
};

3.权限操作码的枚举

/**
 * PermissionOperateCode 权限操作码
 */
export default {
  // 操作[100000 - 未知, 100100 - 读取, 100101 - 修改, 100102 - 审核, 100200 - 改价, 100201 - 退单]
  UNKNOWN: 100000,
  READ: 100100,
  WRITE: 100101,
  VERIFY: 100102,
  REPRICE: 100200,
  RETURN_ORDER: 100201,

  properties: {
    100000: {name: 'UNKNOWN', code: 100000, explain: '未知'},
    100100: {name: 'READ', code: 100100, explain: '读取'},
    100101: {name: 'WRITE', code: 100101, explain: '修改'},
    100102: {name: 'VERIFY', code: 100102, explain: '审核'},
    100200: {name: 'REPRICE', code: 100200, explain: '改价'},
    100201: {name: 'RETURN_ORDER', code: 100201, explain: '退单'},
  },
  getStrFromCode(code){
    return  this.properties[code].explain;
  },
};
上一篇下一篇

猜你喜欢

热点阅读