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,19 +21,11 @@ public class CrmBusinessTransferReqVO {
21 @Schema(description = "新负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430") 21 @Schema(description = "新负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
22 private Long newOwnerUserId; 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 * 关联 {@link CrmPermissionLevelEnum} 26 * 关联 {@link CrmPermissionLevelEnum}
35 */ 27 */
36 @Schema(description = "老负责人加入团队后的权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") 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,18 +21,11 @@ public class CrmContactTransferReqVO {
21 @Schema(description = "新负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430") 21 @Schema(description = "新负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
22 private Long newOwnerUserId; 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 * 关联 {@link CrmPermissionLevelEnum} 26 * 关联 {@link CrmPermissionLevelEnum}
34 */ 27 */
35 @Schema(description = "老负责人加入团队后的权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") 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,19 +21,11 @@ public class CrmContractTransferReqVO {
21 @Schema(description = "新负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430") 21 @Schema(description = "新负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
22 private Long newOwnerUserId; 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 * 关联 {@link CrmPermissionLevelEnum} 26 * 关联 {@link CrmPermissionLevelEnum}
35 */ 27 */
36 @Schema(description = "老负责人加入团队后的权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") 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 package cn.iocoder.yudao.module.crm.controller.admin.customer; 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 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 3 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
7 import cn.iocoder.yudao.framework.common.pojo.PageResult; 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
8 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; 5 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
9 -import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;  
10 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; 6 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
11 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.*; 7 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.*;
12 import cn.iocoder.yudao.module.crm.convert.customer.CrmCustomerConvert; 8 import cn.iocoder.yudao.module.crm.convert.customer.CrmCustomerConvert;
13 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; 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 import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; 13 import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
  14 +import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService;
15 import cn.iocoder.yudao.module.system.api.dept.DeptApi; 15 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
16 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; 16 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
17 import cn.iocoder.yudao.module.system.api.user.AdminUserApi; 17 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
18 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; 18 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
19 -import com.google.common.collect.Lists;  
20 import io.swagger.v3.oas.annotations.Operation; 19 import io.swagger.v3.oas.annotations.Operation;
21 import io.swagger.v3.oas.annotations.Parameter; 20 import io.swagger.v3.oas.annotations.Parameter;
22 import io.swagger.v3.oas.annotations.tags.Tag; 21 import io.swagger.v3.oas.annotations.tags.Tag;
@@ -28,13 +27,16 @@ import javax.annotation.Resource; @@ -28,13 +27,16 @@ import javax.annotation.Resource;
28 import javax.servlet.http.HttpServletResponse; 27 import javax.servlet.http.HttpServletResponse;
29 import javax.validation.Valid; 28 import javax.validation.Valid;
30 import java.io.IOException; 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 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 35 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
36 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; 36 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
37 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSetByFlatMap; 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 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; 40 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
39 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; 41 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
40 42
@@ -51,6 +53,8 @@ public class CrmCustomerController { @@ -51,6 +53,8 @@ public class CrmCustomerController {
51 private DeptApi deptApi; 53 private DeptApi deptApi;
52 @Resource 54 @Resource
53 private AdminUserApi adminUserApi; 55 private AdminUserApi adminUserApi;
  56 + @Resource
  57 + private CrmPermissionService permissionService;
54 58
55 @PostMapping("/create") 59 @PostMapping("/create")
56 @Operation(summary = "创建客户") 60 @Operation(summary = "创建客户")
@@ -81,22 +85,26 @@ public class CrmCustomerController { @@ -81,22 +85,26 @@ public class CrmCustomerController {
81 @Parameter(name = "id", description = "编号", required = true, example = "1024") 85 @Parameter(name = "id", description = "编号", required = true, example = "1024")
82 @PreAuthorize("@ss.hasPermission('crm:customer:query')") 86 @PreAuthorize("@ss.hasPermission('crm:customer:query')")
83 public CommonResult<CrmCustomerRespVO> getCustomer(@RequestParam("id") Long id) { 87 public CommonResult<CrmCustomerRespVO> getCustomer(@RequestParam("id") Long id) {
  88 + // 1. 获取客户
84 CrmCustomerDO customer = customerService.getCustomer(id); 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 @GetMapping("/page") 110 @GetMapping("/page")
@@ -113,6 +121,31 @@ public class CrmCustomerController { @@ -113,6 +121,31 @@ public class CrmCustomerController {
113 Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap( 121 Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(
114 convertSet(userMap.values(), AdminUserRespDTO::getDeptId)); 122 convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
115 return success(CrmCustomerConvert.INSTANCE.convertPage(pageResult, userMap, deptMap)); 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 @GetMapping("/export-excel") 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 package cn.iocoder.yudao.module.crm.controller.admin.customer.vo; 1 package cn.iocoder.yudao.module.crm.controller.admin.customer.vo;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.PageParam; 3 import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import cn.iocoder.yudao.module.crm.enums.customer.CrmCustomerSceneEnum;
4 import io.swagger.v3.oas.annotations.media.Schema; 5 import io.swagger.v3.oas.annotations.media.Schema;
5 import lombok.Data; 6 import lombok.Data;
6 import lombok.EqualsAndHashCode; 7 import lombok.EqualsAndHashCode;
@@ -27,5 +28,10 @@ public class CrmCustomerPageReqVO extends PageParam { @@ -27,5 +28,10 @@ public class CrmCustomerPageReqVO extends PageParam {
27 @Schema(description = "客户来源", example = "1") 28 @Schema(description = "客户来源", example = "1")
28 private Integer source; 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,7 +33,7 @@ public class CrmCustomerRespVO extends CrmCustomerBaseVO {
33 @Schema(description = "负责人名字", example = "25682") 33 @Schema(description = "负责人名字", example = "25682")
34 private String ownerUserName; 34 private String ownerUserName;
35 @Schema(description = "负责人部门") 35 @Schema(description = "负责人部门")
36 - private String ownerUserDept; 36 + private String ownerUserDeptName;
37 37
38 @Schema(description = "地区名称", example = "北京市") 38 @Schema(description = "地区名称", example = "北京市")
39 private String areaName; 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,19 +21,11 @@ public class CrmCustomerTransferReqVO {
21 @Schema(description = "新负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430") 21 @Schema(description = "新负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
22 private Long newOwnerUserId; 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 * 关联 {@link CrmPermissionLevelEnum} 26 * 关联 {@link CrmPermissionLevelEnum}
35 */ 27 */
36 @Schema(description = "老负责人加入团队后的权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") 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 +8,14 @@ import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionR
8 import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionUpdateReqVO; 8 import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionUpdateReqVO;
9 import cn.iocoder.yudao.module.crm.convert.permission.CrmPermissionConvert; 9 import cn.iocoder.yudao.module.crm.convert.permission.CrmPermissionConvert;
10 import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO; 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 import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; 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 import cn.iocoder.yudao.module.system.api.user.AdminUserApi; 19 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
14 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; 20 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
15 import io.swagger.v3.oas.annotations.Operation; 21 import io.swagger.v3.oas.annotations.Operation;
@@ -22,17 +28,16 @@ import org.springframework.web.bind.annotation.*; @@ -22,17 +28,16 @@ import org.springframework.web.bind.annotation.*;
22 28
23 import javax.annotation.Resource; 29 import javax.annotation.Resource;
24 import javax.validation.Valid; 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 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 35 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
29 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 36 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  37 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.anyMatch;
30 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; 38 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
31 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; 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 @Tag(name = "管理后台 - CRM 数据权限(数据团队成员操作)") 42 @Tag(name = "管理后台 - CRM 数据权限(数据团队成员操作)")
38 @RestController 43 @RestController
@@ -41,92 +46,85 @@ import static cn.iocoder.yudao.module.crm.framework.enums.CrmPermissionLevelEnum @@ -41,92 +46,85 @@ import static cn.iocoder.yudao.module.crm.framework.enums.CrmPermissionLevelEnum
41 public class CrmPermissionController { 46 public class CrmPermissionController {
42 47
43 @Resource 48 @Resource
44 - private CrmPermissionService crmPermissionService; 49 + private CrmPermissionService permissionService;
45 50
46 @Resource 51 @Resource
47 private AdminUserApi adminUserApi; 52 private AdminUserApi adminUserApi;
48 @Resource 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 @PutMapping("/add") 58 @PutMapping("/add")
71 @Operation(summary = "添加团队成员") 59 @Operation(summary = "添加团队成员")
72 @PreAuthorize("@ss.hasPermission('crm:permission:create')") 60 @PreAuthorize("@ss.hasPermission('crm:permission:create')")
  61 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_PERMISSION, bizTypeValue = "#reqVO.bizType", bizId = "#reqVO.bizId"
  62 + , level = CrmPermissionLevelEnum.OWNER)
73 public CommonResult<Boolean> addPermission(@Valid @RequestBody CrmPermissionCreateReqVO reqVO) { 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 return success(true); 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 @PutMapping("/update") 86 @PutMapping("/update")
84 - @Operation(summary = "编辑团队成员") 87 + @Operation(summary = "编辑团队成员权限")
85 @PreAuthorize("@ss.hasPermission('crm:permission:update')") 88 @PreAuthorize("@ss.hasPermission('crm:permission:update')")
  89 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_PERMISSION, bizTypeValue = "#updateReqVO.bizType", bizId = "#updateReqVO.bizId"
  90 + , level = CrmPermissionLevelEnum.OWNER)
86 public CommonResult<Boolean> updatePermission(@Valid @RequestBody CrmPermissionUpdateReqVO updateReqVO) { 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 return success(true); 93 return success(true);
93 } 94 }
94 95
95 - // TODO @puhui999:deletemapping  
96 - @GetMapping("/delete") 96 + @DeleteMapping("/delete")
97 @Operation(summary = "移除团队成员") 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 @PreAuthorize("@ss.hasPermission('crm:permission:delete')") 103 @PreAuthorize("@ss.hasPermission('crm:permission:delete')")
  104 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_PERMISSION, bizTypeValue = "#bizType", bizId = "#bizId"
  105 + , level = CrmPermissionLevelEnum.OWNER) // 为了校验权限请求必须带上 bizType 和 bizId
101 public CommonResult<Boolean> deletePermission(@RequestParam("bizType") Integer bizType, 106 public CommonResult<Boolean> deletePermission(@RequestParam("bizType") Integer bizType,
102 @RequestParam("bizId") Long bizId, 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 return success(true); 110 return success(true);
110 } 111 }
111 112
112 - // TODO @puhui999:这个是哪个地方使用到哈?  
113 - // TODO @puhui999:是不是 deletemapping 呀;  
114 - @GetMapping("/quit") 113 + @DeleteMapping("/quit-team")
115 @Operation(summary = "退出团队") 114 @Operation(summary = "退出团队")
116 @Parameters({ 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 @PreAuthorize("@ss.hasPermission('crm:permission:delete')") 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 if (permission == null) { 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 return success(true); 128 return success(true);
131 } 129 }
132 130
@@ -139,16 +137,23 @@ public class CrmPermissionController { @@ -139,16 +137,23 @@ public class CrmPermissionController {
139 @PreAuthorize("@ss.hasPermission('crm:permission:query')") 137 @PreAuthorize("@ss.hasPermission('crm:permission:query')")
140 public CommonResult<List<CrmPermissionRespVO>> getPermissionList(@RequestParam("bizType") Integer bizType, 138 public CommonResult<List<CrmPermissionRespVO>> getPermissionList(@RequestParam("bizType") Integer bizType,
141 @RequestParam("bizId") Long bizId) { 139 @RequestParam("bizId") Long bizId) {
142 - List<CrmPermissionDO> permission = crmPermissionService.getPermissionByBizTypeAndBizId(bizType, bizId); 140 + List<CrmPermissionDO> permission = permissionService.getPermissionByBizTypeAndBizId(bizType, bizId);
143 if (CollUtil.isEmpty(permission)) { 141 if (CollUtil.isEmpty(permission)) {
144 return success(Collections.emptyList()); 142 return success(Collections.emptyList());
145 } 143 }
146 // TODO @puhui999:池子的逻辑; 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 List<AdminUserRespDTO> userList = adminUserApi.getUserList(convertSet(permission, CrmPermissionDO::getUserId)); 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,10 +30,9 @@ public class CrmPermissionBaseVO {
30 @NotNull(message = "Crm 类型数据编号不能为空") 30 @NotNull(message = "Crm 类型数据编号不能为空")
31 private Long bizId; 31 private Long bizId;
32 32
33 - // TODO @puhui999:level;  
34 @Schema(description = "权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") 33 @Schema(description = "权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
35 @InEnum(CrmPermissionLevelEnum.class) 34 @InEnum(CrmPermissionLevelEnum.class)
36 @NotNull(message = "权限级别不能为空") 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,6 +3,7 @@ package cn.iocoder.yudao.module.crm.controller.admin.permission.vo;
3 import io.swagger.v3.oas.annotations.media.Schema; 3 import io.swagger.v3.oas.annotations.media.Schema;
4 import lombok.Data; 4 import lombok.Data;
5 5
  6 +import java.time.LocalDateTime;
6 import java.util.Set; 7 import java.util.Set;
7 8
8 @Schema(description = "管理后台 - CRM 数据权限(团队成员) Response VO") 9 @Schema(description = "管理后台 - CRM 数据权限(团队成员) Response VO")
@@ -12,18 +13,16 @@ public class CrmPermissionRespVO extends CrmPermissionBaseVO { @@ -12,18 +13,16 @@ public class CrmPermissionRespVO extends CrmPermissionBaseVO {
12 @Schema(description = "数据权限编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "13563") 13 @Schema(description = "数据权限编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "13563")
13 private Long id; 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 @Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿") 19 @Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿")
24 private String nickname; 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 package cn.iocoder.yudao.module.crm.controller.admin.permission.vo; 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 import io.swagger.v3.oas.annotations.media.Schema; 6 import io.swagger.v3.oas.annotations.media.Schema;
4 import lombok.Data; 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 @Schema(description = "管理后台 - CRM 数据权限更新 Request VO") 12 @Schema(description = "管理后台 - CRM 数据权限更新 Request VO")
9 @Data 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,8 +3,7 @@ package cn.iocoder.yudao.module.crm.convert.business;
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.*; 4 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.*;
5 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; 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 import org.mapstruct.Mapper; 7 import org.mapstruct.Mapper;
9 import org.mapstruct.Mapping; 8 import org.mapstruct.Mapping;
10 import org.mapstruct.Mappings; 9 import org.mapstruct.Mappings;
@@ -36,8 +35,6 @@ public interface CrmBusinessConvert { @@ -36,8 +35,6 @@ public interface CrmBusinessConvert {
36 @Mapping(target = "bizId", source = "reqVO.id"), 35 @Mapping(target = "bizId", source = "reqVO.id"),
37 @Mapping(target = "newOwnerUserId", source = "reqVO.id") 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,6 +4,9 @@ import java.util.*;
4 4
5 import cn.iocoder.yudao.framework.common.pojo.PageResult; 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 import org.mapstruct.Mapper; 10 import org.mapstruct.Mapper;
8 import org.mapstruct.factory.Mappers; 11 import org.mapstruct.factory.Mappers;
9 import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.*; 12 import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.*;
@@ -30,6 +33,13 @@ public interface ContactConvert { @@ -30,6 +33,13 @@ public interface ContactConvert {
30 PageResult<ContactRespVO> convertPage(PageResult<ContactDO> page); 33 PageResult<ContactRespVO> convertPage(PageResult<ContactDO> page);
31 34
32 List<ContactExcelVO> convertList02(List<ContactDO> list); 35 List<ContactExcelVO> convertList02(List<ContactDO> list);
  36 +
33 List<ContactSimpleRespVO> convertAllList(List<ContactDO> list); 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,7 +3,7 @@ package cn.iocoder.yudao.module.crm.convert.contract;
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.*; 4 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.*;
5 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.ContractDO; 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 import org.mapstruct.Mapper; 7 import org.mapstruct.Mapper;
8 import org.mapstruct.Mapping; 8 import org.mapstruct.Mapping;
9 import org.mapstruct.Mappings; 9 import org.mapstruct.Mappings;
@@ -37,6 +37,6 @@ public interface ContractConvert { @@ -37,6 +37,6 @@ public interface ContractConvert {
37 @Mapping(target = "bizId", source = "reqVO.id"), 37 @Mapping(target = "bizId", source = "reqVO.id"),
38 @Mapping(target = "newOwnerUserId", source = "reqVO.id") 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,12 +4,17 @@ import cn.hutool.core.util.NumberUtil;
4 import cn.iocoder.yudao.framework.common.pojo.PageResult; 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 import cn.iocoder.yudao.framework.common.util.collection.MapUtils; 5 import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
6 import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils; 6 import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
  7 +import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
7 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.*; 8 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.*;
8 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; 9 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
9 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerPoolConfigDO; 10 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerPoolConfigDO;
10 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmTransferPermissionReqBO; 11 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmTransferPermissionReqBO;
11 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; 12 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
12 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; 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 import org.mapstruct.Mapper; 18 import org.mapstruct.Mapper;
14 import org.mapstruct.Mapping; 19 import org.mapstruct.Mapping;
15 import org.mapstruct.Mappings; 20 import org.mapstruct.Mappings;
@@ -18,6 +23,9 @@ import org.mapstruct.factory.Mappers; @@ -18,6 +23,9 @@ import org.mapstruct.factory.Mappers;
18 import java.util.List; 23 import java.util.List;
19 import java.util.Map; 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 * 客户 Convert 30 * 客户 Convert
23 * 31 *
@@ -34,7 +42,24 @@ public interface CrmCustomerConvert { @@ -34,7 +42,24 @@ public interface CrmCustomerConvert {
34 42
35 CrmCustomerRespVO convert(CrmCustomerDO bean); 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 default PageResult<CrmCustomerRespVO> convertPage(PageResult<CrmCustomerDO> page, Map<Long, AdminUserRespDTO> userMap, Map<Long, DeptRespDTO> deptMap) { 64 default PageResult<CrmCustomerRespVO> convertPage(PageResult<CrmCustomerDO> page, Map<Long, AdminUserRespDTO> userMap, Map<Long, DeptRespDTO> deptMap) {
40 PageResult<CrmCustomerRespVO> result = convertPage(page); 65 PageResult<CrmCustomerRespVO> result = convertPage(page);
@@ -57,7 +82,30 @@ public interface CrmCustomerConvert { @@ -57,7 +82,30 @@ public interface CrmCustomerConvert {
57 @Mapping(target = "bizId", source = "reqVO.id"), 82 @Mapping(target = "bizId", source = "reqVO.id"),
58 @Mapping(target = "newOwnerUserId", source = "reqVO.id") 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 CrmCustomerPoolConfigRespVO convert(CrmCustomerPoolConfigDO customerPoolConfig); 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,15 +8,17 @@ import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionU
8 import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO; 8 import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO;
9 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; 9 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO;
10 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionUpdateReqBO; 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 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; 13 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
  14 +import com.google.common.collect.Multimaps;
12 import org.mapstruct.Mapper; 15 import org.mapstruct.Mapper;
13 import org.mapstruct.factory.Mappers; 16 import org.mapstruct.factory.Mappers;
14 17
  18 +import java.util.ArrayList;
15 import java.util.List; 19 import java.util.List;
16 import java.util.Map; 20 import java.util.Map;
17 21
18 -import static cn.iocoder.yudao.module.crm.framework.enums.CrmPermissionLevelEnum.getNameByLevel;  
19 -  
20 /** 22 /**
21 * Crm 数据权限 Convert 23 * Crm 数据权限 Convert
22 * 24 *
@@ -37,15 +39,28 @@ public interface CrmPermissionConvert { @@ -37,15 +39,28 @@ public interface CrmPermissionConvert {
37 39
38 List<CrmPermissionRespVO> convert(List<CrmPermissionDO> permission); 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 Map<Long, AdminUserRespDTO> userMap = CollectionUtils.convertMap(userList, AdminUserRespDTO::getId); 44 Map<Long, AdminUserRespDTO> userMap = CollectionUtils.convertMap(userList, AdminUserRespDTO::getId);
42 return CollectionUtils.convertList(convert(permission), item -> { 45 return CollectionUtils.convertList(convert(permission), item -> {
43 MapUtils.findAndThen(userMap, item.getId(), user -> { 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 return item; 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 package cn.iocoder.yudao.module.crm.dal.dataobject.customer; 1 package cn.iocoder.yudao.module.crm.dal.dataobject.customer;
2 2
3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; 3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import cn.iocoder.yudao.module.crm.enums.DictTypeConstants;
4 import com.baomidou.mybatisplus.annotation.KeySequence; 5 import com.baomidou.mybatisplus.annotation.KeySequence;
5 import com.baomidou.mybatisplus.annotation.TableId; 6 import com.baomidou.mybatisplus.annotation.TableId;
6 import com.baomidou.mybatisplus.annotation.TableName; 7 import com.baomidou.mybatisplus.annotation.TableName;
@@ -49,19 +50,19 @@ public class CrmCustomerDO extends BaseDO { @@ -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 private Integer industryId; 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 private Integer level; 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 private Integer source; 67 private Integer source;
67 /** 68 /**
@@ -97,21 +98,6 @@ public class CrmCustomerDO extends BaseDO { @@ -97,21 +98,6 @@ public class CrmCustomerDO extends BaseDO {
97 */ 98 */
98 private String remark; 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 private Integer areaId; 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,7 +23,7 @@ import lombok.*;
23 @AllArgsConstructor 23 @AllArgsConstructor
24 public class CrmPermissionDO extends BaseDO { 24 public class CrmPermissionDO extends BaseDO {
25 25
26 - // TODO puhui999:是不是公海的数据,就不插入了; 26 + // TODO puhui999:是不是公海的数据,就不插入了;这样方便获取公海数据鸭
27 /** 27 /**
28 * 当数据变为公海数据时,也就是数据团队成员中没有负责人的时候,将原本的负责人 userId 设置为 POOL_USER_ID 方便查询公海数据。 28 * 当数据变为公海数据时,也就是数据团队成员中没有负责人的时候,将原本的负责人 userId 设置为 POOL_USER_ID 方便查询公海数据。
29 * 也就是说每条数据到最后都有一个负责人,如果有人领取则 userId 为领取人 29 * 也就是说每条数据到最后都有一个负责人,如果有人领取则 userId 为领取人
@@ -59,12 +59,11 @@ public class CrmPermissionDO extends BaseDO { @@ -59,12 +59,11 @@ public class CrmPermissionDO extends BaseDO {
59 */ 59 */
60 private Long userId; 60 private Long userId;
61 61
62 - // TODO @puhui999:是不是搞成 level 字段;简洁一点,主要表明已经 perssmion 实体里了;  
63 /** 62 /**
64 * 权限级别 63 * 权限级别
65 * 64 *
66 * 关联 {@link CrmPermissionLevelEnum} 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 package cn.iocoder.yudao.module.crm.dal.mysql.business; 1 package cn.iocoder.yudao.module.crm.dal.mysql.business;
2 2
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
3 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
4 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; 5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
5 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.CrmBusinessExportReqVO; 6 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.CrmBusinessExportReqVO;
@@ -18,14 +19,14 @@ import java.util.List; @@ -18,14 +19,14 @@ import java.util.List;
18 @Mapper 19 @Mapper
19 public interface CrmBusinessMapper extends BaseMapperX<CrmBusinessDO> { 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 .in(CrmBusinessDO::getId, ids) 24 .in(CrmBusinessDO::getId, ids)
24 .likeIfPresent(CrmBusinessDO::getName, reqVO.getName()) 25 .likeIfPresent(CrmBusinessDO::getName, reqVO.getName())
25 .orderByDesc(CrmBusinessDO::getId)); 26 .orderByDesc(CrmBusinessDO::getId));
26 } 27 }
27 28
28 - default List<CrmBusinessDO> selectList(CrmBusinessExportReqVO reqVO) { 29 + default List<CrmBusinessDO> selectPage(CrmBusinessExportReqVO reqVO) {
29 return selectList(new LambdaQueryWrapperX<CrmBusinessDO>() 30 return selectList(new LambdaQueryWrapperX<CrmBusinessDO>()
30 .likeIfPresent(CrmBusinessDO::getName, reqVO.getName()) 31 .likeIfPresent(CrmBusinessDO::getName, reqVO.getName())
31 .eqIfPresent(CrmBusinessDO::getStatusTypeId, reqVO.getStatusTypeId()) 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,12 +3,11 @@ package cn.iocoder.yudao.module.crm.dal.mysql.customer;
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; 5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
6 -import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerExportReqVO;  
7 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerPageReqVO; 6 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerPageReqVO;
8 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; 7 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
9 import org.apache.ibatis.annotations.Mapper; 8 import org.apache.ibatis.annotations.Mapper;
10 9
11 -import java.util.List; 10 +import java.util.Collection;
12 11
13 /** 12 /**
14 * 客户 Mapper 13 * 客户 Mapper
@@ -18,21 +17,14 @@ import java.util.List; @@ -18,21 +17,14 @@ import java.util.List;
18 @Mapper 17 @Mapper
19 public interface CrmCustomerMapper extends BaseMapperX<CrmCustomerDO> { 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 package cn.iocoder.yudao.module.crm.dal.mysql.permission; 1 package cn.iocoder.yudao.module.crm.dal.mysql.permission;
2 2
3 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 3 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; 4 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
6 import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO; 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 import org.apache.ibatis.annotations.Mapper; 6 import org.apache.ibatis.annotations.Mapper;
10 7
  8 +import java.util.Collection;
11 import java.util.List; 9 import java.util.List;
12 10
13 /** 11 /**
@@ -18,15 +16,6 @@ import java.util.List; @@ -18,15 +16,6 @@ import java.util.List;
18 @Mapper 16 @Mapper
19 public interface CrmPermissionMapper extends BaseMapperX<CrmPermissionDO> { 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 default CrmPermissionDO selectByBizTypeAndBizIdByUserId(Integer bizType, Long bizId, Long userId) { 19 default CrmPermissionDO selectByBizTypeAndBizIdByUserId(Integer bizType, Long bizId, Long userId) {
31 return selectOne(new LambdaQueryWrapperX<CrmPermissionDO>() 20 return selectOne(new LambdaQueryWrapperX<CrmPermissionDO>()
32 .eq(CrmPermissionDO::getBizType, bizType) 21 .eq(CrmPermissionDO::getBizType, bizType)
@@ -34,24 +23,28 @@ public interface CrmPermissionMapper extends BaseMapperX&lt;CrmPermissionDO&gt; { @@ -34,24 +23,28 @@ public interface CrmPermissionMapper extends BaseMapperX&lt;CrmPermissionDO&gt; {
34 .eq(CrmPermissionDO::getUserId, userId)); 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 default List<CrmPermissionDO> selectByBizTypeAndBizId(Integer bizType, Long bizId) { 26 default List<CrmPermissionDO> selectByBizTypeAndBizId(Integer bizType, Long bizId) {
46 return selectList(new LambdaQueryWrapperX<CrmPermissionDO>() 27 return selectList(new LambdaQueryWrapperX<CrmPermissionDO>()
47 .eq(CrmPermissionDO::getBizType, bizType) 28 .eq(CrmPermissionDO::getBizType, bizType)
48 .eq(CrmPermissionDO::getBizId, bizId)); 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,17 +26,21 @@ public @interface CrmPermission {
26 */ 26 */
27 CrmBizTypeEnum bizType(); 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,24 +2,32 @@ package cn.iocoder.yudao.module.crm.framework.core.aop;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.hutool.core.util.ObjUtil; 4 import cn.hutool.core.util.ObjUtil;
  5 +import cn.iocoder.yudao.framework.common.core.KeyValue;
5 import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils; 6 import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
6 import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO; 7 import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO;
7 import cn.iocoder.yudao.module.crm.framework.core.annotations.CrmPermission; 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 import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; 11 import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService;
9 import lombok.extern.slf4j.Slf4j; 12 import lombok.extern.slf4j.Slf4j;
10 import org.aspectj.lang.JoinPoint; 13 import org.aspectj.lang.JoinPoint;
11 import org.aspectj.lang.annotation.Aspect; 14 import org.aspectj.lang.annotation.Aspect;
12 import org.aspectj.lang.annotation.Before; 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 import org.springframework.stereotype.Component; 22 import org.springframework.stereotype.Component;
14 23
15 import javax.annotation.Resource; 24 import javax.annotation.Resource;
16 -import java.lang.reflect.Field; 25 +import java.lang.reflect.Method;
17 import java.util.List; 26 import java.util.List;
18 27
19 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 28 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
20 import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; 29 import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
21 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CRM_PERMISSION_DENIED; 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 * Crm 数据权限校验 AOP 切面 33 * Crm 数据权限校验 AOP 切面
@@ -32,6 +40,11 @@ import static cn.iocoder.yudao.module.crm.framework.enums.CrmPermissionLevelEnum @@ -32,6 +40,11 @@ import static cn.iocoder.yudao.module.crm.framework.enums.CrmPermissionLevelEnum
32 public class CrmPermissionAspect { 40 public class CrmPermissionAspect {
33 41
34 @Resource 42 @Resource
  43 + private LocalVariableTableParameterNameDiscoverer discoverer;
  44 + @Resource
  45 + private SpelExpressionParser parser;
  46 +
  47 + @Resource
35 private CrmPermissionService crmPermissionService; 48 private CrmPermissionService crmPermissionService;
36 49
37 /** 50 /**
@@ -43,83 +56,109 @@ public class CrmPermissionAspect { @@ -43,83 +56,109 @@ public class CrmPermissionAspect {
43 return WebFrameworkUtils.getLoginUserId(); 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 @Before("@annotation(crmPermission)") 59 @Before("@annotation(crmPermission)")
67 - public void doBefore(JoinPoint joinPoint, CrmPermission crmPermission) { 60 + public void doBefore(JoinPoint joinPoint, CrmPermission crmPermission) throws NoSuchMethodException {
68 // TODO 芋艿:临时,方便大家调试 61 // TODO 芋艿:临时,方便大家调试
69 if (true) { 62 if (true) {
70 return; 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 return; 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 package cn.iocoder.yudao.module.crm.framework.enums; 1 package cn.iocoder.yudao.module.crm.framework.enums;
2 2
  3 +import cn.hutool.core.collection.CollUtil;
3 import cn.hutool.core.util.ObjUtil; 4 import cn.hutool.core.util.ObjUtil;
4 import cn.iocoder.yudao.framework.common.core.IntArrayValuable; 5 import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
5 import lombok.Getter; 6 import lombok.Getter;
@@ -16,6 +17,7 @@ import java.util.Arrays; @@ -16,6 +17,7 @@ import java.util.Arrays;
16 @Getter 17 @Getter
17 public enum CrmBizTypeEnum implements IntArrayValuable { 18 public enum CrmBizTypeEnum implements IntArrayValuable {
18 19
  20 + CRM_PERMISSION(0, "团队"), // CrmPermissionController 中使用
19 CRM_LEADS(1, "线索"), 21 CRM_LEADS(1, "线索"),
20 CRM_CUSTOMER(2, "客户"), 22 CRM_CUSTOMER(2, "客户"),
21 CRM_CONTACTS(3, "联系人"), 23 CRM_CONTACTS(3, "联系人"),
@@ -33,13 +35,9 @@ public enum CrmBizTypeEnum implements IntArrayValuable { @@ -33,13 +35,9 @@ public enum CrmBizTypeEnum implements IntArrayValuable {
33 private final String name; 35 private final String name;
34 36
35 public static String getNameByType(Integer type) { 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 @Override 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,14 +48,4 @@ public enum CrmPermissionLevelEnum implements IntArrayValuable {
48 return ObjUtil.equal(WRITE.level, level); 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,7 +3,6 @@ package cn.iocoder.yudao.module.crm.service.business;
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.*; 4 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.*;
5 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; 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 import javax.validation.Valid; 7 import javax.validation.Valid;
9 import java.util.Collection; 8 import java.util.Collection;
@@ -14,7 +13,7 @@ import java.util.List; @@ -14,7 +13,7 @@ import java.util.List;
14 * 13 *
15 * @author ljlleo 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,7 +2,6 @@ package cn.iocoder.yudao.module.crm.service.business;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.hutool.core.collection.ListUtil; 4 import cn.hutool.core.collection.ListUtil;
5 -import cn.hutool.core.util.ObjUtil;  
6 import cn.iocoder.yudao.framework.common.pojo.PageResult; 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
7 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.*; 6 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.*;
8 import cn.iocoder.yudao.module.crm.convert.business.CrmBusinessConvert; 7 import cn.iocoder.yudao.module.crm.convert.business.CrmBusinessConvert;
@@ -51,7 +50,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { @@ -51,7 +50,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
51 50
52 // 创建数据权限 51 // 创建数据权限
53 crmPermissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_BUSINESS.getType()) 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 return business.getId(); 56 return business.getId();
@@ -59,8 +58,8 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { @@ -59,8 +58,8 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
59 58
60 @Override 59 @Override
61 @Transactional(rollbackFor = Exception.class) 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 public void updateBusiness(CrmBusinessUpdateReqVO updateReqVO) { 63 public void updateBusiness(CrmBusinessUpdateReqVO updateReqVO) {
65 // 校验存在 64 // 校验存在
66 validateBusinessExists(updateReqVO.getId()); 65 validateBusinessExists(updateReqVO.getId());
@@ -71,7 +70,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { @@ -71,7 +70,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
71 70
72 @Override 71 @Override
73 @Transactional(rollbackFor = Exception.class) 72 @Transactional(rollbackFor = Exception.class)
74 - @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, permissionLevel = CrmPermissionLevelEnum.WRITE) 73 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, level = CrmPermissionLevelEnum.WRITE)
75 public void deleteBusiness(Long id) { 74 public void deleteBusiness(Long id) {
76 // 校验存在 75 // 校验存在
77 validateBusinessExists(id); 76 validateBusinessExists(id);
@@ -88,7 +87,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { @@ -88,7 +87,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
88 } 87 }
89 88
90 @Override 89 @Override
91 - @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, permissionLevel = CrmPermissionLevelEnum.READ) 90 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, level = CrmPermissionLevelEnum.READ)
92 public CrmBusinessDO getBusiness(Long id) { 91 public CrmBusinessDO getBusiness(Long id) {
93 return businessMapper.selectById(id); 92 return businessMapper.selectById(id);
94 } 93 }
@@ -104,21 +103,20 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { @@ -104,21 +103,20 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
104 @Override 103 @Override
105 public PageResult<CrmBusinessDO> getBusinessPage(CrmBusinessPageReqVO pageReqVO, Long userId) { 104 public PageResult<CrmBusinessDO> getBusinessPage(CrmBusinessPageReqVO pageReqVO, Long userId) {
106 // 1. 获取当前用户能看的分页数据 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 if (CollUtil.isEmpty(ids)) { // 没得说明没有什么给他看的 109 if (CollUtil.isEmpty(ids)) { // 没得说明没有什么给他看的
111 return PageResult.empty(); 110 return PageResult.empty();
112 } 111 }
113 112
114 // 2. 获取商机分页数据 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 @Override 117 @Override
120 public List<CrmBusinessDO> getBusinessList(CrmBusinessExportReqVO exportReqVO) { 118 public List<CrmBusinessDO> getBusinessList(CrmBusinessExportReqVO exportReqVO) {
121 - return businessMapper.selectList(exportReqVO); 119 + return businessMapper.selectPage(exportReqVO);
122 } 120 }
123 121
124 @Override 122 @Override
@@ -134,14 +132,4 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { @@ -134,14 +132,4 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
134 // 3. TODO 记录转移日志 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,11 +37,18 @@ public class ContactServiceImpl implements ContactService {
37 // 插入 37 // 插入
38 ContactDO contact = ContactConvert.INSTANCE.convert(createReqVO); 38 ContactDO contact = ContactConvert.INSTANCE.convert(createReqVO);
39 contactMapper.insert(contact); 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 return contact.getId(); 46 return contact.getId();
42 } 47 }
43 48
44 @Override 49 @Override
  50 + @Transactional(rollbackFor = Exception.class)
  51 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACTS, level = CrmPermissionLevelEnum.WRITE)
45 public void updateContact(ContactUpdateReqVO updateReqVO) { 52 public void updateContact(ContactUpdateReqVO updateReqVO) {
46 // 校验存在 53 // 校验存在
47 validateContactExists(updateReqVO.getId()); 54 validateContactExists(updateReqVO.getId());
@@ -51,6 +58,8 @@ public class ContactServiceImpl implements ContactService { @@ -51,6 +58,8 @@ public class ContactServiceImpl implements ContactService {
51 } 58 }
52 59
53 @Override 60 @Override
  61 + @Transactional(rollbackFor = Exception.class)
  62 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACTS, level = CrmPermissionLevelEnum.WRITE)
54 public void deleteContact(Long id) { 63 public void deleteContact(Long id) {
55 // 校验存在 64 // 校验存在
56 validateContactExists(id); 65 validateContactExists(id);
@@ -65,6 +74,7 @@ public class ContactServiceImpl implements ContactService { @@ -65,6 +74,7 @@ public class ContactServiceImpl implements ContactService {
65 } 74 }
66 75
67 @Override 76 @Override
  77 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACTS, level = CrmPermissionLevelEnum.READ)
68 public ContactDO getContact(Long id) { 78 public ContactDO getContact(Long id) {
69 return contactMapper.selectById(id); 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,7 +46,7 @@ public class ContractServiceImpl implements ContractService {
46 46
47 // 创建数据权限 47 // 创建数据权限
48 crmPermissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_CONTRACT.getType()) 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 return contract.getId(); 52 return contract.getId();
@@ -54,8 +54,7 @@ public class ContractServiceImpl implements ContractService { @@ -54,8 +54,7 @@ public class ContractServiceImpl implements ContractService {
54 54
55 @Override 55 @Override
56 @Transactional(rollbackFor = Exception.class) 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 public void updateContract(ContractUpdateReqVO updateReqVO) { 58 public void updateContract(ContractUpdateReqVO updateReqVO) {
60 // 校验存在 59 // 校验存在
61 validateContractExists(updateReqVO.getId()); 60 validateContractExists(updateReqVO.getId());
@@ -66,7 +65,7 @@ public class ContractServiceImpl implements ContractService { @@ -66,7 +65,7 @@ public class ContractServiceImpl implements ContractService {
66 65
67 @Override 66 @Override
68 @Transactional(rollbackFor = Exception.class) 67 @Transactional(rollbackFor = Exception.class)
69 - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, permissionLevel = CrmPermissionLevelEnum.WRITE) 68 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, level = CrmPermissionLevelEnum.WRITE)
70 public void deleteContract(Long id) { 69 public void deleteContract(Long id) {
71 // 校验存在 70 // 校验存在
72 validateContractExists(id); 71 validateContractExists(id);
@@ -83,7 +82,7 @@ public class ContractServiceImpl implements ContractService { @@ -83,7 +82,7 @@ public class ContractServiceImpl implements ContractService {
83 } 82 }
84 83
85 @Override 84 @Override
86 - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, permissionLevel = CrmPermissionLevelEnum.READ) 85 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, level = CrmPermissionLevelEnum.READ)
87 public ContractDO getContract(Long id) { 86 public ContractDO getContract(Long id) {
88 return contractMapper.selectById(id); 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,7 +5,6 @@ import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.*;
5 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; 5 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
6 6
7 import javax.validation.Valid; 7 import javax.validation.Valid;
8 -import java.util.Collection;  
9 import java.util.List; 8 import java.util.List;
10 9
11 /** 10 /**
@@ -50,9 +49,10 @@ public interface CrmCustomerService { @@ -50,9 +49,10 @@ public interface CrmCustomerService {
50 * 获得客户分页 49 * 获得客户分页
51 * 50 *
52 * @param pageReqVO 分页查询 51 * @param pageReqVO 分页查询
  52 + * @param userId 用户编号
53 * @return 客户分页 53 * @return 客户分页
54 */ 54 */
55 - PageResult<CrmCustomerDO> getCustomerPage(CrmCustomerPageReqVO pageReqVO); 55 + PageResult<CrmCustomerDO> getCustomerPage(CrmCustomerPageReqVO pageReqVO, Long userId);
56 56
57 /** 57 /**
58 * 获得客户列表, 用于 Excel 导出 58 * 获得客户列表, 用于 Excel 导出
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java
1 package cn.iocoder.yudao.module.crm.service.customer; 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 import cn.iocoder.yudao.framework.common.pojo.PageResult; 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  6 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
4 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.*; 7 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.*;
5 import cn.iocoder.yudao.module.crm.convert.customer.CrmCustomerConvert; 8 import cn.iocoder.yudao.module.crm.convert.customer.CrmCustomerConvert;
6 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; 9 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
  10 +import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO;
7 import cn.iocoder.yudao.module.crm.dal.mysql.customer.CrmCustomerMapper; 11 import cn.iocoder.yudao.module.crm.dal.mysql.customer.CrmCustomerMapper;
  12 +import cn.iocoder.yudao.module.crm.enums.customer.CrmCustomerSceneEnum;
8 import cn.iocoder.yudao.module.crm.framework.core.annotations.CrmPermission; 13 import cn.iocoder.yudao.module.crm.framework.core.annotations.CrmPermission;
9 import cn.iocoder.yudao.module.crm.framework.enums.CrmBizTypeEnum; 14 import cn.iocoder.yudao.module.crm.framework.enums.CrmBizTypeEnum;
10 import cn.iocoder.yudao.module.crm.framework.enums.CrmPermissionLevelEnum; 15 import cn.iocoder.yudao.module.crm.framework.enums.CrmPermissionLevelEnum;
@@ -15,10 +20,13 @@ import org.springframework.transaction.annotation.Transactional; @@ -15,10 +20,13 @@ import org.springframework.transaction.annotation.Transactional;
15 import org.springframework.validation.annotation.Validated; 20 import org.springframework.validation.annotation.Validated;
16 21
17 import javax.annotation.Resource; 22 import javax.annotation.Resource;
  23 +import java.util.Collections;
18 import java.util.List; 24 import java.util.List;
19 import java.util.Objects; 25 import java.util.Objects;
  26 +import java.util.Set;
20 27
21 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 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 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CUSTOMER_NOT_EXISTS; 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,7 +51,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
43 51
44 // 创建数据权限 52 // 创建数据权限
45 crmPermissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType()) 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 return customer.getId(); 57 return customer.getId();
@@ -51,12 +59,10 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { @@ -51,12 +59,10 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
51 59
52 @Override 60 @Override
53 @Transactional(rollbackFor = Exception.class) 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 public void updateCustomer(CrmCustomerUpdateReqVO updateReqVO) { 63 public void updateCustomer(CrmCustomerUpdateReqVO updateReqVO) {
57 // 校验存在 64 // 校验存在
58 validateCustomerExists(updateReqVO.getId()); 65 validateCustomerExists(updateReqVO.getId());
59 - // TODO 芋艿:数据权限,校验是否可以操作  
60 66
61 // 更新 67 // 更新
62 CrmCustomerDO updateObj = CrmCustomerConvert.INSTANCE.convert(updateReqVO); 68 CrmCustomerDO updateObj = CrmCustomerConvert.INSTANCE.convert(updateReqVO);
@@ -65,11 +71,10 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { @@ -65,11 +71,10 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
65 71
66 @Override 72 @Override
67 @Transactional(rollbackFor = Exception.class) 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 public void deleteCustomer(Long id) { 75 public void deleteCustomer(Long id) {
70 // 校验存在 76 // 校验存在
71 validateCustomerExists(id); 77 validateCustomerExists(id);
72 - // TODO 芋艿:数据权限,校验是否可以操作  
73 78
74 // 删除 79 // 删除
75 customerMapper.deleteById(id); 80 customerMapper.deleteById(id);
@@ -82,20 +87,38 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { @@ -82,20 +87,38 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
82 } 87 }
83 88
84 @Override 89 @Override
85 - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, permissionLevel = CrmPermissionLevelEnum.READ) 90 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#id", level = CrmPermissionLevelEnum.READ)
86 public CrmCustomerDO getCustomer(Long id) { 91 public CrmCustomerDO getCustomer(Long id) {
87 return customerMapper.selectById(id); 92 return customerMapper.selectById(id);
88 } 93 }
89 94
90 @Override 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 @Override 118 @Override
97 public List<CrmCustomerDO> getCustomerList(CrmCustomerExportReqVO exportReqVO) { 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 package cn.iocoder.yudao.module.crm.service.permission; 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 import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO; 5 import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO;
6 import cn.iocoder.yudao.module.crm.framework.enums.CrmBizTypeEnum; 6 import cn.iocoder.yudao.module.crm.framework.enums.CrmBizTypeEnum;
7 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; 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 import javax.validation.Valid; 10 import javax.validation.Valid;
  11 +import java.util.Collection;
13 import java.util.List; 12 import java.util.List;
14 13
15 /** 14 /**
@@ -30,16 +29,16 @@ public interface CrmPermissionService { @@ -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 * 获取用户数据权限通过 数据类型 x 某个数据 x 用户编号 44 * 获取用户数据权限通过 数据类型 x 某个数据 x 用户编号
@@ -52,6 +51,15 @@ public interface CrmPermissionService { @@ -52,6 +51,15 @@ public interface CrmPermissionService {
52 CrmPermissionDO getPermissionByBizTypeAndBizIdAndUserId(Integer bizType, Long bizId, Long userId); 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 * 获取数据权限列表,通过 数据类型 x 某个数据 63 * 获取数据权限列表,通过 数据类型 x 某个数据
56 * 64 *
57 * @param bizType 数据类型,关联 {@link CrmBizTypeEnum} 65 * @param bizType 数据类型,关联 {@link CrmBizTypeEnum}
@@ -61,18 +69,47 @@ public interface CrmPermissionService { @@ -61,18 +69,47 @@ public interface CrmPermissionService {
61 List<CrmPermissionDO> getPermissionByBizTypeAndBizId(Integer bizType, Long bizId); 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,22 +2,21 @@ package cn.iocoder.yudao.module.crm.service.permission;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.hutool.core.util.ObjUtil; 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 import cn.iocoder.yudao.module.crm.convert.permission.CrmPermissionConvert; 6 import cn.iocoder.yudao.module.crm.convert.permission.CrmPermissionConvert;
7 import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO; 7 import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO;
8 import cn.iocoder.yudao.module.crm.dal.mysql.permission.CrmPermissionMapper; 8 import cn.iocoder.yudao.module.crm.dal.mysql.permission.CrmPermissionMapper;
9 import cn.iocoder.yudao.module.crm.framework.enums.CrmBizTypeEnum; 9 import cn.iocoder.yudao.module.crm.framework.enums.CrmBizTypeEnum;
10 import cn.iocoder.yudao.module.crm.framework.enums.CrmPermissionLevelEnum; 10 import cn.iocoder.yudao.module.crm.framework.enums.CrmPermissionLevelEnum;
11 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; 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 import cn.iocoder.yudao.module.system.api.user.AdminUserApi; 13 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
16 import org.springframework.stereotype.Service; 14 import org.springframework.stereotype.Service;
17 import org.springframework.transaction.annotation.Transactional; 15 import org.springframework.transaction.annotation.Transactional;
18 import org.springframework.validation.annotation.Validated; 16 import org.springframework.validation.annotation.Validated;
19 17
20 import javax.annotation.Resource; 18 import javax.annotation.Resource;
  19 +import java.util.Collection;
21 import java.util.Collections; 20 import java.util.Collections;
22 import java.util.List; 21 import java.util.List;
23 22
@@ -54,26 +53,22 @@ public class CrmPermissionServiceImpl implements CrmPermissionService { @@ -54,26 +53,22 @@ public class CrmPermissionServiceImpl implements CrmPermissionService {
54 53
55 @Override 54 @Override
56 @Transactional(rollbackFor = Exception.class) 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 @Override 64 @Override
70 @Transactional(rollbackFor = Exception.class) 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 @Override 74 @Override
@@ -82,62 +77,95 @@ public class CrmPermissionServiceImpl implements CrmPermissionService { @@ -82,62 +77,95 @@ public class CrmPermissionServiceImpl implements CrmPermissionService {
82 } 77 }
83 78
84 @Override 79 @Override
  80 + public CrmPermissionDO getPermissionByIdAndUserId(Long id, Long userId) {
  81 + return crmPermissionMapper.selectByIdAndUserId(id, userId);
  82 + }
  83 +
  84 + @Override
85 public List<CrmPermissionDO> getPermissionByBizTypeAndBizId(Integer bizType, Long bizId) { 85 public List<CrmPermissionDO> getPermissionByBizTypeAndBizId(Integer bizType, Long bizId) {
86 return crmPermissionMapper.selectByBizTypeAndBizId(bizType, bizId); 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 throw exception(CRM_PERMISSION_NOT_EXISTS); 98 throw exception(CRM_PERMISSION_NOT_EXISTS);
92 } 99 }
93 } 100 }
94 101
95 @Override 102 @Override
96 - public void transferPermission(CrmTransferPermissionReqBO transferReqBO) { 103 + @Transactional(rollbackFor = Exception.class)
  104 + public void transferPermission(CrmPermissionTransferReqBO transferReqBO) {
97 // 1. 校验数据权限-是否是负责人,只有负责人才可以转移 105 // 1. 校验数据权限-是否是负责人,只有负责人才可以转移
98 CrmPermissionDO oldPermission = crmPermissionMapper.selectByBizTypeAndBizIdByUserId(transferReqBO.getBizType(), 106 CrmPermissionDO oldPermission = crmPermissionMapper.selectByBizTypeAndBizIdByUserId(transferReqBO.getBizType(),
99 transferReqBO.getBizId(), transferReqBO.getUserId()); 107 transferReqBO.getBizId(), transferReqBO.getUserId());
100 String crmName = CrmBizTypeEnum.getNameByType(transferReqBO.getBizType()); 108 String crmName = CrmBizTypeEnum.getNameByType(transferReqBO.getBizType());
101 // TODO 校验是否为超级管理员 || 1 109 // TODO 校验是否为超级管理员 || 1
102 - if (oldPermission == null || !isOwner(oldPermission.getPermissionLevel())) { 110 + if (oldPermission == null || !isOwner(oldPermission.getLevel())) {
103 throw exception(CRM_PERMISSION_DENIED, crmName); 111 throw exception(CRM_PERMISSION_DENIED, crmName);
104 } 112 }
105 -  
106 - // TODO @puhui999:这个顺序编号,看看调整下;2. 后面是 2.1 ,结果没 2.2 有点怪;  
107 - // 2. 校验转移对象是否已经是该负责人 113 + // 1.1 校验转移对象是否已经是该负责人
108 if (ObjUtil.equal(transferReqBO.getNewOwnerUserId(), oldPermission.getUserId())) { 114 if (ObjUtil.equal(transferReqBO.getNewOwnerUserId(), oldPermission.getUserId())) {
109 throw exception(CRM_PERMISSION_MODEL_TRANSFER_FAIL_OWNER_USER_EXISTS, crmName); 115 throw exception(CRM_PERMISSION_MODEL_TRANSFER_FAIL_OWNER_USER_EXISTS, crmName);
110 } 116 }
111 - // 2.1 校验新负责人是否存在 117 + // 1.2 校验新负责人是否存在
112 adminUserApi.validateUserList(Collections.singletonList(transferReqBO.getNewOwnerUserId())); 118 adminUserApi.validateUserList(Collections.singletonList(transferReqBO.getNewOwnerUserId()));
113 - // 3. 权限转移 119 +
  120 + // 2. 权限转移
114 List<CrmPermissionDO> permissions = crmPermissionMapper.selectByBizTypeAndBizId( 121 List<CrmPermissionDO> permissions = crmPermissionMapper.selectByBizTypeAndBizId(
115 transferReqBO.getBizType(), transferReqBO.getBizId()); // 获取所有团队成员 122 transferReqBO.getBizType(), transferReqBO.getBizId()); // 获取所有团队成员
116 - // 3.1 校验新负责人是否在团队成员中 123 + // 2.1 校验新负责人是否在团队成员中
117 CrmPermissionDO permission = CollUtil.findOne(permissions, 124 CrmPermissionDO permission = CollUtil.findOne(permissions,
118 item -> ObjUtil.equal(item.getUserId(), transferReqBO.getNewOwnerUserId())); 125 item -> ObjUtil.equal(item.getUserId(), transferReqBO.getNewOwnerUserId()));
119 if (permission == null) { // 不存在则以负责人的级别加入这个团队 126 if (permission == null) { // 不存在则以负责人的级别加入这个团队
120 crmPermissionMapper.insert(new CrmPermissionDO().setBizType(transferReqBO.getBizType()) 127 crmPermissionMapper.insert(new CrmPermissionDO().setBizType(transferReqBO.getBizType())
121 .setBizId(transferReqBO.getBizId()).setUserId(transferReqBO.getNewOwnerUserId()) 128 .setBizId(transferReqBO.getBizId()).setUserId(transferReqBO.getNewOwnerUserId())
122 - .setPermissionLevel(CrmPermissionLevelEnum.OWNER.getLevel())); 129 + .setLevel(CrmPermissionLevelEnum.OWNER.getLevel()));
123 130
124 } else { // 存在则修改权限级别 131 } else { // 存在则修改权限级别
125 crmPermissionMapper.updateById(new CrmPermissionDO().setId(permission.getId()) 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 crmPermissionMapper.updateById(new CrmPermissionDO().setId(oldPermission.getId()) 137 crmPermissionMapper.updateById(new CrmPermissionDO().setId(oldPermission.getId())
132 - .setPermissionLevel(transferReqBO.getPermissionLevel())); // 设置加入团队后的级别 138 + .setLevel(transferReqBO.getOldOwnerPermissionLevel())); // 设置加入团队后的级别
133 return; 139 return;
134 } 140 }
135 crmPermissionMapper.deleteById(oldPermission.getId()); // 移除 141 crmPermissionMapper.deleteById(oldPermission.getId()); // 移除
136 } 142 }
137 143
138 @Override 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,12 +33,11 @@ public class CrmPermissionCreateReqBO {
33 @NotNull(message = "Crm 数据编号不能为空") 33 @NotNull(message = "Crm 数据编号不能为空")
34 private Long bizId; 34 private Long bizId;
35 35
36 - // TODO @puhui999:简化成 level  
37 /** 36 /**
38 * 权限级别 37 * 权限级别
39 */ 38 */
40 @NotNull(message = "权限级别不能为空") 39 @NotNull(message = "权限级别不能为空")
41 @InEnum(CrmPermissionLevelEnum.class) 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,14 +7,13 @@ import lombok.Data;
7 7
8 import javax.validation.constraints.NotNull; 8 import javax.validation.constraints.NotNull;
9 9
10 -// TODO @puhui999:CrmPermissionTransferReqBO  
11 /** 10 /**
12 * 数据权限转移 Request BO 11 * 数据权限转移 Request BO
13 * 12 *
14 * @author HUIHUI 13 * @author HUIHUI
15 */ 14 */
16 @Data 15 @Data
17 -public class CrmTransferPermissionReqBO { 16 +public class CrmPermissionTransferReqBO {
18 17
19 /** 18 /**
20 * 当前登录用户编号 19 * 当前登录用户编号
@@ -40,17 +39,10 @@ public class CrmTransferPermissionReqBO { @@ -40,17 +39,10 @@ public class CrmTransferPermissionReqBO {
40 @NotNull(message = "新负责人的用户编号不能为空") 39 @NotNull(message = "新负责人的用户编号不能为空")
41 private Long newOwnerUserId; 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 * 关联 {@link CrmPermissionLevelEnum} 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 package cn.iocoder.yudao.module.crm.service.permission.bo; 1 package cn.iocoder.yudao.module.crm.service.permission.bo;
2 2
3 import cn.iocoder.yudao.framework.common.validation.InEnum; 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 import cn.iocoder.yudao.module.crm.framework.enums.CrmPermissionLevelEnum; 4 import cn.iocoder.yudao.module.crm.framework.enums.CrmPermissionLevelEnum;
7 import lombok.Data; 5 import lombok.Data;
8 6
@@ -28,25 +26,11 @@ public class CrmPermissionUpdateReqBO { @@ -28,25 +26,11 @@ public class CrmPermissionUpdateReqBO {
28 @NotNull(message = "用户编号不能为空") 26 @NotNull(message = "用户编号不能为空")
29 private Long userId; 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 @NotNull(message = "权限级别不能为空") 32 @NotNull(message = "权限级别不能为空")
49 @InEnum(CrmPermissionLevelEnum.class) 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,7 +130,7 @@ public class CrmCustomerServiceImplTest extends BaseDbUnitTest {
130 //reqVO.setWebsite(null); 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 assertEquals(1, pageResult.getTotal()); 135 assertEquals(1, pageResult.getTotal());
136 assertEquals(1, pageResult.getList().size()); 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 package cn.iocoder.yudao.module.system.api.dept; 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 import java.util.Collection; 6 import java.util.Collection;
  7 +import java.util.List;
  8 +import java.util.Map;
4 9
5 /** 10 /**
6 * 岗位 API 接口 11 * 岗位 API 接口
@@ -18,4 +23,11 @@ public interface PostApi { @@ -18,4 +23,11 @@ public interface PostApi {
18 */ 23 */
19 void validPostList(Collection<Long> ids); 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 package cn.iocoder.yudao.module.system.api.dept; 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 import cn.iocoder.yudao.module.system.service.dept.PostService; 5 import cn.iocoder.yudao.module.system.service.dept.PostService;
4 import org.springframework.stereotype.Service; 6 import org.springframework.stereotype.Service;
5 7
6 import javax.annotation.Resource; 8 import javax.annotation.Resource;
7 import java.util.Collection; 9 import java.util.Collection;
  10 +import java.util.List;
8 11
9 /** 12 /**
10 * 岗位 API 实现类 13 * 岗位 API 实现类
@@ -22,4 +25,9 @@ public class PostApiImpl implements PostApi { @@ -22,4 +25,9 @@ public class PostApiImpl implements PostApi {
22 postService.validatePostList(ids); 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 }