|
@@ -2,9 +2,11 @@ package cn.iocoder.yudao.module.crm.service.customer;
|
|
|
|
|
|
import cn.hutool.core.collection.CollUtil;
|
|
|
import cn.hutool.core.lang.Assert;
|
|
|
+import cn.hutool.core.util.ObjUtil;
|
|
|
import cn.hutool.extra.spring.SpringUtil;
|
|
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|
|
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.module.crm.controller.admin.customer.vo.CrmCustomerLockReqVO;
|
|
|
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.dal.dataobject.customer.CrmCustomerDO;
|
|
|
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.enums.common.CrmBizTypeEnum;
|
|
|
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.starter.annotation.LogRecord;
|
|
|
import jakarta.annotation.Resource;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.context.annotation.Lazy;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
@@ -43,12 +47,10 @@ import java.util.Collections;
|
|
|
import java.util.List;
|
|
|
|
|
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
|
|
-import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
|
|
import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*;
|
|
|
import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*;
|
|
|
import static cn.iocoder.yudao.module.crm.enums.customer.CrmCustomerLimitConfigTypeEnum.CUSTOMER_LOCK_LIMIT;
|
|
|
import static cn.iocoder.yudao.module.crm.enums.customer.CrmCustomerLimitConfigTypeEnum.CUSTOMER_OWNER_LIMIT;
|
|
|
-import static java.util.Collections.emptyList;
|
|
|
import static java.util.Collections.singletonList;
|
|
|
|
|
|
/**
|
|
@@ -57,6 +59,7 @@ import static java.util.Collections.singletonList;
|
|
|
* @author Wanwan
|
|
|
*/
|
|
|
@Service
|
|
|
+@Slf4j
|
|
|
@Validated
|
|
|
public class CrmCustomerServiceImpl implements CrmCustomerService {
|
|
|
|
|
@@ -69,6 +72,9 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
|
|
|
private CrmCustomerLimitConfigService customerLimitConfigService;
|
|
|
@Resource
|
|
|
@Lazy
|
|
|
+ private CrmCustomerPoolConfigService customerPoolConfigService;
|
|
|
+ @Resource
|
|
|
+ @Lazy
|
|
|
private CrmContactService contactService;
|
|
|
@Resource
|
|
|
@Lazy
|
|
@@ -91,9 +97,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
|
|
|
|
|
|
// 2. 插入客户
|
|
|
CrmCustomerDO customer = BeanUtils.toBean(createReqVO, CrmCustomerDO.class)
|
|
|
- .setLockStatus(false).setDealStatus(false)
|
|
|
- .setContactLastTime(LocalDateTime.now());
|
|
|
- // TODO @puhui999:可能要加个 receiveTime 字段,记录最后接收时间
|
|
|
+ .setLockStatus(false).setDealStatus(false).setContactLastTime(LocalDateTime.now());
|
|
|
customerMapper.insert(customer);
|
|
|
|
|
|
// 3. 创建数据权限
|
|
@@ -214,24 +218,24 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
|
|
|
|
|
|
@Override
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
- public List<CrmCustomerDO> createCustomerBatch(List<CrmCustomerCreateReqBO> customerCreateReqBOs, Long userId) {
|
|
|
- if (CollUtil.isEmpty(customerCreateReqBOs)) {
|
|
|
- return emptyList();
|
|
|
- }
|
|
|
+ @LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_CREATE_SUB_TYPE, bizNo = "{{#customer.id}}",
|
|
|
+ success = CRM_CUSTOMER_CREATE_SUCCESS)
|
|
|
+ public Long createCustomer(CrmCustomerCreateReqBO customerCreateReq, Long userId) {
|
|
|
+ // 1. 插入客户
|
|
|
+ CrmCustomerDO customer = BeanUtils.toBean(customerCreateReq, CrmCustomerDO.class).setOwnerUserId(userId)
|
|
|
+ .setLockStatus(false).setDealStatus(false).setReceiveTime(LocalDateTime.now());
|
|
|
+ customerMapper.insert(customer);
|
|
|
|
|
|
- // 创建客户
|
|
|
- List<CrmCustomerDO> customers = convertList(customerCreateReqBOs, customerBO ->
|
|
|
- BeanUtils.toBean(customerBO, CrmCustomerDO.class).setOwnerUserId(userId));
|
|
|
- customerMapper.insertBatch(customers);
|
|
|
+ // 2. 创建数据权限
|
|
|
+ permissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType())
|
|
|
+ .setBizId(customer.getId()).setUserId(userId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); // 设置当前操作的人为负责人
|
|
|
|
|
|
- // 创建负责人数据权限
|
|
|
- permissionService.createPermissionBatch(convertList(customers, customer -> new CrmPermissionCreateReqBO()
|
|
|
- .setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType()).setBizId(customer.getId()).setUserId(userId)
|
|
|
- .setLevel(CrmPermissionLevelEnum.OWNER.getLevel())));
|
|
|
- return customers;
|
|
|
+ // 3. 记录操作日志上下文
|
|
|
+ LogRecordContext.putVariable("customer", customer);
|
|
|
+ return customer.getId();
|
|
|
}
|
|
|
|
|
|
- // ==================== 公海相关操作 ====================
|
|
|
+// ==================== 公海相关操作 ====================
|
|
|
|
|
|
@Override
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
@@ -249,17 +253,8 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
|
|
|
// 1.3. 校验客户是否锁定
|
|
|
validateCustomerIsLocked(customer, true);
|
|
|
|
|
|
- // 2.1 设置负责人为 NULL
|
|
|
- int updateOwnerUserIncr = customerMapper.updateOwnerUserIdById(customer.getId(), null);
|
|
|
- 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);
|
|
|
+ // 2. 客户放入公海
|
|
|
+ putCustomerPool(customer);
|
|
|
|
|
|
// 记录操作日志上下文
|
|
|
LogRecordContext.putVariable("customerName", customer.getName());
|
|
@@ -317,6 +312,52 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public int customerAutoPutPoolBySystem() {
|
|
|
+ CrmCustomerPoolConfigDO poolConfig = customerPoolConfigService.getCustomerPoolConfig();
|
|
|
+ if (poolConfig == null || !poolConfig.getEnabled()) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ // 1. 获取没有锁定的不在公海的客户
|
|
|
+ List<CrmCustomerDO> customerList = customerMapper.selectListByLockStatusAndOwnerUserIdNotNull(Boolean.FALSE);
|
|
|
+ List<CrmCustomerDO> poolCustomerList = CollectionUtils.filterList(customerList, customer -> {
|
|
|
+ // TODO @puhui999:建议这里作为一个查询条件哈,不放内存里过滤;
|
|
|
+ // 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;
|
|
|
+ });
|
|
|
+
|
|
|
+ // 2. 逐个放入公海
|
|
|
+ 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}}",
|
|
|
success = CRM_CUSTOMER_RECEIVE_SUCCESS)
|
|
|
public void receiveCustomerLog(CrmCustomerDO customer, String ownerUserName) {
|