Commit d732008ef8ee647d003c91e860aba504ea9c9f25
1 parent
ff7e4928
📖 CRM:code review 跟进日志
Showing
6 changed files
with
27 additions
and
16 deletions
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<CrmFollowUpRecordDO | @@ -26,12 +26,14 @@ public interface CrmFollowUpRecordMapper extends BaseMapperX<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 |