You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中基于react-dual-listbox的权限数组递归校验与去重需求

权限转移处理函数实现方案

需求概述

需要实现一个处理权限转移的函数,接收两个数组参数:

  1. 当前已选中的权限数组:存储最终保留的权限项
  2. 待转移的选中权限数组:react-dual-listbox组件onChange回调返回的新选中权限项集合

函数需满足以下逻辑:

  • 若待转移的权限项已存在于当前数组中,移除原有项并保留新转移的项
  • 递归检查待转移权限的所有子权限,若这些子权限已存在于当前数组中,同样移除

示例场景:先向空数组添加ROLE_READ,后续添加ROLE_EDIT时,需移除已存在的ROLE_READ(因为ROLE_EDIT包含该子权限)


数据格式示例

带子权限的权限列表结构

[
  {
    "name": "ROLE_READ",
    "subPermissions": []
  },
  {
    "name": "ROLE_DELETE",
    "subPermissions": [
      {
        "name": "ROLE_READ",
        "subPermissions": [
          {
            "name": "ROLE_WRITE",
            "subPermissions": [
              {
                "name": "ROLE_EDIT",
                "subPermissions": []
              }
            ]
          }
        ]
      }
    ]
  },
  {
    "name": "ROLE_EDIT",
    "subPermissions": [
      {
        "name": "ROLE_READ",
        "subPermissions": []
      }
    ]
  },
  {
    "name": "PROJECT_MEMBER_READ",
    "subPermissions": []
  },
  {
    "name": "PROJECT_MEMBER_EDIT",
    "subPermissions": [
      {
        "name": "PROJECT_MEMBER_READ",
        "subPermissions": []
      }
    ]
  }
]

React组件配置说明

使用react-dual-listbox时需注意以下配置:

  1. 必须设置simpleValue={false},确保onChange返回完整的权限对象数组
  2. 原始权限数据适配组件格式的转换代码:
const data = options.map(rest => ({ ...rest, label: rest.name, value: rest.name }));
  1. 组件基础使用示例:
import DualListBox from 'react-dual-listbox';
import 'react-dual-listbox/lib/react-dual-listbox.css';

// ...

<DualListBox
  options={data}
  selected={finalArray}
  onChange={(selected) => {
    setFinalArray(prev => handlePermissionTransfer(prev, selected));
  }}
  simpleValue={false}
/>

核心函数实现

1. 递归获取权限及其所有子权限的名称集合

用于快速判断哪些权限需要被移除:

const getAllPermissionNames = (permission) => {
  let names = [permission.name];
  permission.subPermissions.forEach(subPerm => {
    names = [...names, ...getAllPermissionNames(subPerm)];
  });
  return names;
};

2. 权限转移处理核心函数

const handlePermissionTransfer = (currentPermissions, selectedPermissions) => {
  // 收集待转移权限及其所有子权限的名称
  const newPermNames = new Set();
  selectedPermissions.forEach(perm => {
    getAllPermissionNames(perm).forEach(name => newPermNames.add(name));
  });

  // 过滤当前数组:移除所有被新权限覆盖的项(包含子权限已存在的项)
  const filteredCurrent = currentPermissions.filter(perm => !newPermNames.has(perm.name));

  // 合并过滤后的数组与新选中的权限(自动去重,因为已移除冲突项)
  return [...filteredCurrent, ...selectedPermissions];
};

内容的提问来源于stack exchange,提问作者Baran Öden

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 22:12:48