Commit d732008ef8ee647d003c91e860aba504ea9c9f25

Authored by YunaiV
1 parent ff7e4928

📖 CRM:code review 跟进日志

yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/operatelog/CrmOperateLogController.java
@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.crm.controller.admin.operatelog; @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.crm.controller.admin.operatelog;
3 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 3 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 import cn.iocoder.yudao.framework.common.pojo.PageResult; 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 import cn.iocoder.yudao.module.crm.controller.admin.operatelog.vo.CrmOperateLogPageReqVO; 5 import cn.iocoder.yudao.module.crm.controller.admin.operatelog.vo.CrmOperateLogPageReqVO;
  6 +import cn.iocoder.yudao.module.crm.enums.LogRecordConstants;
6 import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; 7 import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
7 import cn.iocoder.yudao.module.system.api.logger.OperateLogApi; 8 import cn.iocoder.yudao.module.system.api.logger.OperateLogApi;
8 import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2PageReqDTO; 9 import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2PageReqDTO;
@@ -25,7 +26,7 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @@ -25,7 +26,7 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
25 import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE; 26 import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE;
26 import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*; 27 import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*;
27 28
28 -@Tag(name = "管理后台 - 操作日志") 29 +@Tag(name = "管理后台 - CRM 操作日志")
29 @RestController 30 @RestController
30 @RequestMapping("/crm/operate-log") 31 @RequestMapping("/crm/operate-log")
31 @Validated 32 @Validated
@@ -34,6 +35,9 @@ public class CrmOperateLogController { @@ -34,6 +35,9 @@ public class CrmOperateLogController {
34 @Resource 35 @Resource
35 private OperateLogApi operateLogApi; 36 private OperateLogApi operateLogApi;
36 37
  38 + /**
  39 + * {@link CrmBizTypeEnum} 与 {@link LogRecordConstants} 的映射关系
  40 + */
37 private static final Map<Integer, String> BIZ_TYPE_MAP = new HashMap<>(); 41 private static final Map<Integer, String> BIZ_TYPE_MAP = new HashMap<>();
38 42
39 static { 43 static {
@@ -47,6 +51,7 @@ public class CrmOperateLogController { @@ -47,6 +51,7 @@ public class CrmOperateLogController {
47 BIZ_TYPE_MAP.put(CrmBizTypeEnum.CRM_RECEIVABLE_PLAN.getType(), CRM_RECEIVABLE_PLAN_TYPE); 51 BIZ_TYPE_MAP.put(CrmBizTypeEnum.CRM_RECEIVABLE_PLAN.getType(), CRM_RECEIVABLE_PLAN_TYPE);
48 } 52 }
49 53
  54 + // TODO @puhui999:还是搞个 VO 出来哈
50 @GetMapping("/page") 55 @GetMapping("/page")
51 @Operation(summary = "获得操作日志") 56 @Operation(summary = "获得操作日志")
52 @Parameter(name = "id", description = "客户编号", required = true) 57 @Parameter(name = "id", description = "客户编号", required = true)
@@ -54,8 +59,7 @@ public class CrmOperateLogController { @@ -54,8 +59,7 @@ public class CrmOperateLogController {
54 public CommonResult<PageResult<OperateLogV2RespDTO>> getCustomerOperateLog(@Valid CrmOperateLogPageReqVO pageReqVO) { 59 public CommonResult<PageResult<OperateLogV2RespDTO>> getCustomerOperateLog(@Valid CrmOperateLogPageReqVO pageReqVO) {
55 OperateLogV2PageReqDTO reqDTO = new OperateLogV2PageReqDTO(); 60 OperateLogV2PageReqDTO reqDTO = new OperateLogV2PageReqDTO();
56 reqDTO.setPageSize(PAGE_SIZE_NONE); // 默认不分页,需要分页需注释 61 reqDTO.setPageSize(PAGE_SIZE_NONE); // 默认不分页,需要分页需注释
57 - reqDTO.setBizType(BIZ_TYPE_MAP.get(pageReqVO.getBizType()));  
58 - reqDTO.setBizId(pageReqVO.getBizId()); 62 + reqDTO.setBizType(BIZ_TYPE_MAP.get(pageReqVO.getBizType())).setBizId(pageReqVO.getBizId());
59 return success(operateLogApi.getOperateLogPage(reqDTO)); 63 return success(operateLogApi.getOperateLogPage(reqDTO));
60 } 64 }
61 65
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/operatelog/vo/CrmOperateLogPageReqVO.java
@@ -9,7 +9,7 @@ import lombok.Data; @@ -9,7 +9,7 @@ import lombok.Data;
9 import lombok.EqualsAndHashCode; 9 import lombok.EqualsAndHashCode;
10 import lombok.ToString; 10 import lombok.ToString;
11 11
12 -@Schema(description = "管理后台 - 跟进记录分页 Request VO") 12 +@Schema(description = "管理后台 - CRM 操作日志 Request VO")
13 @Data 13 @Data
14 @EqualsAndHashCode(callSuper = true) 14 @EqualsAndHashCode(callSuper = true)
15 @ToString(callSuper = true) 15 @ToString(callSuper = true)
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/permission/CrmPermissionConvert.java
@@ -29,6 +29,7 @@ public interface CrmPermissionConvert { @@ -29,6 +29,7 @@ public interface CrmPermissionConvert {
29 29
30 CrmPermissionConvert INSTANCE = Mappers.getMapper(CrmPermissionConvert.class); 30 CrmPermissionConvert INSTANCE = Mappers.getMapper(CrmPermissionConvert.class);
31 31
  32 + // TODO @puhui999:这个要不也搞到 copy 里
32 List<CrmPermissionRespVO> convert(List<CrmPermissionDO> permission); 33 List<CrmPermissionRespVO> convert(List<CrmPermissionDO> permission);
33 34
34 default List<CrmPermissionRespVO> convert(List<CrmPermissionDO> permission, List<AdminUserRespDTO> userList, 35 default List<CrmPermissionRespVO> convert(List<CrmPermissionDO> permission, List<AdminUserRespDTO> userList,
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/followup/CrmFollowUpRecordMapper.java
@@ -26,12 +26,14 @@ public interface CrmFollowUpRecordMapper extends BaseMapperX&lt;CrmFollowUpRecordDO @@ -26,12 +26,14 @@ public interface CrmFollowUpRecordMapper extends BaseMapperX&lt;CrmFollowUpRecordDO
26 } 26 }
27 27
28 default void deleteByBiz(Integer bizType, Long bizId) { 28 default void deleteByBiz(Integer bizType, Long bizId) {
29 - delete(new LambdaQueryWrapperX<CrmFollowUpRecordDO>().eq(CrmFollowUpRecordDO::getBizType, bizType) 29 + delete(new LambdaQueryWrapperX<CrmFollowUpRecordDO>()
  30 + .eq(CrmFollowUpRecordDO::getBizType, bizType)
30 .eq(CrmFollowUpRecordDO::getBizId, bizId)); 31 .eq(CrmFollowUpRecordDO::getBizId, bizId));
31 } 32 }
32 33
33 default List<CrmFollowUpRecordDO> selectListByBiz(Integer bizType, Collection<Long> bizIds) { 34 default List<CrmFollowUpRecordDO> selectListByBiz(Integer bizType, Collection<Long> bizIds) {
34 - return selectList(new LambdaQueryWrapperX<CrmFollowUpRecordDO>().eq(CrmFollowUpRecordDO::getBizType, bizType) 35 + return selectList(new LambdaQueryWrapperX<CrmFollowUpRecordDO>()
  36 + .eq(CrmFollowUpRecordDO::getBizType, bizType)
35 .in(CrmFollowUpRecordDO::getBizId, bizIds)); 37 .in(CrmFollowUpRecordDO::getBizId, bizIds));
36 } 38 }
37 39
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java
@@ -73,17 +73,17 @@ public class CrmClueServiceImpl implements CrmClueService { @@ -73,17 +73,17 @@ public class CrmClueServiceImpl implements CrmClueService {
73 @LogRecord(type = CRM_LEADS_TYPE, subType = CRM_LEADS_CREATE_SUB_TYPE, bizNo = "{{#clue.id}}", 73 @LogRecord(type = CRM_LEADS_TYPE, subType = CRM_LEADS_CREATE_SUB_TYPE, bizNo = "{{#clue.id}}",
74 success = CRM_LEADS_CREATE_SUCCESS) 74 success = CRM_LEADS_CREATE_SUCCESS)
75 public Long createClue(CrmClueSaveReqVO createReqVO, Long userId) { 75 public Long createClue(CrmClueSaveReqVO createReqVO, Long userId) {
76 - // 1. 校验关联数据 76 + // 1.1 校验关联数据
77 validateRelationDataExists(createReqVO); 77 validateRelationDataExists(createReqVO);
  78 + // 1.2 校验负责人是否存在
  79 + if (createReqVO.getOwnerUserId() != null) {
  80 + adminUserApi.validateUserList(singletonList(createReqVO.getOwnerUserId()));
  81 + } else {
  82 + createReqVO.setOwnerUserId(userId); // 如果没有设置负责人那么默认操作人为负责人
  83 + }
78 84
79 // 2. 插入 85 // 2. 插入
80 CrmClueDO clue = BeanUtils.toBean(createReqVO, CrmClueDO.class).setId(null); 86 CrmClueDO clue = BeanUtils.toBean(createReqVO, CrmClueDO.class).setId(null);
81 - if (ObjUtil.isNull(createReqVO.getOwnerUserId())) {  
82 - clue.setOwnerUserId(userId); // 如果没有设置负责人那么默认操作人为负责人  
83 - } else {  
84 - // 校验负责人是否存在  
85 - adminUserApi.validateUserList(singletonList(createReqVO.getOwnerUserId()));  
86 - }  
87 clueMapper.insert(clue); 87 clueMapper.insert(clue);
88 88
89 // 3. 创建数据权限 89 // 3. 创建数据权限
@@ -193,10 +193,13 @@ public class CrmClueServiceImpl implements CrmClueService { @@ -193,10 +193,13 @@ public class CrmClueServiceImpl implements CrmClueService {
193 } 193 }
194 194
195 // 2. 遍历线索(未转化的线索),创建对应的客户 195 // 2. 遍历线索(未转化的线索),创建对应的客户
  196 + // TODO @puhui999:这里不用过滤了;
196 List<CrmClueDO> translateClues = filterList(clues, clue -> ObjUtil.equal(Boolean.FALSE, clue.getTransformStatus())); 197 List<CrmClueDO> translateClues = filterList(clues, clue -> ObjUtil.equal(Boolean.FALSE, clue.getTransformStatus()));
197 List<CrmCustomerDO> customers = customerService.createCustomerBatch(convertList(translateClues, clue -> 198 List<CrmCustomerDO> customers = customerService.createCustomerBatch(convertList(translateClues, clue ->
198 BeanUtils.toBean(clue, CrmCustomerCreateReqBO.class)), userId); 199 BeanUtils.toBean(clue, CrmCustomerCreateReqBO.class)), userId);
199 200
  201 + // TODO @puhui999:这里不用搞一个 clueCustomerIdMap 出来;可以考虑逐个创建,然后把 customerId 设置回 CrmClueDO;避免 name 匹配,极端会有问题哈;
  202 + // TODO 是不是就直接 foreach 处理好了;因为本身量不大,for 处理性能 ok,可阅读性好
200 Map<Long, Long> clueCustomerIdMap = new HashMap<>(translateClues.size()); 203 Map<Long, Long> clueCustomerIdMap = new HashMap<>(translateClues.size());
201 // 2.1 更新线索 204 // 2.1 更新线索
202 clueMapper.updateBatch(convertList(customers, customer -> { 205 clueMapper.updateBatch(convertList(customers, customer -> {
@@ -209,6 +212,7 @@ public class CrmClueServiceImpl implements CrmClueService { @@ -209,6 +212,7 @@ public class CrmClueServiceImpl implements CrmClueService {
209 212
210 // 3. 记录操作日志 213 // 3. 记录操作日志
211 for (CrmClueDO clue : translateClues) { 214 for (CrmClueDO clue : translateClues) {
  215 + // TODO @puhui999:这里优化下,translate 操作日志
212 getSelf().receiveClueLog(clue); 216 getSelf().receiveClueLog(clue);
213 } 217 }
214 } 218 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/CrmFollowUpRecordServiceImpl.java
@@ -120,11 +120,12 @@ public class CrmFollowUpRecordServiceImpl implements CrmFollowUpRecordService { @@ -120,11 +120,12 @@ public class CrmFollowUpRecordServiceImpl implements CrmFollowUpRecordService {
120 // 校验存在 120 // 校验存在
121 CrmFollowUpRecordDO followUpRecord = validateFollowUpRecordExists(id); 121 CrmFollowUpRecordDO followUpRecord = validateFollowUpRecordExists(id);
122 // 校验权限 122 // 校验权限
  123 + // TODO @puhui999:是不是封装一个 hasPermission,更简介一点;
123 List<CrmPermissionDO> permissionList = permissionService.getPermissionListByBiz( 124 List<CrmPermissionDO> permissionList = permissionService.getPermissionListByBiz(
124 followUpRecord.getBizType(), followUpRecord.getBizId()); 125 followUpRecord.getBizType(), followUpRecord.getBizId());
125 - boolean condition = anyMatch(permissionList, permission -> 126 + boolean hasPermission = anyMatch(permissionList, permission ->
126 ObjUtil.equal(permission.getUserId(), userId) && ObjUtil.equal(permission.getLevel(), CrmPermissionLevelEnum.OWNER.getLevel())); 127 ObjUtil.equal(permission.getUserId(), userId) && ObjUtil.equal(permission.getLevel(), CrmPermissionLevelEnum.OWNER.getLevel()));
127 - if (!condition) { 128 + if (!hasPermission) {
128 throw exception(FOLLOW_UP_RECORD_DELETE_DENIED); 129 throw exception(FOLLOW_UP_RECORD_DELETE_DENIED);
129 } 130 }
130 131
@@ -134,7 +135,6 @@ public class CrmFollowUpRecordServiceImpl implements CrmFollowUpRecordService { @@ -134,7 +135,6 @@ public class CrmFollowUpRecordServiceImpl implements CrmFollowUpRecordService {
134 135
135 @Override 136 @Override
136 public void deleteFollowUpRecordByBiz(Integer bizType, Long bizId) { 137 public void deleteFollowUpRecordByBiz(Integer bizType, Long bizId) {
137 - // 删除  
138 crmFollowUpRecordMapper.deleteByBiz(bizType, bizId); 138 crmFollowUpRecordMapper.deleteByBiz(bizType, bizId);
139 } 139 }
140 140