❤ React体系30-角色管理(源码已开放)

❤ React体系30-角色管理(源码已开放)

使用场景

使用背景 有时候我们需要给不同的用户赋予不同的权限进行系统的访问,这个时候我们就需要用到角色权限,通过角色来控制角色可以访问哪些菜单和路由

先来看一下我们最后搭建的效果

1、接口封装

封装相关的接口,还是跟我们之前差不多,但是这次我们新建文件src\api\system\role.js

js 复制代码
import request from '@/utils/request.js'


const apiTypeurl='/api/role';
// 查询角色列表
export function getRoleList (n) {
    return request({
      url: apiTypeurl,
      method: 'get',
      params:n
    })
}

// 添加角色
export function addRole (n) {
    return request({
            url: apiTypeurl,
            method: 'post',
            data:n
    })
}

// 删除角色
export function delRole (id) {
    return request({
      url:apiTypeurl+ '/'+id,
      method: 'delete'
    })      
}

// 修改角色
export function editRole(n) {
    return request({
            url: apiTypeurl,
            method: 'put',
            data:n
    })
}

// 获取角色详情
export function getRole(id) {
    return request({
      url:apiTypeurl+ '/'+id,
      method: 'get'
    })
}
// 修改角色状态 
export function editRoleStatus (RoleId,status) {
    return request({
            url: apiTypeurl+'/status/'+RoleId,
            method: 'put',
            data:status
    })
}

2、页面路由的增加

在页面的路由之中添加相关页面的路由部分src\router\index.tsx

js 复制代码
// 权限部分
const PermissionRole  = lazy(() => import('@/views/system/permission/role'));

{
  key: '8',
  path: "/admin/permission/role",
  element: <PermissionRole/>,
  label: '角色管理',
},

3、查询和页面搭建

整个页面的部分我们都写到这个里面 src\views\system\permission\role.tsx

先来搭建一个简单的页面列表

表格部分搭建

表单引入,这里的表单以及结构的搭建还和我们之前角色的部分差不多,重复的部分我们不再写,但是我们会改一些不一样的写法之类的

js 复制代码
//引入我们的角色相关的接口

import {getRoleList, addRole, delRole, editRole, getRole, editRoleStatus} from '@/api/system/role'; //角色接口

  useEffect(() => {
    handleQuery(); 
  }, [queryParams]);
  
   const handleQuery = () => {
    console.log('handleQuery');
    getList();
  }
  
// 获取用户
const getList = async () => {
try {
  const res:any = await getRoleList(queryForm); // 假设getUser函数能够正确返回Promise对象
  if(res.code == 200){
    message.success('查询成功!');
    setDatatable(res.data);
  }else{
    console.log('查询失败,请重试!',res, 'getUser');
    message.error(res.message);
  }
} catch (error) {
  console.log('查询失败,请重试!');
}
}

查看一下我们返回的数据

查询已经完整了证明!

接下来完善一下我们的表单部分

表单部分我们增加一下

js 复制代码
const [data, setData] = useState([]);
const columns = [
    {
      title: '字典编号',
      dataIndex: 'dict_id',
      key: 'dict_id',
    },
    {
      title: '字典名称',
      dataIndex: 'dict_name',
      key: 'dictName',
    },
    {
      title: '字典类型',
      dataIndex: 'dict_type',
      key: 'dict_type',
      valueType: 'text',
      render: (dom, record) => {
        return (
          <a
          className='text-blue-600/75 text-sm'
            onClick={() => {
              console.log(record.dictId);
              // history.push(`/system/dict-data/index/${record.dictId}`);
            }}
          >
          {dom}
          </a>
        );
      },
    },
    
    {
      title: '状态',
      dataIndex: 'status',
      key: 'status',
      render: (_: any, row) => {
        return (
          <Tag color={row.status == 0 ? '#87d068' : "#f50"} key={row.status}>
            {row.status == 0 ? '正常' : '异常'}
          </Tag>
        )
      },
    },
    {
      title: '备注',
      dataIndex: 'remark',
      key: 'remark',
      render: (_: any, row) => {
        return (<>{row?.remark||'--'}</>);
      },
    },
    {
      title: '创建时间',
      dataIndex: 'create_time',
      key: 'create_time',
      render: (_, record) => {
        return (<span>{record.create_time.toString()} </span>);
      },
    },
    {
      title: '操作',
      dataIndex: 'option',
      key: 'option',
      valueType: 'option',
      width: '220px',
      render: (_, record) => [
        <Button
          type="link"
          size="small"
          key="edit"
          // hidden={!access.hasPerms('system:dictType:edit')}
          // onClick={() => {
          //   setModalVisible(true);
          //   setCurrentRow(record);
          // }}
        >
          编辑
        </Button>,
        <Button
          type="link"
          size="small"
          danger
          key="batchRemove"
          // hidden={!access.hasPerms('system:dictType:remove')}
          onClick={async () => {
            Modal.confirm({
              title: '删除',
              content: '确定删除该项吗?',
              okText: '确认',
              cancelText: '取消',
              onOk: async () => {
                console.log('ok');
              },
            });
          }}
        >
          删除
        </Button>,
      ],
    },
  ];
  

  
 <div className='comback' style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
   <Table rowKey="id" dataSource={data} columns={columns} />
 </div>      

页面搭建部分先看看

这里我们核对一下整个表单

其实也就是更改表单的这部分

我们先简单配置一下相关的参数然后进行显示

4、新增功能部分

接下来搭建我们的新增部分,这里还是跟我们之前用户部分的搭建弹窗差不多!

我们先来简单的写一些参数然后看看我们的效果是什么样子的

我们的接口部分请求的地址部分方面是这样子的

这里我们可以先写个数据试试

js 复制代码
const newRole = { role_name: '新角色', role_key: 'new_role', role_sort: 3, status: '0', create_by: 'admin', create_time: new Date(), remark: '这是一个新角色' };
    let res:any= await addRole(newRole);
    if(res.code==200){
      message.success('添加成功');
      setModalVisible(false);
      handleSearch();  // 刷新数据
    }else{
      message.error('添加失败,请重试!');
}

完善一下我们的角色方面的逻辑

增加逻辑还是我们之前的那一部分,可以看到已经成功了

5、修改部分

js 复制代码
const handleEdit = async (row) => {
    setTitle("编辑");
    try {
      setLoading(true);
      let data = await handleDetail(row); // 接口的方式查询
      form.setFieldsValue(data); // 填充数据到表单中
    } catch (error) {
      message.error('获取数据详情失败,请重试!');
    } finally {
      setLoading(false);
    }
    setVisible(true);
  };
  /**
 * 处理详情
 *
 * @param row 表格行数据
 * @returns 返回获取到的详情数据
 */
  const handleDetail = async (row) => {
    try {
      const response = await getDictType(row.dict_id);
      const data = response.data;
      return data;
    } catch (error) {
      message.error('获取数据详情失败,请重试!');
    }
  }

这边修改部分我们可以看到已经好了,完善一下功能就可以了 ,需要注意我们每次传入的id,直接我们的写法是这样子的

js 复制代码
let data = await handleDetail(row); // 接口的方式查询
const handleDetail = async (row) => {
    try {
      const response: ApiResponse  = await getRole(row.role_id);
      const data = response.data;
      return data;
    } catch (error) {
      message.error('获取数据详情失败,请重试!');
    }
}


let data = await handleDetail(row.role_id); // 接口的方式查询
const handleDetail = async (row) => {
    try {
      const response: ApiResponse  = await getRole(row);
      const data = response.data;
      return data;
    } catch (error) {
      message.error('获取数据详情失败,请重试!');
    }
}
 

我们优化了一下,将传入的id部分由传入的地方进行控制,这样子也方便我们后期对于我们的代码进行抽离,这里留个悬念,想必你后面也猜到了,我会将所有的修改获取详情的接口都进行抽离全局方法一样

6、删除部分

js 复制代码
<Button
          type="link"
          size="small"
          danger
          key="batchRemove"
          // hidden={!access.hasPerms('system:dictType:remove')}
          onClick={async () => {
            console.log(row,'row--1');          
            Modal.confirm({
              title: '删除',
              content: '确定删除该项吗?',
              okText: '确认',
              cancelText: '取消',
              onOk:  () => {
                handleDelete(row);
              },
            });
          }}
        >
          删除
 </Button>
        
        
const handleDelete = async (record) => {
    console.log(record, '确定删除该项吗?');
    try {
     let data:any=  await delDictType(record.dict_id);
     if(data.code==200){
      message.success('删除成功');
     }else{
       message.error('删除失败,请重试!');
     }
    } catch (error) {
      message.error('删除失败,请重试!');
    }
  };

这边我们尝试一下,我们的删除已经成功了 !

7、页面优化

页面的正常操作我们已经完成了,接下来针对我们的页面我们进行一下详细的优化

优化一下我们时间显示

引入之前搭建好的格式化时间的函数

然后我们进行引入和使用

js 复制代码
import { parseTime } from '@/utils/methods';

// 使用这个时间函数
 render: (_, record) => {
        return (<span>{parseTime(record.create_time).toString()} </span>);
 },
相关推荐
Мартин.1 分钟前
[Meachines] [Easy] Sea WonderCMS-XSS-RCE+System Monitor 命令注入
前端·xss
昨天;明天。今天。1 小时前
案例-表白墙简单实现
前端·javascript·css
数云界1 小时前
如何在 DAX 中计算多个周期的移动平均线
java·服务器·前端
风清扬_jd2 小时前
Chromium 如何定义一个chrome.settingsPrivate接口给前端调用c++
前端·c++·chrome
安冬的码畜日常2 小时前
【玩转 JS 函数式编程_006】2.2 小试牛刀:用函数式编程(FP)实现事件只触发一次
开发语言·前端·javascript·函数式编程·tdd·fp·jasmine
ChinaDragonDreamer2 小时前
Vite:为什么选 Vite
前端
小御姐@stella2 小时前
Vue 之组件插槽Slot用法(组件间通信一种方式)
前端·javascript·vue.js
GISer_Jing2 小时前
【React】增量传输与渲染
前端·javascript·面试
GISer_Jing2 小时前
WebGL在低配置电脑的应用
javascript
eHackyd2 小时前
前端知识汇总(持续更新)
前端