From a87fcc60346dfc799bd3c2cddc7acfffb105cb61 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期二, 13 十月 2026 14:34:00 +0800
Subject: [PATCH] feat(crm): 客户公海可见度控制功能实现
---
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/framework/permission/core/aop/CrmPermissionAspect.java | 73 +++++++++++++++++++++++++++++++++---
1 files changed, 66 insertions(+), 7 deletions(-)
diff --git a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/framework/permission/core/aop/CrmPermissionAspect.java b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/framework/permission/core/aop/CrmPermissionAspect.java
index d490258..417e5f8 100644
--- a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/framework/permission/core/aop/CrmPermissionAspect.java
+++ b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/framework/permission/core/aop/CrmPermissionAspect.java
@@ -5,7 +5,10 @@
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.dal.mysql.customer.CrmCustomerMapper;
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;
@@ -22,6 +25,7 @@
import java.util.*;
+import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
@@ -43,6 +47,12 @@
@Resource
private AdminUserApi adminUserApi;
+ @Resource
+ private CrmBusinessMapper businessMapper;
+
+ @Resource
+ private CrmCustomerMapper customerMapper;
+
@Before("@annotation(crmPermission)")
public void doBefore(JoinPoint joinPoint, CrmPermission crmPermission) {
// 1.1 鑾峰彇鐩稿叧灞炴�у��
@@ -51,6 +61,9 @@
crmPermission.bizType()[0].getType() : (Integer) expressionValues.get(crmPermission.bizTypeValue()); // 妯″潡绫诲瀷
// 1.2 澶勭悊鍏煎澶氫釜 bizId 鐨勬儏鍐�
Object object = expressionValues.get(crmPermission.bizId()); // 妯″潡鏁版嵁缂栧彿
+ if (object == null) {
+ throw exception(BAD_REQUEST);
+ }
Set<Long> bizIds = new HashSet<>();
if (object instanceof Collection<?>) {
bizIds.addAll(convertSet((Collection<?>) object, item -> Long.parseLong(item.toString())));
@@ -62,10 +75,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;
@@ -73,19 +86,19 @@
// 鐗规畩锛氭病鏈夋暟鎹潈闄愮殑鎯呭喌锛岄拡瀵� READ 鐨勭壒娈婂鐞�
if (CollUtil.isEmpty(bizPermissions)) {
// 1.1 鍏捣鏁版嵁锛屽鏋滄病鏈夊洟闃熸垚鍛橈紝澶у涔熷簲璇ユ湁 READ 鏉冮檺鎵嶅
- if (CrmPermissionLevelEnum.isRead(permissionLevel)) {
+ if (CrmPermissionLevelEnum.isRead(permissionLevel) && isPublicPoolVisible(bizType, bizId)) {
return;
}
// 娌℃湁鏁版嵁鏉冮檺鐨勬儏鍐典笅瓒呭嚭浜嗚鏉冮檺鐩存帴鎶ラ敊锛岄伩鍏嶅悗闈㈡牎楠岀┖鎸囬拡
throw exception(CRM_PERMISSION_DENIED, CrmBizTypeEnum.getNameByType(bizType));
} else { // 1.2 鏈夋暟鎹潈闄愪絾鏄病鏈夎礋璐d汉鐨勬儏鍐�
if (!anyMatch(bizPermissions, item -> CrmPermissionLevelEnum.isOwner(item.getLevel()))
- && CrmPermissionLevelEnum.isRead(permissionLevel)) {
+ && CrmPermissionLevelEnum.isRead(permissionLevel) && isPublicPoolVisible(bizType, bizId)) {
return;
}
}
- // 2. 鍙�冭檻鑷殑韬潈闄�
+ // 2. 鍙�冭檻鑷韩鐨勬潈闄�
Long userId = getUserId();
CrmPermissionDO userPermission = CollUtil.findOne(bizPermissions, permission -> ObjUtil.equal(permission.getUserId(), userId));
if (userPermission != null) {
@@ -94,7 +107,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,14 +122,53 @@
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));
}
+ /** 鍙栨秷瀹㈡埛鍏捣鍙搴﹀悗锛屼笉鍐嶆巿浜堝叕鍏辫鍙栨潈闄愩�� */
+ private boolean isPublicPoolVisible(Integer bizType, Long bizId) {
+ if (!CrmBizTypeEnum.CRM_CUSTOMER.getType().equals(bizType)) {
+ return true;
+ }
+ var customer = customerMapper.selectById(bizId);
+ return customer != null && !Boolean.FALSE.equals(customer.getAutoPoolEnabled());
+ }
+
+ /** 鍟嗘満鐗规畩鏉冮檺鏍¢獙锛氭鏌ョ敤鎴锋槸鍚︽湁璇ュ晢鏈烘墍灞炲鎴风殑鍥㈤槦鏉冮檺銆� */
+ private boolean validateBusinessCustomerPermission(Long businessId, Long userId, Integer permissionLevel) {
+ // 鑾峰彇鍟嗘満鐨勫鎴稩D
+ 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)) {
+ // 瀹㈡埛鍏捣鏁版嵁锛孯EAD 鏉冮檺鏀捐
+ return CrmPermissionLevelEnum.isRead(permissionLevel)
+ && isPublicPoolVisible(CrmBizTypeEnum.CRM_CUSTOMER.getType(), business.getCustomerId());
+ }
+ // 妫�鏌ョ敤鎴锋槸鍚︽湁瀹㈡埛鍥㈤槦鐨勬潈闄�
+ CrmPermissionDO userCustomerPermission = CollUtil.findOne(customerPermissions,
+ permission -> ObjUtil.equal(permission.getUserId(), userId));
+ if (userCustomerPermission != null && isUserPermissionValid(userCustomerPermission, permissionLevel)) {
+ return true;
+ }
+ return false;
+ }
+
/**
* 鏍¢獙鐢ㄦ埛鏉冮檺鏄惁鏈夋晥
*
--
Gitblit v1.9.3