From be5783c8a7e13bbc76d33c95643d75779cce21db Mon Sep 17 00:00:00 2001
From: liyong <18434998025@163.com>
Date: 星期六, 18 七月 2026 15:39:05 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev_business' into dev_business

---
 yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/api/customer/CrmCustomerApiImpl.java |  164 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 157 insertions(+), 7 deletions(-)

diff --git a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/api/customer/CrmCustomerApiImpl.java b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/api/customer/CrmCustomerApiImpl.java
index f6d901a..75d0cc3 100644
--- a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/api/customer/CrmCustomerApiImpl.java
+++ b/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);
     }
 
-}
\ No newline at end of file
+    @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;
+    }
+
+}

--
Gitblit v1.9.3