mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2024-11-27 01:32:03 +08:00
CRM: 客户自动掉入公海
This commit is contained in:
parent
6850c7c71d
commit
ed92bf45ce
@ -70,5 +70,9 @@
|
|||||||
<groupId>cn.iocoder.boot</groupId>
|
<groupId>cn.iocoder.boot</groupId>
|
||||||
<artifactId>yudao-spring-boot-starter-test</artifactId>
|
<artifactId>yudao-spring-boot-starter-test</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.iocoder.boot</groupId>
|
||||||
|
<artifactId>yudao-spring-boot-starter-biz-tenant</artifactId>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
@ -10,6 +10,7 @@ import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerPageR
|
|||||||
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
|
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
|
||||||
import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
|
import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
|
||||||
import cn.iocoder.yudao.module.crm.util.CrmQueryWrapperUtils;
|
import cn.iocoder.yudao.module.crm.util.CrmQueryWrapperUtils;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
@ -99,4 +100,10 @@ public interface CrmCustomerMapper extends BaseMapperX<CrmCustomerDO> {
|
|||||||
return selectJoinPage(pageReqVO, CrmCustomerDO.class, query);
|
return selectJoinPage(pageReqVO, CrmCustomerDO.class, query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default List<CrmCustomerDO> selectListByLockStatusAndOwnerUserIdNotNull(Boolean lockStatus) {
|
||||||
|
return selectList(new LambdaQueryWrapper<CrmCustomerDO>()
|
||||||
|
.eq(CrmCustomerDO::getLockStatus, lockStatus)
|
||||||
|
.isNotNull(CrmCustomerDO::getOwnerUserId));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
package cn.iocoder.yudao.module.crm.job.customer;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler;
|
||||||
|
import cn.iocoder.yudao.framework.tenant.core.job.TenantJob;
|
||||||
|
import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 客户自动掉入公海 Job
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class CrmCustomerAutoPutPoolJob implements JobHandler {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private CrmCustomerService customerService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@TenantJob
|
||||||
|
public String execute(String param) {
|
||||||
|
int count = customerService.customerAutoPutPoolBySystem();
|
||||||
|
return String.format("掉入公海客户 %s 个", count);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
package cn.iocoder.yudao.module.crm.job;
|
@ -126,4 +126,11 @@ public interface CrmCustomerService {
|
|||||||
*/
|
*/
|
||||||
void receiveCustomer(List<Long> ids, Long ownerUserId, Boolean isReceive);
|
void receiveCustomer(List<Long> ids, Long ownerUserId, Boolean isReceive);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 【系统】客户自动掉入公海
|
||||||
|
*
|
||||||
|
* @return 掉入公海数量
|
||||||
|
*/
|
||||||
|
int customerAutoPutPoolBySystem();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,11 @@ package cn.iocoder.yudao.module.crm.service.customer;
|
|||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.lang.Assert;
|
import cn.hutool.core.lang.Assert;
|
||||||
|
import cn.hutool.core.util.ObjUtil;
|
||||||
import cn.hutool.extra.spring.SpringUtil;
|
import cn.hutool.extra.spring.SpringUtil;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
|
||||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||||
import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerLockReqVO;
|
import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerLockReqVO;
|
||||||
import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerPageReqVO;
|
import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerPageReqVO;
|
||||||
@ -13,6 +15,7 @@ import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerTrans
|
|||||||
import cn.iocoder.yudao.module.crm.convert.customer.CrmCustomerConvert;
|
import cn.iocoder.yudao.module.crm.convert.customer.CrmCustomerConvert;
|
||||||
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
|
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
|
||||||
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerLimitConfigDO;
|
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerLimitConfigDO;
|
||||||
|
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerPoolConfigDO;
|
||||||
import cn.iocoder.yudao.module.crm.dal.mysql.customer.CrmCustomerMapper;
|
import cn.iocoder.yudao.module.crm.dal.mysql.customer.CrmCustomerMapper;
|
||||||
import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
|
import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
|
||||||
import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
|
import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
|
||||||
@ -31,6 +34,7 @@ import com.mzt.logapi.context.LogRecordContext;
|
|||||||
import com.mzt.logapi.service.impl.DiffParseFunction;
|
import com.mzt.logapi.service.impl.DiffParseFunction;
|
||||||
import com.mzt.logapi.starter.annotation.LogRecord;
|
import com.mzt.logapi.starter.annotation.LogRecord;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
@ -55,6 +59,7 @@ import static java.util.Collections.singletonList;
|
|||||||
* @author Wanwan
|
* @author Wanwan
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
|
@Slf4j
|
||||||
@Validated
|
@Validated
|
||||||
public class CrmCustomerServiceImpl implements CrmCustomerService {
|
public class CrmCustomerServiceImpl implements CrmCustomerService {
|
||||||
|
|
||||||
@ -67,6 +72,9 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
|
|||||||
private CrmCustomerLimitConfigService customerLimitConfigService;
|
private CrmCustomerLimitConfigService customerLimitConfigService;
|
||||||
@Resource
|
@Resource
|
||||||
@Lazy
|
@Lazy
|
||||||
|
private CrmCustomerPoolConfigService customerPoolConfigService;
|
||||||
|
@Resource
|
||||||
|
@Lazy
|
||||||
private CrmContactService contactService;
|
private CrmContactService contactService;
|
||||||
@Resource
|
@Resource
|
||||||
@Lazy
|
@Lazy
|
||||||
@ -245,17 +253,8 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
|
|||||||
// 1.3. 校验客户是否锁定
|
// 1.3. 校验客户是否锁定
|
||||||
validateCustomerIsLocked(customer, true);
|
validateCustomerIsLocked(customer, true);
|
||||||
|
|
||||||
// 2.1 设置负责人为 NULL
|
// 2. 客户放入公海
|
||||||
int updateOwnerUserIncr = customerMapper.updateOwnerUserIdById(customer.getId(), null);
|
putCustomerPool(customer);
|
||||||
if (updateOwnerUserIncr == 0) {
|
|
||||||
throw exception(CUSTOMER_UPDATE_OWNER_USER_FAIL);
|
|
||||||
}
|
|
||||||
// 2.2 删除负责人数据权限
|
|
||||||
permissionService.deletePermission(CrmBizTypeEnum.CRM_CUSTOMER.getType(), customer.getId(),
|
|
||||||
CrmPermissionLevelEnum.OWNER.getLevel());
|
|
||||||
|
|
||||||
// 3. 联系人的负责人,也要设置为 null。因为:因为领取后,负责人也要关联过来,这块和 receiveCustomer 是对应的
|
|
||||||
contactService.updateOwnerUserIdByCustomerId(customer.getId(), null);
|
|
||||||
|
|
||||||
// 记录操作日志上下文
|
// 记录操作日志上下文
|
||||||
LogRecordContext.putVariable("customerName", customer.getName());
|
LogRecordContext.putVariable("customerName", customer.getName());
|
||||||
@ -313,6 +312,49 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int customerAutoPutPoolBySystem() {
|
||||||
|
CrmCustomerPoolConfigDO poolConfig = customerPoolConfigService.getCustomerPoolConfig();
|
||||||
|
if (poolConfig == null || !poolConfig.getEnabled()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// 获取没有锁定的不在公海的客户
|
||||||
|
List<CrmCustomerDO> customerList = customerMapper.selectListByLockStatusAndOwnerUserIdNotNull(Boolean.FALSE);
|
||||||
|
List<CrmCustomerDO> poolCustomerList = CollectionUtils.filterList(customerList, customer -> {
|
||||||
|
// 1.1 未成交放入公海
|
||||||
|
if (!customer.getDealStatus()) {
|
||||||
|
return (poolConfig.getDealExpireDays() - LocalDateTimeUtils.between(customer.getCreateTime())) <= 0;
|
||||||
|
}
|
||||||
|
// 1.2 未跟进放入公海
|
||||||
|
LocalDateTime lastTime = ObjUtil.defaultIfNull(customer.getContactLastTime(), customer.getCreateTime());
|
||||||
|
return (poolConfig.getContactExpireDays() - LocalDateTimeUtils.between(lastTime)) <= 0;
|
||||||
|
});
|
||||||
|
int count = 0;
|
||||||
|
for (CrmCustomerDO customer : poolCustomerList) {
|
||||||
|
try {
|
||||||
|
getSelf().putCustomerPool(customer);
|
||||||
|
count++;
|
||||||
|
} catch (Throwable e) {
|
||||||
|
log.error("[customerAutoPutPoolBySystem][Customer 客户({}) 放入公海异常]", customer.getId(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void putCustomerPool(CrmCustomerDO customer) {
|
||||||
|
// 1. 设置负责人为 NULL
|
||||||
|
int updateOwnerUserIncr = customerMapper.updateOwnerUserIdById(customer.getId(), null);
|
||||||
|
if (updateOwnerUserIncr == 0) {
|
||||||
|
throw exception(CUSTOMER_UPDATE_OWNER_USER_FAIL);
|
||||||
|
}
|
||||||
|
// 2. 删除负责人数据权限
|
||||||
|
permissionService.deletePermission(CrmBizTypeEnum.CRM_CUSTOMER.getType(), customer.getId(),
|
||||||
|
CrmPermissionLevelEnum.OWNER.getLevel());
|
||||||
|
|
||||||
|
// 3. 联系人的负责人,也要设置为 null。因为:因为领取后,负责人也要关联过来,这块和 receiveCustomer 是对应的
|
||||||
|
contactService.updateOwnerUserIdByCustomerId(customer.getId(), null);
|
||||||
|
}
|
||||||
|
|
||||||
@LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_RECEIVE_SUB_TYPE, bizNo = "{{#customer.id}}",
|
@LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_RECEIVE_SUB_TYPE, bizNo = "{{#customer.id}}",
|
||||||
success = CRM_CUSTOMER_RECEIVE_SUCCESS)
|
success = CRM_CUSTOMER_RECEIVE_SUCCESS)
|
||||||
public void receiveCustomerLog(CrmCustomerDO customer, String ownerUserName) {
|
public void receiveCustomerLog(CrmCustomerDO customer, String ownerUserName) {
|
||||||
|
Loading…
Reference in New Issue
Block a user