Commit 455a4ebc7bf21b1732a9ca386e8265f675c4bc62

Authored by puhui999
1 parent 78165f21

CRM-客户:实现数据权限、场景检索和公海数据分页查询

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;  
4 -import cn.iocoder.yudao.module.crm.enums.common.CrmSceneEnum; 3 +import cn.iocoder.yudao.module.crm.framework.vo.CrmBasePageReqVO;
5 import io.swagger.v3.oas.annotations.media.Schema; 4 import io.swagger.v3.oas.annotations.media.Schema;
6 import lombok.Data; 5 import lombok.Data;
7 import lombok.EqualsAndHashCode; 6 import lombok.EqualsAndHashCode;
8 import lombok.ToString; 7 import lombok.ToString;
9 8
10 -import javax.validation.constraints.NotNull;  
11 -  
12 @Schema(description = "管理后台 - CRM 客户分页 Request VO") 9 @Schema(description = "管理后台 - CRM 客户分页 Request VO")
13 @Data 10 @Data
14 @EqualsAndHashCode(callSuper = true) 11 @EqualsAndHashCode(callSuper = true)
15 @ToString(callSuper = true) 12 @ToString(callSuper = true)
16 -public class CrmCustomerPageReqVO extends PageParam { 13 +public class CrmCustomerPageReqVO extends CrmBasePageReqVO {
17 14
18 @Schema(description = "客户名称", example = "赵六") 15 @Schema(description = "客户名称", example = "赵六")
19 private String name; 16 private String name;
@@ -30,16 +27,4 @@ public class CrmCustomerPageReqVO extends PageParam { @@ -30,16 +27,4 @@ public class CrmCustomerPageReqVO extends PageParam {
30 @Schema(description = "客户来源", example = "1") 27 @Schema(description = "客户来源", example = "1")
31 private Integer source; 28 private Integer source;
32 29
33 - /**  
34 - * 场景类型  
35 - *  
36 - * 关联 {@link CrmSceneEnum}  
37 - */  
38 - @Schema(description = "场景类型", example = "1")  
39 - private Integer sceneType;  
40 -  
41 - @Schema(description = "是否为公海数据", requiredMode = Schema.RequiredMode.REQUIRED, example = "false")  
42 - @NotNull(message = "是否为公海数据不能为空")  
43 - private Boolean pool;  
44 -  
45 } 30 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/customer/CrmCustomerMapper.java
@@ -3,18 +3,17 @@ package cn.iocoder.yudao.module.crm.dal.mysql.customer; @@ -3,18 +3,17 @@ package cn.iocoder.yudao.module.crm.dal.mysql.customer;
3 import cn.iocoder.yudao.framework.common.pojo.PageParam; 3 import cn.iocoder.yudao.framework.common.pojo.PageParam;
4 import cn.iocoder.yudao.framework.common.pojo.PageResult; 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 5 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
6 -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;  
7 import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX; 6 import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
8 import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils; 7 import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
9 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerPageReqVO; 8 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerPageReqVO;
10 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; 9 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
11 -import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO;  
12 -import cn.iocoder.yudao.module.crm.enums.common.CrmSceneEnum;  
13 import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; 10 import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
  11 +import cn.iocoder.yudao.module.crm.util.CrmQueryPageUtils;
14 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; 12 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
15 import com.baomidou.mybatisplus.core.metadata.IPage; 13 import com.baomidou.mybatisplus.core.metadata.IPage;
16 import org.apache.ibatis.annotations.Mapper; 14 import org.apache.ibatis.annotations.Mapper;
17 15
  16 +import java.util.Collection;
18 import java.util.List; 17 import java.util.List;
19 18
20 /** 19 /**
@@ -31,28 +30,21 @@ public interface CrmCustomerMapper extends BaseMapperX<CrmCustomerDO> { @@ -31,28 +30,21 @@ public interface CrmCustomerMapper extends BaseMapperX<CrmCustomerDO> {
31 .set(CrmCustomerDO::getOwnerUserId, ownerUserId)); 30 .set(CrmCustomerDO::getOwnerUserId, ownerUserId));
32 } 31 }
33 32
34 - default PageResult<CrmCustomerDO> selectPageWithAdmin(CrmCustomerPageReqVO pageReqVO, Long userId) {  
35 - // 情况一:管理员查看  
36 - LambdaQueryWrapperX<CrmCustomerDO> queryWrapperX = new LambdaQueryWrapperX<>();  
37 - appendQueryParams(queryWrapperX, pageReqVO, userId);  
38 - return selectPage(pageReqVO, queryWrapperX  
39 - .likeIfPresent(CrmCustomerDO::getName, pageReqVO.getName())  
40 - .eqIfPresent(CrmCustomerDO::getMobile, pageReqVO.getMobile())  
41 - .eqIfPresent(CrmCustomerDO::getIndustryId, pageReqVO.getIndustryId())  
42 - .eqIfPresent(CrmCustomerDO::getLevel, pageReqVO.getLevel())  
43 - .eqIfPresent(CrmCustomerDO::getSource, pageReqVO.getSource()));  
44 - }  
45 -  
46 - default PageResult<CrmCustomerDO> selectPage(CrmCustomerPageReqVO pageReqVO, Long userId) {  
47 - // 情况二:获取当前用户能看的分页数据 33 + /**
  34 + * 获取客户分页
  35 + *
  36 + * @param pageReqVO 请求
  37 + * @param userId 用户编号
  38 + * @param subordinateIds 下属用户编号
  39 + * @param isAdmin 是否为管理
  40 + * @return 客户分页数据
  41 + */
  42 + default PageResult<CrmCustomerDO> selectPage(CrmCustomerPageReqVO pageReqVO, Long userId, Collection<Long> subordinateIds, Boolean isAdmin) {
48 IPage<CrmCustomerDO> mpPage = MyBatisUtils.buildPage(pageReqVO); 43 IPage<CrmCustomerDO> mpPage = MyBatisUtils.buildPage(pageReqVO);
49 MPJLambdaWrapperX<CrmCustomerDO> mpjLambdaWrapperX = new MPJLambdaWrapperX<>(); 44 MPJLambdaWrapperX<CrmCustomerDO> mpjLambdaWrapperX = new MPJLambdaWrapperX<>();
50 // 构建数据权限连表条件 45 // 构建数据权限连表条件
51 - mpjLambdaWrapperX  
52 - .innerJoin(CrmPermissionDO.class, CrmPermissionDO::getBizId, CrmCustomerDO::getId)  
53 - .eq(CrmPermissionDO::getBizType, CrmBizTypeEnum.CRM_CUSTOMER.getType())  
54 - .eq(CrmPermissionDO::getUserId, userId);  
55 - appendQueryParams(mpjLambdaWrapperX, pageReqVO, userId); 46 + CrmQueryPageUtils.builderQuery(mpjLambdaWrapperX, pageReqVO, userId,
  47 + CrmBizTypeEnum.CRM_CUSTOMER.getType(), CrmCustomerDO::getId, subordinateIds, isAdmin);
56 mpjLambdaWrapperX 48 mpjLambdaWrapperX
57 .selectAll(CrmCustomerDO.class) 49 .selectAll(CrmCustomerDO.class)
58 .likeIfPresent(CrmCustomerDO::getName, pageReqVO.getName()) 50 .likeIfPresent(CrmCustomerDO::getName, pageReqVO.getName())
@@ -69,28 +61,4 @@ public interface CrmCustomerMapper extends BaseMapperX&lt;CrmCustomerDO&gt; { @@ -69,28 +61,4 @@ public interface CrmCustomerMapper extends BaseMapperX&lt;CrmCustomerDO&gt; {
69 return new PageResult<>(mpPage.getRecords(), mpPage.getTotal()); 61 return new PageResult<>(mpPage.getRecords(), mpPage.getTotal());
70 } 62 }
71 63
72 - static void appendQueryParams(MPJLambdaWrapperX<CrmCustomerDO> mpjLambdaWrapperX, CrmCustomerPageReqVO pageReqVO, Long userId) {  
73 - if (pageReqVO.getPool()) { // 情况一:公海  
74 - mpjLambdaWrapperX.isNull(CrmCustomerDO::getOwnerUserId);  
75 - } else { // 情况二:不是公海  
76 - mpjLambdaWrapperX.isNotNull(CrmCustomerDO::getOwnerUserId);  
77 - }  
78 - // TODO 场景数据过滤  
79 - if (CrmSceneEnum.isOwner(pageReqVO.getSceneType())) { // 场景一:我负责的数据  
80 - mpjLambdaWrapperX.eq(CrmCustomerDO::getOwnerUserId, userId);  
81 - }  
82 - }  
83 -  
84 - static void appendQueryParams(LambdaQueryWrapperX<CrmCustomerDO> lambdaQueryWrapperX, CrmCustomerPageReqVO pageReqVO, Long userId) {  
85 - if (pageReqVO.getPool()) { // 情况一:公海  
86 - lambdaQueryWrapperX.isNull(CrmCustomerDO::getOwnerUserId);  
87 - } else { // 情况二:不是公海  
88 - lambdaQueryWrapperX.isNotNull(CrmCustomerDO::getOwnerUserId);  
89 - }  
90 - // TODO 场景数据过滤  
91 - if (CrmSceneEnum.isOwner(pageReqVO.getSceneType())) { // 场景一:我负责的数据  
92 - lambdaQueryWrapperX.eq(CrmCustomerDO::getOwnerUserId, userId);  
93 - }  
94 - }  
95 -  
96 } 64 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/vo/CrmBasePageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.crm.framework.vo;
  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.enums.common.CrmSceneEnum;
  6 +import io.swagger.v3.oas.annotations.media.Schema;
  7 +import lombok.Data;
  8 +import lombok.EqualsAndHashCode;
  9 +
  10 +@Schema(description = "管理后台 - CRM 分页 Base Request VO")
  11 +@Data
  12 +@EqualsAndHashCode(callSuper = true)
  13 +public class CrmBasePageReqVO extends PageParam {
  14 +
  15 + /**
  16 + * 场景类型, 为 null 时则表示全部
  17 + *
  18 + * 关联 {@link CrmSceneEnum}
  19 + */
  20 + @Schema(description = "场景类型", example = "1")
  21 + @InEnum(CrmSceneEnum.class)
  22 + private Integer sceneType;
  23 +
  24 + @Schema(description = "是否为公海数据", requiredMode = Schema.RequiredMode.REQUIRED, example = "false")
  25 + private Boolean pool; // null 则表示为不是公海数据
  26 +
  27 +}
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java
@@ -110,12 +110,8 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { @@ -110,12 +110,8 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
110 110
111 @Override 111 @Override
112 public PageResult<CrmCustomerDO> getCustomerPage(CrmCustomerPageReqVO pageReqVO, Long userId) { 112 public PageResult<CrmCustomerDO> getCustomerPage(CrmCustomerPageReqVO pageReqVO, Long userId) {
113 - boolean admin = false;  
114 - if (admin) { // 1.1. 情况一: TODO 如果是管理员; TODO @puhui999:要不如果是超管,就复用 selectPage;  
115 - customerMapper.selectPageWithAdmin(pageReqVO, userId);  
116 - }  
117 - // 1.2. 情况二:获取当前用户能看的分页数据  
118 - return customerMapper.selectPage(pageReqVO, userId); 113 + boolean admin = false; // TODO 如果是管理员
  114 + return customerMapper.selectPage(pageReqVO, userId, adminUserApi.getSubordinateIds(userId), admin);
119 } 115 }
120 116
121 /** 117 /**
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApi.java
@@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; @@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
6 import java.util.Collection; 6 import java.util.Collection;
7 import java.util.List; 7 import java.util.List;
8 import java.util.Map; 8 import java.util.Map;
  9 +import java.util.Set;
9 10
10 /** 11 /**
11 * Admin 用户 API 接口 12 * Admin 用户 API 接口
@@ -23,6 +24,14 @@ public interface AdminUserApi { @@ -23,6 +24,14 @@ public interface AdminUserApi {
23 AdminUserRespDTO getUser(Long id); 24 AdminUserRespDTO getUser(Long id);
24 25
25 /** 26 /**
  27 + * 通过用户 ID 查询用户下属
  28 + *
  29 + * @param id 用户编号
  30 + * @return 用户下属用户编号列表
  31 + */
  32 + Set<Long> getSubordinateIds(Long id);
  33 +
  34 + /**
26 * 通过用户 ID 查询用户们 35 * 通过用户 ID 查询用户们
27 * 36 *
28 * @param ids 用户 ID 们 37 * @param ids 用户 ID 们
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApiImpl.java
1 package cn.iocoder.yudao.module.system.api.user; 1 package cn.iocoder.yudao.module.system.api.user;
2 2
  3 +import cn.hutool.core.util.ObjUtil;
3 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; 4 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
4 import cn.iocoder.yudao.module.system.convert.user.UserConvert; 5 import cn.iocoder.yudao.module.system.convert.user.UserConvert;
  6 +import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
5 import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; 7 import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
  8 +import cn.iocoder.yudao.module.system.service.dept.DeptService;
6 import cn.iocoder.yudao.module.system.service.user.AdminUserService; 9 import cn.iocoder.yudao.module.system.service.user.AdminUserService;
7 import org.springframework.stereotype.Service; 10 import org.springframework.stereotype.Service;
8 11
9 import javax.annotation.Resource; 12 import javax.annotation.Resource;
10 import java.util.Collection; 13 import java.util.Collection;
  14 +import java.util.Collections;
11 import java.util.List; 15 import java.util.List;
  16 +import java.util.Set;
  17 +
  18 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
12 19
13 /** 20 /**
14 * Admin 用户 API 实现类 21 * Admin 用户 API 实现类
@@ -20,6 +27,8 @@ public class AdminUserApiImpl implements AdminUserApi { @@ -20,6 +27,8 @@ public class AdminUserApiImpl implements AdminUserApi {
20 27
21 @Resource 28 @Resource
22 private AdminUserService userService; 29 private AdminUserService userService;
  30 + @Resource
  31 + private DeptService deptService;
23 32
24 @Override 33 @Override
25 public AdminUserRespDTO getUser(Long id) { 34 public AdminUserRespDTO getUser(Long id) {
@@ -28,6 +37,22 @@ public class AdminUserApiImpl implements AdminUserApi { @@ -28,6 +37,22 @@ public class AdminUserApiImpl implements AdminUserApi {
28 } 37 }
29 38
30 @Override 39 @Override
  40 + public Set<Long> getSubordinateIds(Long id) {
  41 + AdminUserDO user = userService.getUser(id);
  42 + if (user == null) {
  43 + return null;
  44 + }
  45 +
  46 + Set<Long> subordinateIds = null; // 下属用户编号
  47 + DeptDO dept = deptService.getDept(user.getDeptId());
  48 + if (ObjUtil.equal(dept.getLeaderUserId(), id)) { // 校验是否是该部门的负责人
  49 + List<AdminUserDO> users = userService.getUserListByDeptIds(Collections.singletonList(dept.getId()));
  50 + subordinateIds = convertSet(users, AdminUserDO::getId);
  51 + }
  52 + return subordinateIds;
  53 + }
  54 +
  55 + @Override
31 public List<AdminUserRespDTO> getUserList(Collection<Long> ids) { 56 public List<AdminUserRespDTO> getUserList(Collection<Long> ids) {
32 List<AdminUserDO> users = userService.getUserList(ids); 57 List<AdminUserDO> users = userService.getUserList(ids);
33 return UserConvert.INSTANCE.convertList4(users); 58 return UserConvert.INSTANCE.convertList4(users);