mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2024-11-23 07:41:53 +08:00
CRM:完善 review 提到的问题
This commit is contained in:
parent
7dd35f3295
commit
02b63de808
@ -28,6 +28,7 @@ public interface ErrorCodeConstants {
|
||||
ErrorCode CONTACT_NOT_EXISTS = new ErrorCode(1_020_003_000, "联系人不存在");
|
||||
ErrorCode CONTACT_BUSINESS_LINK_NOT_EXISTS = new ErrorCode(1_020_003_001, "联系人商机关联不存在");
|
||||
ErrorCode CONTACT_DELETE_FAIL_CONTRACT_LINK_EXISTS = new ErrorCode(1_020_003_002, "联系人已关联合同,不能删除");
|
||||
ErrorCode CONTACT_UPDATE_OWNER_USER_FAIL = new ErrorCode(1_020_003_003, "更新联系人负责人失败");
|
||||
|
||||
// ========== 回款 1-020-004-000 ==========
|
||||
ErrorCode RECEIVABLE_NOT_EXISTS = new ErrorCode(1_020_004_000, "回款不存在");
|
||||
|
@ -77,6 +77,8 @@ public interface LogRecordConstants {
|
||||
String CRM_CONTACT_TRANSFER_SUCCESS = "将联系人【{{#contact.name}}】的负责人从【{getAdminUserById{#contact.ownerUserId}}】变更为了【{getAdminUserById{#reqVO.newOwnerUserId}}】";
|
||||
String CRM_CONTACT_FOLLOW_UP_SUB_TYPE = "联系人跟进";
|
||||
String CRM_CONTACT_FOLLOW_UP_SUCCESS = "联系人跟进【{{#contactName}}】";
|
||||
String CRM_CONTACT_UPDATE_OWNER_USER_SUB_TYPE = "更新联系人负责人";
|
||||
String CRM_CONTACT_UPDATE_OWNER_USER_SUCCESS = "将联系人【{{#contact.name}}】的负责人从【{getAdminUserById{#contact.ownerUserId}}】变更为了【{getAdminUserById{#ownerUserId}}】";
|
||||
|
||||
// ======================= CRM_BUSINESS 商机 =======================
|
||||
|
||||
|
@ -77,15 +77,14 @@ public class CrmBusinessSaveReqVO {
|
||||
@Schema(description = "联系人编号", example = "110")
|
||||
private Long contactId; // 使用场景,在【联系人详情】添加商机时,如果需要关联两者,需要传递 contactId 字段
|
||||
|
||||
// TODO @puhui999:传递 items 就行啦;
|
||||
@Schema(description = "产品列表")
|
||||
private List<CrmBusinessProductItem> productItems;
|
||||
private List<Item> items;
|
||||
|
||||
@Schema(description = "产品列表")
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public static class CrmBusinessProductItem {
|
||||
public static class Item {
|
||||
|
||||
@Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20529")
|
||||
@NotNull(message = "产品编号不能为空")
|
||||
|
@ -130,14 +130,13 @@ public class CrmContractRespVO {
|
||||
private Integer auditStatus;
|
||||
|
||||
@Schema(description = "产品列表")
|
||||
private List<CrmContractProductItemRespVO> productItems;
|
||||
private List<Item> items;
|
||||
|
||||
// TODO @puhui999:可以直接叫 Item
|
||||
@Schema(description = "产品列表")
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public static class CrmContractProductItemRespVO {
|
||||
public static class Item {
|
||||
|
||||
@Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20529")
|
||||
private Long id;
|
||||
|
@ -59,8 +59,8 @@ public interface CrmContractConvert {
|
||||
|
||||
default void setContractRespVOProductItems(CrmContractRespVO respVO, Map<Long, CrmContractProductDO> contractProductMap,
|
||||
List<CrmProductDO> productList) {
|
||||
respVO.setProductItems(CollectionUtils.convertList(productList, product -> {
|
||||
CrmContractRespVO.CrmContractProductItemRespVO productItemRespVO = BeanUtils.toBean(product, CrmContractRespVO.CrmContractProductItemRespVO.class);
|
||||
respVO.setItems(CollectionUtils.convertList(productList, product -> {
|
||||
CrmContractRespVO.Item productItemRespVO = BeanUtils.toBean(product, CrmContractRespVO.Item.class);
|
||||
findAndThen(contractProductMap, product.getId(), contractProduct ->
|
||||
productItemRespVO.setCount(contractProduct.getCount()).setDiscountPercent(contractProduct.getDiscountPercent()));
|
||||
return productItemRespVO;
|
||||
|
@ -57,8 +57,9 @@ public class CrmContractProductDO extends BaseDO {
|
||||
private Integer discountPercent;
|
||||
/**
|
||||
* 总计价格(折扣后价格)
|
||||
*
|
||||
* TODO @puhui999:可以写下计算公式哈;
|
||||
* = {@link #price}
|
||||
* * {@link #count}
|
||||
* * ({@link #discountPercent / 100})
|
||||
*/
|
||||
private Integer totalPrice;
|
||||
|
||||
|
@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.crm.dal.mysql.business;
|
||||
|
||||
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessProductDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@ -16,18 +15,8 @@ import java.util.List;
|
||||
@Mapper
|
||||
public interface CrmBusinessProductMapper extends BaseMapperX<CrmBusinessProductDO> {
|
||||
|
||||
// TODO @puhui999:用不到的方法,看看是不是删除哈
|
||||
default void deleteByBusinessId(Long getBusinessId) { // TODO @lzxhqs:第一个方法,和类之间最好空一行;
|
||||
delete(CrmBusinessProductDO::getBusinessId, getBusinessId);
|
||||
}
|
||||
|
||||
default CrmBusinessProductDO selectByBusinessId(Long getBusinessId) {
|
||||
return selectOne(CrmBusinessProductDO::getBusinessId, getBusinessId);
|
||||
}
|
||||
|
||||
default List<CrmBusinessProductDO> selectListByBusinessId(Long businessId) {
|
||||
// TODO @puhui999:可以简化,selectList(CrmBusinessProductDO::getBusinessId, businessId)
|
||||
return selectList(new LambdaQueryWrapperX<CrmBusinessProductDO>().eq(CrmBusinessProductDO::getBusinessId, businessId));
|
||||
return selectList(CrmBusinessProductDO::getBusinessId, businessId);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
package cn.iocoder.yudao.module.crm.dal.mysql.contactbusinesslink;
|
||||
package cn.iocoder.yudao.module.crm.dal.mysql.contact;
|
||||
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactBusinessDO;
|
||||
@ -9,7 +9,7 @@ import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* CRM 联系人与商机的关联 Mapper
|
||||
* CRM 联系人商机关联 Mapper
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@ -31,4 +31,4 @@ public interface CrmContactBusinessMapper extends BaseMapperX<CrmContactBusiness
|
||||
return selectList(CrmContactBusinessDO::getContactId, contactId);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -65,4 +65,8 @@ public interface CrmContactMapper extends BaseMapperX<CrmContactDO> {
|
||||
return selectJoinList(CrmContactDO.class, query);
|
||||
}
|
||||
|
||||
default List<CrmContactDO> selectListByCustomerId(Long customerId) {
|
||||
return selectList(CrmContactDO::getCustomerId, customerId);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,15 +16,6 @@ import java.util.List;
|
||||
@Mapper
|
||||
public interface CrmContractProductMapper extends BaseMapperX<CrmContractProductDO> {
|
||||
|
||||
// TODO @puhui999:用不到的方法,看看是不是删除哈
|
||||
default void deleteByContractId(Long contractId) { // TODO @lzxhqs:第一个方法,和类之间最好空一行;
|
||||
delete(CrmContractProductDO::getContractId, contractId);
|
||||
}
|
||||
|
||||
default CrmContractProductDO selectByContractId(Long contractId) {
|
||||
return selectOne(CrmContractProductDO::getContractId, contractId);
|
||||
}
|
||||
|
||||
default List<CrmContractProductDO> selectListByContractId(Long contractId) {
|
||||
return selectList(new LambdaQueryWrapperX<CrmContractProductDO>().eq(CrmContractProductDO::getContractId, contractId));
|
||||
}
|
||||
|
@ -80,16 +80,15 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
|
||||
CrmBusinessDO business = BeanUtils.toBean(createReqVO, CrmBusinessDO.class).setOwnerUserId(userId);
|
||||
businessMapper.insert(business);
|
||||
// 1.2 插入商机关联商品
|
||||
if (CollUtil.isNotEmpty(createReqVO.getProductItems())) { // 如果有的话
|
||||
List<CrmBusinessProductDO> productList = buildBusinessProductList(createReqVO.getProductItems(), business.getId());
|
||||
if (CollUtil.isNotEmpty(createReqVO.getItems())) { // 如果有的话
|
||||
List<CrmBusinessProductDO> productList = buildBusinessProductList(createReqVO.getItems(), business.getId());
|
||||
businessProductMapper.insertBatch(productList);
|
||||
// 更新合同商品总金额
|
||||
businessMapper.updateById(new CrmBusinessDO().setId(business.getId()).setProductPrice(
|
||||
getSumValue(productList, CrmBusinessProductDO::getTotalPrice, Integer::sum)));
|
||||
}
|
||||
// TODO @puhui999:在联系人的详情页,如果直接【新建商机】,则需要关联下。这里要搞个 CrmContactBusinessDO 表
|
||||
createContactBusiness(business.getId(), createReqVO.getContactId());
|
||||
|
||||
// 在联系人的详情页,如果直接【新建商机】,则需要关联下。
|
||||
contactBusinessService.createContactBusiness(createReqVO.getContactId(), business.getId());
|
||||
// 2. 创建数据权限
|
||||
// 设置当前操作的人为负责人
|
||||
permissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_BUSINESS.getType())
|
||||
@ -100,14 +99,6 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
|
||||
return business.getId();
|
||||
}
|
||||
|
||||
// TODO @lzxhqs:CrmContactBusinessService 调用这个;这样逻辑才能收敛哈;
|
||||
private void createContactBusiness(Long businessId, Long contactId) {
|
||||
CrmContactBusinessDO contactBusiness = new CrmContactBusinessDO();
|
||||
contactBusiness.setBusinessId(businessId);
|
||||
contactBusiness.setContactId(contactId);
|
||||
contactBusinessService.insert(contactBusiness);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@LogRecord(type = CRM_BUSINESS_TYPE, subType = CRM_BUSINESS_UPDATE_SUB_TYPE, bizNo = "{{#updateReqVO.id}}",
|
||||
@ -121,7 +112,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
|
||||
CrmBusinessDO updateObj = BeanUtils.toBean(updateReqVO, CrmBusinessDO.class);
|
||||
businessMapper.updateById(updateObj);
|
||||
// 2.2 更新商机关联商品
|
||||
List<CrmBusinessProductDO> productList = buildBusinessProductList(updateReqVO.getProductItems(), updateObj.getId());
|
||||
List<CrmBusinessProductDO> productList = buildBusinessProductList(updateReqVO.getItems(), updateObj.getId());
|
||||
updateBusinessProduct(productList, updateObj.getId());
|
||||
|
||||
// TODO @商机待定:如果状态发生变化,插入商机状态变更记录表
|
||||
@ -175,10 +166,9 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
|
||||
}
|
||||
}
|
||||
|
||||
private List<CrmBusinessProductDO> buildBusinessProductList(List<CrmBusinessSaveReqVO.CrmBusinessProductItem> productItems,
|
||||
Long businessId) {
|
||||
private List<CrmBusinessProductDO> buildBusinessProductList(List<CrmBusinessSaveReqVO.Item> productItems, Long businessId) {
|
||||
// 校验商品存在
|
||||
Set<Long> productIds = convertSet(productItems, CrmBusinessSaveReqVO.CrmBusinessProductItem::getId);
|
||||
Set<Long> productIds = convertSet(productItems, CrmBusinessSaveReqVO.Item::getId);
|
||||
List<CrmProductDO> productList = productService.getProductList(productIds);
|
||||
if (CollUtil.isEmpty(productIds) || productList.size() != productIds.size()) {
|
||||
throw exception(PRODUCT_NOT_EXISTS);
|
||||
@ -237,7 +227,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
|
||||
public void updateBusinessProduct(CrmBusinessUpdateProductReqBO updateProductReqBO) {
|
||||
// 更新商机关联商品
|
||||
List<CrmBusinessProductDO> productList = buildBusinessProductList(
|
||||
BeanUtils.toBean(updateProductReqBO.getProductItems(), CrmBusinessSaveReqVO.CrmBusinessProductItem.class), updateProductReqBO.getId());
|
||||
BeanUtils.toBean(updateProductReqBO.getItems(), CrmBusinessSaveReqVO.Item.class), updateProductReqBO.getId());
|
||||
updateBusinessProduct(productList, updateProductReqBO.getId());
|
||||
}
|
||||
|
||||
|
@ -25,13 +25,13 @@ public class CrmBusinessUpdateProductReqBO {
|
||||
|
||||
// TODO @芋艿:再想想
|
||||
@NotEmpty(message = "产品列表不能为空")
|
||||
private List<CrmBusinessProductItem> productItems;
|
||||
private List<Item> items;
|
||||
|
||||
@Schema(description = "产品列表")
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public static class CrmBusinessProductItem {
|
||||
public static class Item {
|
||||
|
||||
@Schema(description = "产品编号", example = "20529")
|
||||
@NotNull(message = "产品编号不能为空")
|
||||
|
@ -13,6 +13,15 @@ import java.util.List;
|
||||
*/
|
||||
public interface CrmContactBusinessService {
|
||||
|
||||
/**
|
||||
* 创建联系人人商机关联
|
||||
*
|
||||
* @param contactId 联系人编号
|
||||
* @param businessId 商机编号
|
||||
*/
|
||||
void createContactBusiness(Long contactId, Long businessId);
|
||||
|
||||
|
||||
/**
|
||||
* 创建联系人与商机的关联
|
||||
*
|
||||
@ -42,11 +51,4 @@ public interface CrmContactBusinessService {
|
||||
*/
|
||||
List<CrmContactBusinessDO> getContactBusinessListByContactId(Long contactId);
|
||||
|
||||
/**
|
||||
* 新增联系人与商机的关联
|
||||
*
|
||||
* @param contactBusiness 新增联系人与商机的对象
|
||||
*/
|
||||
void insert(CrmContactBusinessDO contactBusiness);
|
||||
|
||||
}
|
@ -5,7 +5,7 @@ import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactBusines
|
||||
import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
|
||||
import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactBusinessDO;
|
||||
import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO;
|
||||
import cn.iocoder.yudao.module.crm.dal.mysql.contactbusinesslink.CrmContactBusinessMapper;
|
||||
import cn.iocoder.yudao.module.crm.dal.mysql.contact.CrmContactBusinessMapper;
|
||||
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;
|
||||
@ -41,6 +41,22 @@ public class CrmContactBusinessServiceImpl implements CrmContactBusinessService
|
||||
@Lazy // 延迟加载,为了解决延迟加载
|
||||
private CrmContactService contactService;
|
||||
|
||||
@Override
|
||||
public void createContactBusiness(Long contactId, Long businessId) {
|
||||
// 校验存在
|
||||
CrmContactDO contact = contactService.getContact(contactId);
|
||||
if (contact == null) {
|
||||
throw exception(CONTACT_NOT_EXISTS);
|
||||
}
|
||||
CrmBusinessDO business = businessService.getBusiness(businessId);
|
||||
if (business == null) {
|
||||
throw exception(BUSINESS_NOT_EXISTS);
|
||||
}
|
||||
|
||||
// 插入
|
||||
contactBusinessMapper.insert(new CrmContactBusinessDO(null, contactId, businessId));
|
||||
}
|
||||
|
||||
@Override
|
||||
@CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACT, bizId = "#createReqVO.contactId", level = CrmPermissionLevelEnum.WRITE)
|
||||
public void createContactBusinessList(CrmContactBusinessReqVO createReqVO) {
|
||||
@ -91,9 +107,4 @@ public class CrmContactBusinessServiceImpl implements CrmContactBusinessService
|
||||
return contactBusinessMapper.selectListByContactId(contactId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insert(CrmContactBusinessDO contactBusiness) {
|
||||
contactBusinessMapper.insert(contactBusiness);
|
||||
}
|
||||
|
||||
}
|
@ -55,6 +55,7 @@ public interface CrmContactService {
|
||||
|
||||
/**
|
||||
* 更新指定客户的联系人的负责人
|
||||
* 数据权限基于 【客户】
|
||||
*
|
||||
* @param customerId 客户编号
|
||||
* @param ownerUserId 用户编号
|
||||
@ -64,8 +65,8 @@ public interface CrmContactService {
|
||||
/**
|
||||
* 更新联系人相关跟进信息
|
||||
*
|
||||
* @param id 编号
|
||||
* @param contactNextTime 下次联系时间
|
||||
* @param id 编号
|
||||
* @param contactNextTime 下次联系时间
|
||||
* @param contactLastContent 最后联系内容
|
||||
*/
|
||||
void updateContactFollowUp(Long id, LocalDateTime contactNextTime, String contactLastContent);
|
||||
@ -73,8 +74,8 @@ public interface CrmContactService {
|
||||
/**
|
||||
* 更新联系人相关跟进信息
|
||||
*
|
||||
* @param ids 编号数组
|
||||
* @param contactNextTime 下次联系时间
|
||||
* @param ids 编号数组
|
||||
* @param contactNextTime 下次联系时间
|
||||
* @param contactLastContent 最后联系内容
|
||||
*/
|
||||
void updateContactFollowUpBatch(Collection<Long> ids, LocalDateTime contactNextTime, String contactLastContent);
|
||||
|
@ -184,7 +184,7 @@ public class CrmContactServiceImpl implements CrmContactService {
|
||||
|
||||
// 2.1 数据权限转移
|
||||
permissionService.transferPermission(new CrmPermissionTransferReqBO(userId, CrmBizTypeEnum.CRM_CONTACT.getType(),
|
||||
reqVO.getId(), reqVO.getNewOwnerUserId(), reqVO.getOldOwnerPermissionLevel()));
|
||||
reqVO.getId(), reqVO.getNewOwnerUserId(), reqVO.getOldOwnerPermissionLevel()));
|
||||
// 2.2 设置新的负责人
|
||||
contactMapper.updateById(new CrmContactDO().setId(reqVO.getId()).setOwnerUserId(reqVO.getNewOwnerUserId()));
|
||||
|
||||
@ -193,9 +193,31 @@ public class CrmContactServiceImpl implements CrmContactService {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#customerId", level = CrmPermissionLevelEnum.OWNER)
|
||||
public void updateOwnerUserIdByCustomerId(Long customerId, Long ownerUserId) {
|
||||
contactMapper.updateOwnerUserIdByCustomerId(customerId, ownerUserId);
|
||||
// TODO @puhui999:操作日志、数据权限;
|
||||
// 1. 校验存在
|
||||
List<CrmContactDO> contacts = contactMapper.selectListByCustomerId(customerId);
|
||||
if (CollUtil.isEmpty(contacts)) {
|
||||
return;
|
||||
}
|
||||
int count = contactMapper.updateOwnerUserIdByCustomerId(customerId, ownerUserId);
|
||||
if (count == 0) {
|
||||
throw exception(CONTACT_UPDATE_OWNER_USER_FAIL);
|
||||
}
|
||||
|
||||
// 2. 记录操作日志
|
||||
for (CrmContactDO contact : contacts) {
|
||||
receiveContactLog(contact, ownerUserId);
|
||||
}
|
||||
}
|
||||
|
||||
@LogRecord(type = CRM_CONTACT_TYPE, subType = CRM_CONTACT_UPDATE_OWNER_USER_SUB_TYPE, bizNo = "{{#contact.id}",
|
||||
success = CRM_CONTACT_UPDATE_OWNER_USER_SUCCESS)
|
||||
public void receiveContactLog(CrmContactDO contact, Long ownerUserId) {
|
||||
// 记录操作日志上下文
|
||||
LogRecordContext.putVariable("contact", contact);
|
||||
LogRecordContext.putVariable("ownerUserId", ownerUserId);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -104,7 +104,7 @@ public class CrmContractServiceImpl implements CrmContractService {
|
||||
// 如果存在合同关联了商机则更新商机商品关联
|
||||
if (contract.getBusinessId() != null) {
|
||||
businessService.updateBusinessProduct(new CrmBusinessUpdateProductReqBO().setId(contract.getBusinessId())
|
||||
.setProductItems(BeanUtils.toBean(createReqVO.getProductItems(), CrmBusinessUpdateProductReqBO.CrmBusinessProductItem.class)));
|
||||
.setItems(BeanUtils.toBean(createReqVO.getProductItems(), CrmBusinessUpdateProductReqBO.Item.class)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -412,7 +412,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
|
||||
return count;
|
||||
}
|
||||
|
||||
@Transactional // 需要 protected 修饰,因为需要在事务中调用
|
||||
@Transactional(rollbackFor = Exception.class) // 需要 protected 修饰,因为需要在事务中调用
|
||||
protected void putCustomerPool(CrmCustomerDO customer) {
|
||||
// 1. 设置负责人为 NULL
|
||||
int updateOwnerUserIncr = customerMapper.updateOwnerUserIdById(customer.getId(), null);
|
||||
|
Loading…
Reference in New Issue
Block a user