Commit 9ea0607339a091c3f1bf1c8d921ae1c3017158f8

Authored by puhui999
1 parent 5c395fc1

CRM-商机:完善数据权限,新增权限关联、场景分页查询,新增权限关联批量查询

yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessController.java
@@ -36,6 +36,7 @@ import java.util.Set; @@ -36,6 +36,7 @@ import java.util.Set;
36 import java.util.stream.Collectors; 36 import java.util.stream.Collectors;
37 37
38 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 38 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  39 +import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE;
39 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; 40 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
40 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; 41 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
41 42
@@ -143,20 +144,13 @@ public class CrmBusinessController { @@ -143,20 +144,13 @@ public class CrmBusinessController {
143 return success(CrmBusinessConvert.INSTANCE.convertPage(pageResult, customerList, statusTypeList, statusList)); 144 return success(CrmBusinessConvert.INSTANCE.convertPage(pageResult, customerList, statusTypeList, statusList));
144 } 145 }
145 146
146 - @GetMapping("/pool-page")  
147 - @Operation(summary = "获得商机公海分页")  
148 - @PreAuthorize("@ss.hasPermission('crm:business:query')")  
149 - public CommonResult<PageResult<CrmBusinessRespVO>> getBusinessPoolPage(@Valid CrmBusinessPageReqVO pageVO) {  
150 - // TODO puhui999: 等数据权限完善后再实现  
151 - return null;  
152 - }  
153 -  
154 @GetMapping("/export-excel") 147 @GetMapping("/export-excel")
155 @Operation(summary = "导出商机 Excel") 148 @Operation(summary = "导出商机 Excel")
156 @PreAuthorize("@ss.hasPermission('crm:business:export')") 149 @PreAuthorize("@ss.hasPermission('crm:business:export')")
157 @OperateLog(type = EXPORT) 150 @OperateLog(type = EXPORT)
158 public void exportBusinessExcel(@Valid CrmBusinessPageReqVO exportReqVO, 151 public void exportBusinessExcel(@Valid CrmBusinessPageReqVO exportReqVO,
159 HttpServletResponse response) throws IOException { 152 HttpServletResponse response) throws IOException {
  153 + exportReqVO.setPageSize(PAGE_SIZE_NONE);
160 PageResult<CrmBusinessDO> pageResult = businessService.getBusinessPage(exportReqVO, getLoginUserId()); 154 PageResult<CrmBusinessDO> pageResult = businessService.getBusinessPage(exportReqVO, getLoginUserId());
161 // 导出 Excel 155 // 导出 Excel
162 ExcelUtils.write(response, "商机.xls", "数据", CrmBusinessExcelVO.class, 156 ExcelUtils.write(response, "商机.xls", "数据", CrmBusinessExcelVO.class,
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessPageReqVO.java
1 package cn.iocoder.yudao.module.crm.controller.admin.business.vo.business; 1 package cn.iocoder.yudao.module.crm.controller.admin.business.vo.business;
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.framework.common.validation.InEnum;
  5 +import cn.iocoder.yudao.module.crm.enums.common.CrmSceneTypeEnum;
4 import io.swagger.v3.oas.annotations.media.Schema; 6 import io.swagger.v3.oas.annotations.media.Schema;
5 import lombok.Data; 7 import lombok.Data;
6 import lombok.EqualsAndHashCode; 8 import lombok.EqualsAndHashCode;
@@ -18,4 +20,14 @@ public class CrmBusinessPageReqVO extends PageParam { @@ -18,4 +20,14 @@ public class CrmBusinessPageReqVO extends PageParam {
18 @Schema(description = "客户编号", example = "10795") 20 @Schema(description = "客户编号", example = "10795")
19 private Long customerId; 21 private Long customerId;
20 22
  23 + /**
  24 + * 场景类型,为 null 时则表示全部
  25 + */
  26 + @Schema(description = "场景类型", example = "1")
  27 + @InEnum(CrmSceneTypeEnum.class)
  28 + private Integer sceneType;
  29 +
  30 + @Schema(description = "是否为公海数据", requiredMode = Schema.RequiredMode.REQUIRED, example = "false")
  31 + private Boolean pool; // null 则表示为不是公海数据
  32 +
21 } 33 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/business/CrmBusinessConvert.java
@@ -39,8 +39,7 @@ public interface CrmBusinessConvert { @@ -39,8 +39,7 @@ public interface CrmBusinessConvert {
39 List<CrmBusinessExcelVO> convertList02(List<CrmBusinessDO> list); 39 List<CrmBusinessExcelVO> convertList02(List<CrmBusinessDO> list);
40 40
41 @Mappings({ 41 @Mappings({
42 - @Mapping(target = "bizId", source = "reqVO.id"),  
43 - @Mapping(target = "newOwnerUserId", source = "reqVO.id") 42 + @Mapping(target = "bizId", source = "reqVO.id")
44 }) 43 })
45 CrmPermissionTransferReqBO convert(CrmBusinessTransferReqVO reqVO, Long userId); 44 CrmPermissionTransferReqBO convert(CrmBusinessTransferReqVO reqVO, Long userId);
46 45
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/business/CrmBusinessDO.java
@@ -97,4 +97,11 @@ public class CrmBusinessDO extends BaseDO { @@ -97,4 +97,11 @@ public class CrmBusinessDO extends BaseDO {
97 */ 97 */
98 private Integer followUpStatus; 98 private Integer followUpStatus;
99 99
  100 + /**
  101 + * 负责人的用户编号
  102 + *
  103 + * 关联 AdminUserDO 的 id 字段
  104 + */
  105 + private Long ownerUserId;
  106 +
100 } 107 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessMapper.java
@@ -2,13 +2,16 @@ package cn.iocoder.yudao.module.crm.dal.mysql.business; @@ -2,13 +2,16 @@ 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.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.MPJLambdaWrapperX;
6 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessPageReqVO; 6 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessPageReqVO;
7 -import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageReqVO;  
8 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; 7 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
  8 +import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
  9 +import cn.iocoder.yudao.module.crm.util.CrmQueryWrapperUtils;
  10 +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
9 import org.apache.ibatis.annotations.Mapper; 11 import org.apache.ibatis.annotations.Mapper;
10 12
11 import java.util.Collection; 13 import java.util.Collection;
  14 +import java.util.List;
12 15
13 /** 16 /**
14 * 商机 Mapper 17 * 商机 Mapper
@@ -18,18 +21,29 @@ import java.util.Collection; @@ -18,18 +21,29 @@ import java.util.Collection;
18 @Mapper 21 @Mapper
19 public interface CrmBusinessMapper extends BaseMapperX<CrmBusinessDO> { 22 public interface CrmBusinessMapper extends BaseMapperX<CrmBusinessDO> {
20 23
21 - default PageResult<CrmBusinessDO> selectPage(CrmBusinessPageReqVO reqVO, Collection<Long> ids) {  
22 - return selectPage(reqVO, new LambdaQueryWrapperX<CrmBusinessDO>()  
23 - .in(CrmBusinessDO::getId, ids)  
24 - .likeIfPresent(CrmBusinessDO::getName, reqVO.getName())  
25 - .orderByDesc(CrmBusinessDO::getId)); 24 + default int updateOwnerUserIdById(Long id, Long ownerUserId) {
  25 + return update(new LambdaUpdateWrapper<CrmBusinessDO>()
  26 + .eq(CrmBusinessDO::getId, id)
  27 + .set(CrmBusinessDO::getOwnerUserId, ownerUserId));
26 } 28 }
27 29
28 - default PageResult<CrmBusinessDO> selectPageByCustomer(CrmContractPageReqVO reqVO) {  
29 - return selectPage(reqVO, new LambdaQueryWrapperX<CrmBusinessDO>()  
30 - .eq(CrmBusinessDO::getCustomerId, reqVO.getCustomerId()) // 必须传递  
31 - .likeIfPresent(CrmBusinessDO::getName, reqVO.getName())  
32 - .orderByDesc(CrmBusinessDO::getId)); 30 + default PageResult<CrmBusinessDO> selectPage(CrmBusinessPageReqVO pageReqVO, Long userId) {
  31 + MPJLambdaWrapperX<CrmBusinessDO> mpjLambdaWrapperX = new MPJLambdaWrapperX<>();
  32 + // 构建数据权限连表条件
  33 + CrmQueryWrapperUtils.builderPageQuery(mpjLambdaWrapperX, CrmBizTypeEnum.CRM_BUSINESS.getType(), CrmBusinessDO::getId,
  34 + userId, pageReqVO.getSceneType(), pageReqVO.getPool());
  35 + mpjLambdaWrapperX.selectAll(CrmBusinessDO.class)
  36 + .eq(CrmBusinessDO::getCustomerId, pageReqVO.getCustomerId()) // 必须传递
  37 + .likeIfPresent(CrmBusinessDO::getName, pageReqVO.getName())
  38 + .orderByDesc(CrmBusinessDO::getId);
  39 + return selectJoinPage(pageReqVO, CrmBusinessDO.class, mpjLambdaWrapperX);
  40 + }
  41 +
  42 + default List<CrmBusinessDO> selectBatchIds(Collection<Long> ids, Long userId) {
  43 + MPJLambdaWrapperX<CrmBusinessDO> mpjLambdaWrapperX = new MPJLambdaWrapperX<>();
  44 + // 构建数据权限连表条件
  45 + CrmQueryWrapperUtils.builderListQueryBatch(mpjLambdaWrapperX, CrmBizTypeEnum.CRM_BUSINESS.getType(), ids, userId);
  46 + return selectJoinList(CrmBusinessDO.class, mpjLambdaWrapperX);
33 } 47 }
34 48
35 } 49 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessService.java
@@ -8,8 +8,8 @@ import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusi @@ -8,8 +8,8 @@ import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusi
8 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageReqVO; 8 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageReqVO;
9 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; 9 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
10 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; 10 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
11 -  
12 import jakarta.validation.Valid; 11 import jakarta.validation.Valid;
  12 +
13 import java.util.Collection; 13 import java.util.Collection;
14 import java.util.List; 14 import java.util.List;
15 15
@@ -57,7 +57,7 @@ public interface CrmBusinessService { @@ -57,7 +57,7 @@ public interface CrmBusinessService {
57 * @param ids 编号 57 * @param ids 编号
58 * @return 商机列表 58 * @return 商机列表
59 */ 59 */
60 - List<CrmBusinessDO> getBusinessList(Collection<Long> ids); 60 + List<CrmBusinessDO> getBusinessList(Collection<Long> ids, Long userId);
61 61
62 /** 62 /**
63 * 获得商机分页 63 * 获得商机分页
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java
@@ -3,28 +3,28 @@ package cn.iocoder.yudao.module.crm.service.business; @@ -3,28 +3,28 @@ package cn.iocoder.yudao.module.crm.service.business;
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.iocoder.yudao.framework.common.pojo.PageResult; 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.*; 6 +import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessCreateReqVO;
  7 +import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessPageReqVO;
  8 +import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessTransferReqVO;
  9 +import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessUpdateReqVO;
7 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageReqVO; 10 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageReqVO;
8 import cn.iocoder.yudao.module.crm.convert.business.CrmBusinessConvert; 11 import cn.iocoder.yudao.module.crm.convert.business.CrmBusinessConvert;
9 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; 12 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
10 -import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO;  
11 import cn.iocoder.yudao.module.crm.dal.mysql.business.CrmBusinessMapper; 13 import cn.iocoder.yudao.module.crm.dal.mysql.business.CrmBusinessMapper;
12 -import cn.iocoder.yudao.module.crm.framework.core.annotations.CrmPermission;  
13 import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; 14 import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
14 import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; 15 import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
  16 +import cn.iocoder.yudao.module.crm.framework.core.annotations.CrmPermission;
15 import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; 17 import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService;
16 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; 18 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO;
  19 +import jakarta.annotation.Resource;
17 import org.springframework.stereotype.Service; 20 import org.springframework.stereotype.Service;
18 import org.springframework.transaction.annotation.Transactional; 21 import org.springframework.transaction.annotation.Transactional;
19 import org.springframework.validation.annotation.Validated; 22 import org.springframework.validation.annotation.Validated;
20 23
21 -import jakarta.annotation.Resource;  
22 import java.util.Collection; 24 import java.util.Collection;
23 import java.util.List; 25 import java.util.List;
24 -import java.util.Set;  
25 26
26 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 27 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
27 -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;  
28 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.BUSINESS_NOT_EXISTS; 28 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.BUSINESS_NOT_EXISTS;
29 29
30 /** 30 /**
@@ -71,7 +71,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { @@ -71,7 +71,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
71 71
72 @Override 72 @Override
73 @Transactional(rollbackFor = Exception.class) 73 @Transactional(rollbackFor = Exception.class)
74 - @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, level = CrmPermissionLevelEnum.WRITE) 74 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, level = CrmPermissionLevelEnum.OWNER)
75 public void deleteBusiness(Long id) { 75 public void deleteBusiness(Long id) {
76 // 校验存在 76 // 校验存在
77 validateBusinessExists(id); 77 validateBusinessExists(id);
@@ -88,38 +88,29 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { @@ -88,38 +88,29 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
88 } 88 }
89 89
90 @Override 90 @Override
91 - @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS,bizId = "#id", level = CrmPermissionLevelEnum.READ) 91 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, bizId = "#id", level = CrmPermissionLevelEnum.READ)
92 public CrmBusinessDO getBusiness(Long id) { 92 public CrmBusinessDO getBusiness(Long id) {
93 return businessMapper.selectById(id); 93 return businessMapper.selectById(id);
94 } 94 }
95 95
96 @Override 96 @Override
97 - public List<CrmBusinessDO> getBusinessList(Collection<Long> ids) { 97 + public List<CrmBusinessDO> getBusinessList(Collection<Long> ids, Long userId) {
98 if (CollUtil.isEmpty(ids)) { 98 if (CollUtil.isEmpty(ids)) {
99 return ListUtil.empty(); 99 return ListUtil.empty();
100 } 100 }
101 - return businessMapper.selectBatchIds(ids); 101 + return businessMapper.selectBatchIds(ids, userId);
102 } 102 }
103 103
104 @Override 104 @Override
105 public PageResult<CrmBusinessDO> getBusinessPage(CrmBusinessPageReqVO pageReqVO, Long userId) { 105 public PageResult<CrmBusinessDO> getBusinessPage(CrmBusinessPageReqVO pageReqVO, Long userId) {
106 - // 1. 获取当前用户能看的分页数据  
107 - // TODO @puhui999:如果业务的数据量比较大,in 太多可能有性能问题噢;看看是不是搞成 join 连表了;可以微信讨论下;  
108 - List<CrmPermissionDO> permissions = crmPermissionService.getPermissionListByBizTypeAndUserId(  
109 - CrmBizTypeEnum.CRM_BUSINESS.getType(), userId);  
110 - Set<Long> ids = convertSet(permissions, CrmPermissionDO::getBizId);  
111 - if (CollUtil.isEmpty(ids)) { // 没得说明没有什么给他看的  
112 - return PageResult.empty();  
113 - }  
114 -  
115 - // 2. 获取商机分页数据  
116 - return businessMapper.selectPage(pageReqVO, ids); 106 + return businessMapper.selectPage(pageReqVO, userId);
117 } 107 }
118 108
119 @Override 109 @Override
120 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#pageReqVO.customerId", level = CrmPermissionLevelEnum.READ) 110 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#pageReqVO.customerId", level = CrmPermissionLevelEnum.READ)
121 public PageResult<CrmBusinessDO> getBusinessPageByCustomer(CrmContractPageReqVO pageReqVO) { 111 public PageResult<CrmBusinessDO> getBusinessPageByCustomer(CrmContractPageReqVO pageReqVO) {
122 - return businessMapper.selectPageByCustomer(pageReqVO); 112 + //return businessMapper.selectPageByCustomer(pageReqVO);
  113 + return null; // TODO puhui999: 可以跟分页合并吗?
123 } 114 }
124 115
125 @Override 116 @Override
@@ -128,10 +119,13 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { @@ -128,10 +119,13 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
128 // 1 校验商机是否存在 119 // 1 校验商机是否存在
129 validateBusinessExists(reqVO.getId()); 120 validateBusinessExists(reqVO.getId());
130 121
131 - // 2. 数据权限转移 122 + // 2.1 数据权限转移
132 crmPermissionService.transferPermission( 123 crmPermissionService.transferPermission(
133 CrmBusinessConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_BUSINESS.getType())); 124 CrmBusinessConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_BUSINESS.getType()));
134 125
  126 + // 2.2 设置新的负责人
  127 + businessMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId());
  128 +
135 // 3. TODO 记录转移日志 129 // 3. TODO 记录转移日志
136 } 130 }
137 131