CRM: 完善一些 TODO 提到的问题

This commit is contained in:
puhui999 2024-01-10 16:25:55 +08:00
parent 1a5fe6fa9a
commit ba103d6e86
11 changed files with 141 additions and 34 deletions

View File

@ -44,6 +44,7 @@ public interface ErrorCodeConstants {
ErrorCode CUSTOMER_UNLOCK_FAIL_IS_UNLOCK = new ErrorCode(1_020_006_008, "解锁客户失败,它已经处于未锁定状态");
ErrorCode CUSTOMER_LOCK_EXCEED_LIMIT = new ErrorCode(1_020_006_009, "锁定客户失败,超出锁定规则上限");
ErrorCode CUSTOMER_OWNER_EXCEED_LIMIT = new ErrorCode(1_020_006_010, "操作失败,超出客户数拥有上限");
ErrorCode CUSTOMER_DELETE_FAIL_HAVE_REFERENCE = new ErrorCode(1_020_006_011, "删除客户失败,有关联{}");
// ========== 权限管理 1_020_007_000 ==========
ErrorCode CRM_PERMISSION_NOT_EXISTS = new ErrorCode(1_020_007_000, "数据权限不存在");
@ -54,6 +55,7 @@ public interface ErrorCodeConstants {
ErrorCode CRM_PERMISSION_DELETE_FAIL_EXIST_OWNER = new ErrorCode(1_020_007_005, "删除数据权限失败,原因:存在负责人");
ErrorCode CRM_PERMISSION_DELETE_DENIED = new ErrorCode(1_020_007_006, "删除数据权限失败,原因:没有权限");
ErrorCode CRM_PERMISSION_DELETE_SELF_PERMISSION_FAIL_EXIST_OWNER = new ErrorCode(1_020_007_007, "删除数据权限失败,原因:不能删除负责人");
ErrorCode CRM_PERMISSION_CREATE_FAIL = new ErrorCode(1_020_007_008, "创建数据权限失败,原因:所加用户已有权限");
// ========== 产品 1_020_008_000 ==========
ErrorCode PRODUCT_NOT_EXISTS = new ErrorCode(1_020_008_000, "产品不存在");

View File

@ -28,6 +28,12 @@ public interface CrmContactMapper extends BaseMapperX<CrmContactDO> {
.set(CrmContactDO::getOwnerUserId, ownerUserId));
}
default int updateOwnerUserIdByCustomerId(Long customerId, Long ownerUserId) {
return update(new LambdaUpdateWrapper<CrmContactDO>()
.eq(CrmContactDO::getCustomerId, customerId)
.set(CrmContactDO::getOwnerUserId, ownerUserId));
}
default PageResult<CrmContactDO> selectPageByCustomerId(CrmContactPageReqVO pageVO) {
return selectPage(pageVO, new LambdaQueryWrapperX<CrmContactDO>()
.eq(CrmContactDO::getCustomerId, pageVO.getCustomerId()) // 指定客户编号

View File

@ -59,4 +59,11 @@ public interface CrmPermissionMapper extends BaseMapperX<CrmPermissionDO> {
.eq(CrmPermissionDO::getBizId, bizId));
}
default Long selectListByBiz(Collection<Integer> bizTypes, Collection<Long> bizIds, Collection<Long> userIds) {
return selectCount(new LambdaQueryWrapperX<CrmPermissionDO>()
.in(CrmPermissionDO::getBizType, bizTypes)
.in(CrmPermissionDO::getBizId, bizIds)
.in(CrmPermissionDO::getUserId, userIds));
}
}

View File

@ -98,4 +98,12 @@ public interface CrmBusinessService {
*/
void transferBusiness(CrmBusinessTransferReqVO reqVO, Long userId);
/**
* 获取关联客户的商机数量
*
* @param customerId 客户编号
* @return 数量
*/
Long getBusinessCountByCustomerId(Long customerId);
}

View File

@ -180,4 +180,9 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
convertSet(contactBusinessList, CrmContactBusinessDO::getBusinessId));
}
@Override
public Long getBusinessCountByCustomerId(Long customerId) {
return businessMapper.selectCount(CrmBusinessDO::getCustomerId, customerId);
}
}

View File

@ -1,7 +1,9 @@
package cn.iocoder.yudao.module.crm.service.contact;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.*;
import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactPageReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactSaveReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactTransferReqVO;
import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO;
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
import jakarta.validation.Valid;
@ -39,6 +41,22 @@ public interface CrmContactService {
*/
void deleteContact(Long id);
/**
* 联系人转移
*
* @param reqVO 请求
* @param userId 用户编号
*/
void transferContact(CrmContactTransferReqVO reqVO, Long userId);
/**
* 更新客户联系人负责人
*
* @param customerId 客户编号
* @param ownerUserId 用户编号
*/
void updateOwnerUserIdByCustomerId(Long customerId, Long ownerUserId);
/**
* 获得联系人
*
@ -85,11 +103,11 @@ public interface CrmContactService {
PageResult<CrmContactDO> getContactPageByCustomerId(CrmContactPageReqVO pageVO);
/**
* 联系人转移
* 获取关联客户的联系人数量
*
* @param reqVO 请求
* @param userId 用户编号
* @param customerId 客户编号
* @return 数量
*/
void transferContact(CrmContactTransferReqVO reqVO, Long userId);
Long getContactCountByCustomerId(Long customerId);
}

View File

@ -187,6 +187,11 @@ public class CrmContactServiceImpl implements CrmContactService {
LogRecordContext.putVariable("contact", contact);
}
@Override
public void updateOwnerUserIdByCustomerId(Long customerId, Long ownerUserId) {
contactMapper.updateOwnerUserIdByCustomerId(customerId, ownerUserId);
}
//======================= 查询相关 =======================
@Override
@ -219,4 +224,9 @@ public class CrmContactServiceImpl implements CrmContactService {
return contactMapper.selectPageByCustomerId(pageVO);
}
@Override
public Long getContactCountByCustomerId(Long customerId) {
return contactMapper.selectCount(CrmContactDO::getCustomerId, customerId);
}
}

View File

@ -95,4 +95,12 @@ public interface CrmContractService {
*/
Long getContractCountByContactId(Long contactId);
/**
* 获取关联客户的合同数量
*
* @param customerId 客户编号
* @return 数量
*/
Long getContractCountByCustomerId(Long customerId);
}

View File

@ -167,5 +167,10 @@ public class CrmContractServiceImpl implements CrmContractService {
return contractMapper.selectCountByContactId(contactId);
}
@Override
public Long getContractCountByCustomerId(Long customerId) {
return contractMapper.selectCount(CrmContractDO::getCustomerId, customerId);
}
// TODO @合同待定需要新增一个 ContractConfigDO 合同配置重点是到期提醒
}

View File

@ -18,6 +18,9 @@ import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
import cn.iocoder.yudao.module.crm.framework.permission.core.annotations.CrmPermission;
import cn.iocoder.yudao.module.crm.framework.permission.core.util.CrmPermissionUtils;
import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService;
import cn.iocoder.yudao.module.crm.service.contact.CrmContactService;
import cn.iocoder.yudao.module.crm.service.contract.CrmContractService;
import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService;
import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
@ -59,6 +62,12 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
private CrmPermissionService permissionService;
@Resource
private CrmCustomerLimitConfigService customerLimitConfigService;
@Resource
private CrmContactService contactService;
@Resource
private CrmBusinessService businessService;
@Resource
private CrmContractService contractService;
@Resource
private AdminUserApi adminUserApi;
@ -116,8 +125,8 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
public void deleteCustomer(Long id) {
// 校验存在
CrmCustomerDO customer = validateCustomerExists(id);
// TODO @puhui999如果有联系人商机则不允许删除
// 检查引用
checkCustomerReference(id);
// 删除
customerMapper.deleteById(id);
// 删除数据权限
@ -128,6 +137,23 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
LogRecordContext.putVariable("customerName", customer.getName());
}
/**
* 校验客户是否被引用
*
* @param id 客户编号
*/
private void checkCustomerReference(Long id) {
if (contactService.getContactCountByCustomerId(id) > 0) {
throw exception(CUSTOMER_DELETE_FAIL_HAVE_REFERENCE, CrmBizTypeEnum.CRM_CONTACT.getName());
}
if (businessService.getBusinessCountByCustomerId(id) > 0) {
throw exception(CUSTOMER_DELETE_FAIL_HAVE_REFERENCE, CrmBizTypeEnum.CRM_BUSINESS.getName());
}
if (contractService.getContractCountByCustomerId(id) > 0) {
throw exception(CUSTOMER_DELETE_FAIL_HAVE_REFERENCE, CrmBizTypeEnum.CRM_CONTRACT.getName());
}
}
@Override
@Transactional(rollbackFor = Exception.class)
@LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_TRANSFER_SUB_TYPE, bizNo = "{{#reqVO.id}}",
@ -200,6 +226,8 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
permissionService.deletePermission(CrmBizTypeEnum.CRM_CUSTOMER.getType(), customer.getId(),
CrmPermissionLevelEnum.OWNER.getLevel());
// TODO @puhui999联系人的负责人也要设置为 null这块和领取是对应的因为领取后负责人也要关联过来
// 提问那是不是可以这样理解客户所有联系人的负责人默认为客户的负责人然后添加客户团队成员时才存在同时分配给的操作
contactService.updateOwnerUserIdByCustomerId(customer.getId(), null);
// 记录操作日志上下文
LogRecordContext.putVariable("customerName", customer.getName());

View File

@ -20,6 +20,7 @@ import org.springframework.validation.annotation.Validated;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@ -36,7 +37,7 @@ import static cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnu
public class CrmPermissionServiceImpl implements CrmPermissionService {
@Resource
private CrmPermissionMapper crmPermissionMapper;
private CrmPermissionMapper permissionMapper;
@Resource
private AdminUserApi adminUserApi;
@ -44,50 +45,59 @@ public class CrmPermissionServiceImpl implements CrmPermissionService {
@Override
@Transactional(rollbackFor = Exception.class)
public Long createPermission(CrmPermissionCreateReqBO createReqBO) {
// TODO @puhui999排重
validatePermissionNotExists(Collections.singletonList(createReqBO));
// 1. 校验用户是否存在
adminUserApi.validateUserList(Collections.singletonList(createReqBO.getUserId()));
// 2. 创建
CrmPermissionDO permission = CrmPermissionConvert.INSTANCE.convert(createReqBO);
crmPermissionMapper.insert(permission);
permissionMapper.insert(permission);
return permission.getId();
}
@Override
public void createPermissionBatch(List<CrmPermissionCreateReqBO> createReqBOs) {
// TODO @puhui999排重
validatePermissionNotExists(createReqBOs);
// 1. 校验用户是否存在
adminUserApi.validateUserList(convertSet(createReqBOs, CrmPermissionCreateReqBO::getUserId));
// 2. 创建
List<CrmPermissionDO> permissions = CrmPermissionConvert.INSTANCE.convertList(createReqBOs);
crmPermissionMapper.insertBatch(permissions);
permissionMapper.insertBatch(permissions);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void updatePermission(CrmPermissionUpdateReqVO updateReqVO) {
// TODO @puhui999排重
// 1. 校验存在
validateCrmPermissionExists(updateReqVO.getIds());
validatePermissionExists(updateReqVO.getIds());
// 2. 更新
List<CrmPermissionDO> updateDO = CrmPermissionConvert.INSTANCE.convertList(updateReqVO);
crmPermissionMapper.updateBatch(updateDO);
permissionMapper.updateBatch(updateDO);
}
private void validateCrmPermissionExists(Collection<Long> ids) {
List<CrmPermissionDO> permissionList = crmPermissionMapper.selectBatchIds(ids);
private void validatePermissionExists(Collection<Long> ids) {
List<CrmPermissionDO> permissionList = permissionMapper.selectBatchIds(ids);
if (ObjUtil.notEqual(permissionList.size(), ids.size())) {
throw exception(CRM_PERMISSION_NOT_EXISTS);
}
}
private void validatePermissionNotExists(Collection<CrmPermissionCreateReqBO> createReqBOs) {
Set<Integer> bizTypes = convertSet(createReqBOs, CrmPermissionCreateReqBO::getBizType);
Set<Long> bizIds = convertSet(createReqBOs, CrmPermissionCreateReqBO::getBizId);
Set<Long> userIds = convertSet(createReqBOs, CrmPermissionCreateReqBO::getUserId);
Long count = permissionMapper.selectListByBiz(bizTypes, bizIds, userIds);
if (count > 0) {
throw exception(CRM_PERMISSION_CREATE_FAIL);
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public void transferPermission(CrmPermissionTransferReqBO transferReqBO) {
// 1. 校验数据权限是否是负责人只有负责人才可以转移
CrmPermissionDO oldPermission = crmPermissionMapper.selectByBizTypeAndBizIdByUserId(
CrmPermissionDO oldPermission = permissionMapper.selectByBizTypeAndBizIdByUserId(
transferReqBO.getBizType(), transferReqBO.getBizId(), transferReqBO.getUserId());
String bizTypeName = CrmBizTypeEnum.getNameByType(transferReqBO.getBizType());
if (oldPermission == null // 不是拥有者并且不是超管
@ -102,25 +112,25 @@ public class CrmPermissionServiceImpl implements CrmPermissionService {
adminUserApi.validateUserList(Collections.singletonList(transferReqBO.getNewOwnerUserId()));
// 2. 修改新负责人的权限
List<CrmPermissionDO> permissions = crmPermissionMapper.selectByBizTypeAndBizId(
List<CrmPermissionDO> permissions = permissionMapper.selectByBizTypeAndBizId(
transferReqBO.getBizType(), transferReqBO.getBizId()); // 获得所有数据权限
CrmPermissionDO permission = CollUtil.findOne(permissions,
item -> ObjUtil.equal(item.getUserId(), transferReqBO.getNewOwnerUserId()));
if (permission == null) {
crmPermissionMapper.insert(new CrmPermissionDO().setBizType(transferReqBO.getBizType())
permissionMapper.insert(new CrmPermissionDO().setBizType(transferReqBO.getBizType())
.setBizId(transferReqBO.getBizId()).setUserId(transferReqBO.getNewOwnerUserId())
.setLevel(CrmPermissionLevelEnum.OWNER.getLevel()));
} else {
crmPermissionMapper.updateById(new CrmPermissionDO().setId(permission.getId())
permissionMapper.updateById(new CrmPermissionDO().setId(permission.getId())
.setLevel(CrmPermissionLevelEnum.OWNER.getLevel()));
}
// 3. 修改老负责人的权限
if (transferReqBO.getOldOwnerPermissionLevel() != null) {
crmPermissionMapper.updateById(new CrmPermissionDO().setId(oldPermission.getId())
permissionMapper.updateById(new CrmPermissionDO().setId(oldPermission.getId())
.setLevel(transferReqBO.getOldOwnerPermissionLevel()));
} else {
crmPermissionMapper.deleteById(oldPermission.getId());
permissionMapper.deleteById(oldPermission.getId());
}
}
@ -128,19 +138,19 @@ public class CrmPermissionServiceImpl implements CrmPermissionService {
@Transactional(rollbackFor = Exception.class)
public void deletePermission(Integer bizType, Long bizId, Integer level) {
// 校验存在
List<CrmPermissionDO> permissions = crmPermissionMapper.selectListByBizTypeAndBizIdAndLevel(
List<CrmPermissionDO> permissions = permissionMapper.selectListByBizTypeAndBizIdAndLevel(
bizType, bizId, level);
if (CollUtil.isEmpty(permissions)) {
throw exception(CRM_PERMISSION_NOT_EXISTS);
}
// 删除数据权限
crmPermissionMapper.deleteBatchIds(convertSet(permissions, CrmPermissionDO::getId));
permissionMapper.deleteBatchIds(convertSet(permissions, CrmPermissionDO::getId));
}
@Override
public void deletePermission(Integer bizType, Long bizId) {
int deletedCount = crmPermissionMapper.deletePermission(bizType, bizId);
int deletedCount = permissionMapper.deletePermission(bizType, bizId);
if (deletedCount == 0) {
throw exception(CRM_PERMISSION_NOT_EXISTS);
}
@ -148,7 +158,7 @@ public class CrmPermissionServiceImpl implements CrmPermissionService {
@Override
public void deletePermissionBatch(Collection<Long> ids, Long userId) {
List<CrmPermissionDO> permissions = crmPermissionMapper.selectBatchIds(ids);
List<CrmPermissionDO> permissions = permissionMapper.selectBatchIds(ids);
if (CollUtil.isEmpty(permissions)) {
throw exception(CRM_PERMISSION_NOT_EXISTS);
}
@ -157,19 +167,19 @@ public class CrmPermissionServiceImpl implements CrmPermissionService {
throw exception(CRM_PERMISSION_DELETE_FAIL);
}
// 校验操作人是否为负责人
CrmPermissionDO permission = crmPermissionMapper.selectByIdAndUserId(permissions.get(0).getBizId(), userId);
CrmPermissionDO permission = permissionMapper.selectByIdAndUserId(permissions.get(0).getBizId(), userId);
if (!CrmPermissionLevelEnum.isOwner(permission.getLevel())) {
throw exception(CRM_PERMISSION_DELETE_DENIED);
}
// 删除数据权限
crmPermissionMapper.deleteBatchIds(ids);
permissionMapper.deleteBatchIds(ids);
}
@Override
public void deleteSelfPermission(Long id, Long userId) {
// 校验数据存在且是自己
CrmPermissionDO permission = crmPermissionMapper.selectByIdAndUserId(id, userId);
CrmPermissionDO permission = permissionMapper.selectByIdAndUserId(id, userId);
if (permission == null) {
throw exception(CRM_PERMISSION_NOT_EXISTS);
}
@ -179,22 +189,22 @@ public class CrmPermissionServiceImpl implements CrmPermissionService {
}
// 删除
crmPermissionMapper.deleteById(id);
permissionMapper.deleteById(id);
}
@Override
public List<CrmPermissionDO> getPermissionListByBiz(Integer bizType, Long bizId) {
return crmPermissionMapper.selectByBizTypeAndBizId(bizType, bizId);
return permissionMapper.selectByBizTypeAndBizId(bizType, bizId);
}
@Override
public List<CrmPermissionDO> getPermissionListByBiz(Integer bizType, Collection<Long> bizIds) {
return crmPermissionMapper.selectByBizTypeAndBizIds(bizType, bizIds);
return permissionMapper.selectByBizTypeAndBizIds(bizType, bizIds);
}
@Override
public List<CrmPermissionDO> getPermissionListByBizTypeAndUserId(Integer bizType, Long userId) {
return crmPermissionMapper.selectListByBizTypeAndUserId(bizType, userId);
return permissionMapper.selectListByBizTypeAndUserId(bizType, userId);
}
}