2 天以前 111270df037596a04df97f787ca8b9199dd99866
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/framework/permission/core/aop/CrmPermissionAspect.java
@@ -5,7 +5,9 @@
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.util.spring.SpringExpressionUtils;
import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO;
import cn.iocoder.yudao.module.crm.dal.mysql.business.CrmBusinessMapper;
import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
import cn.iocoder.yudao.module.crm.framework.permission.core.annotations.CrmPermission;
@@ -43,6 +45,9 @@
    @Resource
    private AdminUserApi adminUserApi;
    @Resource
    private CrmBusinessMapper businessMapper;
    @Before("@annotation(crmPermission)")
    public void doBefore(JoinPoint joinPoint, CrmPermission crmPermission) {
        // 1.1 获取相关属性值
@@ -62,10 +67,10 @@
        // 2. 逐个校验权限
        List<CrmPermissionDO> permissionList = crmPermissionService.getPermissionListByBiz(bizType, bizIds);
        Map<Long, List<CrmPermissionDO>> multiMap = convertMultiMap(permissionList, CrmPermissionDO::getBizId);
        bizIds.forEach(bizId -> validatePermission(bizType, multiMap.get(bizId), permissionLevel));
        bizIds.forEach(bizId -> validatePermission(bizType, bizId, multiMap.get(bizId), permissionLevel));
    }
    private void validatePermission(Integer bizType, List<CrmPermissionDO> bizPermissions, Integer permissionLevel) {
    private void validatePermission(Integer bizType, Long bizId, List<CrmPermissionDO> bizPermissions, Integer permissionLevel) {
        // 1. 如果是超级管理员则直接通过
        if (CrmPermissionUtils.isCrmAdmin()) {
            return;
@@ -85,7 +90,7 @@
            }
        }
        // 2. 只考虑自的身权限
        // 2. 只考虑自身的权限
        Long userId = getUserId();
        CrmPermissionDO userPermission = CollUtil.findOne(bizPermissions, permission -> ObjUtil.equal(permission.getUserId(), userId));
        if (userPermission != null) {
@@ -94,7 +99,14 @@
            }
        }
        // 3. 考虑下级的权限
        // 3. 商机特殊处理:检查客户团队权限
        if (CrmBizTypeEnum.CRM_BUSINESS.getType().equals(bizType)) {
            if (validateBusinessCustomerPermission(bizId, userId, permissionLevel)) {
                return;
            }
        }
        // 4. 考虑下级的权限
        List<AdminUserRespDTO> subordinateUserIds = adminUserApi.getUserListBySubordinate(userId);
        for (Long subordinateUserId : convertSet(subordinateUserIds, AdminUserRespDTO::getId)) {
            CrmPermissionDO subordinatePermission = CollUtil.findOne(bizPermissions,
@@ -102,15 +114,51 @@
            if (subordinatePermission != null && isUserPermissionValid(subordinatePermission, permissionLevel)) {
                return;
            }
            // 商机特殊处理:检查客户团队权限(下属的)
            if (CrmBizTypeEnum.CRM_BUSINESS.getType().equals(bizType)) {
                if (validateBusinessCustomerPermission(bizId, subordinateUserId, permissionLevel)) {
                    return;
                }
            }
        }
        // 4. 没有权限,抛出异常
        // 5. 没有权限,抛出异常
        log.info("[doBefore][userId({}) 要求权限({}) 实际权限({}) 数据校验错误]", // 打个 info 日志,方便后续排查问题、审计
                userId, permissionLevel, toJsonString(userPermission));
        throw exception(CRM_PERMISSION_DENIED, CrmBizTypeEnum.getNameByType(bizType));
    }
    /**
     * 商机特殊权限校验:检查用户是否有该商机所属客户的团队权限
     *
     * @param businessId     商机编号
     * @param userId         用户编号
     * @param permissionLevel 需要的权限级别
     * @return 是否有权限
     */
    private boolean validateBusinessCustomerPermission(Long businessId, Long userId, Integer permissionLevel) {
        // 获取商机的客户ID
        CrmBusinessDO business = businessMapper.selectById(businessId);
        if (business == null || business.getCustomerId() == null) {
            return false;
        }
        // 检查客户团队权限
        List<CrmPermissionDO> customerPermissions = crmPermissionService.getPermissionListByBiz(
                CrmBizTypeEnum.CRM_CUSTOMER.getType(), Collections.singleton(business.getCustomerId()));
        if (CollUtil.isEmpty(customerPermissions)) {
            // 客户公海数据,READ 权限放行
            return CrmPermissionLevelEnum.isRead(permissionLevel);
        }
        // 检查用户是否有客户团队的权限
        CrmPermissionDO userCustomerPermission = CollUtil.findOne(customerPermissions,
                permission -> ObjUtil.equal(permission.getUserId(), userId));
        if (userCustomerPermission != null && isUserPermissionValid(userCustomerPermission, permissionLevel)) {
            return true;
        }
        return false;
    }
    /**
     * 校验用户权限是否有效
     *
     * @param userPermission   用户拥有的权限