model处需要3个表,分别是角色表,用户表,权限表。每个表的具体参数需根据情况而定,此处只做一个简单的示例
具体代码如下
##model.js
const mongoose = require("./db")
//用户表
const userSchema = mongoose.Schema({
username:String,
password:String,
avatar:String,
rid:{
type:mongoose.Types.ObjectId,
ref:"role"
}
})
const userModel = mongoose.model("user",userSchema,"user")
//权限表
const menuSchema = mongoose.Schema({
mname:String,
level:Number,
url:String,
icon:String,
pid:{
type:mongoose.Types.ObjectId,
ref:"menu"
}
})
const menuModel = mongoose.model("menu",menuSchema,"menu")
//角色表
const roleSchema = mongoose.Schema({
rname:String,
mid:{
type:[mongoose.Types.ObjectId],//此处意思为数组中包id
ref:"menu"
}
})
const roleModel = mongoose.model("role",roleSchema,"role")
module.exports={
userModel,
menuModel,
roleModel
}
接着就是接口处的实现
代码如下
router.post('/getPermissions',async (req,res)=>{
let data =await roleModel.find()
let menuid = data.find((ele)=>{
return String(ele._id)==String(req.body.rid)
}).mid
##### 注意 //一定要拿String进行转为字符串,否则可能会有类型不一致的问题,因为前端传递回来的id默认是字符串类型的,并且后端存储的mid的数据一定要是id类型的
let data1 =await menuModel.find().lean()//lean是一个关键点,如果没有,会导致数组加不进去
//将所有的该角色下的权限先全部加入到menuList中
let menuList = []
data1.forEach((ele)=>{
menuid.forEach(element => {
if(String(ele._id)==String(element)){
menuList.push(ele)
}
});
})
//循环menuList,obj中存储为键值对的形式,每一个键对应每一个权限
let obj={}
let list=[]
menuList.forEach((ele)=>{
obj[ele._id]=ele
})
//进行无限极分类,首先判断一个权限有没有pid,如果没有,那么就是1级,直接加入到列表中,然后进行判断,将有pid的字段添加到该pid对应的children中,这里有一个问题,是为什么我们明明修改的是obj,怎么会把list的数据也给修改,这里就涉及到了引用变量会存储到堆中,也就是同一个内存地址,所以一个变了,其它也都会变
menuList.forEach((ele)=>{
if(!ele.pid){
list.push(ele)
}else{
if(!obj[ele.pid]["children"]){
obj[ele.pid]["children"]=[]
}
obj[ele.pid]["children"].push(ele)
}
})
res.send({
code:200,
list
})
})
##### 前端递归算法,通常,我们会利用到导航栏来进行页面的美化,这里是antdesign库中的导航栏的递归,这里前端使用的是react
function getItem(label, key, icon, children, type) {
return {
key,
icon,
children,
label,
type,
};
}
//递归算法
function loop(menuList) {
let menuListItems = [];
console.log(menuList);
menuList.forEach((item) => {
let arr = [];
if (item["children"]) {
arr = loop(item["children"]);
}
console.log(arr);
if (arr.length > 0) {
menuListItems.push(getItem(*item*.mname, item.url, item.icon, arr));
} else {
menuListItems.push(getItem(item.mname, item.url, item.icon));
}
});
console.log(menuListItems);
return menuListItems;
}
##### 注意:如果我们需要把导航栏数据进行修改,千万不要在递归算法中进行修改,否则会多次调用set进行渲染,非常的消耗性能