📖 CRM:code review 跟进日志

This commit is contained in:
YunaiV 2024-01-23 09:22:02 +08:00
parent ff7e492887
commit d732008ef8
6 changed files with 27 additions and 16 deletions

View File

@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.crm.controller.admin.operatelog;
import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.crm.controller.admin.operatelog.vo.CrmOperateLogPageReqVO; import cn.iocoder.yudao.module.crm.controller.admin.operatelog.vo.CrmOperateLogPageReqVO;
import cn.iocoder.yudao.module.crm.enums.LogRecordConstants;
import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
import cn.iocoder.yudao.module.system.api.logger.OperateLogApi; import cn.iocoder.yudao.module.system.api.logger.OperateLogApi;
import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2PageReqDTO; import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2PageReqDTO;
@ -25,7 +26,7 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE; import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE;
import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*; import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*;
@Tag(name = "管理后台 - 操作日志") @Tag(name = "管理后台 - CRM 操作日志")
@RestController @RestController
@RequestMapping("/crm/operate-log") @RequestMapping("/crm/operate-log")
@Validated @Validated
@ -34,6 +35,9 @@ public class CrmOperateLogController {
@Resource @Resource
private OperateLogApi operateLogApi; private OperateLogApi operateLogApi;
/**
* {@link CrmBizTypeEnum} {@link LogRecordConstants} 的映射关系
*/
private static final Map<Integer, String> BIZ_TYPE_MAP = new HashMap<>(); private static final Map<Integer, String> BIZ_TYPE_MAP = new HashMap<>();
static { static {
@ -47,6 +51,7 @@ public class CrmOperateLogController {
BIZ_TYPE_MAP.put(CrmBizTypeEnum.CRM_RECEIVABLE_PLAN.getType(), CRM_RECEIVABLE_PLAN_TYPE); BIZ_TYPE_MAP.put(CrmBizTypeEnum.CRM_RECEIVABLE_PLAN.getType(), CRM_RECEIVABLE_PLAN_TYPE);
} }
// TODO @puhui999还是搞个 VO 出来哈
@GetMapping("/page") @GetMapping("/page")
@Operation(summary = "获得操作日志") @Operation(summary = "获得操作日志")
@Parameter(name = "id", description = "客户编号", required = true) @Parameter(name = "id", description = "客户编号", required = true)
@ -54,8 +59,7 @@ public class CrmOperateLogController {
public CommonResult<PageResult<OperateLogV2RespDTO>> getCustomerOperateLog(@Valid CrmOperateLogPageReqVO pageReqVO) { public CommonResult<PageResult<OperateLogV2RespDTO>> getCustomerOperateLog(@Valid CrmOperateLogPageReqVO pageReqVO) {
OperateLogV2PageReqDTO reqDTO = new OperateLogV2PageReqDTO(); OperateLogV2PageReqDTO reqDTO = new OperateLogV2PageReqDTO();
reqDTO.setPageSize(PAGE_SIZE_NONE); // 默认不分页需要分页需注释 reqDTO.setPageSize(PAGE_SIZE_NONE); // 默认不分页需要分页需注释
reqDTO.setBizType(BIZ_TYPE_MAP.get(pageReqVO.getBizType())); reqDTO.setBizType(BIZ_TYPE_MAP.get(pageReqVO.getBizType())).setBizId(pageReqVO.getBizId());
reqDTO.setBizId(pageReqVO.getBizId());
return success(operateLogApi.getOperateLogPage(reqDTO)); return success(operateLogApi.getOperateLogPage(reqDTO));
} }

View File

@ -9,7 +9,7 @@ import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.ToString; import lombok.ToString;
@Schema(description = "管理后台 - 跟进记录分页 Request VO") @Schema(description = "管理后台 - CRM 操作日志 Request VO")
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true) @ToString(callSuper = true)

View File

@ -29,6 +29,7 @@ public interface CrmPermissionConvert {
CrmPermissionConvert INSTANCE = Mappers.getMapper(CrmPermissionConvert.class); CrmPermissionConvert INSTANCE = Mappers.getMapper(CrmPermissionConvert.class);
// TODO @puhui999这个要不也搞到 copy
List<CrmPermissionRespVO> convert(List<CrmPermissionDO> permission); List<CrmPermissionRespVO> convert(List<CrmPermissionDO> permission);
default List<CrmPermissionRespVO> convert(List<CrmPermissionDO> permission, List<AdminUserRespDTO> userList, default List<CrmPermissionRespVO> convert(List<CrmPermissionDO> permission, List<AdminUserRespDTO> userList,

View File

@ -26,12 +26,14 @@ public interface CrmFollowUpRecordMapper extends BaseMapperX<CrmFollowUpRecordDO
} }
default void deleteByBiz(Integer bizType, Long bizId) { default void deleteByBiz(Integer bizType, Long bizId) {
delete(new LambdaQueryWrapperX<CrmFollowUpRecordDO>().eq(CrmFollowUpRecordDO::getBizType, bizType) delete(new LambdaQueryWrapperX<CrmFollowUpRecordDO>()
.eq(CrmFollowUpRecordDO::getBizType, bizType)
.eq(CrmFollowUpRecordDO::getBizId, bizId)); .eq(CrmFollowUpRecordDO::getBizId, bizId));
} }
default List<CrmFollowUpRecordDO> selectListByBiz(Integer bizType, Collection<Long> bizIds) { default List<CrmFollowUpRecordDO> selectListByBiz(Integer bizType, Collection<Long> bizIds) {
return selectList(new LambdaQueryWrapperX<CrmFollowUpRecordDO>().eq(CrmFollowUpRecordDO::getBizType, bizType) return selectList(new LambdaQueryWrapperX<CrmFollowUpRecordDO>()
.eq(CrmFollowUpRecordDO::getBizType, bizType)
.in(CrmFollowUpRecordDO::getBizId, bizIds)); .in(CrmFollowUpRecordDO::getBizId, bizIds));
} }

View File

@ -73,17 +73,17 @@ public class CrmClueServiceImpl implements CrmClueService {
@LogRecord(type = CRM_LEADS_TYPE, subType = CRM_LEADS_CREATE_SUB_TYPE, bizNo = "{{#clue.id}}", @LogRecord(type = CRM_LEADS_TYPE, subType = CRM_LEADS_CREATE_SUB_TYPE, bizNo = "{{#clue.id}}",
success = CRM_LEADS_CREATE_SUCCESS) success = CRM_LEADS_CREATE_SUCCESS)
public Long createClue(CrmClueSaveReqVO createReqVO, Long userId) { public Long createClue(CrmClueSaveReqVO createReqVO, Long userId) {
// 1. 校验关联数据 // 1.1 校验关联数据
validateRelationDataExists(createReqVO); validateRelationDataExists(createReqVO);
// 1.2 校验负责人是否存在
if (createReqVO.getOwnerUserId() != null) {
adminUserApi.validateUserList(singletonList(createReqVO.getOwnerUserId()));
} else {
createReqVO.setOwnerUserId(userId); // 如果没有设置负责人那么默认操作人为负责人
}
// 2. 插入 // 2. 插入
CrmClueDO clue = BeanUtils.toBean(createReqVO, CrmClueDO.class).setId(null); CrmClueDO clue = BeanUtils.toBean(createReqVO, CrmClueDO.class).setId(null);
if (ObjUtil.isNull(createReqVO.getOwnerUserId())) {
clue.setOwnerUserId(userId); // 如果没有设置负责人那么默认操作人为负责人
} else {
// 校验负责人是否存在
adminUserApi.validateUserList(singletonList(createReqVO.getOwnerUserId()));
}
clueMapper.insert(clue); clueMapper.insert(clue);
// 3. 创建数据权限 // 3. 创建数据权限
@ -193,10 +193,13 @@ public class CrmClueServiceImpl implements CrmClueService {
} }
// 2. 遍历线索(未转化的线索)创建对应的客户 // 2. 遍历线索(未转化的线索)创建对应的客户
// TODO @puhui999这里不用过滤了
List<CrmClueDO> translateClues = filterList(clues, clue -> ObjUtil.equal(Boolean.FALSE, clue.getTransformStatus())); List<CrmClueDO> translateClues = filterList(clues, clue -> ObjUtil.equal(Boolean.FALSE, clue.getTransformStatus()));
List<CrmCustomerDO> customers = customerService.createCustomerBatch(convertList(translateClues, clue -> List<CrmCustomerDO> customers = customerService.createCustomerBatch(convertList(translateClues, clue ->
BeanUtils.toBean(clue, CrmCustomerCreateReqBO.class)), userId); BeanUtils.toBean(clue, CrmCustomerCreateReqBO.class)), userId);
// TODO @puhui999这里不用搞一个 clueCustomerIdMap 出来可以考虑逐个创建然后把 customerId 设置回 CrmClueDO避免 name 匹配极端会有问题哈
// TODO 是不是就直接 foreach 处理好了因为本身量不大for 处理性能 ok可阅读性好
Map<Long, Long> clueCustomerIdMap = new HashMap<>(translateClues.size()); Map<Long, Long> clueCustomerIdMap = new HashMap<>(translateClues.size());
// 2.1 更新线索 // 2.1 更新线索
clueMapper.updateBatch(convertList(customers, customer -> { clueMapper.updateBatch(convertList(customers, customer -> {
@ -209,6 +212,7 @@ public class CrmClueServiceImpl implements CrmClueService {
// 3. 记录操作日志 // 3. 记录操作日志
for (CrmClueDO clue : translateClues) { for (CrmClueDO clue : translateClues) {
// TODO @puhui999这里优化下translate 操作日志
getSelf().receiveClueLog(clue); getSelf().receiveClueLog(clue);
} }
} }

View File

@ -120,11 +120,12 @@ public class CrmFollowUpRecordServiceImpl implements CrmFollowUpRecordService {
// 校验存在 // 校验存在
CrmFollowUpRecordDO followUpRecord = validateFollowUpRecordExists(id); CrmFollowUpRecordDO followUpRecord = validateFollowUpRecordExists(id);
// 校验权限 // 校验权限
// TODO @puhui999是不是封装一个 hasPermission更简介一点
List<CrmPermissionDO> permissionList = permissionService.getPermissionListByBiz( List<CrmPermissionDO> permissionList = permissionService.getPermissionListByBiz(
followUpRecord.getBizType(), followUpRecord.getBizId()); followUpRecord.getBizType(), followUpRecord.getBizId());
boolean condition = anyMatch(permissionList, permission -> boolean hasPermission = anyMatch(permissionList, permission ->
ObjUtil.equal(permission.getUserId(), userId) && ObjUtil.equal(permission.getLevel(), CrmPermissionLevelEnum.OWNER.getLevel())); ObjUtil.equal(permission.getUserId(), userId) && ObjUtil.equal(permission.getLevel(), CrmPermissionLevelEnum.OWNER.getLevel()));
if (!condition) { if (!hasPermission) {
throw exception(FOLLOW_UP_RECORD_DELETE_DENIED); throw exception(FOLLOW_UP_RECORD_DELETE_DENIED);
} }
@ -134,7 +135,6 @@ public class CrmFollowUpRecordServiceImpl implements CrmFollowUpRecordService {
@Override @Override
public void deleteFollowUpRecordByBiz(Integer bizType, Long bizId) { public void deleteFollowUpRecordByBiz(Integer bizType, Long bizId) {
// 删除
crmFollowUpRecordMapper.deleteByBiz(bizType, bizId); crmFollowUpRecordMapper.deleteByBiz(bizType, bizId);
} }