ant design pro v6 如何做好角色管理
先上图:



整个角色管理是如何做的吗?
首先你要处理后端,要先把角色存到用户那。

这是用户管理部分的内容:
可以看到一个用户是有多个角色的。

看到没有,存的是数组
数组的是一个 role 对象
role 对象是这样:

主要是存一个 name 就好。permissions 是权限列表。
import { Request, Response } from 'express';
import Role from '../models/role';
import handleAsync from '../utils/handleAsync';// Build query based on query parameters
const buildQuery = (queryParams: any): any => {const query: any = {};if (queryParams.name) {query.name = { $regex: queryParams.name, $options: 'i' };}return query;
};// 获取所有角色
const getRoles = handleAsync(async (req: Request, res: Response) => {const { current = '1', pageSize = '10' } = req.query;const query = buildQuery(req.query);const roles = await Role.find(query).populate('permissions').sort('-createdAt') // Sort by creation time in descending order.skip((+current - 1) * +pageSize).limit(+pageSize).exec();res.json({success: true,data: roles,});
});// 根据 ID 获取角色
const getRoleById = handleAsync(async (req: Request, res: Response) => {const role = await Role.findById(req.params.id).exec();if (!role) {res.status(404);throw new Error('Role not found');}res.json({success: true,data: role,});
});// 添加新角色
const addRole = handleAsync(async (req: Request, res: Response) => {const newRole = new Role({...req.body,});const savedRole = await newRole.save();res.json({success: true,data: savedRole,});
});// 更新角色
const updateRole = handleAsync(async (req: Request, res: Response) => {const { id } = req.params;const updatedRole = await Role.findByIdAndUpdate(id,{ ...req.body },{ new: true },).exec();if (!updatedRole) {res.status(404);throw new Error('Role not found');}res.json({success: true,data: updatedRole,});
});// 删除角色
const deleteRole = handleAsync(async (req: Request, res: Response) => {const { id } = req.params;const role = await Role.findByIdAndDelete(id).exec();if (!role) {res.status(404);throw new Error('Role not found');}res.json({success: true,data: { message: 'Role deleted successfully' },});
});// 批量删除角色
const deleteMultipleRoles = handleAsync(async (req: Request, res: Response) => {const { ids } = req.body;await Role.deleteMany({_id: { $in: ids },}).exec();res.json({success: true,message: `${ids.length} roles deleted successfully`,});
});export {getRoles,getRoleById,addRole,updateRole,deleteRole,deleteMultipleRoles,
};
这是后端代码,就是增删改查。比较容易理解。
前端:
import { useIntl } from '@umijs/max';
import React, { Key, useState } from 'react';
import { ProForm, ProFormText } from '@ant-design/pro-components';
import { Form, Input, Spin, Tree } from 'antd';
import useQueryList from '@/hooks/useQueryList';
import { FormInstance } from 'antd/es/form';
import { Permission } from '@/apiDataStructures/ApiDataStructure';interface Props {form?: FormInstance<any>;newRecord?: boolean;onFinish: (formData: any) => Promise<void>;values?: any;
}const BasicForm: React.FC<Props> = ({ newRecord, onFinish, values }) => {const intl = useIntl();const { items: permissionGroups, loading } = useQueryList('/permission-groups/list');const [expandedKeys, setExpandedKeys] = useState<Key[]>([]);const [autoExpandParent, setAutoExpandParent] = useState<boolean>(true);const [checkedKeys, setCheckedKeys] = useState<Key[] | { checked: Key[]; halfChecked: Key[] }>(values.permissions?.map((permission: Permission) => `${permission._id}`) ?? [],);const [selectedKeys, setSelectedKeys] = useState<Key[]>([]);const onExpand = (expandedKeysValue: Key[]) => {setExpandedKeys(expandedKeysValue);setAutoExpandParent(false);};const onCheck = (checkedKeysValue: Key[] | { checked: Key[]; halfChecked: Key[] }) => {setCheckedKeys(checkedKeysValue);console.log('checkedKeysValue', checkedKeysValue);};const onSelect = (selectedKeysValue: Key[]) => {setSelectedKeys(selectedKeysValue);};return (<ProForminitialValues={{...values,permissions: values?.permissions?.map((permission: Permission) => permission._id),}}onFinish={async (values) => {await onFinish({...values,permissions: checkedKeys,});}}><ProForm.Group><ProFormTextrules={[{ required: true, message: intl.formatMessage({ id: 'enter_name' }) }]}width="md"label={intl.formatMessage({ id: 'name' })}name="name"/><ProForm.Item name="permissions" label={intl.formatMessage({ id: 'permission_choose' })}><Spin spinning={loading}><TreecheckableonExpand={onExpand}expandedKeys={expandedKeys}autoExpandParent={autoExpandParent}onCheck={onCheck}checkedKeys={checkedKeys}onSelect={onSelect}selectedKeys={selectedKeys}treeData={permissionGroups} // Use filtered top-level groupsfieldNames={{ title: 'name', key: '_id', children: 'children' }}/></Spin></ProForm.Item></ProForm.Group>{!newRecord && (<Form.Item name="_id" label={false}><Input type="hidden" /></Form.Item>)}</ProForm>);
};export default BasicForm;
https://www.qiuzhi99.com/playlists/antdpromakemoney.html
相关文章:
ant design pro v6 如何做好角色管理
先上图: 整个角色管理是如何做的吗? 首先你要处理后端,要先把角色存到用户那。 这是用户管理部分的内容: 可以看到一个用户是有多个角色的。 看到没有,存的是数组 数组的是一个 role 对象 role 对象是这样…...
C++ 设计模式(3. 抽象工厂模式)
抽象工厂模式也是一种创建型设计模式,提供了一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类【引用自大话设计模式第15章】基本结构 抽象工厂模式包含多个抽象产品接口,多个具体产品类,一个抽象工厂接口和多个具体…...
【PHP入门教程】PHPStudy环境搭建+HelloWorld运行
文章目录 PHP 的历史PHP 的用途PHP 的特点和优势PHP 环境搭建环境准备安装window 安装CentOS / Ubuntu / Debian 安装 第一个Hello World使用Apache服务运行命令行运行代码 PHP 的历史 PHP(Hypertext Preprocessor)超文本预处理器是一种开源的通用脚本语…...
补 0 输出。
题目描述 输入一个整数,请在整数前面补 00 补足 88 位后输出。 输入描述 输入一行包含一个整数 nn。 输出描述 输出补00后的整数。 输入输出样例 示例1 输入 2021输出 00002021示例2 输入 202110输出 00202110 import os import sys# 请在此输入您的代码 si…...
因为嫌吵,在自己家也用上了远程控制电脑
加班嘛,赶稿嘛,参加工作的人都懂那种无形的压力和烦躁。 因为家里空间有限,我平常都是直接在客厅用台式电脑加急改写方案,但今天晚上家里来了几位叔,他们边吃饭边聊着秦始皇的话题,都70多分钟了,…...
vue---echarts环形图
1、完整代码直接可以cv <template><div id"main1"></div> </template><script> import * as echarts from echarts; // import { mapState } from vuex; // import { Alarm_Device } from ../utils/api.js; export default {name: P…...
克服编程挫折:从Bug的迷宫中寻找出口与面对算法保持冷静的策略
在编程学习的道路上,挫折感无疑是每个学习者都必须面对的挑战之一。它们仿佛是一座座高墙,阻挡我们前进的步伐。然而,正如许多有经验的编程高手所证明的那样,挫折并不是终点,而是成长和进步的催化剂。本文将分享一些有…...
Flink之SQL client使用案例
Flink的执行模式有以下三种: 前提是我们已经开启了yarnsession的进程,在下图中可以看到启动的id也就是后续任务需要通过此id进行认证,以及任务分配的master主机。 这里启动时候会报错一个ERROR:org.apache.flink.shaded.curator.org.apache…...
实际开发中的模块化开发 - 应用到直播间
实际开发中的模块化开发 - 模块管理(以直播间为例)-CSDN博客 引言 在前面的两篇博客中,我们已经介绍了直播模块的简单结构,创建了模块管理器和模块抽象基类,并且通过模块化实现了两个小业务功能模块。接下来…...
EmguCV学习笔记 VB.Net 第5章 图像变换
版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。 EmguCV是一个基于OpenCV的开源免费的跨平台计算机视觉库,它向C#和VB.NET开发者提供了OpenCV库的大部分功能。 教程VB.net版本请访…...
【初阶数据结构】顺序表与链表的比较(附题)
目录 一、顺序表和链表的区别(其他链表存在缺陷,比较意义不大,这里用带头双向循环链表与顺序表进行比较) 1.1插入、扩容与随机访问 二、缓存利用率的比较 2.1前置知识 详解及补充知识(本文仅为比较顺序表及链表&am…...
git-20240822
目录 初始化仓库 Git init Git init project --bare 查看提交的记录 git log --prettyoneline 查看当前git远程库地址 git remote -v 查看详细提交记录 git log 撤出暂存区的文件 git reset HEAD file(.代表全部文件) 提交数据到远程仓库 git config --global push.…...
【时时三省】c语言例题----华为机试题< 数字颠倒>
目录 1,题目 描述 输入描述: 输出描述: 示例1 2,代码...
【前缀和算法】--- 一维和二维前缀和模板
Welcome to 9ilks Code World (๑•́ ₃ •̀๑) 个人主页: 9ilk (๑•́ ₃ •̀๑) 文章专栏: 算法Journey 本文开始,博主开始讲解有关前缀和的算法,本篇博客我们先来了解一下有关前缀和的两个模板。 🏠 一维前缀和模板 &…...
有些信息注定会丢失
智能在分析问题、做出决策时,总是希望获取尽可能多的信息,以此更加准确地决策。然而,很遗憾的是,有一些信息注定会丢失,不可能获取完全的信息,而且即使能够获取,智能也不能完全利用。 这一点与…...
c#中Task.Run 和使用 Task 构造函数创建任务的区别
Task.Run 和使用 Task 构造函数创建任务是两种不同的方法,它们在某些方面有显著的区别: 启动方式: Task.Run 是一个静态方法,它立即启动一个任务并在后台执行指定的工作。它通常用于快速启动一个简单的后台任务。使用 Task 构造函数创建任务&…...
使用nginx做代理转发
需求1:通过监听服务器的80端口,将请求转发到另一台服务器的8070端口 打开nginx/nginx.conf文件 server {listen 80;server_name localhost;location /analys {proxy_pass http://10.xx.xx.xx:8070/;} }需求2:通过监听服务器的80端口&am…...
Java前端与后端交互:JSON与XML数据交换 - 掌握现代Web开发的核心技能
引言 随着互联网技术的不断进步,Web应用变得越来越复杂,从前端到后端的每一个环节都需要精心设计以保证良好的用户体验。在这个过程中,数据的传递扮演着至关重要的角色。无论是简单的表单提交还是复杂的API调用,都需要一种可靠的…...
网络攻击原理及过程
网络攻击原理表 攻击者 内容 攻击访问 攻击效果 攻击意图 黑客 挑战 间谍 用户命令 破坏信息 好奇 恐怖主义者 脚本或程序 本地访问 信息泄密 获取情报 公司职员 自治主体 远程访问 窃取服务 经济利益 职业犯罪分子 电磁泄露 拒绝服务 恐怖事…...
day30(8/16)——ansible
目录 一、回顾 1、mysql和python 1. mysql5.7 2. 可以使用pymysql非交互的管理mysql 2、mycat中间件 1. 独属于mysql主从的负载均衡策略 2.配置写主读从 3. 步骤 3.1 安装jdk 3.2 mycat 3.3 配置 3.4 启动和调试 二、运维自动化(ansible) 1、任务背…...
基于Gemini CLI Blueprint框架构建AI命令行工具:从原理到实践
1. 项目概述与核心价值最近在折腾AI命令行工具,发现了一个挺有意思的项目:gplasky/gemini-cli-blueprint-extension。乍一看这个名字,你可能觉得它就是个给某个AI模型(Gemini)做的命令行扩展。但如果你深入进去&#x…...
Windows安全组件深度解析与优化:2025专业版系统性能调优完整指南
Windows安全组件深度解析与优化:2025专业版系统性能调优完整指南 【免费下载链接】windows-defender-remover A tool which is uses to remove Windows Defender in Windows 8.x, Windows 10 (every version) and Windows 11. 项目地址: https://gitcode.com/gh_m…...
中性原子量子计算架构:原理、优势与应用
1. 中性原子量子计算架构概述量子计算作为后摩尔时代最具潜力的计算范式之一,其核心优势在于利用量子比特(Qubit)的叠加态和纠缠态实现并行计算。在众多物理实现方案中,中性原子量子架构近年来异军突起,展现出独特的工…...
Cadence Allegro 17.2 PCB设计避坑指南:从焊盘制作到封装绘制的完整流程
Cadence Allegro 17.2 PCB设计避坑指南:从焊盘制作到封装绘制的完整流程 刚接触Cadence Allegro 17.2的硬件工程师,往往会在焊盘制作和封装绘制环节踩不少坑。这些看似基础的操作,一旦参数设置不当或概念理解有误,轻则导致设计返工…...
DES算法C++实现踩坑实录:S盒置换与比特操作的那些坑
DES算法C实现中的五大典型陷阱与解决方案 在实现DES算法的过程中,许多开发者都会遇到一些看似简单却容易导致加密结果错误的细节问题。本文将聚焦于实际编码中最常见的五个"坑点",通过具体案例分析和解决方案,帮助开发者快速定位和…...
41_《智能体微服务架构企业级实战教程》智能助手主应用服务之创建FastMCP客户端
前言 配套视频教程: 在 Bilibili课堂、CSDN课程、51CTO学堂 同步发售,提供:源码+部署脚本+文档。 bilibili课堂视频教程:智能体微服务架构企业级实战教程_哔哩哔哩_bilibili CSDN课程视频教程:智能体微服务架构企业级实战教程_在线视频教程-CSDN程序员研修院 51CTO学堂…...
Android 14 + Linux 6.1 平台 RTL8822CE Wi‑Fi 适配实战:从 PCI 已枚举到成功扫描热点
摘要 在 Android 14 Linux 6.1 的移植过程中,RTL8822CE Wi‑Fi 很容易出现一种“硬件已经被 PCI 枚举到,但系统就是没有 wlan0”的尴尬状态。本文复盘一次完整的 RTL8822CE 适配过程,最终定位出两个连续阻塞点:第一,目…...
InjectFix实战:除了修Bug,如何在Unity里用它安全地‘新增’功能与属性?
InjectFix实战:突破Bug修复边界,安全扩展Unity功能 在Unity开发中,InjectFix作为热修复方案早已被开发者熟知,但大多数教程仅停留在修复Bug的基础用法上。当线上版本需要临时增加活动界面属性或工具函数时,重新打包发布…...
片上网络架构设计:集体通信硬件加速与优化
1. 轻量级片上网络架构设计解析 在当今机器学习(ML)模型规模呈指数级增长的背景下,大规模并行加速器已成为支撑AI计算的关键基础设施。这类系统通常采用数千个处理单元(PE)的集成设计,而连接这些计算资源的片上网络(NoC)性能直接决定了整个系统的效率瓶颈…...
别再傻等进位了!手把手教你用Verilog实现4位超前进位加法器(附完整代码)
超前进位加法器的Verilog实战:从理论到硬件加速的完整实现 在数字电路设计中,加法器是最基础却又最关键的运算单元之一。传统行波进位加法器虽然结构简单,但在高位宽运算时,其级联进位方式导致的延迟问题会严重影响系统性能。想象…...
