diff --git a/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/ErrorCodeConstants.java b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/ErrorCodeConstants.java index b04644a41..6b5eea184 100644 --- a/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/ErrorCodeConstants.java +++ b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/ErrorCodeConstants.java @@ -46,6 +46,10 @@ public interface ErrorCodeConstants { ErrorCode CRM_PERMISSION_DENIED = new ErrorCode(1_020_007_001, "{}操作失败,原因:没有权限"); ErrorCode CRM_PERMISSION_MODEL_NOT_EXISTS = new ErrorCode(1_020_007_002, "{}不存在"); ErrorCode CRM_PERMISSION_MODEL_TRANSFER_FAIL_OWNER_USER_EXISTS = new ErrorCode(1_020_007_003, "{}操作失败,原因:转移对象已经是该负责人"); + ErrorCode CRM_PERMISSION_DELETE_FAIL = new ErrorCode(1_020_007_004, "删除数据权限失败,原因:参数异常"); + ErrorCode CRM_PERMISSION_DELETE_FAIL_EXIST_OWNER = new ErrorCode(1_020_007_005, "删除数据权限失败,原因:存在负责人"); + ErrorCode CRM_PERMISSION_DELETE_DENIED = new ErrorCode(1_020_007_006, "删除数据权限失败,原因:没有权限"); + ErrorCode CRM_PERMISSION_DELETE_SELF_PERMISSION_FAIL_EXIST_OWNER = new ErrorCode(1_020_007_007, "删除数据权限失败,原因:不能删除负责人"); // ========== 产品 1_020_008_000 ========== ErrorCode PRODUCT_NOT_EXISTS = new ErrorCode(1_020_008_000, "产品不存在"); diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/CrmPermissionController.http b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/CrmPermissionController.http index 1a7faecdd..1ef2bc1a1 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/CrmPermissionController.http +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/CrmPermissionController.http @@ -1,5 +1,5 @@ ### 请求 /add -PUT {{baseUrl}}/crm/permission/add +POST {{baseUrl}}/crm/permission/create Content-Type: application/json Authorization: Bearer {{token}} tenant-id: {{adminTenentId}} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/CrmPermissionController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/CrmPermissionController.java index 75e8ad658..fcae121f5 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/CrmPermissionController.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/CrmPermissionController.java @@ -3,13 +3,13 @@ package cn.iocoder.yudao.module.crm.controller.admin.permission; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjUtil; import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionCreateReqVO; import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionRespVO; import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionUpdateReqVO; import cn.iocoder.yudao.module.crm.convert.permission.CrmPermissionConvert; import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO; import cn.iocoder.yudao.module.crm.framework.core.annotations.CrmPermission; -import cn.iocoder.yudao.module.crm.framework.enums.CrmBizTypeEnum; import cn.iocoder.yudao.module.crm.framework.enums.CrmPermissionLevelEnum; import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; import cn.iocoder.yudao.module.system.api.dept.DeptApi; @@ -29,17 +29,14 @@ import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.validation.Valid; import java.util.*; -import java.util.function.Predicate; -import java.util.stream.Collectors; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.anyMatch; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; -import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CRM_PERMISSION_NOT_EXISTS; +import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*; -@Tag(name = "管理后台 - CRM 数据权限(数据团队成员操作)") +@Tag(name = "管理后台 - CRM 数据权限") @RestController @RequestMapping("/crm/permission") @Validated @@ -55,72 +52,59 @@ public class CrmPermissionController { @Resource private PostApi postApi; - // TODO @puhui999:保持统一,create 噢;然后是 PostMapping - @PutMapping("/add") - @Operation(summary = "添加团队成员") + @PostMapping("/create") + @Operation(summary = "创建数据权限") @PreAuthorize("@ss.hasPermission('crm:permission:create')") - @CrmPermission(bizType = CrmBizTypeEnum.CRM_PERMISSION, bizTypeValue = "#reqVO.bizType", bizId = "#reqVO.bizId", - level = CrmPermissionLevelEnum.OWNER) + @CrmPermission(bizTypeValue = "#reqVO.bizType", bizId = "#reqVO.bizId", level = CrmPermissionLevelEnum.OWNER) public CommonResult addPermission(@Valid @RequestBody CrmPermissionCreateReqVO reqVO) { permissionService.createPermission(CrmPermissionConvert.INSTANCE.convert(reqVO)); return success(true); } - // TODO @puhui999:领取公海客户,是不是放到客户那更合适哈? - @PutMapping("/receive") - @Operation(summary = "领取公海数据") - @PreAuthorize("@ss.hasPermission('crm:permission:update')") - public CommonResult receive(@RequestParam("bizType") Integer bizType, @RequestParam("bizId") Long bizId) { - permissionService.receiveBiz(bizType, bizId, getLoginUserId()); - return success(true); - } - - // TODO @puhui999:是不是放到客户那更合适哈? - @PutMapping("/put-pool") - @Operation(summary = "数据放入公海") - @PreAuthorize("@ss.hasPermission('crm:permission:update')") - @CrmPermission(bizType = CrmBizTypeEnum.CRM_PERMISSION, bizTypeValue = "#bizType", bizId = "#bizId" - , level = CrmPermissionLevelEnum.OWNER) - public CommonResult putPool(@RequestParam(value = "bizType") Integer bizType, @RequestParam("bizId") Long bizId) { - permissionService.putPool(bizType, bizId, getLoginUserId()); - return success(true); - } - @PutMapping("/update") - @Operation(summary = "编辑团队成员权限") + @Operation(summary = "编辑数据权限") @PreAuthorize("@ss.hasPermission('crm:permission:update')") - @CrmPermission(bizType = CrmBizTypeEnum.CRM_PERMISSION, bizTypeValue = "#updateReqVO.bizType", bizId = "#updateReqVO.bizId" + @CrmPermission(bizTypeValue = "#updateReqVO.bizType", bizId = "#updateReqVO.bizId" , level = CrmPermissionLevelEnum.OWNER) public CommonResult updatePermission(@Valid @RequestBody CrmPermissionUpdateReqVO updateReqVO) { permissionService.updatePermission(updateReqVO); return success(true); } - // TODO @puhui999:bizType 和 bizId 是不是不用啦;因为参数校验需要 bizType 和 bizId,可以先查询下,在直接调用方法;不一定都要注解哈; @DeleteMapping("/delete") - @Operation(summary = "移除团队成员") - @Parameters({ - @Parameter(name = "bizType", description = "CRM 类型", required = true, example = "2"), - @Parameter(name = "bizId", description = "CRM 类型数据编号", required = true, example = "1024"), - @Parameter(name = "ids", description = "团队成员编号", required = true, example = "1024") - }) + @Operation(summary = "删除数据权限") + @Parameter(name = "ids", description = "数据权限编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('crm:permission:delete')") - @CrmPermission(bizType = CrmBizTypeEnum.CRM_PERMISSION, bizTypeValue = "#bizType", bizId = "#bizId" - , level = CrmPermissionLevelEnum.OWNER) // 为了校验权限请求必须带上 bizType 和 bizId - public CommonResult deletePermission(@RequestParam("bizType") Integer bizType, - @RequestParam("bizId") Long bizId, - @RequestParam("ids") Collection ids) { + public CommonResult deletePermission(@RequestParam("ids") Collection ids) { + List permissions = permissionService.getPermissionListByIds(ids); + if (CollUtil.isEmpty(permissions)) { + throw exception(CRM_PERMISSION_NOT_EXISTS); + } + Set bizIds = convertSet(permissions, CrmPermissionDO::getBizId); + if (bizIds.size() > 1) { // 情况一:数据权限的模块数据编号是一致的不可能存在两个 + throw exception(CRM_PERMISSION_DELETE_FAIL); + } + if (permissions.size() != ids.size()) { // 情况二:期望数量和实际结果不一致 + throw exception(CRM_PERMISSION_NOT_EXISTS); + } + // 情况三:不能包含负责人 + boolean isOwner = CollectionUtils.anyMatch(permissions, item -> ObjUtil.equal(item.getLevel(), CrmPermissionLevelEnum.OWNER.getLevel())); + if (isOwner) { + throw exception(CRM_PERMISSION_DELETE_FAIL_EXIST_OWNER); + } + // 校验操作人是否为负责人 + CrmPermissionDO permission = permissionService.getPermissionByIdAndUserId(permissions.get(0).getBizId(), getLoginUserId()); + if (!CrmPermissionLevelEnum.isOwner(permission.getLevel())) { + throw exception(CRM_PERMISSION_DELETE_DENIED); + } + // 删除数据权限 permissionService.deletePermission(ids); return success(true); } - // TODO @puhui999:deleteSelfPermission;尽量归成 crud 这样的操作哈; - @DeleteMapping("/quit-team") - @Operation(summary = "退出团队") - @Parameters({ - // TODO @puhui999:这个可以拿出来,不用包在 @Parameters 里,在只有一个参数时哈; - @Parameter(name = "id", description = "团队成员编号", required = true, example = "1024") - }) + @DeleteMapping("/deleteSelfPermission") + @Operation(summary = "删除自己的数据权限") + @Parameter(name = "id", description = "数据权限编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('crm:permission:delete')") public CommonResult deletePermission(@RequestParam("id") Long id) { // 校验数据存在且是自己 @@ -128,6 +112,10 @@ public class CrmPermissionController { if (permission == null) { throw exception(CRM_PERMISSION_NOT_EXISTS); } + // 校验是否是负责人 + if (CrmPermissionLevelEnum.isOwner(permission.getLevel())) { + throw exception(CRM_PERMISSION_DELETE_SELF_PERMISSION_FAIL_EXIST_OWNER); + } // 删除 permissionService.deletePermission(Collections.singletonList(id)); @@ -135,7 +123,7 @@ public class CrmPermissionController { } @GetMapping("/list") - @Operation(summary = "获取团队成员") + @Operation(summary = "获取数据权限列表") @Parameters({ @Parameter(name = "bizType", description = "CRM 类型", required = true, example = "2"), @Parameter(name = "bizId", description = "CRM 类型数据编号", required = true, example = "1024") @@ -147,19 +135,11 @@ public class CrmPermissionController { if (CollUtil.isEmpty(permission)) { return success(Collections.emptyList()); } - // TODO @puhui999:池子的逻辑; - // 判断是否是公海数据 - // TODO @puhui999:这段逻辑,可以删除么? - Predicate filter = item -> ObjUtil.equal(item.getUserId(), CrmPermissionDO.POOL_USER_ID); - if (anyMatch(permission, filter)) { - permission.removeIf(filter); // 排除 - } // 拼接数据 List userList = adminUserApi.getUserList(convertSet(permission, CrmPermissionDO::getUserId)); Map deptMap = deptApi.getDeptMap(convertSet(userList, AdminUserRespDTO::getDeptId)); - // TODO @puhui999:CollectionUtils.convertSetByFlatMap() 看看可以不 - Set postIds = userList.stream().flatMap(item -> item.getPostIds().stream()).collect(Collectors.toSet()); + Set postIds = CollectionUtils.convertSetByFlatMap(userList, AdminUserRespDTO::getPostIds, Collection::stream); Map postMap = postApi.getPostMap(postIds); return success(CrmPermissionConvert.INSTANCE.convert(permission, userList, deptMap, postMap)); } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/vo/CrmPermissionBaseVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/vo/CrmPermissionBaseVO.java index 595b8f9f2..086cbb42b 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/vo/CrmPermissionBaseVO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/vo/CrmPermissionBaseVO.java @@ -9,7 +9,7 @@ import lombok.Data; import javax.validation.constraints.NotNull; /** - * 数据权限(团队成员) Base VO,提供给添加、修改、详细的子 VO 使用 + * 数据权限 Base VO,提供给添加、修改、详细的子 VO 使用 * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 * * @author HUIHUI diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/vo/CrmPermissionRespVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/vo/CrmPermissionRespVO.java index 9440a949f..10f1ce198 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/vo/CrmPermissionRespVO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/vo/CrmPermissionRespVO.java @@ -6,7 +6,7 @@ import lombok.Data; import java.time.LocalDateTime; import java.util.Set; -@Schema(description = "管理后台 - CRM 数据权限(团队成员) Response VO") +@Schema(description = "管理后台 - CRM 数据权限 Response VO") @Data public class CrmPermissionRespVO extends CrmPermissionBaseVO { diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/permission/CrmPermissionConvert.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/permission/CrmPermissionConvert.java index 42f784ba7..03492b2c0 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/permission/CrmPermissionConvert.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/permission/CrmPermissionConvert.java @@ -15,10 +15,11 @@ import com.google.common.collect.Multimaps; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; -import java.util.ArrayList; import java.util.List; import java.util.Map; +import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen; + /** * Crm 数据权限 Convert * @@ -43,9 +44,9 @@ public interface CrmPermissionConvert { Map deptMap, Map postMap) { Map userMap = CollectionUtils.convertMap(userList, AdminUserRespDTO::getId); return CollectionUtils.convertList(convert(permission), item -> { - MapUtils.findAndThen(userMap, item.getId(), user -> { + findAndThen(userMap, item.getUserId(), user -> { item.setNickname(user.getNickname()); - MapUtils.findAndThen(deptMap, user.getDeptId(), deptRespDTO -> { + findAndThen(deptMap, user.getDeptId(), deptRespDTO -> { item.setDeptName(deptRespDTO.getName()); }); List postRespList = MapUtils.getList(Multimaps.forMap(postMap), user.getPostIds()); @@ -56,12 +57,8 @@ public interface CrmPermissionConvert { } default List convertList(CrmPermissionUpdateReqVO updateReqVO) { - // TODO @puhui999:CollectionUtils.convert - List permissions = new ArrayList<>(); - updateReqVO.getIds().forEach(id -> { - permissions.add(new CrmPermissionDO().setId(id).setLevel(updateReqVO.getLevel())); - }); - return permissions; + return CollectionUtils.convertList(updateReqVO.getIds(), + id -> new CrmPermissionDO().setId(id).setLevel(updateReqVO.getLevel())); } } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionService.java index 96ac1e145..e1f471669 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionService.java @@ -78,6 +78,7 @@ public interface CrmPermissionService { */ List getPermissionByBizTypeAndBizIdsAndLevel(Integer bizType, Collection bizIds, Integer level); + List getPermissionListByIds(Collection ids); /** * 数据权限转移 * diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionServiceImpl.java index 681c1654b..5ae70779b 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionServiceImpl.java @@ -24,7 +24,6 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*; import static cn.iocoder.yudao.module.crm.framework.enums.CrmPermissionLevelEnum.isOwner; -// TODO @puhui999:尽量规避用“团队”这个词哈;这个只是我们给前端展示用的; /** * CRM 数据权限 Service 接口实现类 * @@ -92,6 +91,14 @@ public class CrmPermissionServiceImpl implements CrmPermissionService { return crmPermissionMapper.selectListByBizTypeAndBizIdsAndLevel(bizType, bizIds, level); } + @Override + public List getPermissionListByIds(Collection ids) { + if (CollUtil.isEmpty(ids)) { + return Collections.emptyList(); + } + return crmPermissionMapper.selectBatchIds(ids); + } + private void validateCrmPermissionExists(Collection ids) { List permissionList = crmPermissionMapper.selectBatchIds(ids); // 校验存在 @@ -118,14 +125,12 @@ public class CrmPermissionServiceImpl implements CrmPermissionService { // 1.2 校验新负责人是否存在 adminUserApi.validateUserList(Collections.singletonList(transferReqBO.getNewOwnerUserId())); - // TODO @puhui999:2. 和 2.1 合并成 2;2.2 单独成 3;说白了,就是 2. 修改新负责人的权限;3. 修改老负责人的权限;这样整体注释会简洁一点,也清晰一点; - // 2. 权限转移 + // 2. 修改新负责人的权限 List permissions = crmPermissionMapper.selectByBizTypeAndBizId( - transferReqBO.getBizType(), transferReqBO.getBizId()); // 获取所有团队成员 - // 2.1 校验新负责人是否在团队成员中 + transferReqBO.getBizType(), transferReqBO.getBizId()); // 获得所有数据权限 CrmPermissionDO permission = CollUtil.findOne(permissions, - item -> ObjUtil.equal(item.getUserId(), transferReqBO.getNewOwnerUserId())); - if (permission == null) { // 不存在则以负责人的级别加入这个团队 + item -> ObjUtil.equal(item.getUserId(), transferReqBO.getNewOwnerUserId())); // 校验新负责人是否存在于数据权限列表 + if (permission == null) { // 不存在则以负责人的级别加入 crmPermissionMapper.insert(new CrmPermissionDO().setBizType(transferReqBO.getBizType()) .setBizId(transferReqBO.getBizId()).setUserId(transferReqBO.getNewOwnerUserId()) .setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); @@ -133,10 +138,11 @@ public class CrmPermissionServiceImpl implements CrmPermissionService { crmPermissionMapper.updateById(new CrmPermissionDO().setId(permission.getId()) .setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); } - // 2.2. 老负责人处理 - if (transferReqBO.getOldOwnerPermissionLevel() != null) { // 加入团队 + + // 3. 修改老负责人的权限 + if (transferReqBO.getOldOwnerPermissionLevel() != null) { // 加入数据权限列表 crmPermissionMapper.updateById(new CrmPermissionDO().setId(oldPermission.getId()) - .setLevel(transferReqBO.getOldOwnerPermissionLevel())); // 设置加入团队后的级别 + .setLevel(transferReqBO.getOldOwnerPermissionLevel())); // 设置权限级别 return; } crmPermissionMapper.deleteById(oldPermission.getId());