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 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 4 import io.swagger.v3.oas.annotations.media.Schema;
6 5 import lombok.Data;
7 6 import lombok.EqualsAndHashCode;
8 7 import lombok.ToString;
9 8  
10   -import javax.validation.constraints.NotNull;
11   -
12 9 @Schema(description = "管理后台 - CRM 客户分页 Request VO")
13 10 @Data
14 11 @EqualsAndHashCode(callSuper = true)
15 12 @ToString(callSuper = true)
16   -public class CrmCustomerPageReqVO extends PageParam {
  13 +public class CrmCustomerPageReqVO extends CrmBasePageReqVO {
17 14  
18 15 @Schema(description = "客户名称", example = "赵六")
19 16 private String name;
... ... @@ -30,16 +27,4 @@ public class CrmCustomerPageReqVO extends PageParam {
30 27 @Schema(description = "客户来源", example = "1")
31 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 3 import cn.iocoder.yudao.framework.common.pojo.PageParam;
4 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 5 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
6   -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
7 6 import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
8 7 import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
9 8 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerPageReqVO;
10 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 10 import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
  11 +import cn.iocoder.yudao.module.crm.util.CrmQueryPageUtils;
14 12 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
15 13 import com.baomidou.mybatisplus.core.metadata.IPage;
16 14 import org.apache.ibatis.annotations.Mapper;
17 15  
  16 +import java.util.Collection;
18 17 import java.util.List;
19 18  
20 19 /**
... ... @@ -31,28 +30,21 @@ public interface CrmCustomerMapper extends BaseMapperX<CrmCustomerDO> {
31 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 43 IPage<CrmCustomerDO> mpPage = MyBatisUtils.buildPage(pageReqVO);
49 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 48 mpjLambdaWrapperX
57 49 .selectAll(CrmCustomerDO.class)
58 50 .likeIfPresent(CrmCustomerDO::getName, pageReqVO.getName())
... ... @@ -69,28 +61,4 @@ public interface CrmCustomerMapper extends BaseMapperX&lt;CrmCustomerDO&gt; {
69 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 110  
111 111 @Override
112 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 import java.util.Collection;
7 7 import java.util.List;
8 8 import java.util.Map;
  9 +import java.util.Set;
9 10  
10 11 /**
11 12 * Admin 用户 API 接口
... ... @@ -23,6 +24,14 @@ public interface AdminUserApi {
23 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 35 * 通过用户 ID 查询用户们
27 36 *
28 37 * @param ids 用户 ID 们
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApiImpl.java
1 1 package cn.iocoder.yudao.module.system.api.user;
2 2  
  3 +import cn.hutool.core.util.ObjUtil;
3 4 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
4 5 import cn.iocoder.yudao.module.system.convert.user.UserConvert;
  6 +import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
5 7 import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
  8 +import cn.iocoder.yudao.module.system.service.dept.DeptService;
6 9 import cn.iocoder.yudao.module.system.service.user.AdminUserService;
7 10 import org.springframework.stereotype.Service;
8 11  
9 12 import javax.annotation.Resource;
10 13 import java.util.Collection;
  14 +import java.util.Collections;
11 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 21 * Admin 用户 API 实现类
... ... @@ -20,6 +27,8 @@ public class AdminUserApiImpl implements AdminUserApi {
20 27  
21 28 @Resource
22 29 private AdminUserService userService;
  30 + @Resource
  31 + private DeptService deptService;
23 32  
24 33 @Override
25 34 public AdminUserRespDTO getUser(Long id) {
... ... @@ -28,6 +37,22 @@ public class AdminUserApiImpl implements AdminUserApi {
28 37 }
29 38  
30 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 56 public List<AdminUserRespDTO> getUserList(Collection<Long> ids) {
32 57 List<AdminUserDO> users = userService.getUserList(ids);
33 58 return UserConvert.INSTANCE.convertList4(users);
... ...