Commit d8b2da8eed232143f04f90c43472bf51fb9e4e02

Authored by puhui999
1 parent d492dace

CRM-客户: 完善 TODO

yudao-module-crm/yudao-module-crm-biz/pom.xml
@@ -37,6 +37,10 @@ @@ -37,6 +37,10 @@
37 <groupId>cn.iocoder.boot</groupId> 37 <groupId>cn.iocoder.boot</groupId>
38 <artifactId>yudao-spring-boot-starter-biz-ip</artifactId> 38 <artifactId>yudao-spring-boot-starter-biz-ip</artifactId>
39 </dependency> 39 </dependency>
  40 + <dependency>
  41 + <groupId>cn.iocoder.boot</groupId>
  42 + <artifactId>yudao-spring-boot-starter-biz-tenant</artifactId>
  43 + </dependency>
40 44
41 <!-- Web 相关 --> 45 <!-- Web 相关 -->
42 <dependency> 46 <dependency>
@@ -70,11 +74,5 @@ @@ -70,11 +74,5 @@
70 <groupId>cn.iocoder.boot</groupId> 74 <groupId>cn.iocoder.boot</groupId>
71 <artifactId>yudao-spring-boot-starter-test</artifactId> 75 <artifactId>yudao-spring-boot-starter-test</artifactId>
72 </dependency> 76 </dependency>
73 -  
74 - <!-- TODO @puhui999:放的位置,要整齐哈。 -->  
75 - <dependency>  
76 - <groupId>cn.iocoder.boot</groupId>  
77 - <artifactId>yudao-spring-boot-starter-biz-tenant</artifactId>  
78 - </dependency>  
79 </dependencies> 77 </dependencies>
80 </project> 78 </project>
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/customer/CrmCustomerMapper.java
@@ -100,11 +100,11 @@ public interface CrmCustomerMapper extends BaseMapperX&lt;CrmCustomerDO&gt; { @@ -100,11 +100,11 @@ public interface CrmCustomerMapper extends BaseMapperX&lt;CrmCustomerDO&gt; {
100 return selectJoinPage(pageReqVO, CrmCustomerDO.class, query); 100 return selectJoinPage(pageReqVO, CrmCustomerDO.class, query);
101 } 101 }
102 102
103 - default List<CrmCustomerDO> selectListByLockStatusAndOwnerUserIdNotNull(Boolean lockStatus) { 103 + default List<CrmCustomerDO> selectListByLockAndDealStatusAndNotPool(Boolean lockStatus, Boolean dealStatus) {
104 return selectList(new LambdaQueryWrapper<CrmCustomerDO>() 104 return selectList(new LambdaQueryWrapper<CrmCustomerDO>()
105 .eq(CrmCustomerDO::getLockStatus, lockStatus) 105 .eq(CrmCustomerDO::getLockStatus, lockStatus)
106 - // TODO @puhui999:not null 可以转化成大于 0  
107 - .isNotNull(CrmCustomerDO::getOwnerUserId)); 106 + .eq(CrmCustomerDO::getDealStatus, dealStatus)
  107 + .gt(CrmCustomerDO::getOwnerUserId, 0));
108 } 108 }
109 109
110 } 110 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/permission/core/util/CrmPermissionUtils.java
1 package cn.iocoder.yudao.module.crm.framework.permission.core.util; 1 package cn.iocoder.yudao.module.crm.framework.permission.core.util;
2 2
3 -import cn.hutool.core.util.ObjUtil;  
4 import cn.hutool.extra.spring.SpringUtil; 3 import cn.hutool.extra.spring.SpringUtil;
5 -import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO;  
6 -import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;  
7 -import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;  
8 import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionRoleCodeEnum; 4 import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionRoleCodeEnum;
9 -import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService;  
10 import cn.iocoder.yudao.module.system.api.permission.PermissionApi; 5 import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
11 6
12 -import java.util.List;  
13 -  
14 -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.anyMatch;  
15 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; 7 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
16 8
17 /** 9 /**
@@ -30,22 +22,6 @@ public class CrmPermissionUtils { @@ -30,22 +22,6 @@ public class CrmPermissionUtils {
30 return SingletonManager.getPermissionApi().hasAnyRoles(getLoginUserId(), CrmPermissionRoleCodeEnum.CRM_ADMIN.getCode()); 22 return SingletonManager.getPermissionApi().hasAnyRoles(getLoginUserId(), CrmPermissionRoleCodeEnum.CRM_ADMIN.getCode());
31 } 23 }
32 24
33 - // TODO @puhui999:这个貌似直接放到 CrmPermissionService 会更好?  
34 - /**  
35 - * 校验权限  
36 - *  
37 - * @param bizType 数据类型,关联 {@link CrmBizTypeEnum}  
38 - * @param bizId 数据编号,关联 {@link CrmBizTypeEnum} 对应模块 DO#getId()  
39 - * @param userId 用户编号  
40 - * @param levelEnum 权限级别  
41 - * @return boolean  
42 - */  
43 - public static boolean hasPermission(Integer bizType, Long bizId, Long userId, CrmPermissionLevelEnum levelEnum) {  
44 - List<CrmPermissionDO> permissionList = SingletonManager.getCrmPermissionService().getPermissionListByBiz(bizType, bizId);  
45 - return anyMatch(permissionList, permission ->  
46 - ObjUtil.equal(permission.getUserId(), userId) && ObjUtil.equal(permission.getLevel(), levelEnum.getLevel()));  
47 - }  
48 -  
49 /** 25 /**
50 * 静态内部类实现单例获取 26 * 静态内部类实现单例获取
51 * 27 *
@@ -54,16 +30,11 @@ public class CrmPermissionUtils { @@ -54,16 +30,11 @@ public class CrmPermissionUtils {
54 private static class SingletonManager { 30 private static class SingletonManager {
55 31
56 private static final PermissionApi PERMISSION_API = SpringUtil.getBean(PermissionApi.class); 32 private static final PermissionApi PERMISSION_API = SpringUtil.getBean(PermissionApi.class);
57 - private static final CrmPermissionService CRM_PERMISSION_SERVICE = SpringUtil.getBean(CrmPermissionService.class);  
58 33
59 public static PermissionApi getPermissionApi() { 34 public static PermissionApi getPermissionApi() {
60 return PERMISSION_API; 35 return PERMISSION_API;
61 } 36 }
62 37
63 - public static CrmPermissionService getCrmPermissionService() {  
64 - return CRM_PERMISSION_SERVICE;  
65 - }  
66 -  
67 } 38 }
68 39
69 } 40 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/job/customer/CrmCustomerAutoPutPoolJob.java
@@ -20,7 +20,7 @@ public class CrmCustomerAutoPutPoolJob implements JobHandler { @@ -20,7 +20,7 @@ public class CrmCustomerAutoPutPoolJob implements JobHandler {
20 @Override 20 @Override
21 @TenantJob 21 @TenantJob
22 public String execute(String param) { 22 public String execute(String param) {
23 - int count = customerService.customerAutoPutPoolBySystem(); 23 + int count = customerService.autoPutCustomerPool();
24 return String.format("掉入公海客户 %s 个", count); 24 return String.format("掉入公海客户 %s 个", count);
25 } 25 }
26 26
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerService.java
@@ -126,12 +126,11 @@ public interface CrmCustomerService { @@ -126,12 +126,11 @@ public interface CrmCustomerService {
126 */ 126 */
127 void receiveCustomer(List<Long> ids, Long ownerUserId, Boolean isReceive); 127 void receiveCustomer(List<Long> ids, Long ownerUserId, Boolean isReceive);
128 128
129 - // TODO @puhui999:autoPutCustomerPool,注释说明是系统就好哈;  
130 /** 129 /**
131 * 【系统】客户自动掉入公海 130 * 【系统】客户自动掉入公海
132 * 131 *
133 * @return 掉入公海数量 132 * @return 掉入公海数量
134 */ 133 */
135 - int customerAutoPutPoolBySystem(); 134 + int autoPutCustomerPool();
136 135
137 } 136 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java
@@ -47,6 +47,7 @@ import java.util.Collections; @@ -47,6 +47,7 @@ import java.util.Collections;
47 import java.util.List; 47 import java.util.List;
48 48
49 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 49 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  50 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList;
50 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*; 51 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*;
51 import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*; 52 import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*;
52 import static cn.iocoder.yudao.module.crm.enums.customer.CrmCustomerLimitConfigTypeEnum.CUSTOMER_LOCK_LIMIT; 53 import static cn.iocoder.yudao.module.crm.enums.customer.CrmCustomerLimitConfigTypeEnum.CUSTOMER_LOCK_LIMIT;
@@ -313,23 +314,22 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { @@ -313,23 +314,22 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
313 } 314 }
314 315
315 @Override 316 @Override
316 - public int customerAutoPutPoolBySystem() { 317 + public int autoPutCustomerPool() {
317 CrmCustomerPoolConfigDO poolConfig = customerPoolConfigService.getCustomerPoolConfig(); 318 CrmCustomerPoolConfigDO poolConfig = customerPoolConfigService.getCustomerPoolConfig();
318 if (poolConfig == null || !poolConfig.getEnabled()) { 319 if (poolConfig == null || !poolConfig.getEnabled()) {
319 return 0; 320 return 0;
320 } 321 }
321 - // 1. 获取没有锁定的不在公海的客户  
322 - List<CrmCustomerDO> customerList = customerMapper.selectListByLockStatusAndOwnerUserIdNotNull(Boolean.FALSE);  
323 - List<CrmCustomerDO> poolCustomerList = CollectionUtils.filterList(customerList, customer -> {  
324 - // TODO @puhui999:建议这里作为一个查询条件哈,不放内存里过滤;  
325 - // 1.1 未成交放入公海  
326 - if (!customer.getDealStatus()) {  
327 - return (poolConfig.getDealExpireDays() - LocalDateTimeUtils.between(customer.getCreateTime())) <= 0;  
328 - }  
329 - // 1.2 未跟进放入公海 322 + // 1.1 获取没有锁定的不在公海的客户且没有成交的
  323 + List<CrmCustomerDO> notDealCustomerList = customerMapper.selectListByLockAndDealStatusAndNotPool(Boolean.FALSE, Boolean.FALSE);
  324 + // 1.2 获取没有锁定的不在公海的客户且成交的
  325 + List<CrmCustomerDO> dealCustomerList = customerMapper.selectListByLockAndDealStatusAndNotPool(Boolean.FALSE, Boolean.TRUE);
  326 + List<CrmCustomerDO> poolCustomerList = new ArrayList<>();
  327 + poolCustomerList.addAll(filterList(notDealCustomerList, customer ->
  328 + (poolConfig.getDealExpireDays() - LocalDateTimeUtils.between(customer.getCreateTime())) <= 0));
  329 + poolCustomerList.addAll(filterList(dealCustomerList, customer -> {
330 LocalDateTime lastTime = ObjUtil.defaultIfNull(customer.getContactLastTime(), customer.getCreateTime()); 330 LocalDateTime lastTime = ObjUtil.defaultIfNull(customer.getContactLastTime(), customer.getCreateTime());
331 return (poolConfig.getContactExpireDays() - LocalDateTimeUtils.between(lastTime)) <= 0; 331 return (poolConfig.getContactExpireDays() - LocalDateTimeUtils.between(lastTime)) <= 0;
332 - }); 332 + }));
333 333
334 // 2. 逐个放入公海 334 // 2. 逐个放入公海
335 int count = 0; 335 int count = 0;
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/CrmFollowUpRecordServiceImpl.java
@@ -33,7 +33,6 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU @@ -33,7 +33,6 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU
33 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; 33 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
34 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.FOLLOW_UP_RECORD_DELETE_DENIED; 34 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.FOLLOW_UP_RECORD_DELETE_DENIED;
35 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.FOLLOW_UP_RECORD_NOT_EXISTS; 35 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.FOLLOW_UP_RECORD_NOT_EXISTS;
36 -import static cn.iocoder.yudao.module.crm.framework.permission.core.util.CrmPermissionUtils.hasPermission;  
37 36
38 /** 37 /**
39 * 跟进记录 Service 实现类 38 * 跟进记录 Service 实现类
@@ -119,7 +118,7 @@ public class CrmFollowUpRecordServiceImpl implements CrmFollowUpRecordService { @@ -119,7 +118,7 @@ public class CrmFollowUpRecordServiceImpl implements CrmFollowUpRecordService {
119 // 校验存在 118 // 校验存在
120 CrmFollowUpRecordDO followUpRecord = validateFollowUpRecordExists(id); 119 CrmFollowUpRecordDO followUpRecord = validateFollowUpRecordExists(id);
121 // 校验权限 120 // 校验权限
122 - if (!hasPermission(followUpRecord.getBizType(), followUpRecord.getBizId(), userId, CrmPermissionLevelEnum.OWNER)) { 121 + if (!permissionService.hasPermission(followUpRecord.getBizType(), followUpRecord.getBizId(), userId, CrmPermissionLevelEnum.OWNER)) {
123 throw exception(FOLLOW_UP_RECORD_DELETE_DENIED); 122 throw exception(FOLLOW_UP_RECORD_DELETE_DENIED);
124 } 123 }
125 124
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionService.java
@@ -108,4 +108,15 @@ public interface CrmPermissionService { @@ -108,4 +108,15 @@ public interface CrmPermissionService {
108 */ 108 */
109 List<CrmPermissionDO> getPermissionListByBizTypeAndUserId(Integer bizType, Long userId); 109 List<CrmPermissionDO> getPermissionListByBizTypeAndUserId(Integer bizType, Long userId);
110 110
  111 + /**
  112 + * 校验权限
  113 + *
  114 + * @param bizType 数据类型,关联 {@link CrmBizTypeEnum}
  115 + * @param bizId 数据编号,关联 {@link CrmBizTypeEnum} 对应模块 DO#getId()
  116 + * @param userId 用户编号
  117 + * @param levelEnum 权限级别
  118 + * @return boolean
  119 + */
  120 + boolean hasPermission(Integer bizType, Long bizId, Long userId, CrmPermissionLevelEnum levelEnum);
  121 +
111 } 122 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionServiceImpl.java
@@ -24,6 +24,7 @@ import java.util.List; @@ -24,6 +24,7 @@ import java.util.List;
24 import java.util.Set; 24 import java.util.Set;
25 25
26 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 26 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  27 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.anyMatch;
27 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; 28 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
28 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*; 29 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*;
29 import static cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum.isOwner; 30 import static cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum.isOwner;
@@ -211,4 +212,11 @@ public class CrmPermissionServiceImpl implements CrmPermissionService { @@ -211,4 +212,11 @@ public class CrmPermissionServiceImpl implements CrmPermissionService {
211 return permissionMapper.selectListByBizTypeAndUserId(bizType, userId); 212 return permissionMapper.selectListByBizTypeAndUserId(bizType, userId);
212 } 213 }
213 214
  215 + @Override
  216 + public boolean hasPermission(Integer bizType, Long bizId, Long userId, CrmPermissionLevelEnum levelEnum) {
  217 + List<CrmPermissionDO> permissionList = permissionMapper.selectByBizTypeAndBizId(bizType, bizId);
  218 + return anyMatch(permissionList, permission ->
  219 + ObjUtil.equal(permission.getUserId(), userId) && ObjUtil.equal(permission.getLevel(), levelEnum.getLevel()));
  220 + }
  221 +
214 } 222 }