一个用户对于一个资源的是否具有一系列操作权限的判断的重构

1、在获取资源列表的接口中,响应参数:actions,决定了当前用户对于一个资源的是否具有某个操作权限,值为 1 表示具有,值为 0 表示不具有。如图1

图1

    "actions": {
        "enable": 0,
        "plan_task_create": 0,
        "disable": 1,
        "edit": 1,
        "update": 1,
        "submit": 1,
        "pass": 0,
        "refuse": 0,
        "return": 0,
        "view": 1,
        "delete": 1,
        "plan_task_index": 0,
        "review_opinion": 0,
        "invite": 0,
        "invite_accept": 0,
        "invite_refuse": 0,
        "plan_log_index": 1,
        "plan_resource_index": 0
    },

2、接口文档说明,如图2

图2

3、当调用删除资源的接口时,判断用户是否具有资源的操作权限:删除选题,删除 2 个资源,如图3

图3

        // 判断用户是否具有资源的操作权限:删除选题(场景:编辑选题、指派任务等操作时,判断选题ID的存在性、操作按钮的显示与否(我的选题(获取选题列表)))
        PlanService::isActionAllow(explode(';', $id), Plan::ACTION_DELETE, $identity);

4、判断逻辑分为 2 个步骤,第 1 个步骤为:判断用户是否为选题的所有者(场景:编辑选题、指派任务等操作时,判断选题ID的存在性(我的选题(获取选题列表))),即资源列表中是否存在对应的资源 ID,如果不存在,则抛出异常,SQL 如下

    /**
     * 判断用户是否为选题的所有者(场景:编辑选题、指派任务等操作时,判断选题ID的存在性(我的选题(获取选题列表)))
     *
     * @param array $ids 多个选题ID
     * 格式如下:[1, 2, 3]
     * @param object $identity 当前用户的身份实例
     *
     * @return array $models 多个选题对象
     *
     * @throws NotFoundHttpException if the model cannot be found
     */    public static function isHaveIdentityOwner($ids, $identity) {
        /* @var $haveQuery PlanQuery */        // 获取查询对象(我的选题(获取选题列表))
        $haveQuery = Plan::getHaveQuery($identity);

        $models = $haveQuery
            ->orderBy([Plan::tableName() . '.id' => SORT_DESC])
            ->andWhere(['in', Plan::tableName() . '.id', $ids])
            ->indexBy('id')
            ->all();

        if (!empty($models)) {
            // ID的数量与模型资源数量是否相等,如果不相等,响应失败
            $flipIds = array_flip($ids);
            if (count($models) == count($flipIds)) {
                return $models;
            } else {
                $ids = implode(';', array_keys(array_diff_key($flipIds, $models)));
            }
        } else {
            $ids = implode(';', $ids);
        }

        throw new NotFoundHttpException(Yii::t('error', Yii::t('error', Yii::t('error', '202080'), ['ids' => $ids])), 202080);
    }
SELECT `pa_plan`.* FROM `pa_plan` LEFT JOIN `pa_config_column` ON `pa_plan`.`config_column_id` = `pa_config_column`.`id` LEFT JOIN `pa_config_column_user` `ccu_plan_create` ON `pa_plan`.`config_column_id` = `ccu_plan_create`.`config_column_id` AND `pa_plan`.`create_user_id` = `ccu_plan_create`.`user_id` LEFT JOIN `pa_plan_attended_user_relation` ON `pa_plan`.`id` = `pa_plan_attended_user_relation`.`plan_id` LEFT JOIN `pa_config_column_user` `ccu_plan_relation` ON `pa_plan_attended_user_relation`.`config_column_id` = `ccu_plan_relation`.`config_column_id` AND `pa_plan_attended_user_relation`.`relation_user_id` = `ccu_plan_relation`.`user_id` LEFT JOIN `pa_plan_group_relation` ON `pa_plan`.`id` = `pa_plan_group_relation`.`plan_id` LEFT JOIN `pa_config_column_user` `ccu_plan_accepted` ON `pa_plan_group_relation`.`config_column_id` = `ccu_plan_accepted`.`config_column_id` AND `pa_plan_group_relation`.`accepted_user_id` = `ccu_plan_accepted`.`user_id` WHERE (`pa_config_column`.`is_deleted`=0) AND (`pa_plan`.`is_deleted`=0) AND (((`pa_plan`.`group_id`='c10e87f39873512a16727e17f57456a5') AND (`pa_plan`.`create_user_id`='1') AND (`ccu_plan_create`.`is_deleted`=0)) OR ((`pa_plan`.`group_id`='c10e87f39873512a16727e17f57456a5') AND (`pa_plan_attended_user_relation`.`relation_user_id`='1') AND (FIND_IN_SET('1', `pa_plan_attended_user_relation`.role)) AND (`pa_plan_attended_user_relation`.`is_deleted`=0) AND (`ccu_plan_relation`.`is_deleted`=0)) OR ((`pa_plan`.`group_id`='c10e87f39873512a16727e17f57456a5') AND (`pa_plan`.`config_column_id`=2)) OR ((`pa_plan`.`is_not_isolated`=1) AND (`pa_plan_group_relation`.`relation_group_id`='c10e87f39873512a16727e17f57456a5') AND (`pa_plan_group_relation`.`is_inviter`=0) AND (`pa_plan_group_relation`.`is_deleted`=0) AND ((`pa_plan_group_relation`.`accepted_status` IN (0, 2)) OR ((`pa_plan_group_relation`.`accepted_status`=1) AND (`pa_plan_group_relation`.`accepted_user_id`='1') AND (`ccu_plan_accepted`.`is_deleted`=0)) OR ((`pa_plan_group_relation`.`accepted_status`=1) AND (`pa_plan`.`config_column_id`=2))))) AND (`pa_plan`.`id` IN ('38', '39')) GROUP BY `pa_plan`.`id` ORDER BY `pa_plan`.`id` DESC

5、如果需要删除的资源 ID 皆存在资源列表中,即确认用户为资源的所有者。判断用户是否具有资源的操作权限(场景:编辑选题、指派任务等操作时,判断操作按钮的显示与否(我的选题(获取选题列表)))。如果不具有,则抛出异常,如果具有,由执行后续的操作。

    /**
     * 判断用户是否具有资源的操作权限(场景:编辑选题、指派任务等操作时,判断操作按钮的显示与否(我的选题(获取选题列表)))
     *
     * @param array|object $item 选题数组
     * @param string $action 资源的操作权限
     * 格式如下:update
     * @param array $configColumns 栏目配置列表
     * @param int $configColumnUserStatus 栏目人员状态
     * @param array $planTaskCreatePlanAttendedUserRelations 基于 关联的用户ID、角色包含执行(负责)、多个选题ID 查找资源列表(场景:我的选题列表中,当前用户可指派任务的资源列表)
     * @param array $inviteAcceptPlanGroupRelations 基于 关联的租户ID、多个选题ID 查找资源列表(场景:我的选题列表中,当前租户可接受邀请/拒绝邀请的资源列表)
     * @param array $planTaskCreatePlanGroupRelations 基于 关联的租户ID、多个选题ID 查找资源列表(场景:我的选题列表中,当前租户可指派任务的资源列表)
     * @param array $isColumnManagerPlanIds 当前用户身为栏目负责人下的选题ID列表
     * @param object $identity 当前用户的身份实例
     *
     * @return int $isActionShow 0:无;1:有
     */    public static function isActionShow($item, $action, $configColumns, $configColumnUserStatus, $planTaskCreatePlanAttendedUserRelations, $inviteAcceptPlanGroupRelations, $planTaskCreatePlanGroupRelations, $isColumnManagerPlanIds, $identity) {
        $isActionShow = 0;
        if ($action == Plan::ACTION_ENABLE) {
            // 启用选题的权限,0:无;1:有(选题的租户ID为当前租户ID && 栏目状态,1:启用 && 栏目人员状态,1:启用 && (选题创建用户ID为当前登录用户ID || 栏目人员配置角色标识包含栏目负责人标识) && 选题状态,0:禁用)
            if ($item['group_id'] == $identity->group_id && $configColumns[$item['config_column_id']]['status'] == ConfigColumn::STATUS_ENABLED && $configColumnUserStatus == ConfigColumnUser::STATUS_ENABLED && ($item['create_user_id'] == $identity->id || in_array($item['id'], $isColumnManagerPlanIds)) && $item['status'] == Plan::STATUS_DISABLED) {
                $isActionShow = 1;
            }
        } elseif ($action == Plan::ACTION_PLAN_TASK_CREATE) {
            // 指派任务的权限,0:无;1:有(栏目状态,1:启用 && 栏目人员状态,1:启用 && ((选题的租户ID为当前租户ID && 选题与参与用户的关联模型的关联的用户ID为当前登录用户ID && 选题与参与用户的关联模型的角色包含执行(负责) && 选题与参与用户的关联模型是否被删除,0:否 && 栏目人员是否被删除,0:否) || 栏目人员配置角色标识包含栏目负责人标识) && 选题状态,3:通过;5:指派;6:完成 && (选题的租户ID为当前租户ID || (选题的是否联合,1:是 && 选题与租户的关联模型的关联的租户ID为当前租户ID && 选题与租户的关联模型的是否邀请者,0:否 && 选题与租户的关联模型的接受状态,1:已接受 && 选题与租户的关联模型是否被删除,0:否 && 选题与租户的关联模型的状态,1:启用)))
            if ($configColumns[$item['config_column_id']]['status'] == ConfigColumn::STATUS_ENABLED && $configColumnUserStatus == ConfigColumnUser::STATUS_ENABLED && (isset($planTaskCreatePlanAttendedUserRelations[$item['id']]) || in_array($item['id'], $isColumnManagerPlanIds)) && in_array($item['status'], [Plan::STATUS_PASSED, Plan::STATUS_ASSIGNED, Plan::STATUS_COMPLETED]) && ($item['group_id'] == $identity->group_id || isset($planTaskCreatePlanGroupRelations[$item['id']]))) {
                $isActionShow = 1;
            }
        } elseif ($action == Plan::ACTION_DISABLE) {
            // 禁用选题的权限,0:无;1:有(选题的租户ID为当前租户ID && 栏目状态,1:启用 && 栏目人员状态,1:启用 && (选题创建用户ID为当前登录用户ID || 栏目人员配置角色标识包含栏目负责人标识) && 选题状态,1:编辑;2:待审;3:通过;4:拒绝;5:指派;6:完成)
            if ($item['group_id'] == $identity->group_id && $configColumns[$item['config_column_id']]['status'] == ConfigColumn::STATUS_ENABLED && $configColumnUserStatus == ConfigColumnUser::STATUS_ENABLED && ($item['create_user_id'] == $identity->id || in_array($item['id'], $isColumnManagerPlanIds)) && in_array($item['status'], [Plan::STATUS_EDITED, Plan::STATUS_WAITING_REVIEW, Plan::STATUS_PASSED, Plan::STATUS_REFUSED, Plan::STATUS_ASSIGNED, Plan::STATUS_COMPLETED])) {
                $isActionShow = 1;
            }
        } elseif ($action == Plan::ACTION_EDIT) {
            // 编辑选题的权限,0:无;1:有(选题的租户ID为当前租户ID && 栏目状态,1:启用 && 栏目人员状态,1:启用 && (选题创建用户ID为当前登录用户ID || 栏目人员配置角色标识包含栏目负责人标识) && 选题状态,1:编辑;2:待审;3:通过;4:拒绝;5:指派;6:完成)
            if ($item['group_id'] == $identity->group_id && $configColumns[$item['config_column_id']]['status'] == ConfigColumn::STATUS_ENABLED && $configColumnUserStatus == ConfigColumnUser::STATUS_ENABLED && ($item['create_user_id'] == $identity->id || in_array($item['id'], $isColumnManagerPlanIds)) && in_array($item['status'], [Plan::STATUS_EDITED, Plan::STATUS_WAITING_REVIEW, Plan::STATUS_PASSED, Plan::STATUS_REFUSED, Plan::STATUS_ASSIGNED, Plan::STATUS_COMPLETED])) {
                $isActionShow = 1;
            }
        } elseif ($action == Plan::ACTION_UPDATE) {
            // 更新选题的权限,0:无;1:有(选题的租户ID为当前租户ID && 栏目状态,1:启用 && 栏目人员状态,1:启用 && (选题创建用户ID为当前登录用户ID || 栏目人员配置角色标识包含栏目负责人标识) && 选题状态,1:编辑;2:待审;3:通过;4:拒绝;5:指派;6:完成)
            if ($item['group_id'] == $identity->group_id && $configColumns[$item['config_column_id']]['status'] == ConfigColumn::STATUS_ENABLED && $configColumnUserStatus == ConfigColumnUser::STATUS_ENABLED && ($item['create_user_id'] == $identity->id || in_array($item['id'], $isColumnManagerPlanIds)) && in_array($item['status'], [Plan::STATUS_EDITED, Plan::STATUS_WAITING_REVIEW, Plan::STATUS_PASSED, Plan::STATUS_REFUSED, Plan::STATUS_ASSIGNED, Plan::STATUS_COMPLETED])) {
                $isActionShow = 1;
            }
        } elseif ($action == Plan::ACTION_SUBMIT) {
            // 提交审核选题的权限,0:无;1:有(选题的租户ID为当前租户ID && 栏目状态,1:启用 && 栏目人员状态,1:启用 && (选题创建用户ID为当前登录用户ID || 栏目人员配置角色标识包含栏目负责人标识) && 选题状态,1:编辑;4:拒绝)
            if ($item['group_id'] == $identity->group_id && $configColumns[$item['config_column_id']]['status'] == ConfigColumn::STATUS_ENABLED && $configColumnUserStatus == ConfigColumnUser::STATUS_ENABLED && ($item['create_user_id'] == $identity->id || in_array($item['id'], $isColumnManagerPlanIds)) && in_array($item['status'], [Plan::STATUS_EDITED, Plan::STATUS_REFUSED])) {
                $isActionShow = 1;
            }
        } elseif ($action == Plan::ACTION_PASS) {
            // 通过选题的权限,0:无;1:有(选题的租户ID为当前租户ID && 栏目状态,1:启用 && 栏目人员状态,1:启用 && 栏目人员配置角色标识包含栏目负责人标识 && 选题状态,2:待审)
            if ($item['group_id'] == $identity->group_id && $configColumns[$item['config_column_id']]['status'] == ConfigColumn::STATUS_ENABLED && $configColumnUserStatus == ConfigColumnUser::STATUS_ENABLED && in_array($item['id'], $isColumnManagerPlanIds) && $item['status'] == Plan::STATUS_WAITING_REVIEW) {
                $isActionShow = 1;
            }
        } elseif ($action == Plan::ACTION_REFUSE) {
            // 拒绝选题的权限,0:无;1:有(选题的租户ID为当前租户ID && 栏目状态,1:启用 && 栏目人员状态,1:启用 && 栏目人员配置角色标识包含栏目负责人标识 && 选题状态,2:待审)
            if ($item['group_id'] == $identity->group_id && $configColumns[$item['config_column_id']]['status'] == ConfigColumn::STATUS_ENABLED && $configColumnUserStatus == ConfigColumnUser::STATUS_ENABLED && in_array($item['id'], $isColumnManagerPlanIds) && $item['status'] == Plan::STATUS_WAITING_REVIEW) {
                $isActionShow = 1;
            }
        } elseif ($action == Plan::ACTION_RETURN) {
            // 退回选题的权限,0:无;1:有(选题的租户ID为当前租户ID && 栏目状态,1:启用 && 栏目人员状态,1:启用 && 栏目人员配置角色标识包含栏目负责人标识 && 选题状态,3:通过;5:指派)
            if ($item['group_id'] == $identity->group_id && $configColumns[$item['config_column_id']]['status'] == ConfigColumn::STATUS_ENABLED && $configColumnUserStatus == ConfigColumnUser::STATUS_ENABLED && in_array($item['id'], $isColumnManagerPlanIds) && in_array($item['status'], [Plan::STATUS_PASSED, Plan::STATUS_ASSIGNED])) {
                $isActionShow = 1;
            }
        } elseif ($action == Plan::ACTION_VIEW) {
            // 详情的权限,0:无;1:有()
            $isActionShow = 1;
        } elseif ($action == Plan::ACTION_DELETE) {
            // 删除选题的权限,0:无;1:有(选题的租户ID为当前租户ID && (选题创建用户ID为当前登录用户ID || 栏目人员配置角色标识包含栏目负责人标识))
            if($item['group_id'] == $identity->group_id && ($item['create_user_id'] == $identity->id || in_array($item['id'], $isColumnManagerPlanIds))){
                $isActionShow = 1;
            }
        } elseif ($action == Plan::ACTION_PLAN_TASK_INDEX) {
            // 相关任务的权限,0:无;1:有(选题状态,3:通过;5:指派;6:完成)
            if (in_array($item['status'], [Plan::STATUS_PASSED, Plan::STATUS_ASSIGNED, Plan::STATUS_COMPLETED])) {
                $isActionShow = 1;
            }
        } elseif ($action == Plan::ACTION_REVIEW_OPINION) {
            // 审核意见的权限,0:无;1:有(选题的租户ID为当前租户ID && 栏目状态,1:启用 && 栏目人员状态,1:启用 && (选题创建用户ID为当前登录用户ID || 栏目人员配置角色标识包含栏目负责人标识) && 选题状态,4:拒绝)
            if ($item['group_id'] == $identity->group_id && $configColumns[$item['config_column_id']]['status'] == ConfigColumn::STATUS_ENABLED && $configColumnUserStatus == ConfigColumnUser::STATUS_ENABLED && ($item['create_user_id'] == $identity->id || in_array($item['id'], $isColumnManagerPlanIds)) && $item['status'] == Plan::STATUS_REFUSED) {
                $isActionShow = 1;
            }
        } elseif ($action == Plan::ACTION_INVITE) {
            // 邀请的权限,0:无;1:有(选题的租户ID为当前租户ID && 栏目状态,1:启用 && 栏目人员状态,1:启用 && (选题创建用户ID为当前登录用户ID || 栏目人员配置角色标识包含栏目负责人标识) && 选题的是否联合,1:是 && 选题状态,3:通过;5:指派;6:完成)
            if ($item['group_id'] == $identity->group_id && $configColumns[$item['config_column_id']]['status'] == ConfigColumn::STATUS_ENABLED && $configColumnUserStatus == ConfigColumnUser::STATUS_ENABLED && ($item['create_user_id'] == $identity->id || in_array($item['id'], $isColumnManagerPlanIds)) && $item['is_united'] == Plan::IS_UNITED_YES && in_array($item['status'], [Plan::STATUS_PASSED, Plan::STATUS_ASSIGNED, Plan::STATUS_COMPLETED])) {
                $isActionShow = 1;
            }
        } elseif ($action == Plan::ACTION_INVITE_ACCEPT) {
            // 同意邀请的权限,0:无;1:有
            if ($configColumns[$item['config_column_id']]['status'] == ConfigColumn::STATUS_ENABLED && isset($inviteAcceptPlanGroupRelations[$item['id']]) && in_array($item['status'], [Plan::STATUS_PASSED, Plan::STATUS_ASSIGNED, Plan::STATUS_COMPLETED])) {
                $isActionShow = 1;
            }
        } elseif ($action == Plan::ACTION_INVITE_REFUSE) {
            // 拒绝邀请的权限,0:无;1:有
            if ($configColumns[$item['config_column_id']]['status'] == ConfigColumn::STATUS_ENABLED && isset($inviteAcceptPlanGroupRelations[$item['id']]) && in_array($item['status'], [Plan::STATUS_PASSED, Plan::STATUS_ASSIGNED, Plan::STATUS_COMPLETED])) {
                $isActionShow = 0;
            }
        } elseif ($action == Plan::ACTION_PLAN_LOG_INDEX) {
            // 选题日志的权限,0:无;1:有()
            $isActionShow = 1;
        } elseif ($action == Plan::ACTION_PLAN_RESOURCE_INDEX) {
            // 选题素材的权限,0:无;1:有(选题状态,5:指派;6:完成)
            if (in_array($item['status'], [Plan::STATUS_ASSIGNED, Plan::STATUS_COMPLETED])) {
                $isActionShow = 1;
            }
        }
        return $isActionShow;
    }

6、由于新增加了选题资源的一些列表接口,因此,导致第 1 个步骤:判断用户是否为选题的所有者(场景:编辑选题、指派任务等操作时,判断选题ID的存在性(我的选题(获取选题列表))),需要兼容多个列表,进而导致多个 SQL。存在一定的难度,而且后续不可控。因此,最终决定,简化第 1 个步骤,完善第 2 个步骤。如图4

图4

7、以启用选题举例,调整前的规则:

( 7 ) actions['enable']:启用选题
( 
    选题的租户ID为当前租户ID &&
    栏目状态,1:启用 &&
    栏目人员状态,1:启用 &&
    (
        选题创建用户ID为当前登录用户ID ||
        栏目人员配置角色标识包含栏目负责人标识
    ) &&
    选题状态,0:禁用
)
    if ($item['group_id'] == $identity->group_id && $configColumns[$item['config_column_id']]['status'] == ConfigColumn::STATUS_ENABLED && $configColumnUserStatus == ConfigColumnUser::STATUS_ENABLED && ($item['create_user_id'] == $identity->id || in_array($item['id'], $isColumnManagerPlanIds)) && $item['status'] == Plan::STATUS_DISABLED) {
        $isActionShow = 1;
    }

8、以启用选题举例,调整后的规则:

( 7 ) actions['enable']:启用选题
(
    选题状态,0:禁用 &&
    (
        是否下发,0:否 && 
        栏目是否被删除,0:否 &&
        栏目人员是否被删除,0:否 &&
        栏目状态,1:启用 &&
        栏目人员状态,1:启用 &&
        选题的租户ID为当前租户ID &&
        (
            选题创建用户ID为当前登录用户ID ||
            栏目人员配置角色标识包含栏目负责人标识
        )
    ) ||
    (
        是否下发,1:是 &&
        选题的租户ID为当前租户ID &&
        选题创建用户ID为当前登录用户ID
    )
)
    if ($item['status'] == Plan::STATUS_DISABLED &&
        (
            $item['is_send_down'] == Plan::IS_SEND_DOWN_NO &&
            $configColumnIsDeleted == ConfigColumn::IS_DELETED_NO &&
            $configColumnUserIsDeleted == ConfigColumnUser::IS_DELETED_NO &&
            $configColumnStatus == ConfigColumn::STATUS_ENABLED &&
            $configColumnUserStatus == ConfigColumnUser::STATUS_ENABLED &&
            $item['group_id'] == $identity->group_id &&
            (
                $item['create_user_id'] == $identity->id ||
                in_array($item['id'], $isColumnManagerPlanIds)
            )
        ) ||
        (
            $item['is_send_down'] == Plan::IS_SEND_DOWN_YES &&
            $item['group_id'] == $identity->group_id &&
            $item['create_user_id'] == $identity->id
        )
    ) {
        $isActionShow = 1;
    }

9、删除 16 与 43 时,由于第 1 个步骤验证失败,响应如下,如图5

图5

{
    "name": "Not Found",
    "message": "选题ID:16,不存在于我的选题列表中",
    "code": 202080,
    "status": 404,
    "type": "yii\\web\\NotFoundHttpException"
}

10、简化第 1 个步骤,且调整第 2 个步骤后,删除 16 与 43 时,由于由于第 1 个步骤验证成功,且第 2 个步骤验证失败,响应如下,如图6

图6


    /**
     * 判断用户是否为选题的所有者(场景:编辑选题、指派任务等操作时,判断选题ID的存在性(我的选题、待审核选题、相关选题)))
     *
     * @param array $ids 多个选题ID
     * 格式如下:[1, 2, 3]
     *
     * @return array $models 多个选题对象
     *
     * @throws NotFoundHttpException if the model cannot be found
     */    public static function isIndexIdentityOwner($ids) {
        $models = Plan::find()
            ->where(['in', Plan::tableName() . '.id', $ids])
            ->isDeletedNo()
            ->indexBy('id')
            ->all();

        if (!empty($models)) {
            // ID的数量与模型资源数量是否相等,如果不相等,响应失败
            $flipIds = array_flip($ids);
            if (count($models) == count($flipIds)) {
                return $models;
            } else {
                $ids = implode(';', array_keys(array_diff_key($flipIds, $models)));
            }
        } else {
            $ids = implode(';', $ids);
        }

        throw new NotFoundHttpException(Yii::t('error', Yii::t('error', Yii::t('error', '202080'), ['ids' => $ids])), 202080);
    }

    /**
     * 判断用户是否具有资源的操作权限(场景:编辑选题、指派任务等操作时,判断选题ID的存在性、操作按钮的显示与否(我的选题(获取选题列表)))
     *
     * @param array $ids 多个选题ID
     * 格式如下:[1, 2, 3]
     * @param string $action 资源的操作权限
     * 格式如下:update
     * @param object $identity 当前用户的身份实例
     *
     * @return bool
     *
     * @throws NotFoundHttpException if the model cannot be found
     * @throws UnprocessableEntityHttpException
     */    public static function isActionAllow($ids, $action, $identity) {
        // 判断用户是否为选题的所有者(场景:编辑选题、指派任务等操作时,判断选题ID的存在性(我的选题、待审核选题、相关选题)))
        $models = static::isIndexIdentityOwner($ids);

        $serialize = static::getPlanSerializer($models, $identity);

        /* 查询当前分页的栏目配置列表 */        $configColumns = $serialize['configColumns'];

        /* 查询当前分页的栏目人员配置列表 */        $configColumnUsers = $serialize['configColumnUsers'];

        // 基于 关联的用户ID、角色包含执行(负责)、多个选题ID 查找资源列表(场景:我的选题列表中,当前用户可指派任务的资源列表)
        $planTaskCreatePlanAttendedUserRelations = $serialize['planTaskCreatePlanAttendedUserRelations'];

        // 基于 关联的租户ID、多个选题ID 查找资源列表(场景:我的选题列表中,当前租户可接受邀请/拒绝邀请的资源列表)
        $inviteAcceptPlanGroupRelations = $serialize['inviteAcceptPlanGroupRelations'];

        // 基于 关联的租户ID、多个选题ID 查找资源列表(场景:我的选题列表中,当前租户可指派任务的资源列表)
        $planTaskCreatePlanGroupRelations = $serialize['planTaskCreatePlanGroupRelations'];

        /* 查询多个选题对象的角色包含执行(负责)、状态为启用的选题与参与用户的关联列表 */        $planAttendedUserRoleExecs = $serialize['planAttendedUserRoleExecs'];

        /* 查询当前分页的框架服务控制台用户列表 */        $redisCmcConsoleUsers = $serialize['redisCmcConsoleUsers'];

        /* 当前用户身为栏目负责人下的选题ID列表 */        $isColumnManagerPlanIds = $serialize['isColumnManagerPlanIds'];

        // 不具有相关操作权限的选题ID
        $ids = [];
        /* @var $model Plan */        foreach ($models as $key => $model) {

            // 栏目人员状态
            $configColumnUserStatus = $configColumnUsers[$model->config_column_id . '_' . $identity->id]['status'] ?? ConfigColumnUser::STATUS_DISABLED;

            // 权限,0:无;1:有
            $isActionAllow = static::isActionShow($model, $action, $configColumns, $configColumnUsers, $planTaskCreatePlanAttendedUserRelations, $inviteAcceptPlanGroupRelations, $planTaskCreatePlanGroupRelations, $isColumnManagerPlanIds, $identity);

            if ($isActionAllow == 0) {
                $ids[] = $model->id;
            }
        }

        if (!empty($ids)) {
            $ids = implode(';', $ids);
            throw new UnprocessableEntityHttpException(Yii::t('error', Yii::t('error', Yii::t('error', '202081'), ['ids' => $ids, 'action' => $action])), 202081);
        }

        return true;
    }
SELECT * FROM `pa_plan` WHERE (`pa_plan`.`id` IN ('16', '43')) AND (`is_deleted`=0)
{
    "name": "Unprocessable entity",
    "message": "当前用户不具有选题ID:16,的权限:enable",
    "code": 202081,
    "status": 422,
    "type": "yii\\web\\UnprocessableEntityHttpException"
}

11、其他的操作权限皆遵循上述类似的规则调整。便能够实现完整的操作权限控制,且降低了判断的性能开销。

永夜