更新父用户权限后移除子用户对应权限的Mongoose实现问题
解决Mongoose中父用户权限变更后子用户权限同步问题
核心逻辑
当父用户停止付费缩减权限时,遍历子用户权限的各个模块,仅保留父用户当前允许的权限项,移除超出范围的部分。
实现步骤与代码示例
const updateChildPermissions = async (parentId, childId) => { // 获取父、子用户的最新数据 const parent = await User.findById(parentId); const child = await User.findById(childId); if (!parent || !child) return; // 处理analytic模块的布尔型权限:父用户禁用的项,子用户同步禁用 Object.entries(parent.grant.analytic).forEach(([key, value]) => { if (value === false) { child.grant.analytic[key] = false; } }); // 处理entity下的普通数组权限:保留子用户数组中父用户也允许的元素 const arrayFields = ['brands', 'categorys', 'providers', 'types']; arrayFields.forEach(field => { const parentAllowedSet = new Set(parent.grant.entity[field]); child.grant.entity[field] = child.grant.entity[field].filter(item => parentAllowedSet.has(item)); }); // 处理entity下的嵌套competitors数组:匹配父用户对应的品牌,保留允许的竞品ID const parentCompetitorMap = new Map(); parent.grant.entity.competitors.forEach(item => { parentCompetitorMap.set(item._id, new Set(item.competitors)); }); child.grant.entity.competitors = child.grant.entity.competitors .map(childCompItem => { const allowedCompetitors = parentCompetitorMap.get(childCompItem._id); if (allowedCompetitors) { return { ...childCompItem, competitors: childCompItem.competitors.filter(id => allowedCompetitors.has(id)) }; } // 父用户无对应品牌权限,直接移除该子项 return null; }) .filter(Boolean); // 保存更新后的子用户数据 await child.save(); };
关键说明
- 布尔型权限:直接同步父用户的
false状态,确保子用户无法访问父用户已禁用的功能。 - 普通数组权限:利用
Set快速判断元素是否在父用户允许列表中,过滤掉子用户超出的项。 - 嵌套数组权限:先将父用户的竞品权限转为Map结构,再匹配子用户对应品牌的竞品列表,仅保留父用户允许的ID。
- 若需处理并发场景,可结合MongoDB事务或乐观锁避免数据冲突。
内容的提问来源于stack exchange,提问作者Anatoli Stasheuski
相关产品推荐
相关产品推荐

