Commit 8c9873c425a38ef9547acd983e30df5b37cbcdf4

Authored by YunaiV
2 parents 8c9c91f0 794649ea

Merge branch 'feature/crm' of https://gitee.com/puhui999/ruoyi-vue-pro into feature/crm

# Conflicts:
#	yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java
#	yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contact/ContactConvert.java
#	yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/customer/CrmCustomerConvert.java
#	yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/ContactServiceImpl.java
#	yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java
#	yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/dept/PostConvert.java
Showing 45 changed files with 749 additions and 490 deletions
yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/customer/CrmCustomerSceneEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.crm.enums.customer;
  2 +
  3 +import cn.hutool.core.util.ObjUtil;
  4 +import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
  5 +import lombok.AllArgsConstructor;
  6 +import lombok.Getter;
  7 +
  8 +import java.util.Arrays;
  9 +
  10 +/**
  11 + * CRM 客户等级
  12 + *
  13 + * @author Wanwan
  14 + */
  15 +@Getter
  16 +@AllArgsConstructor
  17 +public enum CrmCustomerSceneEnum implements IntArrayValuable {
  18 +
  19 + OWNER(1, "我负责的客户"),
  20 + FOLLOW(2, "我关注的客户");
  21 +
  22 + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CrmCustomerSceneEnum::getType).toArray();
  23 +
  24 + /**
  25 + * 场景类型
  26 + */
  27 + private final Integer type;
  28 + /**
  29 + * 场景名称
  30 + */
  31 + private final String name;
  32 +
  33 + public static boolean isOwner(Integer type) {
  34 + return ObjUtil.equal(OWNER.getType(), type);
  35 + }
  36 +
  37 + public static boolean isFollow(Integer type) {
  38 + return ObjUtil.equal(FOLLOW.getType(), type);
  39 + }
  40 +
  41 + @Override
  42 + public int[] array() {
  43 + return ARRAYS;
  44 + }
  45 +
  46 +}
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/CrmBusinessTransferReqVO.java
... ... @@ -21,19 +21,11 @@ public class CrmBusinessTransferReqVO {
21 21 @Schema(description = "新负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
22 22 private Long newOwnerUserId;
23 23  
24   - // TODO @puhui999:joinTeam 可以合并成 permissionLevel 里;oldOwnerPermissionLevel;这样 null 说明移除,因为都换负责人啦;
25 24 /**
26   - * 老负责人是否加入团队,是/否
27   - */
28   - @Schema(description = "老负责人是否加入团队", requiredMode = Schema.RequiredMode.REQUIRED, example = "false")
29   - @NotNull(message = "老负责人是否加入团队不能为空")
30   - private Boolean joinTeam;
31   -
32   - /**
33   - * 老负责人加入团队后的权限级别。如果 {@link #joinTeam} 为 false, permissionLevel 为 null
  25 + * 老负责人加入团队后的权限级别。如果 null 说明移除
34 26 * 关联 {@link CrmPermissionLevelEnum}
35 27 */
36 28 @Schema(description = "老负责人加入团队后的权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
37   - private Integer permissionLevel;
  29 + private Integer oldOwnerPermissionLevel;
38 30  
39 31 }
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/vo/CrmContactTransferReqVO.java
... ... @@ -21,18 +21,11 @@ public class CrmContactTransferReqVO {
21 21 @Schema(description = "新负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
22 22 private Long newOwnerUserId;
23 23  
24   - // TODO @puhui999:joinTeam 可以合并成 permissionLevel 里;oldOwnerPermissionLevel;这样 null 说明移除,因为都换负责人啦;
25 24 /**
26   - * 老负责人是否加入团队,是/否
27   - */
28   - @Schema(description = "老负责人是否加入团队", requiredMode = Schema.RequiredMode.REQUIRED, example = "false")
29   - @NotNull(message = "老负责人是否加入团队不能为空")
30   - private Boolean joinTeam;
31   - /**
32   - * 老负责人加入团队后的权限级别。如果 {@link #joinTeam} 为 false, permissionLevel 为 null
  25 + * 老负责人加入团队后的权限级别。如果 null 说明移除
33 26 * 关联 {@link CrmPermissionLevelEnum}
34 27 */
35 28 @Schema(description = "老负责人加入团队后的权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
36   - private Integer permissionLevel;
  29 + private Integer oldOwnerPermissionLevel;
37 30  
38 31 }
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/CrmContractTransferReqVO.java
... ... @@ -21,19 +21,11 @@ public class CrmContractTransferReqVO {
21 21 @Schema(description = "新负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
22 22 private Long newOwnerUserId;
23 23  
24   - // TODO @puhui999:joinTeam 可以合并成 permissionLevel 里;oldOwnerPermissionLevel;这样 null 说明移除,因为都换负责人啦;
25 24 /**
26   - * 老负责人是否加入团队,是/否
27   - */
28   - @Schema(description = "老负责人是否加入团队", requiredMode = Schema.RequiredMode.REQUIRED, example = "false")
29   - @NotNull(message = "老负责人是否加入团队不能为空")
30   - private Boolean joinTeam;
31   -
32   - /**
33   - * 老负责人加入团队后的权限级别。如果 {@link #joinTeam} 为 false, permissionLevel 为 null
  25 + * 老负责人加入团队后的权限级别。如果 null 说明移除
34 26 * 关联 {@link CrmPermissionLevelEnum}
35 27 */
36 28 @Schema(description = "老负责人加入团队后的权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
37   - private Integer permissionLevel;
  29 + private Integer oldOwnerPermissionLevel;
38 30  
39 31 }
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java
1 1 package cn.iocoder.yudao.module.crm.controller.admin.customer;
2 2  
3   -import cn.hutool.core.collection.CollUtil;
4   -import cn.hutool.core.util.NumberUtil;
5   -import cn.hutool.core.util.ObjectUtil;
6 3 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
7 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
8 5 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
9   -import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
10 6 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
11 7 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.*;
12 8 import cn.iocoder.yudao.module.crm.convert.customer.CrmCustomerConvert;
13 9 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
  10 +import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO;
  11 +import cn.iocoder.yudao.module.crm.framework.enums.CrmBizTypeEnum;
  12 +import cn.iocoder.yudao.module.crm.framework.enums.CrmPermissionLevelEnum;
14 13 import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
  14 +import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService;
15 15 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
16 16 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
17 17 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
18 18 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
19   -import com.google.common.collect.Lists;
20 19 import io.swagger.v3.oas.annotations.Operation;
21 20 import io.swagger.v3.oas.annotations.Parameter;
22 21 import io.swagger.v3.oas.annotations.tags.Tag;
... ... @@ -28,13 +27,16 @@ import javax.annotation.Resource;
28 27 import javax.servlet.http.HttpServletResponse;
29 28 import javax.validation.Valid;
30 29 import java.io.IOException;
31   -import java.util.*;
32   -import java.util.stream.Collectors;
33   -import java.util.stream.Stream;
  30 +import java.util.Collections;
  31 +import java.util.List;
  32 +import java.util.Map;
  33 +import java.util.Set;
34 34  
35 35 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
36 36 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
37 37 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSetByFlatMap;
  38 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
  39 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
38 40 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
39 41 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
40 42  
... ... @@ -51,6 +53,8 @@ public class CrmCustomerController {
51 53 private DeptApi deptApi;
52 54 @Resource
53 55 private AdminUserApi adminUserApi;
  56 + @Resource
  57 + private CrmPermissionService permissionService;
54 58  
55 59 @PostMapping("/create")
56 60 @Operation(summary = "创建客户")
... ... @@ -81,22 +85,26 @@ public class CrmCustomerController {
81 85 @Parameter(name = "id", description = "编号", required = true, example = "1024")
82 86 @PreAuthorize("@ss.hasPermission('crm:customer:query')")
83 87 public CommonResult<CrmCustomerRespVO> getCustomer(@RequestParam("id") Long id) {
  88 + // 1. 获取客户
84 89 CrmCustomerDO customer = customerService.getCustomer(id);
85   - CrmCustomerRespVO customerRespVO = CrmCustomerConvert.INSTANCE.convert(customer);
86   - if (ObjectUtil.isAllNotEmpty(customer, customer.getAreaId())) {
87   - customerRespVO.setAreaName(AreaUtils.format(customer.getAreaId()));
88   - }
89   - Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(CollUtil.removeNull(Lists.newArrayList(NumberUtil.parseLong(customerRespVO.getCreator()), customerRespVO.getOwnerUserId())));
90   - customerRespVO.setCreatorName(Optional.ofNullable(userMap.get(NumberUtil.parseLong(customerRespVO.getCreator()))).map(AdminUserRespDTO::getNickname).orElse(null));
91   - AdminUserRespDTO ownerUser = userMap.get(customer.getOwnerUserId());
92   - if (Objects.nonNull(ownerUser)) {
93   - customerRespVO.setOwnerUserName(ownerUser.getNickname());
94   - DeptRespDTO dept = deptApi.getDept(ownerUser.getDeptId());
95   - if (Objects.nonNull(dept)) {
96   - customerRespVO.setOwnerUserDept(dept.getName());
97   - }
  90 + if (customer == null) {
  91 + return success(null);
98 92 }
99   - return success(customerRespVO);
  93 +
  94 + // 2. 拼接数据
  95 + // 2.1 获取负责人
  96 + List<CrmPermissionDO> ownerList = permissionService.getPermissionByBizTypeAndBizIdsAndLevel(
  97 + CrmBizTypeEnum.CRM_CUSTOMER.getType(), Collections.singletonList(customer.getId()),
  98 + CrmPermissionLevelEnum.OWNER.getLevel());
  99 + Map<Long, CrmPermissionDO> ownerMap = convertMap(ownerList, CrmPermissionDO::getBizId);
  100 + // 2.2 获取负责人详情
  101 + Set<Long> userIds = convertSet(ownerList, CrmPermissionDO::getUserId);
  102 + userIds.add(Long.parseLong(customer.getCreator())); // 加入创建者
  103 + List<AdminUserRespDTO> userList = adminUserApi.getUserList(userIds);
  104 + Map<Long, AdminUserRespDTO> userMap = convertMap(userList, AdminUserRespDTO::getId);
  105 + // 2.3 获取部门详情
  106 + Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userList, AdminUserRespDTO::getDeptId));
  107 + return success(CrmCustomerConvert.INSTANCE.convert(customer, ownerMap, userMap, deptMap));
100 108 }
101 109  
102 110 @GetMapping("/page")
... ... @@ -113,6 +121,31 @@ public class CrmCustomerController {
113 121 Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(
114 122 convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
115 123 return success(CrmCustomerConvert.INSTANCE.convertPage(pageResult, userMap, deptMap));
  124 + return convertPage(customerService.getCustomerPage(pageVO, getLoginUserId()));
  125 + }
  126 +
  127 + @GetMapping("/pool-page")
  128 + @Operation(summary = "获得公海客户分页")
  129 + @PreAuthorize("@ss.hasPermission('crm:customer:query')")
  130 + public CommonResult<PageResult<CrmCustomerRespVO>> getPoolCustomerPage(@Valid CrmCustomerPageReqVO pageVO) {
  131 + return convertPage(customerService.getCustomerPage(pageVO, CrmPermissionDO.POOL_USER_ID));
  132 + }
  133 +
  134 + private CommonResult<PageResult<CrmCustomerRespVO>> convertPage(PageResult<CrmCustomerDO> pageResult) {
  135 + // 2. 拼接数据
  136 + Set<Long> ids = convertSet(pageResult.getList(), CrmCustomerDO::getId);
  137 + // 2.1 获取负责人
  138 + List<CrmPermissionDO> ownerList = permissionService.getPermissionByBizTypeAndBizIdsAndLevel(
  139 + CrmBizTypeEnum.CRM_CUSTOMER.getType(), ids, CrmPermissionLevelEnum.OWNER.getLevel());
  140 + Map<Long, CrmPermissionDO> ownerMap = convertMap(ownerList, CrmPermissionDO::getBizId);
  141 + // 2.2 获取负责人详情
  142 + Set<Long> userIds = convertSet(ownerList, CrmPermissionDO::getUserId);
  143 + userIds.addAll(convertSet(pageResult.getList(), item -> Long.parseLong(item.getCreator()))); // 加入创建者
  144 + List<AdminUserRespDTO> userList = adminUserApi.getUserList(userIds);
  145 + Map<Long, AdminUserRespDTO> userMap = convertMap(userList, AdminUserRespDTO::getId);
  146 + // 2.3 获取部门详情
  147 + Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userList, AdminUserRespDTO::getDeptId));
  148 + return success(CrmCustomerConvert.INSTANCE.convertPage(pageResult, ownerMap, userMap, deptMap));
116 149 }
117 150  
118 151 @GetMapping("/export-excel")
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/CrmCustomerPageReqVO.java
1 1 package cn.iocoder.yudao.module.crm.controller.admin.customer.vo;
2 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import cn.iocoder.yudao.module.crm.enums.customer.CrmCustomerSceneEnum;
4 5 import io.swagger.v3.oas.annotations.media.Schema;
5 6 import lombok.Data;
6 7 import lombok.EqualsAndHashCode;
... ... @@ -27,5 +28,10 @@ public class CrmCustomerPageReqVO extends PageParam {
27 28 @Schema(description = "客户来源", example = "1")
28 29 private Integer source;
29 30  
30   - // TODO @芋艿:场景;
  31 + /**
  32 + * 场景类型,关联 {@link CrmCustomerSceneEnum}
  33 + */
  34 + @Schema(description = "场景类型", example = "1")
  35 + private Integer sceneType;
  36 +
31 37 }
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/CrmCustomerRespVO.java
... ... @@ -33,7 +33,7 @@ public class CrmCustomerRespVO extends CrmCustomerBaseVO {
33 33 @Schema(description = "负责人名字", example = "25682")
34 34 private String ownerUserName;
35 35 @Schema(description = "负责人部门")
36   - private String ownerUserDept;
  36 + private String ownerUserDeptName;
37 37  
38 38 @Schema(description = "地区名称", example = "北京市")
39 39 private String areaName;
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/CrmCustomerTransferReqVO.java
... ... @@ -21,19 +21,11 @@ public class CrmCustomerTransferReqVO {
21 21 @Schema(description = "新负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
22 22 private Long newOwnerUserId;
23 23  
24   - // TODO @puhui999:joinTeam 可以合并成 permissionLevel 里;oldOwnerPermissionLevel;这样 null 说明移除,因为都换负责人啦;
25 24 /**
26   - * 老负责人是否加入团队,是/否
27   - */
28   - @Schema(description = "老负责人是否加入团队", requiredMode = Schema.RequiredMode.REQUIRED, example = "false")
29   - @NotNull(message = "老负责人是否加入团队不能为空")
30   - private Boolean joinTeam;
31   -
32   - /**
33   - * 老负责人加入团队后的权限级别。如果 {@link #joinTeam} 为 false, permissionLevel 为 null
  25 + * 老负责人加入团队后的权限级别。如果 null 说明移除
34 26 * 关联 {@link CrmPermissionLevelEnum}
35 27 */
36 28 @Schema(description = "老负责人加入团队后的权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
37   - private Integer permissionLevel;
  29 + private Integer oldOwnerPermissionLevel;
38 30  
39 31 }
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/CrmPermissionController.http 0 → 100644
  1 +### 请求 /add
  2 +PUT {{baseUrl}}/crm/permission/add
  3 +Content-Type: application/json
  4 +Authorization: Bearer {{token}}
  5 +tenant-id: {{adminTenentId}}
  6 +
  7 +{
  8 + "userId": 1,
  9 + "bizType": 2,
  10 + "bizId": 2,
  11 + "level": 1
  12 +}
  13 +
  14 +### 请求 /update
  15 +PUT {{baseUrl}}/crm/permission/update
  16 +Content-Type: application/json
  17 +Authorization: Bearer {{token}}
  18 +tenant-id: {{adminTenentId}}
  19 +
  20 +{
  21 + "userId": 1,
  22 + "bizType": 2,
  23 + "bizId": 2,
  24 + "level": 1,
  25 + "id": 1
  26 +}
  27 +
  28 +### 请求 /delete
  29 +DELETE {{baseUrl}}/crm/permission/delete?bizType=2&bizId=1&id=1
  30 +Authorization: Bearer {{token}}
  31 +tenant-id: {{adminTenentId}}
  32 +
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/CrmPermissionController.java
... ... @@ -8,8 +8,14 @@ import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionR
8 8 import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionUpdateReqVO;
9 9 import cn.iocoder.yudao.module.crm.convert.permission.CrmPermissionConvert;
10 10 import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO;
11   -import cn.iocoder.yudao.module.crm.framework.core.service.CrmPermissionValidateService;
  11 +import cn.iocoder.yudao.module.crm.framework.core.annotations.CrmPermission;
  12 +import cn.iocoder.yudao.module.crm.framework.enums.CrmBizTypeEnum;
  13 +import cn.iocoder.yudao.module.crm.framework.enums.CrmPermissionLevelEnum;
12 14 import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService;
  15 +import cn.iocoder.yudao.module.system.api.dept.DeptApi;
  16 +import cn.iocoder.yudao.module.system.api.dept.PostApi;
  17 +import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
  18 +import cn.iocoder.yudao.module.system.api.dept.dto.PostRespDTO;
13 19 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
14 20 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
15 21 import io.swagger.v3.oas.annotations.Operation;
... ... @@ -22,17 +28,16 @@ import org.springframework.web.bind.annotation.*;
22 28  
23 29 import javax.annotation.Resource;
24 30 import javax.validation.Valid;
25   -import java.util.Collections;
26   -import java.util.List;
  31 +import java.util.*;
  32 +import java.util.function.Predicate;
  33 +import java.util.stream.Collectors;
27 34  
28 35 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
29 36 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  37 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.anyMatch;
30 38 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
31 39 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
32   -import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CRM_PERMISSION_DENIED;
33   -import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CRM_PERMISSION_MODEL_NOT_EXISTS;
34   -import static cn.iocoder.yudao.module.crm.framework.enums.CrmBizTypeEnum.getNameByType;
35   -import static cn.iocoder.yudao.module.crm.framework.enums.CrmPermissionLevelEnum.isOwner;
  40 +import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CRM_PERMISSION_NOT_EXISTS;
36 41  
37 42 @Tag(name = "管理后台 - CRM 数据权限(数据团队成员操作)")
38 43 @RestController
... ... @@ -41,92 +46,85 @@ import static cn.iocoder.yudao.module.crm.framework.enums.CrmPermissionLevelEnum
41 46 public class CrmPermissionController {
42 47  
43 48 @Resource
44   - private CrmPermissionService crmPermissionService;
  49 + private CrmPermissionService permissionService;
45 50  
46 51 @Resource
47 52 private AdminUserApi adminUserApi;
48 53 @Resource
49   - private List<CrmPermissionValidateService> permissionValidateServices;
50   -
51   - // TODO @puhui999:这个能不能使用 CrmPermission 注解替代?
52   - private void validatePermission(Integer bizType, Long bizId) {
53   - // 1. TODO 校验是否为超级管理员
54   - // 2. 防御一手,如果是超级管理员不校验权限还是得校验一下数据是否存在
55   - // TODO @puhui999:是不是不用校验每个业务方的数据是否存在;其实不是很关键哈;简单一点~ 说白了,负责人只要在,它的数据就是存在~
56   - permissionValidateServices.forEach(item -> {
57   - if (!item.validateBizIdExists(bizType, bizId)) {
58   - throw exception(CRM_PERMISSION_MODEL_NOT_EXISTS, getNameByType(bizType));
59   - }
60   - });
61   - // 3. 校验数据权限 (如果存在则表示 bizId 也存在)
62   - CrmPermissionDO permission = crmPermissionService.getPermissionByBizTypeAndBizIdAndUserId(
63   - bizType, bizId, getLoginUserId());
64   - if (isOwner(permission.getPermissionLevel())) { // 只有负责人才可以操作团队成员
65   - return;
66   - }
67   - throw exception(CRM_PERMISSION_DENIED, getNameByType(bizType));
68   - }
  54 + private DeptApi deptApi;
  55 + @Resource
  56 + private PostApi postApi;
69 57  
70 58 @PutMapping("/add")
71 59 @Operation(summary = "添加团队成员")
72 60 @PreAuthorize("@ss.hasPermission('crm:permission:create')")
  61 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_PERMISSION, bizTypeValue = "#reqVO.bizType", bizId = "#reqVO.bizId"
  62 + , level = CrmPermissionLevelEnum.OWNER)
73 63 public CommonResult<Boolean> addPermission(@Valid @RequestBody CrmPermissionCreateReqVO reqVO) {
74   - // 1. 前置校验
75   - validatePermission(reqVO.getBizType(), reqVO.getBizId());
  64 + permissionService.createPermission(CrmPermissionConvert.INSTANCE.convert(reqVO));
  65 + return success(true);
  66 + }
76 67  
77   - // 2. 加入成员
78   - crmPermissionService.createPermission(CrmPermissionConvert.INSTANCE.convert(reqVO));
  68 + @PutMapping("/receive")
  69 + @Operation(summary = "领取公海数据")
  70 + @PreAuthorize("@ss.hasPermission('crm:permission:update')")
  71 + public CommonResult<Boolean> receive(@RequestParam("bizType") Integer bizType, @RequestParam("bizId") Long bizId) {
  72 + permissionService.receiveBiz(bizType, bizId, getLoginUserId());
79 73 return success(true);
80 74 }
81 75  
  76 + @PutMapping("/put-pool")
  77 + @Operation(summary = "数据放入公海")
  78 + @PreAuthorize("@ss.hasPermission('crm:permission:update')")
  79 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_PERMISSION, bizTypeValue = "#bizType", bizId = "#bizId"
  80 + , level = CrmPermissionLevelEnum.OWNER)
  81 + public CommonResult<Boolean> putPool(@RequestParam(value = "bizType") Integer bizType, @RequestParam("bizId") Long bizId) {
  82 + permissionService.putPool(bizType, bizId, getLoginUserId());
  83 + return success(true);
  84 + }
82 85  
83 86 @PutMapping("/update")
84   - @Operation(summary = "编辑团队成员")
  87 + @Operation(summary = "编辑团队成员权限")
85 88 @PreAuthorize("@ss.hasPermission('crm:permission:update')")
  89 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_PERMISSION, bizTypeValue = "#updateReqVO.bizType", bizId = "#updateReqVO.bizId"
  90 + , level = CrmPermissionLevelEnum.OWNER)
86 91 public CommonResult<Boolean> updatePermission(@Valid @RequestBody CrmPermissionUpdateReqVO updateReqVO) {
87   - // 1. 前置校验
88   - validatePermission(updateReqVO.getBizType(), updateReqVO.getBizId());
89   -
90   - // 2. 编辑团队成员
91   - crmPermissionService.updatePermission(CrmPermissionConvert.INSTANCE.convert(updateReqVO));
  92 + permissionService.updatePermission(updateReqVO);
92 93 return success(true);
93 94 }
94 95  
95   - // TODO @puhui999:deletemapping
96   - @GetMapping("/delete")
  96 + @DeleteMapping("/delete")
97 97 @Operation(summary = "移除团队成员")
98   - @Parameter(name = "id", description = "团队成员编号", required = true)
99   - // TODO @puhui999:是不是 id 参数就够了?
  98 + @Parameters({
  99 + @Parameter(name = "bizType", description = "CRM 类型", required = true, example = "2"),
  100 + @Parameter(name = "bizId", description = "CRM 类型数据编号", required = true, example = "1024"),
  101 + @Parameter(name = "ids", description = "团队成员编号", required = true, example = "1024")
  102 + })
100 103 @PreAuthorize("@ss.hasPermission('crm:permission:delete')")
  104 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_PERMISSION, bizTypeValue = "#bizType", bizId = "#bizId"
  105 + , level = CrmPermissionLevelEnum.OWNER) // 为了校验权限请求必须带上 bizType 和 bizId
101 106 public CommonResult<Boolean> deletePermission(@RequestParam("bizType") Integer bizType,
102 107 @RequestParam("bizId") Long bizId,
103   - @RequestParam("id") Long id) {
104   - // 1. 前置校验
105   - validatePermission(bizType, bizId);
106   -
107   - // 2. 移除团队成员
108   - crmPermissionService.deletePermission(id);
  108 + @RequestParam("ids") Collection<Long> ids) {
  109 + permissionService.deletePermission(ids);
109 110 return success(true);
110 111 }
111 112  
112   - // TODO @puhui999:这个是哪个地方使用到哈?
113   - // TODO @puhui999:是不是 deletemapping 呀;
114   - @GetMapping("/quit")
  113 + @DeleteMapping("/quit-team")
115 114 @Operation(summary = "退出团队")
116 115 @Parameters({
117   - @Parameter(name = "bizType", description = "CRM 类型", required = true, example = "2"),
118   - @Parameter(name = "bizId", description = "CRM 类型数据编号", required = true, example = "1024")
  116 + @Parameter(name = "id", description = "团队成员编号", required = true, example = "1024")
119 117 })
120 118 @PreAuthorize("@ss.hasPermission('crm:permission:delete')")
121   - public CommonResult<Boolean> quitPermission(@RequestParam("bizType") Integer bizType,
122   - @RequestParam("bizId") Long bizId) {
123   - // 没有就不是团队成员
124   - CrmPermissionDO permission = crmPermissionService.getPermissionByBizTypeAndBizIdAndUserId(
125   - bizType, bizId, getLoginUserId());
  119 + public CommonResult<Boolean> deletePermission(@RequestParam("id") Long id) {
  120 + // 校验数据存在且是自己
  121 + CrmPermissionDO permission = permissionService.getPermissionByIdAndUserId(id, getLoginUserId());
126 122 if (permission == null) {
127   - return success(false);
  123 + throw exception(CRM_PERMISSION_NOT_EXISTS);
128 124 }
129   - crmPermissionService.deletePermission(permission.getId());
  125 +
  126 + // 删除
  127 + permissionService.deletePermission(Collections.singletonList(id));
130 128 return success(true);
131 129 }
132 130  
... ... @@ -139,16 +137,23 @@ public class CrmPermissionController {
139 137 @PreAuthorize("@ss.hasPermission('crm:permission:query')")
140 138 public CommonResult<List<CrmPermissionRespVO>> getPermissionList(@RequestParam("bizType") Integer bizType,
141 139 @RequestParam("bizId") Long bizId) {
142   - List<CrmPermissionDO> permission = crmPermissionService.getPermissionByBizTypeAndBizId(bizType, bizId);
  140 + List<CrmPermissionDO> permission = permissionService.getPermissionByBizTypeAndBizId(bizType, bizId);
143 141 if (CollUtil.isEmpty(permission)) {
144 142 return success(Collections.emptyList());
145 143 }
146 144 // TODO @puhui999:池子的逻辑;
147   - permission.removeIf(item -> ObjUtil.equal(item.getUserId(), CrmPermissionDO.POOL_USER_ID)); // 排除
  145 + // 判断是否是公海数据
  146 + Predicate<CrmPermissionDO> filter = item -> ObjUtil.equal(item.getUserId(), CrmPermissionDO.POOL_USER_ID);
  147 + if (anyMatch(permission, filter)) {
  148 + permission.removeIf(filter); // 排除
  149 + }
148 150  
149 151 // 拼接数据
150 152 List<AdminUserRespDTO> userList = adminUserApi.getUserList(convertSet(permission, CrmPermissionDO::getUserId));
151   - return success(CrmPermissionConvert.INSTANCE.convert(permission, userList));
  153 + Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userList, AdminUserRespDTO::getDeptId));
  154 + Set<Long> postIds = userList.stream().flatMap(item -> item.getPostIds().stream()).collect(Collectors.toSet());
  155 + Map<Long, PostRespDTO> postMap = postApi.getPostMap(postIds);
  156 + return success(CrmPermissionConvert.INSTANCE.convert(permission, userList, deptMap, postMap));
152 157 }
153 158  
154 159 }
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/vo/CrmPermissionBaseVO.java
... ... @@ -30,10 +30,9 @@ public class CrmPermissionBaseVO {
30 30 @NotNull(message = "Crm 类型数据编号不能为空")
31 31 private Long bizId;
32 32  
33   - // TODO @puhui999:level;
34 33 @Schema(description = "权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
35 34 @InEnum(CrmPermissionLevelEnum.class)
36 35 @NotNull(message = "权限级别不能为空")
37   - private Integer permissionLevel;
  36 + private Integer level;
38 37  
39 38 }
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/vo/CrmPermissionRespVO.java
... ... @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.crm.controller.admin.permission.vo;
3 3 import io.swagger.v3.oas.annotations.media.Schema;
4 4 import lombok.Data;
5 5  
  6 +import java.time.LocalDateTime;
6 7 import java.util.Set;
7 8  
8 9 @Schema(description = "管理后台 - CRM 数据权限(团队成员) Response VO")
... ... @@ -12,18 +13,16 @@ public class CrmPermissionRespVO extends CrmPermissionBaseVO {
12 13 @Schema(description = "数据权限编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "13563")
13 14 private Long id;
14 15  
15   - // TODO @puhui999:搞到字典里;
16   - @Schema(description = "团队级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "负责人")
17   - private String permissionLevelName;
18   -
19   - // TODO @puhui999:deptId、postIds 是不是要提供中文名哈;
20   - @Schema(description = "部门编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
21   - private Long deptId;
  16 + @Schema(description = "部门名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "研发部")
  17 + private String deptName;
22 18  
23 19 @Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿")
24 20 private String nickname;
25 21  
26   - @Schema(description = "岗位编号数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1,2,3]")
27   - private Set<Long> postIds;
  22 + @Schema(description = "岗位名称数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "[BOOS,经理]")
  23 + private Set<String> postNames;
  24 +
  25 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2023-01-01 00:00:00")
  26 + private LocalDateTime createTime;
28 27  
29 28 }
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/vo/CrmPermissionUpdateReqVO.java
1 1 package cn.iocoder.yudao.module.crm.controller.admin.permission.vo;
2 2  
  3 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  4 +import cn.iocoder.yudao.module.crm.framework.enums.CrmBizTypeEnum;
  5 +import cn.iocoder.yudao.module.crm.framework.enums.CrmPermissionLevelEnum;
3 6 import io.swagger.v3.oas.annotations.media.Schema;
4 7 import lombok.Data;
5   -import lombok.EqualsAndHashCode;
6   -import lombok.ToString;
  8 +
  9 +import javax.validation.constraints.NotNull;
  10 +import java.util.List;
7 11  
8 12 @Schema(description = "管理后台 - CRM 数据权限更新 Request VO")
9 13 @Data
10   -@EqualsAndHashCode(callSuper = true)
11   -@ToString(callSuper = true)
12   -public class CrmPermissionUpdateReqVO extends CrmPermissionBaseVO {
  14 +public class CrmPermissionUpdateReqVO {
  15 +
  16 + @Schema(description = "数据权限编号列表", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1,2]")
  17 + @NotNull(message = "数据权限编号列表不能为空")
  18 + private List<Long> ids;
  19 +
  20 + @Schema(description = "Crm 类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
  21 + @InEnum(CrmBizTypeEnum.class)
  22 + @NotNull(message = "Crm 类型不能为空")
  23 + private Integer bizType;
13 24  
14   - @Schema(description = "数据权限编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "13563")
15   - // TODO @puhui999:非空判断;
16   - private Long id;
  25 + @Schema(description = "Crm 类型数据编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  26 + @NotNull(message = "Crm 类型数据编号不能为空")
  27 + private Long bizId;
17 28  
18   - // TODO @puhui999:是不是只更新 permission???
  29 + @Schema(description = "权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
  30 + @InEnum(CrmPermissionLevelEnum.class)
  31 + @NotNull(message = "权限级别不能为空")
  32 + private Integer level;
19 33  
20 34 }
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/business/CrmBusinessConvert.java
... ... @@ -3,8 +3,7 @@ package cn.iocoder.yudao.module.crm.convert.business;
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 4 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.*;
5 5 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
6   -import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionPageReqBO;
7   -import cn.iocoder.yudao.module.crm.service.permission.bo.CrmTransferPermissionReqBO;
  6 +import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO;
8 7 import org.mapstruct.Mapper;
9 8 import org.mapstruct.Mapping;
10 9 import org.mapstruct.Mappings;
... ... @@ -36,8 +35,6 @@ public interface CrmBusinessConvert {
36 35 @Mapping(target = "bizId", source = "reqVO.id"),
37 36 @Mapping(target = "newOwnerUserId", source = "reqVO.id")
38 37 })
39   - CrmTransferPermissionReqBO convert(CrmBusinessTransferReqVO reqVO, Long userId);
40   -
41   - CrmPermissionPageReqBO convert(CrmBusinessPageReqVO pageReqVO);
  38 + CrmPermissionTransferReqBO convert(CrmBusinessTransferReqVO reqVO, Long userId);
42 39  
43 40 }
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contact/ContactConvert.java
... ... @@ -4,6 +4,9 @@ import java.util.*;
4 4  
5 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 6  
  7 +import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.*;
  8 +import cn.iocoder.yudao.module.crm.dal.dataobject.contact.ContactDO;
  9 +import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO;
7 10 import org.mapstruct.Mapper;
8 11 import org.mapstruct.factory.Mappers;
9 12 import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.*;
... ... @@ -30,6 +33,13 @@ public interface ContactConvert {
30 33 PageResult<ContactRespVO> convertPage(PageResult<ContactDO> page);
31 34  
32 35 List<ContactExcelVO> convertList02(List<ContactDO> list);
  36 +
33 37 List<ContactSimpleRespVO> convertAllList(List<ContactDO> list);
34 38  
  39 + @Mappings({
  40 + @Mapping(target = "bizId", source = "reqVO.id"),
  41 + @Mapping(target = "newOwnerUserId", source = "reqVO.id")
  42 + })
  43 + CrmPermissionTransferReqBO convert(CrmContactTransferReqVO reqVO, Long userId);
  44 +
35 45 }
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contract/ContractConvert.java
... ... @@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.crm.convert.contract;
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 4 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.*;
5 5 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.ContractDO;
6   -import cn.iocoder.yudao.module.crm.service.permission.bo.CrmTransferPermissionReqBO;
  6 +import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO;
7 7 import org.mapstruct.Mapper;
8 8 import org.mapstruct.Mapping;
9 9 import org.mapstruct.Mappings;
... ... @@ -37,6 +37,6 @@ public interface ContractConvert {
37 37 @Mapping(target = "bizId", source = "reqVO.id"),
38 38 @Mapping(target = "newOwnerUserId", source = "reqVO.id")
39 39 })
40   - CrmTransferPermissionReqBO convert(CrmContractTransferReqVO reqVO, Long userId);
  40 + CrmPermissionTransferReqBO convert(CrmContractTransferReqVO reqVO, Long userId);
41 41  
42 42 }
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/customer/CrmCustomerConvert.java
... ... @@ -4,12 +4,17 @@ import cn.hutool.core.util.NumberUtil;
4 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 5 import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
6 6 import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
  7 +import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
7 8 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.*;
8 9 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
9 10 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerPoolConfigDO;
10 11 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmTransferPermissionReqBO;
11 12 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
12 13 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
  14 +import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO;
  15 +import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO;
  16 +import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
  17 +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
13 18 import org.mapstruct.Mapper;
14 19 import org.mapstruct.Mapping;
15 20 import org.mapstruct.Mappings;
... ... @@ -18,6 +23,9 @@ import org.mapstruct.factory.Mappers;
18 23 import java.util.List;
19 24 import java.util.Map;
20 25  
  26 +import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
  27 +import java.util.Map;
  28 +
21 29 /**
22 30 * 客户 Convert
23 31 *
... ... @@ -34,7 +42,24 @@ public interface CrmCustomerConvert {
34 42  
35 43 CrmCustomerRespVO convert(CrmCustomerDO bean);
36 44  
37   - PageResult<CrmCustomerRespVO> convertPage(PageResult<CrmCustomerDO> page);
  45 + default CrmCustomerRespVO convert(CrmCustomerDO customer, Map<Long, CrmPermissionDO> ownerMap,
  46 + Map<Long, AdminUserRespDTO> userMap, Map<Long, DeptRespDTO> deptMap) {
  47 + CrmCustomerRespVO customerResp = convert(customer);
  48 + findAndThen(ownerMap, customerResp.getId(), owner -> {
  49 + customerResp.setOwnerUserId(owner.getUserId());
  50 + customerResp.setAreaName(AreaUtils.format(customerResp.getAreaId()));
  51 + findAndThen(userMap, owner.getUserId(), user -> {
  52 + customerResp.setOwnerUserName(user.getNickname());
  53 + });
  54 + findAndThen(userMap, Long.parseLong(customerResp.getCreator()), user -> {
  55 + customerResp.setCreatorName(user.getNickname());
  56 + });
  57 + findAndThen(deptMap, customerResp.getOwnerUserId(), dept -> {
  58 + customerResp.setOwnerUserDeptName(dept.getName());
  59 + });
  60 + });
  61 + return customerResp;
  62 + }
38 63  
39 64 default PageResult<CrmCustomerRespVO> convertPage(PageResult<CrmCustomerDO> page, Map<Long, AdminUserRespDTO> userMap, Map<Long, DeptRespDTO> deptMap) {
40 65 PageResult<CrmCustomerRespVO> result = convertPage(page);
... ... @@ -57,7 +82,30 @@ public interface CrmCustomerConvert {
57 82 @Mapping(target = "bizId", source = "reqVO.id"),
58 83 @Mapping(target = "newOwnerUserId", source = "reqVO.id")
59 84 })
60   - CrmTransferPermissionReqBO convert(CrmCustomerTransferReqVO reqVO, Long userId);
  85 + CrmPermissionTransferReqBO convert(CrmCustomerTransferReqVO reqVO, Long userId);
  86 +
  87 + PageResult<CrmCustomerRespVO> convertPage(PageResult<CrmCustomerDO> page);
  88 +
  89 + default PageResult<CrmCustomerRespVO> convertPage(PageResult<CrmCustomerDO> pageResult, Map<Long, CrmPermissionDO> ownerMap,
  90 + Map<Long, AdminUserRespDTO> userMap, Map<Long, DeptRespDTO> deptMap) {
  91 + PageResult<CrmCustomerRespVO> result = convertPage(pageResult);
  92 + result.getList().forEach(item -> {
  93 + findAndThen(ownerMap, item.getId(), owner -> {
  94 + item.setOwnerUserId(owner.getUserId());
  95 + item.setAreaName(AreaUtils.format(item.getAreaId()));
  96 + findAndThen(userMap, owner.getUserId(), user -> {
  97 + item.setOwnerUserName(user.getNickname());
  98 + });
  99 + findAndThen(userMap, Long.parseLong(item.getCreator()), user -> {
  100 + item.setCreatorName(user.getNickname());
  101 + });
  102 + findAndThen(deptMap, item.getOwnerUserId(), dept -> {
  103 + item.setOwnerUserDeptName(dept.getName());
  104 + });
  105 + });
  106 + });
  107 + return result;
  108 + }
61 109  
62 110 CrmCustomerPoolConfigRespVO convert(CrmCustomerPoolConfigDO customerPoolConfig);
63 111  
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/permission/CrmPermissionConvert.java
... ... @@ -8,15 +8,17 @@ import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionU
8 8 import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO;
9 9 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO;
10 10 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionUpdateReqBO;
  11 +import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
  12 +import cn.iocoder.yudao.module.system.api.dept.dto.PostRespDTO;
11 13 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
  14 +import com.google.common.collect.Multimaps;
12 15 import org.mapstruct.Mapper;
13 16 import org.mapstruct.factory.Mappers;
14 17  
  18 +import java.util.ArrayList;
15 19 import java.util.List;
16 20 import java.util.Map;
17 21  
18   -import static cn.iocoder.yudao.module.crm.framework.enums.CrmPermissionLevelEnum.getNameByLevel;
19   -
20 22 /**
21 23 * Crm 数据权限 Convert
22 24 *
... ... @@ -37,15 +39,28 @@ public interface CrmPermissionConvert {
37 39  
38 40 List<CrmPermissionRespVO> convert(List<CrmPermissionDO> permission);
39 41  
40   - default List<CrmPermissionRespVO> convert(List<CrmPermissionDO> permission, List<AdminUserRespDTO> userList) {
  42 + default List<CrmPermissionRespVO> convert(List<CrmPermissionDO> permission, List<AdminUserRespDTO> userList,
  43 + Map<Long, DeptRespDTO> deptMap, Map<Long, PostRespDTO> postMap) {
41 44 Map<Long, AdminUserRespDTO> userMap = CollectionUtils.convertMap(userList, AdminUserRespDTO::getId);
42 45 return CollectionUtils.convertList(convert(permission), item -> {
43 46 MapUtils.findAndThen(userMap, item.getId(), user -> {
44   - item.setNickname(user.getNickname()).setDeptId(user.getDeptId()).setPostIds(user.getPostIds())
45   - .setPermissionLevelName(getNameByLevel(item.getPermissionLevel()));
  47 + item.setNickname(user.getNickname());
  48 + MapUtils.findAndThen(deptMap, user.getDeptId(), deptRespDTO -> {
  49 + item.setDeptName(deptRespDTO.getName());
  50 + });
  51 + List<PostRespDTO> postRespList = MapUtils.getList(Multimaps.forMap(postMap), user.getPostIds());
  52 + item.setPostNames(CollectionUtils.convertSet(postRespList, PostRespDTO::getName));
46 53 });
47 54 return item;
48 55 });
49 56 }
50 57  
  58 + default List<CrmPermissionDO> convertList(CrmPermissionUpdateReqVO updateReqVO) {
  59 + List<CrmPermissionDO> permissions = new ArrayList<>();
  60 + updateReqVO.getIds().forEach(id -> {
  61 + permissions.add(new CrmPermissionDO().setId(id).setLevel(updateReqVO.getLevel()));
  62 + });
  63 + return permissions;
  64 + }
  65 +
51 66 }
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/customer/CrmCustomerDO.java
1 1 package cn.iocoder.yudao.module.crm.dal.dataobject.customer;
2 2  
3 3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import cn.iocoder.yudao.module.crm.enums.DictTypeConstants;
4 5 import com.baomidou.mybatisplus.annotation.KeySequence;
5 6 import com.baomidou.mybatisplus.annotation.TableId;
6 7 import com.baomidou.mybatisplus.annotation.TableName;
... ... @@ -49,19 +50,19 @@ public class CrmCustomerDO extends BaseDO {
49 50 /**
50 51 * 所属行业
51 52 *
52   - * 对应字典 {@link cn.iocoder.yudao.module.crm.enums.DictTypeConstants#CRM_CUSTOMER_INDUSTRY}
  53 + * 对应字典 {@link DictTypeConstants#CRM_CUSTOMER_INDUSTRY}
53 54 */
54 55 private Integer industryId;
55 56 /**
56 57 * 客户等级
57 58 *
58   - * 对应字典 {@link cn.iocoder.yudao.module.crm.enums.DictTypeConstants#CRM_CUSTOMER_LEVEL}
  59 + * 对应字典 {@link DictTypeConstants#CRM_CUSTOMER_LEVEL}
59 60 */
60 61 private Integer level;
61 62 /**
62 63 * 客户来源
63 64 *
64   - * 对应字典 {@link cn.iocoder.yudao.module.crm.enums.DictTypeConstants#CRM_CUSTOMER_SOURCE}
  65 + * 对应字典 {@link DictTypeConstants#CRM_CUSTOMER_SOURCE}
65 66 */
66 67 private Integer source;
67 68 /**
... ... @@ -97,21 +98,6 @@ public class CrmCustomerDO extends BaseDO {
97 98 */
98 99 private String remark;
99 100 /**
100   - * 负责人的用户编号
101   - *
102   - * 关联 AdminUserDO 的 id 字段
103   - */
104   - private Long ownerUserId;
105   - // TODO @puhui999:这块抽到 permission 里;
106   - /**
107   - * 只读权限的用户编号数组
108   - */
109   - private String roUserIds;
110   - /**
111   - * 读写权限的用户编号数组
112   - */
113   - private String rwUserIds;
114   - /**
115 101 * 地区编号
116 102 */
117 103 private Integer areaId;
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/permission/CrmPermissionDO.java
... ... @@ -23,7 +23,7 @@ import lombok.*;
23 23 @AllArgsConstructor
24 24 public class CrmPermissionDO extends BaseDO {
25 25  
26   - // TODO puhui999:是不是公海的数据,就不插入了;
  26 + // TODO puhui999:是不是公海的数据,就不插入了;这样方便获取公海数据鸭
27 27 /**
28 28 * 当数据变为公海数据时,也就是数据团队成员中没有负责人的时候,将原本的负责人 userId 设置为 POOL_USER_ID 方便查询公海数据。
29 29 * 也就是说每条数据到最后都有一个负责人,如果有人领取则 userId 为领取人
... ... @@ -59,12 +59,11 @@ public class CrmPermissionDO extends BaseDO {
59 59 */
60 60 private Long userId;
61 61  
62   - // TODO @puhui999:是不是搞成 level 字段;简洁一点,主要表明已经 perssmion 实体里了;
63 62 /**
64 63 * 权限级别
65 64 *
66 65 * 关联 {@link CrmPermissionLevelEnum}
67 66 */
68   - private Integer permissionLevel;
  67 + private Integer level;
69 68  
70 69 }
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessMapper.java
1 1 package cn.iocoder.yudao.module.crm.dal.mysql.business;
2 2  
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
3 4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
4 5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
5 6 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.CrmBusinessExportReqVO;
... ... @@ -18,14 +19,14 @@ import java.util.List;
18 19 @Mapper
19 20 public interface CrmBusinessMapper extends BaseMapperX<CrmBusinessDO> {
20 21  
21   - default List<CrmBusinessDO> selectList(CrmBusinessPageReqVO reqVO, Collection<Long> ids) {
22   - return selectList(new LambdaQueryWrapperX<CrmBusinessDO>()
  22 + default PageResult<CrmBusinessDO> selectPage(CrmBusinessPageReqVO reqVO, Collection<Long> ids) {
  23 + return selectPage(reqVO, new LambdaQueryWrapperX<CrmBusinessDO>()
23 24 .in(CrmBusinessDO::getId, ids)
24 25 .likeIfPresent(CrmBusinessDO::getName, reqVO.getName())
25 26 .orderByDesc(CrmBusinessDO::getId));
26 27 }
27 28  
28   - default List<CrmBusinessDO> selectList(CrmBusinessExportReqVO reqVO) {
  29 + default List<CrmBusinessDO> selectPage(CrmBusinessExportReqVO reqVO) {
29 30 return selectList(new LambdaQueryWrapperX<CrmBusinessDO>()
30 31 .likeIfPresent(CrmBusinessDO::getName, reqVO.getName())
31 32 .eqIfPresent(CrmBusinessDO::getStatusTypeId, reqVO.getStatusTypeId())
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/customer/CrmCustomerMapper.java
... ... @@ -3,12 +3,11 @@ package cn.iocoder.yudao.module.crm.dal.mysql.customer;
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
6   -import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerExportReqVO;
7 6 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerPageReqVO;
8 7 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
9 8 import org.apache.ibatis.annotations.Mapper;
10 9  
11   -import java.util.List;
  10 +import java.util.Collection;
12 11  
13 12 /**
14 13 * 客户 Mapper
... ... @@ -18,21 +17,14 @@ import java.util.List;
18 17 @Mapper
19 18 public interface CrmCustomerMapper extends BaseMapperX<CrmCustomerDO> {
20 19  
21   - default PageResult<CrmCustomerDO> selectPage(CrmCustomerPageReqVO reqVO) {
22   - return selectPage(reqVO, new LambdaQueryWrapperX<CrmCustomerDO>()
23   - .likeIfPresent(CrmCustomerDO::getName, reqVO.getName())
24   - .eqIfPresent(CrmCustomerDO::getMobile, reqVO.getMobile())
25   - .eqIfPresent(CrmCustomerDO::getIndustryId, reqVO.getIndustryId())
26   - .eqIfPresent(CrmCustomerDO::getLevel, reqVO.getLevel())
27   - .eqIfPresent(CrmCustomerDO::getSource, reqVO.getSource())
28   - .orderByDesc(CrmCustomerDO::getId));
29   - }
30   -
31   - default List<CrmCustomerDO> selectList(CrmCustomerExportReqVO reqVO) {
32   - return selectList(new LambdaQueryWrapperX<CrmCustomerDO>()
33   - .likeIfPresent(CrmCustomerDO::getName, reqVO.getName())
34   - .eqIfPresent(CrmCustomerDO::getMobile, reqVO.getMobile())
35   - .orderByDesc(CrmCustomerDO::getId));
  20 + default PageResult<CrmCustomerDO> selectPage(CrmCustomerPageReqVO pageReqVO, Collection<Long> ids) {
  21 + return selectPage(pageReqVO, new LambdaQueryWrapperX<CrmCustomerDO>()
  22 + .inIfPresent(CrmCustomerDO::getId, ids)
  23 + .likeIfPresent(CrmCustomerDO::getName, pageReqVO.getName())
  24 + .eqIfPresent(CrmCustomerDO::getMobile, pageReqVO.getMobile())
  25 + .eqIfPresent(CrmCustomerDO::getIndustryId, pageReqVO.getIndustryId())
  26 + .eqIfPresent(CrmCustomerDO::getLevel, pageReqVO.getLevel())
  27 + .eqIfPresent(CrmCustomerDO::getSource, pageReqVO.getSource()));
36 28 }
37 29  
38 30 }
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/permission/CrmPermissionMapper.java
1 1 package cn.iocoder.yudao.module.crm.dal.mysql.permission;
2 2  
3   -import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 3 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 4 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
6 5 import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO;
7   -import cn.iocoder.yudao.module.crm.framework.enums.CrmBizTypeEnum;
8   -import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionPageReqBO;
9 6 import org.apache.ibatis.annotations.Mapper;
10 7  
  8 +import java.util.Collection;
11 9 import java.util.List;
12 10  
13 11 /**
... ... @@ -18,15 +16,6 @@ import java.util.List;
18 16 @Mapper
19 17 public interface CrmPermissionMapper extends BaseMapperX<CrmPermissionDO> {
20 18  
21   - // TODO @puhui999:是不是不用谢这个注释;因为方法名,可以自解释;
22   - /**
23   - * 获取用户数据权限通过 数据类型 x 某个数据 x 用户编号
24   - *
25   - * @param bizType 数据类型,关联 {@link CrmBizTypeEnum}
26   - * @param bizId 数据编号,关联 {@link CrmBizTypeEnum} 对应模块 DO#getId()
27   - * @param userId 用户编号,AdminUser#id
28   - * @return Crm 数据权限
29   - */
30 19 default CrmPermissionDO selectByBizTypeAndBizIdByUserId(Integer bizType, Long bizId, Long userId) {
31 20 return selectOne(new LambdaQueryWrapperX<CrmPermissionDO>()
32 21 .eq(CrmPermissionDO::getBizType, bizType)
... ... @@ -34,24 +23,28 @@ public interface CrmPermissionMapper extends BaseMapperX&lt;CrmPermissionDO&gt; {
34 23 .eq(CrmPermissionDO::getUserId, userId));
35 24 }
36 25  
37   - // TODO @puhui999:是不是不用谢这个注释;因为方法名,可以自解释;
38   - /**
39   - * 获取数据权限列表通过 数据类型 x 某个数据
40   - *
41   - * @param bizType 数据类型,关联 {@link CrmBizTypeEnum}
42   - * @param bizId 数据编号,关联 {@link CrmBizTypeEnum} 对应模块 DO#getId()
43   - * @return Crm 数据权限列表
44   - */
45 26 default List<CrmPermissionDO> selectByBizTypeAndBizId(Integer bizType, Long bizId) {
46 27 return selectList(new LambdaQueryWrapperX<CrmPermissionDO>()
47 28 .eq(CrmPermissionDO::getBizType, bizType)
48 29 .eq(CrmPermissionDO::getBizId, bizId));
49 30 }
50 31  
51   - default PageResult<CrmPermissionDO> selectPage(CrmPermissionPageReqBO pageReqBO) {
52   - return selectPage(pageReqBO, new LambdaQueryWrapperX<CrmPermissionDO>()
53   - .eq(CrmPermissionDO::getBizType, pageReqBO.getBizType())
54   - .eq(CrmPermissionDO::getUserId, pageReqBO.getUserId())); // 只要是团队成员都有读取的权限
  32 + default List<CrmPermissionDO> selectListByBizTypeAndUserId(Integer bizType, Long userId) {
  33 + return selectList(new LambdaQueryWrapperX<CrmPermissionDO>()
  34 + .eq(CrmPermissionDO::getBizType, bizType)
  35 + .eq(CrmPermissionDO::getUserId, userId));
  36 + }
  37 +
  38 + default List<CrmPermissionDO> selectListByBizTypeAndBizIdsAndLevel(Integer bizType, Collection<Long> bizIds, Integer level) {
  39 + return selectList(new LambdaQueryWrapperX<CrmPermissionDO>()
  40 + .eq(CrmPermissionDO::getBizType, bizType)
  41 + .in(CrmPermissionDO::getBizId, bizIds)
  42 + .eq(CrmPermissionDO::getLevel, level));
  43 + }
  44 +
  45 + default CrmPermissionDO selectByIdAndUserId(Long id, Long userId) {
  46 + return selectOne(new LambdaQueryWrapperX<CrmPermissionDO>()
  47 + .eq(CrmPermissionDO::getId, id).eq(CrmPermissionDO::getUserId, userId));
55 48 }
56 49  
57 50 }
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/core/annotations/CrmPermission.java
... ... @@ -26,17 +26,21 @@ public @interface CrmPermission {
26 26 */
27 27 CrmBizTypeEnum bizType();
28 28  
29   - // TODO @puhui999:id,通过 spring el 表达式获取;
30 29 /**
31   - * 数据编号获取来源类,确保数据 id 编号在此类中,不能在父类中。
32   - * 例:如果在 baseVO 中需要把 id 弄到 updateVO 中。
  30 + * crm 类型扩展
  31 + * 用于 CrmPermissionController 团队权限校验
33 32 */
34   - Class<?>[] getIdFor() default {};
  33 + String bizTypeValue() default "";
35 34  
36   - // TODO @puhui999:是不是搞成 level 字段;简洁一点,主要表明已经 perssmion 实体里了;
37 35 /**
38   - * 操作类型
  36 + * 数据编号,通过 spring el 表达式获取
  37 + * TODO 数据权限完成后去除 default ""
39 38 */
40   - CrmPermissionLevelEnum permissionLevel();
  39 + String bizId() default "";
  40 +
  41 + /**
  42 + * 操作所需权限级别
  43 + */
  44 + CrmPermissionLevelEnum level();
41 45  
42 46 }
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/core/aop/CrmPermissionAspect.java
... ... @@ -2,24 +2,32 @@ package cn.iocoder.yudao.module.crm.framework.core.aop;
2 2  
3 3 import cn.hutool.core.collection.CollUtil;
4 4 import cn.hutool.core.util.ObjUtil;
  5 +import cn.iocoder.yudao.framework.common.core.KeyValue;
5 6 import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
6 7 import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO;
7 8 import cn.iocoder.yudao.module.crm.framework.core.annotations.CrmPermission;
  9 +import cn.iocoder.yudao.module.crm.framework.enums.CrmBizTypeEnum;
  10 +import cn.iocoder.yudao.module.crm.framework.enums.CrmPermissionLevelEnum;
8 11 import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService;
9 12 import lombok.extern.slf4j.Slf4j;
10 13 import org.aspectj.lang.JoinPoint;
11 14 import org.aspectj.lang.annotation.Aspect;
12 15 import org.aspectj.lang.annotation.Before;
  16 +import org.aspectj.lang.reflect.MethodSignature;
  17 +import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
  18 +import org.springframework.expression.EvaluationContext;
  19 +import org.springframework.expression.Expression;
  20 +import org.springframework.expression.spel.standard.SpelExpressionParser;
  21 +import org.springframework.expression.spel.support.StandardEvaluationContext;
13 22 import org.springframework.stereotype.Component;
14 23  
15 24 import javax.annotation.Resource;
16   -import java.lang.reflect.Field;
  25 +import java.lang.reflect.Method;
17 26 import java.util.List;
18 27  
19 28 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
20 29 import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
21 30 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CRM_PERMISSION_DENIED;
22   -import static cn.iocoder.yudao.module.crm.framework.enums.CrmPermissionLevelEnum.*;
23 31  
24 32 /**
25 33 * Crm 数据权限校验 AOP 切面
... ... @@ -32,6 +40,11 @@ import static cn.iocoder.yudao.module.crm.framework.enums.CrmPermissionLevelEnum
32 40 public class CrmPermissionAspect {
33 41  
34 42 @Resource
  43 + private LocalVariableTableParameterNameDiscoverer discoverer;
  44 + @Resource
  45 + private SpelExpressionParser parser;
  46 +
  47 + @Resource
35 48 private CrmPermissionService crmPermissionService;
36 49  
37 50 /**
... ... @@ -43,83 +56,109 @@ public class CrmPermissionAspect {
43 56 return WebFrameworkUtils.getLoginUserId();
44 57 }
45 58  
46   - // TODO @puhui999:id,通过 spring el 表达式获取;
47   - private Long getBizId(JoinPoint joinPoint, CrmPermission crmPermission) throws NoSuchFieldException, IllegalAccessException {
48   - Object[] args = joinPoint.getArgs();
49   - for (Object arg : args) {
50   - if (arg == null) {
51   - continue;
52   - }
53   - if (ObjUtil.notEqual(arg.getClass().getName(), crmPermission.getIdFor()[0].getName())) {
54   - continue;
55   - }
56   - // 使用反射获取id属性
57   - Field idValue = arg.getClass().getDeclaredField("id");
58   - // 设置字段为可访问
59   - idValue.setAccessible(true);
60   - return (Long) idValue.get(arg);
61   - }
62   - return null;
63   - }
64   -
65   - // TODO @puhui999:一般核心的方法,放到最前面,private 放后面。主要是,主次要分出来哈;
66 59 @Before("@annotation(crmPermission)")
67   - public void doBefore(JoinPoint joinPoint, CrmPermission crmPermission) {
  60 + public void doBefore(JoinPoint joinPoint, CrmPermission crmPermission) throws NoSuchMethodException {
68 61 // TODO 芋艿:临时,方便大家调试
69 62 if (true) {
70 63 return;
71 64 }
72   - try {
73   - Long bizId = crmPermission.getIdFor().length > 0 ? getBizId(joinPoint, crmPermission) : (Long) joinPoint.getArgs()[0]; // 获取操作数据的编号
74   - Integer bizType = crmPermission.bizType().getType(); // 模块类型
75   - Integer permissionLevel = crmPermission.permissionLevel().getLevel(); // 需要的权限级别
76   -
77   - // TODO 如果是超级管理员则直接通过
78   - //if (superAdmin){
79   - // return;
80   - //}
81   -
82   - // 1. 获取数据权限
83   - List<CrmPermissionDO> bizPermissions = crmPermissionService.getPermissionByBizTypeAndBizId(bizType, bizId);
84   - // TODO puhui999:这种情况下,最好是 CrmPermissionLevelEnum.isOwner
85   - // 2.1 情况一:如果自己是负责人,则默认有所有权限
86   - // TODO @puhui999:会不会存在空指针的问题?
87   - CrmPermissionDO userPermission = CollUtil.findOne(bizPermissions, item -> ObjUtil.equal(item.getUserId(), getUserId()));
88   - if (isOwner(userPermission.getPermissionLevel())) {
  65 + KeyValue<Long, Integer> bizIdAndBizType = getBizIdAndBizType(joinPoint, crmPermission);
  66 + Integer bizType = bizIdAndBizType.getValue(); // 模块类型
  67 + Long bizId = bizIdAndBizType.getKey(); // 模块数据编号
  68 + Integer permissionLevel = crmPermission.level().getLevel(); // 需要的权限级别
  69 +
  70 + // TODO 如果是超级管理员则直接通过
  71 + //if (superAdmin){
  72 + // return;
  73 + //}
  74 +
  75 + // 1. 获取数据权限
  76 + List<CrmPermissionDO> bizPermissions = crmPermissionService.getPermissionByBizTypeAndBizId(bizType, bizId);
  77 + // 2.1 情况一:如果自己是负责人,则默认有所有权限
  78 + // TODO @puhui999:会不会存在空指针的问题?
  79 + CrmPermissionDO userPermission = CollUtil.findOne(bizPermissions, item -> ObjUtil.equal(item.getUserId(), getUserId()));
  80 + if (CrmPermissionLevelEnum.isOwner(userPermission.getLevel())) {
  81 + return;
  82 + }
  83 + // 2.2 情况二:校验自己是否有读权限
  84 + if (CrmPermissionLevelEnum.isRead(permissionLevel)) {
  85 + // 如果没有数据权限或没有负责人则表示此记录为公海数据所有人都有只读权限可以领取成为负责人(团队成员领取的)
  86 + // TODO @puhui999:89 到 92 这块的逻辑,感觉可以不用 @CrmPermission,公海那自己 check 即可;
  87 + if (CollUtil.isEmpty(bizPermissions) || CollUtil.anyMatch(bizPermissions,
  88 + item -> ObjUtil.equal(item.getUserId(), CrmPermissionDO.POOL_USER_ID))) { // 详见 CrmPermissionDO.POOL_USER_ID 注释
89 89 return;
90 90 }
91   - // 2.2 情况二:校验自己是否有读权限
92   - if (isRead(permissionLevel)) {
93   - // 如果没有数据权限或没有负责人则表示此记录为公海数据所有人都有只读权限可以领取成为负责人(团队成员领取的)
94   - // TODO @puhui999:89 到 92 这块的逻辑,感觉可以不用 @CrmPermission,公海那自己 check 即可;
95   - if (CollUtil.isEmpty(bizPermissions) || CollUtil.anyMatch(bizPermissions,
96   - item -> ObjUtil.equal(item.getUserId(), CrmPermissionDO.POOL_USER_ID))) { // 详见 CrmPermissionDO.POOL_USER_ID 注释
97   - return;
98   - }
99   - if (isRead(userPermission.getPermissionLevel())) { // 校验当前用户是否有读权限
100   - return;
101   - }
102   - // 如果查询数据的话拥有写权限的也能查询
103   - if (isWrite(userPermission.getPermissionLevel())) { // 校验当前用户是否有写权限
104   - return;
105   - }
  91 + if (CrmPermissionLevelEnum.isRead(userPermission.getLevel())) { // 校验当前用户是否有读权限
  92 + return;
106 93 }
107   - // 2.3 情况三:校验自己是否有写权限
108   - if (isWrite(permissionLevel)) {
109   - if (isWrite(userPermission.getPermissionLevel())) { // 校验当前用户是否有写权限
110   - return;
111   - }
  94 + // 如果查询数据的话拥有写权限的也能查询
  95 + if (CrmPermissionLevelEnum.isWrite(userPermission.getLevel())) { // 校验当前用户是否有写权限
  96 + return;
  97 + }
  98 + }
  99 + // 2.3 情况三:校验自己是否有写权限
  100 + if (CrmPermissionLevelEnum.isWrite(permissionLevel)) {
  101 + if (CrmPermissionLevelEnum.isWrite(userPermission.getLevel())) { // 校验当前用户是否有写权限
  102 + return;
112 103 }
  104 + }
  105 +
  106 + // 打个 info 日志,方便后续排查问题、审计;
  107 + log.info("[doBefore][crmPermission({}) 数据校验错误]", toJsonString(userPermission));
  108 + throw exception(CRM_PERMISSION_DENIED, crmPermission.bizType().getName());
  109 + }
  110 +
  111 + private KeyValue<Long, Integer> getBizIdAndBizType(JoinPoint joinPoint, CrmPermission crmPermission) throws NoSuchMethodException {
  112 + Method method = getMethod(joinPoint);
  113 + // 1. 获取方法的参数值
  114 + Object[] args = joinPoint.getArgs();
  115 + EvaluationContext context = bindParam(method, args);
113 116  
114   - // 3. 没通过结束,报错 {} 操作失败,原因:没有权限
115   - // TODO @puhui999:这里打个 info 日志,方便后续排查问题、审计;
116   - throw exception(CRM_PERMISSION_DENIED, crmPermission.bizType().getName());
117   - } catch (Exception ex) {
118   - // TODO @puhui999:不用 catch 掉,就是系统异常;
119   - log.error("[doBefore][crmPermission({}) 数据校验错误]", toJsonString(crmPermission), ex);
120   - // TODO 报错抛个什么异常好呢
121   - throw exception(CRM_PERMISSION_DENIED, crmPermission.bizType().getName());
  117 + // 2. 根据spel表达式获取值
  118 + KeyValue<Long, Integer> keyValue = new KeyValue<>();
  119 + // 2.1 获取模块数据编号
  120 + Expression expression = parser.parseExpression(crmPermission.bizId());
  121 + keyValue.setKey(expression.getValue(context, Long.class));
  122 + // 2.2 获取模块类型
  123 + if (ObjUtil.equal(crmPermission.bizType().getType(), CrmBizTypeEnum.CRM_PERMISSION.getType())) {
  124 + // 情况一:用于 CrmPermissionController 中数据权限校验
  125 + Expression expression2 = parser.parseExpression(crmPermission.bizTypeValue());
  126 + keyValue.setValue(expression2.getValue(context, Integer.class));
  127 + return keyValue;
  128 + }
  129 + // 情况二:正常数据权限校验
  130 + keyValue.setValue(crmPermission.bizType().getType());
  131 + return keyValue;
  132 + }
  133 +
  134 + /**
  135 + * 获取当前执行的方法
  136 + */
  137 + private Method getMethod(JoinPoint joinPoint) throws NoSuchMethodException {
  138 + MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
  139 + Method method = methodSignature.getMethod();
  140 + return joinPoint.getTarget().getClass().getMethod(method.getName(), method.getParameterTypes());
  141 + }
  142 +
  143 + /**
  144 + * 将方法的参数名和参数值绑定
  145 + *
  146 + * @param method 方法,根据方法获取参数名
  147 + * @param args 方法的参数值
  148 + * @return 求值上下文
  149 + */
  150 + private EvaluationContext bindParam(Method method, Object[] args) {
  151 + //获取方法的参数名
  152 + String[] params = discoverer.getParameterNames(method);
  153 +
  154 + //将参数名与参数值对应起来
  155 + EvaluationContext context = new StandardEvaluationContext();
  156 + if (params != null) {
  157 + for (int len = 0; len < params.length; len++) {
  158 + context.setVariable(params[len], args[len]);
  159 + }
122 160 }
  161 + return context;
123 162 }
124 163  
125 164 }
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/core/config/SpelConfig.java 0 → 100644
  1 +package cn.iocoder.yudao.module.crm.framework.core.config;
  2 +
  3 +import org.springframework.context.annotation.Bean;
  4 +import org.springframework.context.annotation.Configuration;
  5 +import org.springframework.expression.spel.standard.SpelExpressionParser;
  6 +
  7 +/**
  8 + * 注册 Spel 所需 Bean
  9 + *
  10 + * @author HUIHUI
  11 + */
  12 +@Configuration
  13 +public class SpelConfig {
  14 +
  15 + @Bean
  16 + public SpelExpressionParser spelExpressionParser() {
  17 + return new SpelExpressionParser();
  18 + }
  19 +
  20 +}
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/core/service/CrmPermissionValidateService.java deleted
1   -package cn.iocoder.yudao.module.crm.framework.core.service;
2   -
3   -/**
4   - * 校验数据是否存在 service 接口
5   - * TODO 需要使用团队成员相关操作的业务接口都需要继承此接口
6   - *
7   - * @author HUIHUI
8   - */
9   -public interface CrmPermissionValidateService {
10   -
11   - /**
12   - * 校验数据是否存在
13   - *
14   - * @param bizType CRM 类型
15   - * @param bizId 数据编号
16   - * @return 是/否
17   - */
18   - boolean validateBizIdExists(Integer bizType, Long bizId);
19   -
20   -}
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/enums/CrmBizTypeEnum.java
1 1 package cn.iocoder.yudao.module.crm.framework.enums;
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.Getter;
... ... @@ -16,6 +17,7 @@ import java.util.Arrays;
16 17 @Getter
17 18 public enum CrmBizTypeEnum implements IntArrayValuable {
18 19  
  20 + CRM_PERMISSION(0, "团队"), // CrmPermissionController 中使用
19 21 CRM_LEADS(1, "线索"),
20 22 CRM_CUSTOMER(2, "客户"),
21 23 CRM_CONTACTS(3, "联系人"),
... ... @@ -33,13 +35,9 @@ public enum CrmBizTypeEnum implements IntArrayValuable {
33 35 private final String name;
34 36  
35 37 public static String getNameByType(Integer type) {
36   - // TODO @puhui999:可以 findone,更简洁;另外,不存在返回 null 即可啦;
37   - for (CrmBizTypeEnum crmBizTypeEnum : CrmBizTypeEnum.values()) {
38   - if (ObjUtil.equal(crmBizTypeEnum.type, type)) {
39   - return crmBizTypeEnum.name;
40   - }
41   - }
42   - return "";
  38 + CrmBizTypeEnum typeEnum = CollUtil.findOne(CollUtil.newArrayList(CrmBizTypeEnum.values()),
  39 + item -> ObjUtil.equal(item.type, type));
  40 + return typeEnum == null ? null : typeEnum.getName();
43 41 }
44 42  
45 43 @Override
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/enums/CrmPermissionLevelEnum.java
... ... @@ -48,14 +48,4 @@ public enum CrmPermissionLevelEnum implements IntArrayValuable {
48 48 return ObjUtil.equal(WRITE.level, level);
49 49 }
50 50  
51   - public static String getNameByLevel(Integer level) {
52   - // TODO @puhui999:可以 findone,更简洁;另外,不存在返回 null 即可啦;
53   - for (CrmPermissionLevelEnum levelEnum : CrmPermissionLevelEnum.values()) {
54   - if (ObjUtil.equal(levelEnum.level, level)) {
55   - return levelEnum.name;
56   - }
57   - }
58   - return "";
59   - }
60   -
61 51 }
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessService.java
... ... @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.crm.service.business;
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 4 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.*;
5 5 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
6   -import cn.iocoder.yudao.module.crm.framework.core.service.CrmPermissionValidateService;
7 6  
8 7 import javax.validation.Valid;
9 8 import java.util.Collection;
... ... @@ -14,7 +13,7 @@ import java.util.List;
14 13 *
15 14 * @author ljlleo
16 15 */
17   -public interface CrmBusinessService extends CrmPermissionValidateService {
  16 +public interface CrmBusinessService {
18 17  
19 18 /**
20 19 * 创建商机
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java
... ... @@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.crm.service.business;
2 2  
3 3 import cn.hutool.core.collection.CollUtil;
4 4 import cn.hutool.core.collection.ListUtil;
5   -import cn.hutool.core.util.ObjUtil;
6 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
7 6 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.*;
8 7 import cn.iocoder.yudao.module.crm.convert.business.CrmBusinessConvert;
... ... @@ -51,7 +50,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
51 50  
52 51 // 创建数据权限
53 52 crmPermissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_BUSINESS.getType())
54   - .setBizId(business.getId()).setUserId(userId).setPermissionLevel(CrmPermissionLevelEnum.OWNER.getLevel())); // 设置当前操作的人为负责人
  53 + .setBizId(business.getId()).setUserId(userId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); // 设置当前操作的人为负责人
55 54  
56 55 // 返回
57 56 return business.getId();
... ... @@ -59,8 +58,8 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
59 58  
60 59 @Override
61 60 @Transactional(rollbackFor = Exception.class)
62   - @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, getIdFor = CrmBusinessUpdateReqVO.class,
63   - permissionLevel = CrmPermissionLevelEnum.WRITE)
  61 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, bizId = "#updateReqVO.id",
  62 + level = CrmPermissionLevelEnum.WRITE)
64 63 public void updateBusiness(CrmBusinessUpdateReqVO updateReqVO) {
65 64 // 校验存在
66 65 validateBusinessExists(updateReqVO.getId());
... ... @@ -71,7 +70,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
71 70  
72 71 @Override
73 72 @Transactional(rollbackFor = Exception.class)
74   - @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, permissionLevel = CrmPermissionLevelEnum.WRITE)
  73 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, level = CrmPermissionLevelEnum.WRITE)
75 74 public void deleteBusiness(Long id) {
76 75 // 校验存在
77 76 validateBusinessExists(id);
... ... @@ -88,7 +87,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
88 87 }
89 88  
90 89 @Override
91   - @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, permissionLevel = CrmPermissionLevelEnum.READ)
  90 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, level = CrmPermissionLevelEnum.READ)
92 91 public CrmBusinessDO getBusiness(Long id) {
93 92 return businessMapper.selectById(id);
94 93 }
... ... @@ -104,21 +103,20 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
104 103 @Override
105 104 public PageResult<CrmBusinessDO> getBusinessPage(CrmBusinessPageReqVO pageReqVO, Long userId) {
106 105 // 1. 获取当前用户能看的分页数据
107   - PageResult<CrmPermissionDO> permissionPage = crmPermissionService.getPermissionPage(
108   - CrmBusinessConvert.INSTANCE.convert(pageReqVO).setBizType(CrmBizTypeEnum.CRM_BUSINESS.getType()).setUserId(userId));
109   - Set<Long> ids = convertSet(permissionPage.getList(), CrmPermissionDO::getBizId);
  106 + List<CrmPermissionDO> permissions = crmPermissionService.getPermissionListByBizTypeAndUserId(
  107 + CrmBizTypeEnum.CRM_BUSINESS.getType(), userId);
  108 + Set<Long> ids = convertSet(permissions, CrmPermissionDO::getBizId);
110 109 if (CollUtil.isEmpty(ids)) { // 没得说明没有什么给他看的
111 110 return PageResult.empty();
112 111 }
113 112  
114 113 // 2. 获取商机分页数据
115   - List<CrmBusinessDO> businessList = businessMapper.selectList(pageReqVO, ids);
116   - return new PageResult<>(businessList, (long) businessList.size());
  114 + return businessMapper.selectPage(pageReqVO, ids);
117 115 }
118 116  
119 117 @Override
120 118 public List<CrmBusinessDO> getBusinessList(CrmBusinessExportReqVO exportReqVO) {
121   - return businessMapper.selectList(exportReqVO);
  119 + return businessMapper.selectPage(exportReqVO);
122 120 }
123 121  
124 122 @Override
... ... @@ -134,14 +132,4 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
134 132 // 3. TODO 记录转移日志
135 133 }
136 134  
137   - @Override
138   - public boolean validateBizIdExists(Integer bizType, Long bizId) {
139   - // 1. 校验模块类型
140   - if (!ObjUtil.equal(CrmBizTypeEnum.CRM_BUSINESS.getType(), bizId)) {
141   - return false;
142   - }
143   - // 2. 校验是否存在
144   - return businessMapper.selectById(bizId) != null;
145   - }
146   -
147 135 }
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/ContactServiceImpl.java
... ... @@ -37,11 +37,18 @@ public class ContactServiceImpl implements ContactService {
37 37 // 插入
38 38 ContactDO contact = ContactConvert.INSTANCE.convert(createReqVO);
39 39 contactMapper.insert(contact);
  40 +
  41 + // 创建数据权限
  42 + crmPermissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_CONTACTS.getType())
  43 + .setBizId(contact.getId()).setUserId(userId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); // 设置当前操作的人为负责人
  44 +
40 45 // 返回
41 46 return contact.getId();
42 47 }
43 48  
44 49 @Override
  50 + @Transactional(rollbackFor = Exception.class)
  51 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACTS, level = CrmPermissionLevelEnum.WRITE)
45 52 public void updateContact(ContactUpdateReqVO updateReqVO) {
46 53 // 校验存在
47 54 validateContactExists(updateReqVO.getId());
... ... @@ -51,6 +58,8 @@ public class ContactServiceImpl implements ContactService {
51 58 }
52 59  
53 60 @Override
  61 + @Transactional(rollbackFor = Exception.class)
  62 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACTS, level = CrmPermissionLevelEnum.WRITE)
54 63 public void deleteContact(Long id) {
55 64 // 校验存在
56 65 validateContactExists(id);
... ... @@ -65,6 +74,7 @@ public class ContactServiceImpl implements ContactService {
65 74 }
66 75  
67 76 @Override
  77 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACTS, level = CrmPermissionLevelEnum.READ)
68 78 public ContactDO getContact(Long id) {
69 79 return contactMapper.selectById(id);
70 80 }
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/ContractServiceImpl.java
... ... @@ -46,7 +46,7 @@ public class ContractServiceImpl implements ContractService {
46 46  
47 47 // 创建数据权限
48 48 crmPermissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_CONTRACT.getType())
49   - .setBizId(contract.getId()).setUserId(userId).setPermissionLevel(CrmPermissionLevelEnum.OWNER.getLevel())); // 设置当前操作的人为负责人
  49 + .setBizId(contract.getId()).setUserId(userId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); // 设置当前操作的人为负责人
50 50  
51 51 // 返回
52 52 return contract.getId();
... ... @@ -54,8 +54,7 @@ public class ContractServiceImpl implements ContractService {
54 54  
55 55 @Override
56 56 @Transactional(rollbackFor = Exception.class)
57   - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, getIdFor = ContractUpdateReqVO.class,
58   - permissionLevel = CrmPermissionLevelEnum.WRITE)
  57 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, level = CrmPermissionLevelEnum.WRITE)
59 58 public void updateContract(ContractUpdateReqVO updateReqVO) {
60 59 // 校验存在
61 60 validateContractExists(updateReqVO.getId());
... ... @@ -66,7 +65,7 @@ public class ContractServiceImpl implements ContractService {
66 65  
67 66 @Override
68 67 @Transactional(rollbackFor = Exception.class)
69   - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, permissionLevel = CrmPermissionLevelEnum.WRITE)
  68 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, level = CrmPermissionLevelEnum.WRITE)
70 69 public void deleteContract(Long id) {
71 70 // 校验存在
72 71 validateContractExists(id);
... ... @@ -83,7 +82,7 @@ public class ContractServiceImpl implements ContractService {
83 82 }
84 83  
85 84 @Override
86   - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, permissionLevel = CrmPermissionLevelEnum.READ)
  85 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, level = CrmPermissionLevelEnum.READ)
87 86 public ContractDO getContract(Long id) {
88 87 return contractMapper.selectById(id);
89 88 }
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerService.java
... ... @@ -5,7 +5,6 @@ import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.*;
5 5 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
6 6  
7 7 import javax.validation.Valid;
8   -import java.util.Collection;
9 8 import java.util.List;
10 9  
11 10 /**
... ... @@ -50,9 +49,10 @@ public interface CrmCustomerService {
50 49 * 获得客户分页
51 50 *
52 51 * @param pageReqVO 分页查询
  52 + * @param userId 用户编号
53 53 * @return 客户分页
54 54 */
55   - PageResult<CrmCustomerDO> getCustomerPage(CrmCustomerPageReqVO pageReqVO);
  55 + PageResult<CrmCustomerDO> getCustomerPage(CrmCustomerPageReqVO pageReqVO, Long userId);
56 56  
57 57 /**
58 58 * 获得客户列表, 用于 Excel 导出
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java
1 1 package cn.iocoder.yudao.module.crm.service.customer;
2 2  
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.util.ObjUtil;
3 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  6 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
4 7 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.*;
5 8 import cn.iocoder.yudao.module.crm.convert.customer.CrmCustomerConvert;
6 9 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
  10 +import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO;
7 11 import cn.iocoder.yudao.module.crm.dal.mysql.customer.CrmCustomerMapper;
  12 +import cn.iocoder.yudao.module.crm.enums.customer.CrmCustomerSceneEnum;
8 13 import cn.iocoder.yudao.module.crm.framework.core.annotations.CrmPermission;
9 14 import cn.iocoder.yudao.module.crm.framework.enums.CrmBizTypeEnum;
10 15 import cn.iocoder.yudao.module.crm.framework.enums.CrmPermissionLevelEnum;
... ... @@ -15,10 +20,13 @@ import org.springframework.transaction.annotation.Transactional;
15 20 import org.springframework.validation.annotation.Validated;
16 21  
17 22 import javax.annotation.Resource;
  23 +import java.util.Collections;
18 24 import java.util.List;
19 25 import java.util.Objects;
  26 +import java.util.Set;
20 27  
21 28 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  29 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
22 30 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CUSTOMER_NOT_EXISTS;
23 31  
24 32 /**
... ... @@ -43,7 +51,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
43 51  
44 52 // 创建数据权限
45 53 crmPermissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType())
46   - .setBizId(customer.getId()).setUserId(userId).setPermissionLevel(CrmPermissionLevelEnum.OWNER.getLevel())); // 设置当前操作的人为负责人
  54 + .setBizId(customer.getId()).setUserId(userId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); // 设置当前操作的人为负责人
47 55  
48 56 // 返回
49 57 return customer.getId();
... ... @@ -51,12 +59,10 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
51 59  
52 60 @Override
53 61 @Transactional(rollbackFor = Exception.class)
54   - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, getIdFor = CrmCustomerUpdateReqVO.class,
55   - permissionLevel = CrmPermissionLevelEnum.WRITE)
  62 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE)
56 63 public void updateCustomer(CrmCustomerUpdateReqVO updateReqVO) {
57 64 // 校验存在
58 65 validateCustomerExists(updateReqVO.getId());
59   - // TODO 芋艿:数据权限,校验是否可以操作
60 66  
61 67 // 更新
62 68 CrmCustomerDO updateObj = CrmCustomerConvert.INSTANCE.convert(updateReqVO);
... ... @@ -65,11 +71,10 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
65 71  
66 72 @Override
67 73 @Transactional(rollbackFor = Exception.class)
68   - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, permissionLevel = CrmPermissionLevelEnum.WRITE)
  74 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#id", level = CrmPermissionLevelEnum.OWNER)
69 75 public void deleteCustomer(Long id) {
70 76 // 校验存在
71 77 validateCustomerExists(id);
72   - // TODO 芋艿:数据权限,校验是否可以操作
73 78  
74 79 // 删除
75 80 customerMapper.deleteById(id);
... ... @@ -82,20 +87,38 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
82 87 }
83 88  
84 89 @Override
85   - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, permissionLevel = CrmPermissionLevelEnum.READ)
  90 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#id", level = CrmPermissionLevelEnum.READ)
86 91 public CrmCustomerDO getCustomer(Long id) {
87 92 return customerMapper.selectById(id);
88 93 }
89 94  
90 95 @Override
91   - public PageResult<CrmCustomerDO> getCustomerPage(CrmCustomerPageReqVO pageReqVO) {
92   - // TODO 芋艿:数据权限,是否可以查询到;
93   - return customerMapper.selectPage(pageReqVO);
  96 + public PageResult<CrmCustomerDO> getCustomerPage(CrmCustomerPageReqVO pageReqVO, Long userId) {
  97 + // 1.1 TODO 如果是超级管理员
  98 + boolean admin = false;
  99 + if (admin && ObjUtil.notEqual(userId, CrmPermissionDO.POOL_USER_ID)) {
  100 + return customerMapper.selectPage(pageReqVO, Collections.emptyList());
  101 + }
  102 + // 1.2 获取当前用户能看的分页数据
  103 + List<CrmPermissionDO> permissions = crmPermissionService.getPermissionListByBizTypeAndUserId(
  104 + CrmBizTypeEnum.CRM_CUSTOMER.getType(), userId);
  105 + // 1.3 TODO 场景数据过滤
  106 + if (CrmCustomerSceneEnum.isOwner(pageReqVO.getSceneType())) { // 场景一:我负责的数据
  107 + permissions = CollectionUtils.filterList(permissions, item -> CrmPermissionLevelEnum.isOwner(item.getLevel()));
  108 + }
  109 + Set<Long> ids = convertSet(permissions, CrmPermissionDO::getBizId);
  110 + if (CollUtil.isEmpty(ids)) { // 没得说明没有什么给他看的
  111 + return PageResult.empty();
  112 + }
  113 +
  114 + // 2. 获取客户分页数据
  115 + return customerMapper.selectPage(pageReqVO, ids);
94 116 }
95 117  
96 118 @Override
97 119 public List<CrmCustomerDO> getCustomerList(CrmCustomerExportReqVO exportReqVO) {
98   - return customerMapper.selectList(exportReqVO);
  120 + //return customerMapper.selectList(exportReqVO);
  121 + return Collections.emptyList();
99 122 }
100 123  
101 124 /**
... ...
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.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionUpdateReqVO;
5 5 import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO;
6 6 import cn.iocoder.yudao.module.crm.framework.enums.CrmBizTypeEnum;
7 7 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO;
8   -import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionPageReqBO;
9   -import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionUpdateReqBO;
10   -import cn.iocoder.yudao.module.crm.service.permission.bo.CrmTransferPermissionReqBO;
  8 +import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO;
11 9  
12 10 import javax.validation.Valid;
  11 +import java.util.Collection;
13 12 import java.util.List;
14 13  
15 14 /**
... ... @@ -30,16 +29,16 @@ public interface CrmPermissionService {
30 29 /**
31 30 * 更新数据权限
32 31 *
33   - * @param updateBO 更新信息
  32 + * @param updateReqVO 更新信息
34 33 */
35   - void updatePermission(@Valid CrmPermissionUpdateReqBO updateBO);
  34 + void updatePermission(CrmPermissionUpdateReqVO updateReqVO);
36 35  
37 36 /**
38 37 * 删除数据权限
39 38 *
40   - * @param id 编号
  39 + * @param ids 编号
41 40 */
42   - void deletePermission(Long id);
  41 + void deletePermission(Collection<Long> ids);
43 42  
44 43 /**
45 44 * 获取用户数据权限通过 数据类型 x 某个数据 x 用户编号
... ... @@ -52,6 +51,15 @@ public interface CrmPermissionService {
52 51 CrmPermissionDO getPermissionByBizTypeAndBizIdAndUserId(Integer bizType, Long bizId, Long userId);
53 52  
54 53 /**
  54 + * 获取用户数据权限通过 权限编号 x 用户编号
  55 + *
  56 + * @param id 权限编号
  57 + * @param userId 用户编号
  58 + * @return 数据权限
  59 + */
  60 + CrmPermissionDO getPermissionByIdAndUserId(Long id, Long userId);
  61 +
  62 + /**
55 63 * 获取数据权限列表,通过 数据类型 x 某个数据
56 64 *
57 65 * @param bizType 数据类型,关联 {@link CrmBizTypeEnum}
... ... @@ -61,18 +69,47 @@ public interface CrmPermissionService {
61 69 List<CrmPermissionDO> getPermissionByBizTypeAndBizId(Integer bizType, Long bizId);
62 70  
63 71 /**
  72 + * 获取数据权限列表,通过 数据类型 x 某个数据
  73 + *
  74 + * @param bizType 数据类型,关联 {@link CrmBizTypeEnum}
  75 + * @param bizIds 数据编号,关联 {@link CrmBizTypeEnum} 对应模块 DO#getId()
  76 + * @param level 权限级别
  77 + * @return Crm 数据权限列表
  78 + */
  79 + List<CrmPermissionDO> getPermissionByBizTypeAndBizIdsAndLevel(Integer bizType, Collection<Long> bizIds, Integer level);
  80 +
  81 + /**
64 82 * 数据权限转移
65 83 *
66   - * @param crmTransferPermissionReqBO 数据权限转移请求
  84 + * @param crmPermissionTransferReqBO 数据权限转移请求
67 85 */
68   - void transferPermission(@Valid CrmTransferPermissionReqBO crmTransferPermissionReqBO);
  86 + void transferPermission(@Valid CrmPermissionTransferReqBO crmPermissionTransferReqBO);
69 87  
70 88 /**
71   - * 获取数据权限分页数据
  89 + * 获取用户参与的模块数据列表
72 90 *
73   - * @param pageReqBO 分页请求
74   - * @return 数据权限分页数据
  91 + * @param bizType 模块类型
  92 + * @param userId 用户编号
  93 + * @return 模块数据列表
  94 + */
  95 + List<CrmPermissionDO> getPermissionListByBizTypeAndUserId(Integer bizType, Long userId);
  96 +
  97 + /**
  98 + * 领取公海数据
  99 + *
  100 + * @param bizType 数据类型,关联 {@link CrmBizTypeEnum}
  101 + * @param bizId 数据编号,关联 {@link CrmBizTypeEnum} 对应模块 DO#getId()
  102 + * @param userId 用户编号,AdminUser#id
  103 + */
  104 + void receiveBiz(Integer bizType, Long bizId, Long userId);
  105 +
  106 + /**
  107 + * 数据放入公海
  108 + *
  109 + * @param bizType 数据类型,关联 {@link CrmBizTypeEnum}
  110 + * @param bizId 数据编号,关联 {@link CrmBizTypeEnum} 对应模块 DO#getId()
  111 + * @param userId 用户编号,AdminUser#id
75 112 */
76   - PageResult<CrmPermissionDO> getPermissionPage(CrmPermissionPageReqBO pageReqBO);
  113 + void putPool(Integer bizType, Long bizId, Long userId);
77 114  
78 115 }
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionServiceImpl.java
... ... @@ -2,22 +2,21 @@ package cn.iocoder.yudao.module.crm.service.permission;
2 2  
3 3 import cn.hutool.core.collection.CollUtil;
4 4 import cn.hutool.core.util.ObjUtil;
5   -import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionUpdateReqVO;
6 6 import cn.iocoder.yudao.module.crm.convert.permission.CrmPermissionConvert;
7 7 import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO;
8 8 import cn.iocoder.yudao.module.crm.dal.mysql.permission.CrmPermissionMapper;
9 9 import cn.iocoder.yudao.module.crm.framework.enums.CrmBizTypeEnum;
10 10 import cn.iocoder.yudao.module.crm.framework.enums.CrmPermissionLevelEnum;
11 11 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO;
12   -import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionPageReqBO;
13   -import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionUpdateReqBO;
14   -import cn.iocoder.yudao.module.crm.service.permission.bo.CrmTransferPermissionReqBO;
  12 +import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO;
15 13 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
16 14 import org.springframework.stereotype.Service;
17 15 import org.springframework.transaction.annotation.Transactional;
18 16 import org.springframework.validation.annotation.Validated;
19 17  
20 18 import javax.annotation.Resource;
  19 +import java.util.Collection;
21 20 import java.util.Collections;
22 21 import java.util.List;
23 22  
... ... @@ -54,26 +53,22 @@ public class CrmPermissionServiceImpl implements CrmPermissionService {
54 53  
55 54 @Override
56 55 @Transactional(rollbackFor = Exception.class)
57   - public void updatePermission(CrmPermissionUpdateReqBO updateBO) {
58   - // TODO @puhui999:这里 1.1 1.2;下面 2.;这样更有序一点;
59   - // 1. 校验用户是否存在
60   - adminUserApi.validateUserList(Collections.singletonList(updateBO.getUserId()));
61   - // 2. 校验存在
62   - validateCrmPermissionExists(updateBO.getId());
  56 + public void updatePermission(CrmPermissionUpdateReqVO updateReqVO) {
  57 + // 校验存在
  58 + validateCrmPermissionExists(updateReqVO.getIds());
63 59  
64   - // 更新操作
65   - CrmPermissionDO updateDO = CrmPermissionConvert.INSTANCE.convert(updateBO);
66   - crmPermissionMapper.updateById(updateDO);
  60 + List<CrmPermissionDO> updateDO = CrmPermissionConvert.INSTANCE.convertList(updateReqVO);
  61 + crmPermissionMapper.updateBatch(updateDO);
67 62 }
68 63  
69 64 @Override
70 65 @Transactional(rollbackFor = Exception.class)
71   - public void deletePermission(Long id) {
  66 + public void deletePermission(Collection<Long> ids) {
72 67 // 校验存在
73   - validateCrmPermissionExists(id);
  68 + validateCrmPermissionExists(ids);
74 69  
75 70 // 删除
76   - crmPermissionMapper.deleteById(id);
  71 + crmPermissionMapper.deleteBatchIds(ids);
77 72 }
78 73  
79 74 @Override
... ... @@ -82,62 +77,95 @@ public class CrmPermissionServiceImpl implements CrmPermissionService {
82 77 }
83 78  
84 79 @Override
  80 + public CrmPermissionDO getPermissionByIdAndUserId(Long id, Long userId) {
  81 + return crmPermissionMapper.selectByIdAndUserId(id, userId);
  82 + }
  83 +
  84 + @Override
85 85 public List<CrmPermissionDO> getPermissionByBizTypeAndBizId(Integer bizType, Long bizId) {
86 86 return crmPermissionMapper.selectByBizTypeAndBizId(bizType, bizId);
87 87 }
88 88  
89   - private void validateCrmPermissionExists(Long id) {
90   - if (crmPermissionMapper.selectById(id) == null) {
  89 + @Override
  90 + public List<CrmPermissionDO> getPermissionByBizTypeAndBizIdsAndLevel(Integer bizType, Collection<Long> bizIds, Integer level) {
  91 + return crmPermissionMapper.selectListByBizTypeAndBizIdsAndLevel(bizType, bizIds, level);
  92 + }
  93 +
  94 + private void validateCrmPermissionExists(Collection<Long> ids) {
  95 + List<CrmPermissionDO> permissionList = crmPermissionMapper.selectBatchIds(ids);
  96 + // 校验存在
  97 + if (ObjUtil.notEqual(permissionList.size(), ids.size())) {
91 98 throw exception(CRM_PERMISSION_NOT_EXISTS);
92 99 }
93 100 }
94 101  
95 102 @Override
96   - public void transferPermission(CrmTransferPermissionReqBO transferReqBO) {
  103 + @Transactional(rollbackFor = Exception.class)
  104 + public void transferPermission(CrmPermissionTransferReqBO transferReqBO) {
97 105 // 1. 校验数据权限-是否是负责人,只有负责人才可以转移
98 106 CrmPermissionDO oldPermission = crmPermissionMapper.selectByBizTypeAndBizIdByUserId(transferReqBO.getBizType(),
99 107 transferReqBO.getBizId(), transferReqBO.getUserId());
100 108 String crmName = CrmBizTypeEnum.getNameByType(transferReqBO.getBizType());
101 109 // TODO 校验是否为超级管理员 || 1
102   - if (oldPermission == null || !isOwner(oldPermission.getPermissionLevel())) {
  110 + if (oldPermission == null || !isOwner(oldPermission.getLevel())) {
103 111 throw exception(CRM_PERMISSION_DENIED, crmName);
104 112 }
105   -
106   - // TODO @puhui999:这个顺序编号,看看调整下;2. 后面是 2.1 ,结果没 2.2 有点怪;
107   - // 2. 校验转移对象是否已经是该负责人
  113 + // 1.1 校验转移对象是否已经是该负责人
108 114 if (ObjUtil.equal(transferReqBO.getNewOwnerUserId(), oldPermission.getUserId())) {
109 115 throw exception(CRM_PERMISSION_MODEL_TRANSFER_FAIL_OWNER_USER_EXISTS, crmName);
110 116 }
111   - // 2.1 校验新负责人是否存在
  117 + // 1.2 校验新负责人是否存在
112 118 adminUserApi.validateUserList(Collections.singletonList(transferReqBO.getNewOwnerUserId()));
113   - // 3. 权限转移
  119 +
  120 + // 2. 权限转移
114 121 List<CrmPermissionDO> permissions = crmPermissionMapper.selectByBizTypeAndBizId(
115 122 transferReqBO.getBizType(), transferReqBO.getBizId()); // 获取所有团队成员
116   - // 3.1 校验新负责人是否在团队成员中
  123 + // 2.1 校验新负责人是否在团队成员中
117 124 CrmPermissionDO permission = CollUtil.findOne(permissions,
118 125 item -> ObjUtil.equal(item.getUserId(), transferReqBO.getNewOwnerUserId()));
119 126 if (permission == null) { // 不存在则以负责人的级别加入这个团队
120 127 crmPermissionMapper.insert(new CrmPermissionDO().setBizType(transferReqBO.getBizType())
121 128 .setBizId(transferReqBO.getBizId()).setUserId(transferReqBO.getNewOwnerUserId())
122   - .setPermissionLevel(CrmPermissionLevelEnum.OWNER.getLevel()));
  129 + .setLevel(CrmPermissionLevelEnum.OWNER.getLevel()));
123 130  
124 131 } else { // 存在则修改权限级别
125 132 crmPermissionMapper.updateById(new CrmPermissionDO().setId(permission.getId())
126   - .setPermissionLevel(CrmPermissionLevelEnum.OWNER.getLevel()));
  133 + .setLevel(CrmPermissionLevelEnum.OWNER.getLevel()));
127 134 }
128   -
129   - // 4. 老负责人处理
130   - if (transferReqBO.getJoinTeam()) { // 加入团队
  135 + // 2.2. 老负责人处理
  136 + if (transferReqBO.getOldOwnerPermissionLevel() != null) { // 加入团队
131 137 crmPermissionMapper.updateById(new CrmPermissionDO().setId(oldPermission.getId())
132   - .setPermissionLevel(transferReqBO.getPermissionLevel())); // 设置加入团队后的级别
  138 + .setLevel(transferReqBO.getOldOwnerPermissionLevel())); // 设置加入团队后的级别
133 139 return;
134 140 }
135 141 crmPermissionMapper.deleteById(oldPermission.getId()); // 移除
136 142 }
137 143  
138 144 @Override
139   - public PageResult<CrmPermissionDO> getPermissionPage(CrmPermissionPageReqBO pageReqBO) {
140   - return crmPermissionMapper.selectPage(pageReqBO);
  145 + public List<CrmPermissionDO> getPermissionListByBizTypeAndUserId(Integer bizType, Long userId) {
  146 + return crmPermissionMapper.selectListByBizTypeAndUserId(bizType, userId);
  147 + }
  148 +
  149 + @Override
  150 + @Transactional(rollbackFor = Exception.class)
  151 + public void receiveBiz(Integer bizType, Long bizId, Long userId) {
  152 + CrmPermissionDO permission = crmPermissionMapper.selectByBizTypeAndBizIdByUserId(bizType, bizId, CrmPermissionDO.POOL_USER_ID);
  153 + if (permission == null) { // 不存在则模块数据也不存在
  154 + throw exception(CRM_PERMISSION_MODEL_NOT_EXISTS, CrmBizTypeEnum.getNameByType(bizType));
  155 + }
  156 +
  157 + crmPermissionMapper.updateById(new CrmPermissionDO().setId(permission.getId()).setUserId(userId));
  158 + }
  159 +
  160 + @Override
  161 + @Transactional(rollbackFor = Exception.class)
  162 + public void putPool(Integer bizType, Long bizId, Long userId) {
  163 + CrmPermissionDO permission = crmPermissionMapper.selectByBizTypeAndBizIdByUserId(bizType, bizId, userId);
  164 + if (permission == null) { // 不存在则模块数据也不存在
  165 + throw exception(CRM_PERMISSION_MODEL_NOT_EXISTS, CrmBizTypeEnum.getNameByType(bizType));
  166 + }
  167 +
  168 + crmPermissionMapper.updateById(new CrmPermissionDO().setId(permission.getId()).setUserId(CrmPermissionDO.POOL_USER_ID));
141 169 }
142 170  
143 171 }
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/bo/CrmPermissionCreateReqBO.java
... ... @@ -33,12 +33,11 @@ public class CrmPermissionCreateReqBO {
33 33 @NotNull(message = "Crm 数据编号不能为空")
34 34 private Long bizId;
35 35  
36   - // TODO @puhui999:简化成 level
37 36 /**
38 37 * 权限级别
39 38 */
40 39 @NotNull(message = "权限级别不能为空")
41 40 @InEnum(CrmPermissionLevelEnum.class)
42   - private Integer permissionLevel;
  41 + private Integer level;
43 42  
44 43 }
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/bo/CrmPermissionPageReqBO.java deleted
1   -package cn.iocoder.yudao.module.crm.service.permission.bo;
2   -
3   -import cn.iocoder.yudao.framework.common.pojo.PageParam;
4   -import cn.iocoder.yudao.framework.common.validation.InEnum;
5   -import cn.iocoder.yudao.module.crm.framework.enums.CrmBizTypeEnum;
6   -import io.swagger.v3.oas.annotations.media.Schema;
7   -import lombok.Data;
8   -import lombok.EqualsAndHashCode;
9   -import lombok.ToString;
10   -
11   -import javax.validation.constraints.NotNull;
12   -
13   -@Schema(description = "管理后台 - CRM 数据权限分页 Request BO")
14   -@Data
15   -@EqualsAndHashCode(callSuper = true)
16   -@ToString(callSuper = true)
17   -public class CrmPermissionPageReqBO extends PageParam {
18   -
19   - /**
20   - * 当前登录用户编号
21   - */
22   - @NotNull(message = "用户编号不能为空")
23   - private Long userId;
24   -
25   - /**
26   - * Crm 类型
27   - */
28   - @NotNull(message = "Crm 类型不能为空")
29   - @InEnum(CrmBizTypeEnum.class)
30   - private Integer bizType;
31   -
32   -}
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/bo/CrmTransferPermissionReqBO.java renamed to yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/bo/CrmPermissionTransferReqBO.java
... ... @@ -7,14 +7,13 @@ import lombok.Data;
7 7  
8 8 import javax.validation.constraints.NotNull;
9 9  
10   -// TODO @puhui999:CrmPermissionTransferReqBO
11 10 /**
12 11 * 数据权限转移 Request BO
13 12 *
14 13 * @author HUIHUI
15 14 */
16 15 @Data
17   -public class CrmTransferPermissionReqBO {
  16 +public class CrmPermissionTransferReqBO {
18 17  
19 18 /**
20 19 * 当前登录用户编号
... ... @@ -40,17 +39,10 @@ public class CrmTransferPermissionReqBO {
40 39 @NotNull(message = "新负责人的用户编号不能为空")
41 40 private Long newOwnerUserId;
42 41  
43   - // TODO @puhui999:joinTeam 可以合并成 permissionLevel 里;oldOwnerPermissionLevel;这样 null 说明移除,因为都换负责人啦;
44 42 /**
45   - * 老负责人是否加入团队,是/否
46   - */
47   - @NotNull(message = "老负责人是否加入团队不能为空")
48   - private Boolean joinTeam;
49   -
50   - /**
51   - * 老负责人加入团队后的权限级别。如果 {@link #joinTeam} 为 false, permissionLevel 为 null
  43 + * 老负责人加入团队后的权限级别。如果 null 说明移除
52 44 * 关联 {@link CrmPermissionLevelEnum}
53 45 */
54   - private Integer permissionLevel;
  46 + private Integer oldOwnerPermissionLevel;
55 47  
56 48 }
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/bo/CrmPermissionUpdateReqBO.java
1 1 package cn.iocoder.yudao.module.crm.service.permission.bo;
2 2  
3 3 import cn.iocoder.yudao.framework.common.validation.InEnum;
4   -import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO;
5   -import cn.iocoder.yudao.module.crm.framework.enums.CrmBizTypeEnum;
6 4 import cn.iocoder.yudao.module.crm.framework.enums.CrmPermissionLevelEnum;
7 5 import lombok.Data;
8 6  
... ... @@ -28,25 +26,11 @@ public class CrmPermissionUpdateReqBO {
28 26 @NotNull(message = "用户编号不能为空")
29 27 private Long userId;
30 28  
31   - // TODO @puhui999:id 字段,和 bizType + bizId 是否二选一;
32   - /**
33   - * Crm 类型
34   - */
35   - @NotNull(message = "Crm 类型不能为空")
36   - @InEnum(CrmBizTypeEnum.class)
37   - private Integer bizType;
38   - /**
39   - * 数据编号
40   - */
41   - @NotNull(message = "Crm 数据编号不能为空")
42   - private Long bizId;
43   -
44   - // TODO @puhui999:简化成 level
45 29 /**
46 30 * 权限级别
47 31 */
48 32 @NotNull(message = "权限级别不能为空")
49 33 @InEnum(CrmPermissionLevelEnum.class)
50   - private Integer permissionLevel;
  34 + private Integer level;
51 35  
52 36 }
... ...
yudao-module-crm/yudao-module-crm-biz/src/test/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImplTest.java
... ... @@ -130,7 +130,7 @@ public class CrmCustomerServiceImplTest extends BaseDbUnitTest {
130 130 //reqVO.setWebsite(null);
131 131  
132 132 // 调用
133   - PageResult<CrmCustomerDO> pageResult = customerService.getCustomerPage(reqVO);
  133 + PageResult<CrmCustomerDO> pageResult = customerService.getCustomerPage(reqVO, 1L);
134 134 // 断言
135 135 assertEquals(1, pageResult.getTotal());
136 136 assertEquals(1, pageResult.getList().size());
... ...
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/dept/PostApi.java
1 1 package cn.iocoder.yudao.module.system.api.dept;
2 2  
  3 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  4 +import cn.iocoder.yudao.module.system.api.dept.dto.PostRespDTO;
  5 +
3 6 import java.util.Collection;
  7 +import java.util.List;
  8 +import java.util.Map;
4 9  
5 10 /**
6 11 * 岗位 API 接口
... ... @@ -18,4 +23,11 @@ public interface PostApi {
18 23 */
19 24 void validPostList(Collection<Long> ids);
20 25  
  26 + List<PostRespDTO> getPostList(Collection<Long> ids);
  27 +
  28 + default Map<Long, PostRespDTO> getPostMap(Collection<Long> ids) {
  29 + List<PostRespDTO> list = getPostList(ids);
  30 + return CollectionUtils.convertMap(list, PostRespDTO::getId);
  31 + }
  32 +
21 33 }
... ...
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/dept/dto/PostRespDTO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.system.api.dept.dto;
  2 +
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  4 +import lombok.Data;
  5 +
  6 +/**
  7 + * 岗位 Response DTO
  8 + *
  9 + * @author 芋道源码
  10 + */
  11 +@Data
  12 +public class PostRespDTO {
  13 +
  14 + /**
  15 + * 岗位序号
  16 + */
  17 + private Long id;
  18 + /**
  19 + * 岗位名称
  20 + */
  21 + private String name;
  22 + /**
  23 + * 岗位编码
  24 + */
  25 + private String code;
  26 + /**
  27 + * 岗位排序
  28 + */
  29 + private Integer sort;
  30 + /**
  31 + * 状态
  32 + *
  33 + * 枚举 {@link CommonStatusEnum}
  34 + */
  35 + private Integer status;
  36 +
  37 +}
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/dept/PostApiImpl.java
1 1 package cn.iocoder.yudao.module.system.api.dept;
2 2  
  3 +import cn.iocoder.yudao.module.system.api.dept.dto.PostRespDTO;
  4 +import cn.iocoder.yudao.module.system.convert.dept.PostConvert;
3 5 import cn.iocoder.yudao.module.system.service.dept.PostService;
4 6 import org.springframework.stereotype.Service;
5 7  
6 8 import javax.annotation.Resource;
7 9 import java.util.Collection;
  10 +import java.util.List;
8 11  
9 12 /**
10 13 * 岗位 API 实现类
... ... @@ -22,4 +25,9 @@ public class PostApiImpl implements PostApi {
22 25 postService.validatePostList(ids);
23 26 }
24 27  
  28 + @Override
  29 + public List<PostRespDTO> getPostList(Collection<Long> ids) {
  30 + return PostConvert.INSTANCE.convert(postService.getPostList(ids));
  31 + }
  32 +
25 33 }
... ...