📖 CRM:code review CRM 客户逻辑

This commit is contained in:
YunaiV 2024-01-07 22:07:17 +08:00
parent 3c7f63c356
commit 2d1e57554d
17 changed files with 62 additions and 104 deletions

View File

@ -122,6 +122,7 @@ public class LocalDateTimeUtils {
return date.with(TemporalAdjusters.lastDayOfMonth()).with(LocalTime.MAX); return date.with(TemporalAdjusters.lastDayOfMonth()).with(LocalTime.MAX);
} }
// TODO @puhui999加下注释哈
public static Long between(LocalDateTime dateTime) { public static Long between(LocalDateTime dateTime) {
return LocalDateTimeUtil.between(dateTime, LocalDateTime.now(), ChronoUnit.DAYS); return LocalDateTimeUtil.between(dateTime, LocalDateTime.now(), ChronoUnit.DAYS);
} }

View File

@ -46,7 +46,7 @@ import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.CRM_CONTACT; import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.CRM_CONTACT_TYPE;
@Tag(name = "管理后台 - CRM 联系人") @Tag(name = "管理后台 - CRM 联系人")
@RestController @RestController
@ -156,7 +156,7 @@ public class CrmContactController {
public CommonResult<PageResult<OperateLogV2RespDTO>> getCustomerOperateLog(@RequestParam("bizId")Long bizId) { public CommonResult<PageResult<OperateLogV2RespDTO>> getCustomerOperateLog(@RequestParam("bizId")Long bizId) {
OperateLogV2PageReqDTO reqVO = new OperateLogV2PageReqDTO(); OperateLogV2PageReqDTO reqVO = new OperateLogV2PageReqDTO();
reqVO.setPageSize(PAGE_SIZE_NONE); // 不分页 reqVO.setPageSize(PAGE_SIZE_NONE); // 不分页
reqVO.setBizType(CRM_CONTACT); reqVO.setBizType(CRM_CONTACT_TYPE);
reqVO.setBizId(bizId); reqVO.setBizId(bizId);
return success(operateLogApi.getOperateLogPage(BeanUtils.toBean(reqVO, OperateLogV2PageReqDTO.class))); return success(operateLogApi.getOperateLogPage(BeanUtils.toBean(reqVO, OperateLogV2PageReqDTO.class)));
} }

View File

@ -112,37 +112,42 @@ public class CrmCustomerController {
} }
// 2. 拼接数据 // 2. 拼接数据
// 距离进入公海的时间 Map<Long, Long> poolDayMap = getPoolDayMap(pageResult); // 距离进入公海的时间
Map<Long, Long> poolDayMap = getPoolDayMap(pageResult);
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap( Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
convertSetByFlatMap(pageResult.getList(), user -> Stream.of(Long.parseLong(user.getCreator()), user.getOwnerUserId()))); convertSetByFlatMap(pageResult.getList(), user -> Stream.of(Long.parseLong(user.getCreator()), user.getOwnerUserId())));
Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId)); Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
return success(CrmCustomerConvert.INSTANCE.convertPage(pageResult, userMap, deptMap, poolDayMap)); return success(CrmCustomerConvert.INSTANCE.convertPage(pageResult, userMap, deptMap, poolDayMap));
} }
// TODO @puhui999加下注释哈
private Map<Long, Long> getPoolDayMap(PageResult<CrmCustomerDO> pageResult) { private Map<Long, Long> getPoolDayMap(PageResult<CrmCustomerDO> pageResult) {
Map<Long, Long> poolDayMap = null; Map<Long, Long> poolDayMap = null;
CrmCustomerPoolConfigDO customerPoolConfig = customerPoolConfigService.getCustomerPoolConfig(); CrmCustomerPoolConfigDO customerPoolConfig = customerPoolConfigService.getCustomerPoolConfig();
// TODO @puhui999if return 减少括号
if (customerPoolConfig != null && customerPoolConfig.getEnabled()) { // 有公海配置的情况 if (customerPoolConfig != null && customerPoolConfig.getEnabled()) { // 有公海配置的情况
// TODO @puhui999item 改成 customer 更好容易理解
poolDayMap = convertMap(pageResult.getList(), CrmCustomerDO::getId, item -> { poolDayMap = convertMap(pageResult.getList(), CrmCustomerDO::getId, item -> {
long dealExpireDay = 0; long dealExpireDay = 0;
if (!item.getDealStatus()) { // 检查是否成交 if (!item.getDealStatus()) { // 检查是否成交
dealExpireDay = customerPoolConfig.getDealExpireDays() - LocalDateTimeUtils.between(item.getCreateTime()); dealExpireDay = customerPoolConfig.getDealExpireDays() - LocalDateTimeUtils.between(item.getCreateTime());
} }
// TODO @puhui999需要考虑 contactLastTime 为空的情况哈
long contactExpireDay = customerPoolConfig.getContactExpireDays() - LocalDateTimeUtils.between(item.getContactLastTime()); long contactExpireDay = customerPoolConfig.getContactExpireDays() - LocalDateTimeUtils.between(item.getContactLastTime());
return dealExpireDay == 0 ? contactExpireDay : Math.min(dealExpireDay, contactExpireDay); return dealExpireDay == 0 ? contactExpireDay : Math.min(dealExpireDay, contactExpireDay);
}); });
// TODO @puhui999需要考虑 lock 的情况么
} }
return poolDayMap; return poolDayMap;
} }
@GetMapping(value = "/list-all-simple") @GetMapping(value = "/list-all-simple")
@Operation(summary = "获取客户精简信息列表", description = "只包含有读权限的客户,主要用于前端的下拉选项") @Operation(summary = "获取客户精简信息列表", description = "只包含有读权限的客户,主要用于前端的下拉选项")
public CommonResult<List<CrmCustomerSimpleRespVO>> getSimpleDeptList() { public CommonResult<List<CrmCustomerRespVO>> getSimpleDeptList() {
CrmCustomerPageReqVO reqVO = new CrmCustomerPageReqVO(); CrmCustomerPageReqVO reqVO = new CrmCustomerPageReqVO();
reqVO.setPageSize(PAGE_SIZE_NONE); // 不分页 reqVO.setPageSize(PAGE_SIZE_NONE); // 不分页
List<CrmCustomerDO> list = customerService.getCustomerPage(reqVO, getLoginUserId()).getList(); List<CrmCustomerDO> list = customerService.getCustomerPage(reqVO, getLoginUserId()).getList();
return success(BeanUtils.toBean(list, CrmCustomerSimpleRespVO.class)); return success(convertList(list, customer -> // 只返回 idname 精简字段
new CrmCustomerRespVO().setId(customer.getId()).setName(customer.getName())));
} }
@GetMapping("/export-excel") @GetMapping("/export-excel")
@ -154,8 +159,8 @@ public class CrmCustomerController {
pageVO.setPageSize(PAGE_SIZE_NONE); // 不分页 pageVO.setPageSize(PAGE_SIZE_NONE); // 不分页
List<CrmCustomerDO> list = customerService.getCustomerPage(pageVO, getLoginUserId()).getList(); List<CrmCustomerDO> list = customerService.getCustomerPage(pageVO, getLoginUserId()).getList();
// 导出 Excel // 导出 Excel
List<CrmCustomerRespVO> datas = CrmCustomerConvert.INSTANCE.convertList02(list); ExcelUtils.write(response, "客户.xls", "数据", CrmCustomerRespVO.class,
ExcelUtils.write(response, "客户.xls", "数据", CrmCustomerRespVO.class, datas); BeanUtils.toBean(list, CrmCustomerRespVO.class));
} }
@PutMapping("/transfer") @PutMapping("/transfer")

View File

@ -11,7 +11,7 @@ import java.util.List;
public class CrmCustomerDistributeReqVO { public class CrmCustomerDistributeReqVO {
@Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1024]") @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1024]")
@NotNull(message = "客户编号不能为空") @NotNull(message = "客户编号不能为空") // TODO @puhui999list @NotEmpty
private List<Long> ids; private List<Long> ids;
@Schema(description = "负责人", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") @Schema(description = "负责人", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")

View File

@ -1,20 +0,0 @@
package cn.iocoder.yudao.module.crm.controller.admin.customer.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Schema(description = "管理后台 - 客户精简信息 Response VO")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class CrmCustomerSimpleRespVO {
@Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long id;
@Schema(description = "客户名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道")
private String name;
}

View File

@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.crm.controller.admin.customer.vo.limitconfig;
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data; import lombok.Data;
import java.time.LocalDateTime; import java.time.LocalDateTime;
@ -17,7 +16,6 @@ public class CrmCustomerLimitConfigRespVO {
private Long id; private Long id;
@Schema(description = "规则类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") @Schema(description = "规则类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@NotNull(message = "规则类型不能为空")
private Integer type; private Integer type;
@Schema(description = "规则适用人群") @Schema(description = "规则适用人群")
@ -27,10 +25,9 @@ public class CrmCustomerLimitConfigRespVO {
private List<Long> deptIds; private List<Long> deptIds;
@Schema(description = "数量上限", requiredMode = Schema.RequiredMode.REQUIRED, example = "28384") @Schema(description = "数量上限", requiredMode = Schema.RequiredMode.REQUIRED, example = "28384")
@NotNull(message = "数量上限不能为空")
private Integer maxCount; private Integer maxCount;
@Schema(description = "成交客户是否占有拥有客户数(当 type = 1 时)") @Schema(description = "成交客户是否占有拥有客户数")
private Boolean dealCountEnabled; private Boolean dealCountEnabled;
@Schema(description = "规则适用人群名称") @Schema(description = "规则适用人群名称")

View File

@ -15,10 +15,11 @@ public class CrmCustomerLimitConfigSaveReqVO {
private Long id; private Long id;
@Schema(description = "规则类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") @Schema(description = "规则类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@DiffLogField(name = "规则类型")
@NotNull(message = "规则类型不能为空") @NotNull(message = "规则类型不能为空")
@DiffLogField(name = "规则类型")
private Integer type; private Integer type;
// TODO @puhui999可以把 Function 那的 functionName 搞成 NAME 枚举这里直接引用这样后续改动更方便哈
@Schema(description = "规则适用人群") @Schema(description = "规则适用人群")
@DiffLogField(name = "规则适用人群", function = "getAdminUserById") @DiffLogField(name = "规则适用人群", function = "getAdminUserById")
private List<Long> userIds; private List<Long> userIds;
@ -28,8 +29,8 @@ public class CrmCustomerLimitConfigSaveReqVO {
private List<Long> deptIds; private List<Long> deptIds;
@Schema(description = "数量上限", requiredMode = Schema.RequiredMode.REQUIRED, example = "28384") @Schema(description = "数量上限", requiredMode = Schema.RequiredMode.REQUIRED, example = "28384")
@DiffLogField(name = "数量上限")
@NotNull(message = "数量上限不能为空") @NotNull(message = "数量上限不能为空")
@DiffLogField(name = "数量上限")
private Integer maxCount; private Integer maxCount;
@Schema(description = "成交客户是否占有拥有客户数(当 type = 1 时)") @Schema(description = "成交客户是否占有拥有客户数(当 type = 1 时)")

View File

@ -16,7 +16,6 @@ import org.mapstruct.Mapper;
import org.mapstruct.Mapping; import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers; import org.mapstruct.factory.Mappers;
import java.util.List;
import java.util.Map; import java.util.Map;
import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen; import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
@ -31,6 +30,7 @@ public interface CrmCustomerConvert {
CrmCustomerConvert INSTANCE = Mappers.getMapper(CrmCustomerConvert.class); CrmCustomerConvert INSTANCE = Mappers.getMapper(CrmCustomerConvert.class);
// TODO @puhui999可以清理掉可以用 BeanUtil 替代的方法哈
CrmCustomerDO convert(CrmCustomerSaveReqVO bean); CrmCustomerDO convert(CrmCustomerSaveReqVO bean);
CrmCustomerRespVO convert(CrmCustomerDO bean); CrmCustomerRespVO convert(CrmCustomerDO bean);
@ -51,8 +51,6 @@ public interface CrmCustomerConvert {
findAndThen(userMap, Long.parseLong(customer.getCreator()), user -> customer.setCreatorName(user.getNickname())); findAndThen(userMap, Long.parseLong(customer.getCreator()), user -> customer.setCreatorName(user.getNickname()));
} }
List<CrmCustomerRespVO> convertList02(List<CrmCustomerDO> list);
@Mapping(target = "bizId", source = "reqVO.id") @Mapping(target = "bizId", source = "reqVO.id")
CrmPermissionTransferReqBO convert(CrmCustomerTransferReqVO reqVO, Long userId); CrmPermissionTransferReqBO convert(CrmCustomerTransferReqVO reqVO, Long userId);

View File

@ -23,6 +23,7 @@ public interface CrmCustomerLimitConfigConvert {
CrmCustomerLimitConfigConvert INSTANCE = Mappers.getMapper(CrmCustomerLimitConfigConvert.class); CrmCustomerLimitConfigConvert INSTANCE = Mappers.getMapper(CrmCustomerLimitConfigConvert.class);
// TODO @puhui999可以把 convert 改成 BeanUtils
CrmCustomerLimitConfigDO convert(CrmCustomerLimitConfigSaveReqVO bean); CrmCustomerLimitConfigDO convert(CrmCustomerLimitConfigSaveReqVO bean);
CrmCustomerLimitConfigRespVO convert(CrmCustomerLimitConfigDO bean); CrmCustomerLimitConfigRespVO convert(CrmCustomerLimitConfigDO bean);

View File

@ -48,9 +48,7 @@ public interface CrmPermissionConvert {
return CollectionUtils.convertList(convert(permission), item -> { return CollectionUtils.convertList(convert(permission), item -> {
findAndThen(userMap, item.getUserId(), user -> { findAndThen(userMap, item.getUserId(), user -> {
item.setNickname(user.getNickname()); item.setNickname(user.getNickname());
findAndThen(deptMap, user.getDeptId(), deptRespDTO -> { findAndThen(deptMap, user.getDeptId(), deptRespDTO -> item.setDeptName(deptRespDTO.getName()));
item.setDeptName(deptRespDTO.getName());
});
List<PostRespDTO> postRespList = MapUtils.getList(Multimaps.forMap(postMap), user.getPostIds()); List<PostRespDTO> postRespList = MapUtils.getList(Multimaps.forMap(postMap), user.getPostIds());
if (CollUtil.isEmpty(postRespList)) { if (CollUtil.isEmpty(postRespList)) {
item.setPostNames(Collections.emptySet()); item.setPostNames(Collections.emptySet());

View File

@ -40,12 +40,12 @@ public class CrmPermissionAspect {
@Before("@annotation(crmPermission)") @Before("@annotation(crmPermission)")
public void doBefore(JoinPoint joinPoint, CrmPermission crmPermission) { public void doBefore(JoinPoint joinPoint, CrmPermission crmPermission) {
// 获取相关属性值 // 1.1 获取相关属性值
Map<String, Object> expressionValues = parseExpressions(joinPoint, crmPermission); Map<String, Object> expressionValues = parseExpressions(joinPoint, crmPermission);
Integer bizType = StrUtil.isEmpty(crmPermission.bizTypeValue()) ? Integer bizType = StrUtil.isEmpty(crmPermission.bizTypeValue()) ?
crmPermission.bizType()[0].getType() : (Integer) expressionValues.get(crmPermission.bizTypeValue()); // 模块类型 crmPermission.bizType()[0].getType() : (Integer) expressionValues.get(crmPermission.bizTypeValue()); // 模块类型
// 处理兼容多个 bizId 的情况 // 1.2 处理兼容多个 bizId 的情况
Object object = expressionValues.get(crmPermission.bizId());// 模块数据编号 Object object = expressionValues.get(crmPermission.bizId()); // 模块数据编号
Set<Long> bizIds = new HashSet<>(); Set<Long> bizIds = new HashSet<>();
if (object instanceof Collection<?>) { if (object instanceof Collection<?>) {
bizIds.addAll(convertSet((Collection<?>) object, item -> Long.parseLong(item.toString()))); bizIds.addAll(convertSet((Collection<?>) object, item -> Long.parseLong(item.toString())));
@ -53,11 +53,11 @@ public class CrmPermissionAspect {
bizIds.add(Long.parseLong(object.toString())); bizIds.add(Long.parseLong(object.toString()));
} }
Integer permissionLevel = crmPermission.level().getLevel(); // 需要的权限级别 Integer permissionLevel = crmPermission.level().getLevel(); // 需要的权限级别
// 2. 逐个校验权限
List<CrmPermissionDO> permissionList = crmPermissionService.getPermissionListByBiz(bizType, bizIds); List<CrmPermissionDO> permissionList = crmPermissionService.getPermissionListByBiz(bizType, bizIds);
Map<Long, List<CrmPermissionDO>> multiMap = convertMultiMap(permissionList, CrmPermissionDO::getBizId); Map<Long, List<CrmPermissionDO>> multiMap = convertMultiMap(permissionList, CrmPermissionDO::getBizId);
bizIds.forEach(bizId -> { bizIds.forEach(bizId -> validatePermission(bizType, multiMap.get(bizId), permissionLevel));
validatePermission(bizType, multiMap.get(bizId), permissionLevel);
});
} }
private void validatePermission(Integer bizType, List<CrmPermissionDO> bizPermissions, Integer permissionLevel) { private void validatePermission(Integer bizType, List<CrmPermissionDO> bizPermissions, Integer permissionLevel) {
@ -71,7 +71,6 @@ public class CrmPermissionAspect {
if (CrmPermissionLevelEnum.isRead(permissionLevel)) { if (CrmPermissionLevelEnum.isRead(permissionLevel)) {
return; return;
} }
// 没有数据权限的情况下超出了读权限直接报错避免后面校验空指针 // 没有数据权限的情况下超出了读权限直接报错避免后面校验空指针
throw exception(CRM_PERMISSION_DENIED, CrmBizTypeEnum.getNameByType(bizType)); throw exception(CRM_PERMISSION_DENIED, CrmBizTypeEnum.getNameByType(bizType));
} else { // 1.2 有数据权限但是没有负责人的情况 } else { // 1.2 有数据权限但是没有负责人的情况
@ -102,9 +101,8 @@ public class CrmPermissionAspect {
} }
} }
} }
// 2.4 没有权限 // 2.4 没有权限抛出异常
// 打个 info 日志方便后续排查问题审计 log.info("[doBefore][userId({}) 要求权限({}) 实际权限({}) 数据校验错误]", // 打个 info 日志方便后续排查问题审计
log.info("[doBefore][userId({}) 要求权限({}) 实际权限({}) 数据校验错误]",
getUserId(), permissionLevel, toJsonString(userPermission)); getUserId(), permissionLevel, toJsonString(userPermission));
throw exception(CRM_PERMISSION_DENIED, CrmBizTypeEnum.getNameByType(bizType)); throw exception(CRM_PERMISSION_DENIED, CrmBizTypeEnum.getNameByType(bizType));
} }

View File

@ -33,7 +33,7 @@ import java.util.List;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*; import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.CRM_CONTACT; import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.CRM_CONTACT_TYPE;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_NOT_EXISTS; import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_NOT_EXISTS;
import static java.util.Collections.singletonList; import static java.util.Collections.singletonList;
@ -65,7 +65,7 @@ public class CrmContactServiceImpl implements CrmContactService {
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@LogRecord(type = CRM_CONTACT, subType = "创建联系人", bizNo = "{{#contactId}}", success = "创建了联系人[{{#contactName}}]") @LogRecord(type = CRM_CONTACT_TYPE, subType = "创建联系人", bizNo = "{{#contactId}}", success = "创建了联系人[{{#contactName}}]")
public Long createContact(CrmContactSaveReqVO createReqVO, Long userId) { public Long createContact(CrmContactSaveReqVO createReqVO, Long userId) {
// 1. 校验 // 1. 校验
validateRelationDataExists(createReqVO); validateRelationDataExists(createReqVO);
@ -93,7 +93,7 @@ public class CrmContactServiceImpl implements CrmContactService {
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@LogRecord(type = CRM_CONTACT, subType = "更新联系人", bizNo = "{{#updateReqVO.id}}", success = "更新了联系人{_DIFF{#updateReqVO}}") @LogRecord(type = CRM_CONTACT_TYPE, subType = "更新联系人", bizNo = "{{#updateReqVO.id}}", success = "更新了联系人{_DIFF{#updateReqVO}}")
@CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACT, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE) @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACT, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE)
public void updateContact(CrmContactSaveReqVO updateReqVO) { public void updateContact(CrmContactSaveReqVO updateReqVO) {
// 1. 校验存在 // 1. 校验存在

View File

@ -44,7 +44,8 @@ public class CrmCustomerLimitConfigServiceImpl implements CrmCustomerLimitConfig
private AdminUserApi adminUserApi; private AdminUserApi adminUserApi;
@Override @Override
@LogRecord(type = CRM_CUSTOMER_LIMIT_CONFIG_TYPE, subType = CRM_CUSTOMER_LIMIT_CONFIG_CREATE_SUB_TYPE, bizNo = "{{#limitId}}", success = CRM_CUSTOMER_LIMIT_CONFIG_CREATE_SUCCESS) @LogRecord(type = CRM_CUSTOMER_LIMIT_CONFIG_TYPE, subType = CRM_CUSTOMER_LIMIT_CONFIG_CREATE_SUB_TYPE, bizNo = "{{#limitId}}",
success = CRM_CUSTOMER_LIMIT_CONFIG_CREATE_SUCCESS)
public Long createCustomerLimitConfig(CrmCustomerLimitConfigSaveReqVO createReqVO) { public Long createCustomerLimitConfig(CrmCustomerLimitConfigSaveReqVO createReqVO) {
validateUserAndDept(createReqVO.getUserIds(), createReqVO.getDeptIds()); validateUserAndDept(createReqVO.getUserIds(), createReqVO.getDeptIds());
// 插入 // 插入
@ -54,12 +55,12 @@ public class CrmCustomerLimitConfigServiceImpl implements CrmCustomerLimitConfig
// 记录操作日志上下文 // 记录操作日志上下文
LogRecordContext.putVariable("limitType", CrmCustomerLimitConfigTypeEnum.getNameByType(customerLimitConfig.getType())); LogRecordContext.putVariable("limitType", CrmCustomerLimitConfigTypeEnum.getNameByType(customerLimitConfig.getType()));
LogRecordContext.putVariable("limitId", customerLimitConfig.getId()); LogRecordContext.putVariable("limitId", customerLimitConfig.getId());
// 返回
return customerLimitConfig.getId(); return customerLimitConfig.getId();
} }
@Override @Override
@LogRecord(type = CRM_CUSTOMER_LIMIT_CONFIG_TYPE, subType = CRM_CUSTOMER_LIMIT_CONFIG_UPDATE_SUB_TYPE, bizNo = "{{#updateReqVO.id}}", success = CRM_CUSTOMER_LIMIT_CONFIG_UPDATE_SUCCESS) @LogRecord(type = CRM_CUSTOMER_LIMIT_CONFIG_TYPE, subType = CRM_CUSTOMER_LIMIT_CONFIG_UPDATE_SUB_TYPE, bizNo = "{{#updateReqVO.id}}",
success = CRM_CUSTOMER_LIMIT_CONFIG_UPDATE_SUCCESS)
public void updateCustomerLimitConfig(CrmCustomerLimitConfigSaveReqVO updateReqVO) { public void updateCustomerLimitConfig(CrmCustomerLimitConfigSaveReqVO updateReqVO) {
// 校验存在 // 校验存在
CrmCustomerLimitConfigDO oldLimitConfig = validateCustomerLimitConfigExists(updateReqVO.getId()); CrmCustomerLimitConfigDO oldLimitConfig = validateCustomerLimitConfigExists(updateReqVO.getId());
@ -73,7 +74,8 @@ public class CrmCustomerLimitConfigServiceImpl implements CrmCustomerLimitConfig
} }
@Override @Override
@LogRecord(type = CRM_CUSTOMER_LIMIT_CONFIG_TYPE, subType = CRM_CUSTOMER_LIMIT_CONFIG_DELETE_SUB_TYPE, bizNo = "{{#id}}", success = CRM_CUSTOMER_LIMIT_CONFIG_DELETE_SUCCESS) @LogRecord(type = CRM_CUSTOMER_LIMIT_CONFIG_TYPE, subType = CRM_CUSTOMER_LIMIT_CONFIG_DELETE_SUB_TYPE, bizNo = "{{#id}}",
success = CRM_CUSTOMER_LIMIT_CONFIG_DELETE_SUCCESS)
public void deleteCustomerLimitConfig(Long id) { public void deleteCustomerLimitConfig(Long id) {
// 校验存在 // 校验存在
CrmCustomerLimitConfigDO limitConfigDO = validateCustomerLimitConfigExists(id); CrmCustomerLimitConfigDO limitConfigDO = validateCustomerLimitConfigExists(id);

View File

@ -34,6 +34,7 @@ public class CrmCustomerPoolConfigServiceImpl implements CrmCustomerPoolConfigSe
*/ */
@Override @Override
public CrmCustomerPoolConfigDO getCustomerPoolConfig() { public CrmCustomerPoolConfigDO getCustomerPoolConfig() {
// TODO @puhui999这个要搞到 mapper 里噢
return customerPoolConfigMapper.selectOne(new LambdaQueryWrapperX<CrmCustomerPoolConfigDO>().last("LIMIT 1")); return customerPoolConfigMapper.selectOne(new LambdaQueryWrapperX<CrmCustomerPoolConfigDO>().last("LIMIT 1"));
} }
@ -43,7 +44,8 @@ public class CrmCustomerPoolConfigServiceImpl implements CrmCustomerPoolConfigSe
* @param saveReqVO 更新信息 * @param saveReqVO 更新信息
*/ */
@Override @Override
@LogRecord(type = CRM_CUSTOMER_POOL_CONFIG_TYPE, subType = CRM_CUSTOMER_POOL_CONFIG_SUB_TYPE, bizNo = "{{#poolConfigId}}", success = CRM_CUSTOMER_POOL_CONFIG_SUCCESS) @LogRecord(type = CRM_CUSTOMER_POOL_CONFIG_TYPE, subType = CRM_CUSTOMER_POOL_CONFIG_SUB_TYPE, bizNo = "{{#poolConfigId}}",
success = CRM_CUSTOMER_POOL_CONFIG_SUCCESS)
public void saveCustomerPoolConfig(CrmCustomerPoolConfigSaveReqVO saveReqVO) { public void saveCustomerPoolConfig(CrmCustomerPoolConfigSaveReqVO saveReqVO) {
// 存在则进行更新 // 存在则进行更新
CrmCustomerPoolConfigDO dbConfig = getCustomerPoolConfig(); CrmCustomerPoolConfigDO dbConfig = getCustomerPoolConfig();

View File

@ -65,7 +65,8 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_CREATE_SUB_TYPE, bizNo = "{{#customer.id}}", success = CRM_CUSTOMER_CREATE_SUCCESS) @LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_CREATE_SUB_TYPE, bizNo = "{{#customer.id}}",
success = CRM_CUSTOMER_CREATE_SUCCESS)
public Long createCustomer(CrmCustomerSaveReqVO createReqVO, Long userId) { public Long createCustomer(CrmCustomerSaveReqVO createReqVO, Long userId) {
createReqVO.setId(null); createReqVO.setId(null);
// 1. 校验拥有客户是否到达上限 // 1. 校验拥有客户是否到达上限
@ -89,12 +90,12 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_UPDATE_SUB_TYPE, bizNo = "{{#updateReqVO.id}}", success = CRM_CUSTOMER_UPDATE_SUCCESS) @LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_UPDATE_SUB_TYPE, bizNo = "{{#updateReqVO.id}}",
success = CRM_CUSTOMER_UPDATE_SUCCESS)
@CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE) @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE)
public void updateCustomer(CrmCustomerSaveReqVO updateReqVO) { public void updateCustomer(CrmCustomerSaveReqVO updateReqVO) {
Assert.notNull(updateReqVO.getId(), "客户编号不能为空"); Assert.notNull(updateReqVO.getId(), "客户编号不能为空");
// 更新的时候要把 updateReqVO 负责人设置为空避免修改 updateReqVO.setOwnerUserId(null); // 更新的时候要把 updateReqVO 负责人设置为空避免修改
updateReqVO.setOwnerUserId(null);
// 1. 校验存在 // 1. 校验存在
CrmCustomerDO oldCustomer = validateCustomerExists(updateReqVO.getId()); CrmCustomerDO oldCustomer = validateCustomerExists(updateReqVO.getId());
@ -109,7 +110,8 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_DELETE_SUB_TYPE, bizNo = "{{#id}}", success = CRM_CUSTOMER_DELETE_SUCCESS) @LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_DELETE_SUB_TYPE, bizNo = "{{#id}}",
success = CRM_CUSTOMER_DELETE_SUCCESS)
@CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#id", level = CrmPermissionLevelEnum.OWNER) @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#id", level = CrmPermissionLevelEnum.OWNER)
public void deleteCustomer(Long id) { public void deleteCustomer(Long id) {
// 校验存在 // 校验存在
@ -128,7 +130,8 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_TRANSFER_SUB_TYPE, bizNo = "{{#reqVO.id}}", success = CRM_CUSTOMER_TRANSFER_SUCCESS) @LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_TRANSFER_SUB_TYPE, bizNo = "{{#reqVO.id}}",
success = CRM_CUSTOMER_TRANSFER_SUCCESS)
@CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#reqVO.id", level = CrmPermissionLevelEnum.OWNER) @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#reqVO.id", level = CrmPermissionLevelEnum.OWNER)
public void transferCustomer(CrmCustomerTransferReqVO reqVO, Long userId) { public void transferCustomer(CrmCustomerTransferReqVO reqVO, Long userId) {
// 1.1 校验客户是否存在 // 1.1 校验客户是否存在
@ -144,11 +147,13 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
// 3. TODO 记录转移日志 // 3. TODO 记录转移日志
// 记录操作日志上下文 // 记录操作日志上下文
// TODO @puhui999crmCustomer=customer也看看其他有没类似的情况哈
LogRecordContext.putVariable("crmCustomer", customer); LogRecordContext.putVariable("crmCustomer", customer);
} }
@Override @Override
@LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_LOCK_SUB_TYPE, bizNo = "{{#lockReqVO.id}}", success = CRM_CUSTOMER_LOCK_SUCCESS) @LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_LOCK_SUB_TYPE, bizNo = "{{#lockReqVO.id}}",
success = CRM_CUSTOMER_LOCK_SUCCESS)
@CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#lockReqVO.id", level = CrmPermissionLevelEnum.OWNER) @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#lockReqVO.id", level = CrmPermissionLevelEnum.OWNER)
public void lockCustomer(CrmCustomerLockReqVO lockReqVO, Long userId) { public void lockCustomer(CrmCustomerLockReqVO lockReqVO, Long userId) {
// 1.1 校验当前客户是否存在 // 1.1 校验当前客户是否存在
@ -165,7 +170,8 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
// 2. 更新锁定状态 // 2. 更新锁定状态
customerMapper.updateById(BeanUtils.toBean(lockReqVO, CrmCustomerDO.class)); customerMapper.updateById(BeanUtils.toBean(lockReqVO, CrmCustomerDO.class));
// 3. 记录操作日志上下文. tips: 因为这里使用的是老的状态所以记录时反着记录也就是 lockStatus true 那么就是解锁反之为锁定 // 3. 记录操作日志上下文
// tips: 因为这里使用的是老的状态所以记录时反着记录也就是 lockStatus true 那么就是解锁反之为锁定
LogRecordContext.putVariable("crmCustomer", customer); LogRecordContext.putVariable("crmCustomer", customer);
} }
@ -173,7 +179,8 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_POOL_SUB_TYPE, bizNo = "{{#id}}", success = CRM_CUSTOMER_POOL_SUCCESS) @LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_POOL_SUB_TYPE, bizNo = "{{#id}}",
success = CRM_CUSTOMER_POOL_SUCCESS)
@CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#id", level = CrmPermissionLevelEnum.OWNER) @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#id", level = CrmPermissionLevelEnum.OWNER)
public void putCustomerPool(Long id) { public void putCustomerPool(Long id) {
// 1. 校验存在 // 1. 校验存在
@ -252,7 +259,8 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
} }
} }
@LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_RECEIVE_SUB_TYPE, bizNo = "{{#customer.id}}", success = CRM_CUSTOMER_RECEIVE_SUCCESS) @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) { public void receiveCustomerLog(CrmCustomerDO customer, String ownerUserName) {
// 记录操作日志上下文 // 记录操作日志上下文
LogRecordContext.putVariable("customer", customer); LogRecordContext.putVariable("customer", customer);
@ -280,7 +288,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
return customerMapper.selectPage(pageReqVO, userId); return customerMapper.selectPage(pageReqVO, userId);
} }
//======================= 校验相关 ======================= // ======================= 校验相关 =======================
/** /**
* 校验客户是否存在 * 校验客户是否存在

View File

@ -138,38 +138,4 @@ public class CrmCustomerServiceImplTest extends BaseDbUnitTest {
//assertPojoEquals(dbCustomer, pageResult.getList().get(0)); //assertPojoEquals(dbCustomer, pageResult.getList().get(0));
} }
@Test
@Disabled // TODO 请修改 null 为需要的值然后删除 @Disabled 注解
public void testGetCustomerList() {
// mock 数据
CrmCustomerDO dbCustomer = randomPojo(CrmCustomerDO.class, o -> { // 等会查询到
o.setName(null);
o.setMobile(null);
o.setTelephone(null);
o.setWebsite(null);
});
customerMapper.insert(dbCustomer);
// 测试 name 不匹配
customerMapper.insert(cloneIgnoreId(dbCustomer, o -> o.setName(null)));
// 测试 mobile 不匹配
customerMapper.insert(cloneIgnoreId(dbCustomer, o -> o.setMobile(null)));
// 测试 telephone 不匹配
customerMapper.insert(cloneIgnoreId(dbCustomer, o -> o.setTelephone(null)));
// 测试 website 不匹配
customerMapper.insert(cloneIgnoreId(dbCustomer, o -> o.setWebsite(null)));
// 准备参数
CrmCustomerPageReqVO reqVO = new CrmCustomerPageReqVO();
reqVO.setName("张三");
reqVO.setMobile("13888888888");
reqVO.setPageSize(PAGE_SIZE_NONE);
//reqVO.setTelephone(null);
//reqVO.setWebsite(null);
// 调用
PageResult<CrmCustomerDO> pageResult = customerService.getCustomerPage(reqVO, 1L);
// 断言
assertEquals(1, pageResult.getList().size());
assertPojoEquals(dbCustomer, pageResult.getList().get(0));
}
} }

View File

@ -74,6 +74,7 @@ public class MpMessageServiceImpl implements MpMessageService {
Assert.notNull(account, "公众号账号({}) 不存在", appId); Assert.notNull(account, "公众号账号({}) 不存在", appId);
// 订阅事件不记录因为此时公众号粉丝表中还没有此粉丝的数据 // 订阅事件不记录因为此时公众号粉丝表中还没有此粉丝的数据
// TODO @芋艿这个修复后续看看还有啥问题
if (ObjUtil.equal(wxMessage.getEvent(), WxConsts.EventType.SUBSCRIBE)) { if (ObjUtil.equal(wxMessage.getEvent(), WxConsts.EventType.SUBSCRIBE)) {
return; return;
} }