2 天以前 111270df037596a04df97f787ca8b9199dd99866
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/api/customer/CrmCustomerApiImpl.java
@@ -1,15 +1,25 @@
package cn.iocoder.yudao.module.crm.api.customer;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
import cn.iocoder.yudao.module.crm.api.customer.dto.CrmCustomerRespDTO;
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO;
import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService;
import cn.iocoder.yudao.module.crm.util.CrmPermissionUtils;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.anyMatch;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
/**
 * CRM 客户 API 实现类
@@ -21,6 +31,10 @@
    @Resource
    private CrmCustomerService customerService;
    @Resource
    private CrmPermissionService permissionService;
    @Resource
    private AdminUserApi adminUserApi;
    @Override
    public CrmCustomerRespDTO getCustomer(Long id) {
@@ -30,15 +44,25 @@
    @Override
    public List<CrmCustomerRespDTO> getCustomerList(Collection<Long> ids) {
        if (CollUtil.isEmpty(ids)) {
            return Collections.emptyList();
        }
        List<CrmCustomerDO> customers = customerService.getCustomerList(ids);
        return BeanUtils.toBean(customers, CrmCustomerRespDTO.class);
        // 过滤掉用户没有权限的客户
        List<CrmCustomerDO> filteredCustomers = filterCustomersByPermission(customers);
        return BeanUtils.toBean(filteredCustomers, CrmCustomerRespDTO.class);
    }
    @Override
    public Map<Long, CrmCustomerRespDTO> getCustomerMap(Collection<Long> ids) {
        if (CollUtil.isEmpty(ids)) {
            return Collections.emptyMap();
        }
        List<CrmCustomerDO> customers = customerService.getCustomerList(ids);
        return customers.stream()
                .collect(java.util.stream.Collectors.toMap(
        // 过滤掉用户没有权限的客户
        List<CrmCustomerDO> filteredCustomers = filterCustomersByPermission(customers);
        return filteredCustomers.stream()
                .collect(Collectors.toMap(
                        CrmCustomerDO::getId,
                        customer -> BeanUtils.toBean(customer, CrmCustomerRespDTO.class)));
    }
@@ -49,4 +73,130 @@
        return getCustomer(id);
    }
}
    @Override
    public List<Long> getPermittedCustomerIds() {
        // 1. 超级管理员有所有权限
        if (CrmPermissionUtils.isCrmAdmin()) {
            return null; // null 表示不限制
        }
        Long userId = WebFrameworkUtils.getLoginUserId();
        if (userId == null) {
            return Collections.emptyList();
        }
        // 2. 获取用户自己有权限的客户 ID
        List<CrmPermissionDO> userPermissions = permissionService.getPermissionListByBizTypeAndUserId(
                CrmBizTypeEnum.CRM_CUSTOMER.getType(), userId);
        Set<Long> permittedIds = new HashSet<>(convertSet(userPermissions, CrmPermissionDO::getBizId));
        // 3. 获取用户的下级用户有权限的客户 ID
        List<AdminUserRespDTO> subordinates = adminUserApi.getUserListBySubordinate(userId);
        if (CollUtil.isNotEmpty(subordinates)) {
            Set<Long> subordinateUserIds = convertSet(subordinates, AdminUserRespDTO::getId);
            for (Long subordinateId : subordinateUserIds) {
                List<CrmPermissionDO> subordinatePermissions = permissionService.getPermissionListByBizTypeAndUserId(
                        CrmBizTypeEnum.CRM_CUSTOMER.getType(), subordinateId);
                permittedIds.addAll(convertSet(subordinatePermissions, CrmPermissionDO::getBizId));
            }
        }
        // 4. 查询所有客户,找出公海数据(没有团队成员的客户)
        // 公海数据所有人都有读权限
        List<CrmCustomerDO> allCustomers = customerService.getCustomerList();
        Set<Long> allCustomerIds = convertSet(allCustomers, CrmCustomerDO::getId);
        // 获取有权限配置的客户
        List<CrmPermissionDO> allPermissions = permissionService.getPermissionListByBiz(
                CrmBizTypeEnum.CRM_CUSTOMER.getType(), allCustomerIds);
        Set<Long> hasTeamCustomerIds = convertSet(allPermissions, CrmPermissionDO::getBizId);
        // 公海数据 = 所有客户 - 有团队的客户
        Set<Long> publicSeaCustomerIds = new HashSet<>(allCustomerIds);
        publicSeaCustomerIds.removeAll(hasTeamCustomerIds);
        // 合并:有权限的客户 + 公海客户
        permittedIds.addAll(publicSeaCustomerIds);
        return new ArrayList<>(permittedIds);
    }
    /**
     * 过滤掉用户没有权限的客户
     * <p>
     * 权限判断逻辑:
     * 1. 超级管理员有所有权限
     * 2. 公海数据(没有团队成员)所有人都有读权限
     * 3. 用户自己在团队成员中
     * 4. 用户的下级在团队成员中
     *
     * @param customers 客户列表
     * @return 过滤后的客户列表
     */
    private List<CrmCustomerDO> filterCustomersByPermission(List<CrmCustomerDO> customers) {
        if (CollUtil.isEmpty(customers)) {
            return Collections.emptyList();
        }
        // 1. 超级管理员有所有权限
        if (CrmPermissionUtils.isCrmAdmin()) {
            return customers;
        }
        Long userId = WebFrameworkUtils.getLoginUserId();
        if (userId == null) {
            // 没有登录用户,返回空列表
            return Collections.emptyList();
        }
        // 2. 获取这些客户的权限配置
        Set<Long> customerIds = convertSet(customers, CrmCustomerDO::getId);
        List<CrmPermissionDO> permissionList = permissionService.getPermissionListByBiz(
                CrmBizTypeEnum.CRM_CUSTOMER.getType(), customerIds);
        Map<Long, List<CrmPermissionDO>> permissionMap = permissionList.stream()
                .collect(Collectors.groupingBy(CrmPermissionDO::getBizId));
        // 3. 获取用户的下级用户
        List<AdminUserRespDTO> subordinates = adminUserApi.getUserListBySubordinate(userId);
        Set<Long> subordinateUserIds = convertSet(subordinates, AdminUserRespDTO::getId);
        // 4. 过滤有权限的客户
        return customers.stream()
                .filter(customer -> hasCustomerPermission(customer.getId(), permissionMap, userId, subordinateUserIds))
                .collect(Collectors.toList());
    }
    /**
     * 判断用户是否有客户权限
     */
    private boolean hasCustomerPermission(Long customerId,
                                           Map<Long, List<CrmPermissionDO>> permissionMap,
                                           Long userId,
                                           Set<Long> subordinateUserIds) {
        List<CrmPermissionDO> permissions = permissionMap.get(customerId);
        // 公海数据(没有团队成员),所有人都有读权限
        if (CollUtil.isEmpty(permissions)) {
            return true;
        }
        // 没有负责人的情况,所有人都有读权限
        if (!anyMatch(permissions, item -> item.getLevel() == 1)) { // 1 = 负责人
            return true;
        }
        // 检查用户自己在团队成员中
        if (anyMatch(permissions, item -> item.getUserId().equals(userId))) {
            return true;
        }
        // 检查用户的下级在团队成员中
        for (Long subordinateId : subordinateUserIds) {
            if (anyMatch(permissions, item -> item.getUserId().equals(subordinateId))) {
                return true;
            }
        }
        return false;
    }
}