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

如何在对象数组中筛选指定角色可用的模块与操作

解决getAvailableModulesAndActionsWithRoles多角色适配问题

需求说明

实现getAvailableModulesAndActionsWithRoles方法,传入roles字符串数组,提取所有启用(isEnabled为true)的模块中,对任一指定角色可用的操作。

现有代码问题

当前实现仅支持单个角色,且遍历角色时直接删除不匹配的action键,导致后续角色无法再判断该action的权限,逻辑不符合多角色场景需求。

现有实现代码

getAvailableModulesAndActionsWithRoles(roles: string[]): IHubModule[] {
    const modules = [...this.getModules()];
    const activeModules = modules.filter(module => module.isEnabled);
    activeModules.map(module => {
      Object.keys(module.actions).map(action => {
        roles.map(role => {
          if (!module.actions[action]?.includes(role)) {
            delete module.actions[action];
             return;
          }
        });
      });
    });
    return activeModules;
  }

模块接口定义

export interface IHubModule {
  name: ModuleName;
  isEnabled: boolean;
  actions: Record<Topic, string[]>;
}

测试用例

it('returns only active modules and actions for a list of roles', () => {
      const moduleInfos: IHubModule[] = [
        {
          name: ModuleNameTest.TEST as any,
          isEnabled: true,
          actions: {
            get: [BaseRole.STUDENT, BaseRole.EMPLOYEE],
            post: [BaseRole.ADMIN, BaseRole.UNVERIFIED_GUEST],
            update: [],
            del: [BaseRole.ADMIN, BaseRole.UNVERIFIED_GUEST, BaseRole.STUDENT],
          },
        },
      ];

      jest
        .spyOn(hubService, 'getModules')
        .mockImplementation(() => moduleInfos);

      const results: IHubModule[] = [
        {
          name: ModuleNameTest.TEST as any,
          isEnabled: true,
          actions: {
            post: [BaseRole.ADMIN, BaseRole.UNVERIFIED_GUEST],
            del: [BaseRole.ADMIN, BaseRole.UNVERIFIED_GUEST, BaseRole.STUDENT],
          },
        },
         {
          name: ModuleNameTest.TEST as any,
          isEnabled: true,
          actions: {
            get: [BaseRole.STUDENT, BaseRole.EMPLOYEE],
            del: [BaseRole.ADMIN, BaseRole.UNVERIFIED_GUEST, BaseRole.STUDENT],
          },
        },
       ]

      expect(
        hubService.getAvailableModulesAndActionsWithRoles([
          BaseRole.ADMIN,
          BaseRole.STUDENT,
        ]),
      ).toStrictEqual(results);
    });

修正后的实现代码

getAvailableModulesAndActionsWithRoles(roles: string[]): IHubModule[] {
    return this.getModules()
      // 过滤启用的模块
      .filter(module => module.isEnabled)
      // 为每个模块生成新对象,避免修改原数据
      .map(module => {
        // 过滤出对任一指定角色可用的action
        const filteredActions = Object.fromEntries(
          Object.entries(module.actions).filter(([_, allowedRoles]) => {
            // 判断是否存在至少一个传入角色在允许列表中
            return roles.some(role => allowedRoles.includes(role));
          })
        );

        return {
          ...module,
          actions: filteredActions
        };
      });
  }

改动说明

  1. 避免副作用:不修改原模块对象,通过扩展运算符(...)生成新对象,防止污染原始数据
  2. 修正权限判断逻辑:使用roles.some()判断该action是否对任一传入角色开放,替代原有的逐个角色删除逻辑
  3. 高效过滤action:用Object.entries()+filter()+Object.fromEntries()组合,直接生成过滤后的actions对象,逻辑更清晰
  4. 链式调用简化代码:将过滤、映射操作链式调用,代码更简洁易读

测试验证

修正后的代码可以正确通过测试用例:当传入[BaseRole.ADMIN, BaseRole.STUDENT]时,会保留get(对STUDENT开放)、post(对ADMIN开放)、del(对两个角色都开放)的action,与预期结果一致。

内容的提问来源于stack exchange,提问作者Ibrahim

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 08:20:24