Commit 47a698868c19f6457b19790d1aeaf5d7db2b26f4

Authored by puhui999
1 parent 0043d02d

CRM: 根据 review 完善数据权限

yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/ErrorCodeConstants.java
... ... @@ -74,6 +74,7 @@ public interface ErrorCodeConstants {
74 74 ErrorCode CRM_PERMISSION_DELETE_DENIED = new ErrorCode(1_020_007_006, "删除数据权限失败,原因:没有权限");
75 75 ErrorCode CRM_PERMISSION_DELETE_SELF_PERMISSION_FAIL_EXIST_OWNER = new ErrorCode(1_020_007_007, "删除数据权限失败,原因:不能删除负责人");
76 76 ErrorCode CRM_PERMISSION_CREATE_FAIL = new ErrorCode(1_020_007_008, "创建数据权限失败,原因:所加用户已有权限");
  77 + ErrorCode CRM_PERMISSION_CREATE_FAIL_EXISTS = new ErrorCode(1_020_007_009, "同时添加数据权限失败,原因:用户【{}】已有模块【{}】数据【{}】的【{}】权限");
77 78  
78 79 // ========== 产品 1_020_008_000 ==========
79 80 ErrorCode PRODUCT_NOT_EXISTS = new ErrorCode(1_020_008_000, "产品不存在");
... ...
yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/permission/CrmPermissionLevelEnum.java
1 1 package cn.iocoder.yudao.module.crm.enums.permission;
2 2  
  3 +import cn.hutool.core.collection.CollUtil;
3 4 import cn.hutool.core.util.ObjUtil;
4 5 import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
5 6 import lombok.AllArgsConstructor;
... ... @@ -50,4 +51,10 @@ public enum CrmPermissionLevelEnum implements IntArrayValuable {
50 51 return ObjUtil.equal(WRITE.level, level);
51 52 }
52 53  
  54 + public static String getNameByLevel(Integer level) {
  55 + CrmPermissionLevelEnum typeEnum = CollUtil.findOne(CollUtil.newArrayList(CrmPermissionLevelEnum.values()),
  56 + item -> ObjUtil.equal(item.level, level));
  57 + return typeEnum == null ? null : typeEnum.getName();
  58 + }
  59 +
53 60 }
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/CrmPermissionController.java
1 1 package cn.iocoder.yudao.module.crm.controller.admin.permission;
2 2  
3 3 import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.extra.spring.SpringUtil;
4 5 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
5 6 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
6 7 import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
... ... @@ -56,63 +57,20 @@ public class CrmPermissionController {
56 57 @Resource
57 58 private CrmPermissionService permissionService;
58 59 @Resource
59   - private CrmContactService contactService;
60   - @Resource
61   - private CrmBusinessService businessService;
62   - @Resource
63   - private CrmContractService contractService;
64   - @Resource
65 60 private AdminUserApi adminUserApi;
66 61 @Resource
67 62 private DeptApi deptApi;
68 63 @Resource
69 64 private PostApi postApi;
70 65  
71   - // TODO @puhui999:是不是还是叫 create 好点哈。
72 66 @PostMapping("/create")
73 67 @Operation(summary = "创建数据权限")
74   - @Transactional(rollbackFor = Exception.class)
75 68 @PreAuthorize("@ss.hasPermission('crm:permission:create')")
76   - @CrmPermission(bizTypeValue = "#reqVO.bizType", bizId = "#reqVO.bizId", level = CrmPermissionLevelEnum.OWNER)
77   - public CommonResult<Boolean> savePermission(@Valid @RequestBody CrmPermissionSaveReqVO reqVO) {
78   - permissionService.createPermission(BeanUtils.toBean(reqVO, CrmPermissionCreateReqBO.class));
79   - // 处理【同时添加至】的权限
80   - if (CollUtil.isNotEmpty(reqVO.getToBizTypes())) {
81   - createBizTypePermissions(reqVO);
82   - }
  69 + public CommonResult<Boolean> create(@Valid @RequestBody CrmPermissionSaveReqVO reqVO) {
  70 + permissionService.createPermission(reqVO, getLoginUserId());
83 71 return success(true);
84 72 }
85 73  
86   - private void createBizTypePermissions(CrmPermissionSaveReqVO reqVO) {
87   - List<CrmPermissionCreateReqBO> createPermissions = new ArrayList<>();
88   - // TODO @puhui999:需要考虑,被添加人,是不是应该有对应的权限了;
89   - if (reqVO.getToBizTypes().contains(CrmBizTypeEnum.CRM_CONTACT.getType())) {
90   - List<CrmContactDO> contactList = contactService.getContactListByCustomerIdOwnerUserId(reqVO.getBizId(), getLoginUserId());
91   - contactList.forEach(item -> {
92   - createPermissions.add(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_CONTACT.getType())
93   - .setBizId(item.getId()).setUserId(reqVO.getUserId()).setLevel(reqVO.getLevel()));
94   - });
95   - }
96   - if (reqVO.getToBizTypes().contains(CrmBizTypeEnum.CRM_BUSINESS.getType())) {
97   - List<CrmBusinessDO> businessList = businessService.getBusinessListByCustomerIdOwnerUserId(reqVO.getBizId(), getLoginUserId());
98   - businessList.forEach(item -> {
99   - createPermissions.add(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_BUSINESS.getType())
100   - .setBizId(item.getId()).setUserId(reqVO.getUserId()).setLevel(reqVO.getLevel()));
101   - });
102   - }
103   - if (reqVO.getToBizTypes().contains(CrmBizTypeEnum.CRM_CONTRACT.getType())) {
104   - List<CrmContractDO> contractList = contractService.getContractListByCustomerIdOwnerUserId(reqVO.getBizId(), getLoginUserId());
105   - contractList.forEach(item -> {
106   - createPermissions.add(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_CONTRACT.getType())
107   - .setBizId(item.getId()).setUserId(reqVO.getUserId()).setLevel(reqVO.getLevel()));
108   - });
109   - }
110   - if (CollUtil.isEmpty(createPermissions)) {
111   - return;
112   - }
113   - permissionService.createPermissionBatch(createPermissions);
114   - }
115   -
116 74 @PutMapping("/update")
117 75 @Operation(summary = "编辑数据权限")
118 76 @PreAuthorize("@ss.hasPermission('crm:permission:update')")
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/permission/CrmPermissionMapper.java
... ... @@ -53,9 +53,11 @@ public interface CrmPermissionMapper extends BaseMapperX&lt;CrmPermissionDO&gt; {
53 53 CrmPermissionDO::getUserId, userId);
54 54 }
55 55  
56   - default CrmPermissionDO selectByBizIdAndUserId(Long bizId, Long userId) {
57   - return selectOne(CrmPermissionDO::getBizId, bizId,
58   - CrmPermissionDO::getUserId, userId);
  56 + default CrmPermissionDO selectByBizAndUserId(Integer bizType, Long bizId, Long userId) {
  57 + return selectOne(new LambdaQueryWrapperX<CrmPermissionDO>()
  58 + .eq(CrmPermissionDO::getBizType, bizType)
  59 + .eq(CrmPermissionDO::getBizId, bizId)
  60 + .eq(CrmPermissionDO::getUserId, userId));
59 61 }
60 62  
61 63 default int deletePermission(Integer bizType, Long bizId) {
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionService.java
1 1 package cn.iocoder.yudao.module.crm.service.permission;
2 2  
3 3  
  4 +import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionSaveReqVO;
4 5 import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionUpdateReqVO;
5 6 import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO;
6 7 import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
... ... @@ -22,6 +23,14 @@ public interface CrmPermissionService {
22 23 /**
23 24 * 创建数据权限
24 25 *
  26 + * @param reqVO 创建信息
  27 + * @param userId 用户编号
  28 + */
  29 + void createPermission(CrmPermissionSaveReqVO reqVO, Long userId);
  30 +
  31 + /**
  32 + * 创建数据权限
  33 + *
25 34 * @param createReqBO 创建信息
26 35 * @return 编号
27 36 */
... ... @@ -111,10 +120,10 @@ public interface CrmPermissionService {
111 120 /**
112 121 * 校验是否有指定数据的操作权限
113 122 *
114   - * @param bizType 数据类型,关联 {@link CrmBizTypeEnum}
115   - * @param bizId 数据编号,关联 {@link CrmBizTypeEnum} 对应模块 DO#getId()
116   - * @param userId 用户编号
117   - * @param level 权限级别
  123 + * @param bizType 数据类型,关联 {@link CrmBizTypeEnum}
  124 + * @param bizId 数据编号,关联 {@link CrmBizTypeEnum} 对应模块 DO#getId()
  125 + * @param userId 用户编号
  126 + * @param level 权限级别
118 127 * @return 是否有权限
119 128 */
120 129 boolean hasPermission(Integer bizType, Long bizId, Long userId, CrmPermissionLevelEnum level);
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionServiceImpl.java
... ... @@ -4,28 +4,34 @@ import cn.hutool.core.collection.CollUtil;
4 4 import cn.hutool.core.util.ObjUtil;
5 5 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
6 6 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  7 +import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionSaveReqVO;
7 8 import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionUpdateReqVO;
  9 +import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
  10 +import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO;
  11 +import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
8 12 import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO;
9 13 import cn.iocoder.yudao.module.crm.dal.mysql.permission.CrmPermissionMapper;
10 14 import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
11 15 import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
  16 +import cn.iocoder.yudao.module.crm.framework.permission.core.annotations.CrmPermission;
  17 +import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService;
  18 +import cn.iocoder.yudao.module.crm.service.contact.CrmContactService;
  19 +import cn.iocoder.yudao.module.crm.service.contract.CrmContractService;
12 20 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO;
13 21 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO;
14 22 import cn.iocoder.yudao.module.crm.util.CrmPermissionUtils;
15 23 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
  24 +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
16 25 import jakarta.annotation.Resource;
  26 +import org.springframework.context.annotation.Lazy;
17 27 import org.springframework.stereotype.Service;
18 28 import org.springframework.transaction.annotation.Transactional;
19 29 import org.springframework.validation.annotation.Validated;
20 30  
21   -import java.util.Collection;
22   -import java.util.Collections;
23   -import java.util.List;
24   -import java.util.Set;
  31 +import java.util.*;
25 32  
26 33 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
27   -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.anyMatch;
28   -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
  34 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
29 35 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*;
30 36 import static cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum.isOwner;
31 37  
... ... @@ -40,13 +46,124 @@ public class CrmPermissionServiceImpl implements CrmPermissionService {
40 46  
41 47 @Resource
42 48 private CrmPermissionMapper permissionMapper;
43   -
  49 + @Resource
  50 + @Lazy // 解决依赖循环
  51 + private CrmContactService contactService;
  52 + @Resource
  53 + @Lazy // 解决依赖循环
  54 + private CrmBusinessService businessService;
  55 + @Resource
  56 + @Lazy // 解决依赖循环
  57 + private CrmContractService contractService;
44 58 @Resource
45 59 private AdminUserApi adminUserApi;
46 60  
  61 +
  62 + @Override
  63 + @Transactional(rollbackFor = Exception.class)
  64 + @CrmPermission(bizTypeValue = "#reqVO.bizType", bizId = "#reqVO.bizId", level = CrmPermissionLevelEnum.OWNER)
  65 + public void createPermission(CrmPermissionSaveReqVO reqVO, Long userId) {
  66 + // 创建数据权限
  67 + createPermission0(BeanUtils.toBean(reqVO, CrmPermissionCreateReqBO.class));
  68 +
  69 + // 处理【同时添加至】的权限
  70 + if (CollUtil.isEmpty(reqVO.getToBizTypes())) {
  71 + return;
  72 + }
  73 + List<CrmPermissionCreateReqBO> createPermissions = new ArrayList<>();
  74 + createContactPermissions(reqVO, userId, createPermissions);
  75 + createBusinessPermissions(reqVO, userId, createPermissions);
  76 + createContractPermissions(reqVO, userId, createPermissions);
  77 + if (CollUtil.isEmpty(createPermissions)) {
  78 + return;
  79 + }
  80 + createPermissionBatch(createPermissions);
  81 + }
  82 +
  83 + /**
  84 + * 处理同时添加至联系人
  85 + *
  86 + * @param reqVO 请求
  87 + * @param userId 操作人
  88 + * @param createPermissions 待添加权限列表
  89 + */
  90 + private void createContactPermissions(CrmPermissionSaveReqVO reqVO, Long userId, List<CrmPermissionCreateReqBO> createPermissions) {
  91 + // 1. 校验是否被同时添加
  92 + Integer type = CrmBizTypeEnum.CRM_CONTACT.getType();
  93 + if (!reqVO.getToBizTypes().contains(type)) {
  94 + return;
  95 + }
  96 +
  97 + // 2.1 添加数据权限
  98 + List<CrmContactDO> contactList = contactService.getContactListByCustomerIdOwnerUserId(reqVO.getBizId(), userId);
  99 + contactList.forEach(item -> {
  100 + createBizTypePermissions(reqVO, type, item.getId(), item.getName(), createPermissions);
  101 + });
  102 + }
  103 +
  104 + /**
  105 + * 处理同时添加至商机
  106 + *
  107 + * @param reqVO 请求
  108 + * @param userId 操作人
  109 + * @param createPermissions 待添加权限列表
  110 + */
  111 + private void createBusinessPermissions(CrmPermissionSaveReqVO reqVO, Long userId, List<CrmPermissionCreateReqBO> createPermissions) {
  112 + // 1. 校验是否被同时添加
  113 + Integer type = CrmBizTypeEnum.CRM_BUSINESS.getType();
  114 + if (!reqVO.getToBizTypes().contains(type)) {
  115 + return;
  116 + }
  117 +
  118 + // 2.1 添加数据权限
  119 + List<CrmBusinessDO> businessList = businessService.getBusinessListByCustomerIdOwnerUserId(reqVO.getBizId(), userId);
  120 + businessList.forEach(item -> {
  121 + createBizTypePermissions(reqVO, type, item.getId(), item.getName(), createPermissions);
  122 + });
  123 + }
  124 +
  125 + /**
  126 + * 处理同时添加至合同
  127 + *
  128 + * @param reqVO 请求
  129 + * @param userId 操作人
  130 + * @param createPermissions 待添加权限列表
  131 + */
  132 + private void createContractPermissions(CrmPermissionSaveReqVO reqVO, Long userId, List<CrmPermissionCreateReqBO> createPermissions) {
  133 + // 1. 校验是否被同时添加
  134 + Integer type = CrmBizTypeEnum.CRM_CONTRACT.getType();
  135 + if (!reqVO.getToBizTypes().contains(type)) {
  136 + return;
  137 + }
  138 +
  139 + // 2.1 添加数据权限
  140 + List<CrmContractDO> contractList = contractService.getContractListByCustomerIdOwnerUserId(reqVO.getBizId(), userId);
  141 + contractList.forEach(item -> {
  142 + createBizTypePermissions(reqVO, type, item.getId(), item.getName(), createPermissions);
  143 + });
  144 + }
  145 +
  146 + private void createBizTypePermissions(CrmPermissionSaveReqVO reqVO, Integer type, Long bizId, String name,
  147 + List<CrmPermissionCreateReqBO> createPermissions) {
  148 + AdminUserRespDTO user = adminUserApi.getUser(reqVO.getUserId());
  149 + // 1. 需要考虑,被添加人,是不是应该有对应的权限了;
  150 + CrmPermissionDO permission = hasAnyPermission(type, bizId, reqVO.getUserId());
  151 + if (ObjUtil.isNotNull(permission)) {
  152 + throw exception(CRM_PERMISSION_CREATE_FAIL_EXISTS, user.getNickname(), CrmBizTypeEnum.getNameByType(type),
  153 + name, CrmPermissionLevelEnum.getNameByLevel(permission.getLevel()));
  154 + }
  155 + // 2. 添加数据权限
  156 + createPermissions.add(new CrmPermissionCreateReqBO().setBizType(type)
  157 + .setBizId(bizId).setUserId(reqVO.getUserId()).setLevel(reqVO.getLevel()));
  158 + }
  159 +
47 160 @Override
48 161 @Transactional(rollbackFor = Exception.class)
49 162 public Long createPermission(CrmPermissionCreateReqBO createReqBO) {
  163 + return createPermission0(createReqBO);
  164 + }
  165 +
  166 + private Long createPermission0(CrmPermissionCreateReqBO createReqBO) {
50 167 validatePermissionNotExists(Collections.singletonList(createReqBO));
51 168 // 1. 校验用户是否存在
52 169 adminUserApi.validateUserList(Collections.singletonList(createReqBO.getUserId()));
... ... @@ -170,7 +287,7 @@ public class CrmPermissionServiceImpl implements CrmPermissionService {
170 287 throw exception(CRM_PERMISSION_DELETE_FAIL);
171 288 }
172 289 // 校验操作人是否为负责人
173   - CrmPermissionDO permission = permissionMapper.selectByBizIdAndUserId(permissions.get(0).getBizId(), userId);
  290 + CrmPermissionDO permission = permissionMapper.selectByBizAndUserId(permissions.get(0).getBizType(), permissions.get(0).getBizId(), userId);
174 291 if (permission == null) {
175 292 throw exception(CRM_PERMISSION_DELETE_DENIED);
176 293 }
... ... @@ -220,4 +337,9 @@ public class CrmPermissionServiceImpl implements CrmPermissionService {
220 337 ObjUtil.equal(permission.getUserId(), userId) && ObjUtil.equal(permission.getLevel(), level.getLevel()));
221 338 }
222 339  
  340 + public CrmPermissionDO hasAnyPermission(Integer bizType, Long bizId, Long userId) {
  341 + List<CrmPermissionDO> permissionList = permissionMapper.selectByBizTypeAndBizId(bizType, bizId);
  342 + return findFirst(permissionList, permission -> ObjUtil.equal(permission.getUserId(), userId));
  343 + }
  344 +
223 345 }
... ...