mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-11-01 02:38:43 +08:00 
			
		
		
		
	CRM-客户:完善操作日志
This commit is contained in:
		| @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.crm.controller.admin.customer; | ||||
| import cn.hutool.core.collection.CollUtil; | ||||
| import cn.iocoder.yudao.framework.common.pojo.CommonResult; | ||||
| import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||||
| import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | ||||
| import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; | ||||
| import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; | ||||
| import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.*; | ||||
| @@ -38,7 +39,7 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils. | ||||
| import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSetByFlatMap; | ||||
| 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.module.crm.enums.LogRecordConstants.CRM_CUSTOMER; | ||||
| import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.CRM_CUSTOMER_TYPE; | ||||
|  | ||||
| @Tag(name = "管理后台 - CRM 客户") | ||||
| @RestController | ||||
| @@ -115,6 +116,15 @@ public class CrmCustomerController { | ||||
|         return success(CrmCustomerConvert.INSTANCE.convertPage(pageResult, userMap, deptMap)); | ||||
|     } | ||||
|  | ||||
|     @GetMapping(value = {"/list-all-simple"}) | ||||
|     @Operation(summary = "获取客户精简信息列表", description = "只包含有读权限的客户,主要用于前端的下拉选项") | ||||
|     public CommonResult<List<CrmCustomerSimpleRespVO>> getSimpleDeptList() { | ||||
|         CrmCustomerPageReqVO reqVO = new CrmCustomerPageReqVO(); | ||||
|         reqVO.setPageSize(PAGE_SIZE_NONE); // 不分页 | ||||
|         List<CrmCustomerDO> list = customerService.getCustomerPage(reqVO, getLoginUserId()).getList(); | ||||
|         return success(BeanUtils.toBean(list, CrmCustomerSimpleRespVO.class)); | ||||
|     } | ||||
|  | ||||
|     @GetMapping("/export-excel") | ||||
|     @Operation(summary = "导出客户 Excel") | ||||
|     @PreAuthorize("@ss.hasPermission('crm:customer:export')") | ||||
| @@ -143,7 +153,7 @@ public class CrmCustomerController { | ||||
|     public CommonResult<PageResult<OperateLogV2RespDTO>> getCustomerOperateLog(@RequestParam("id") Long id) { | ||||
|         OperateLogV2PageReqDTO reqDTO = new OperateLogV2PageReqDTO(); | ||||
|         reqDTO.setPageSize(PAGE_SIZE_NONE); // 不分页 | ||||
|         reqDTO.setBizType(CRM_CUSTOMER); | ||||
|         reqDTO.setBizType(CRM_CUSTOMER_TYPE); | ||||
|         reqDTO.setBizId(id); | ||||
|         return success(operateLogApi.getOperateLogPage(reqDTO)); | ||||
|     } | ||||
| @@ -172,7 +182,7 @@ public class CrmCustomerController { | ||||
|     @Parameter(name = "ids", description = "编号数组", required = true, example = "1,2,3") | ||||
|     @PreAuthorize("@ss.hasPermission('crm:customer:receive')") | ||||
|     public CommonResult<Boolean> receiveCustomer(@RequestParam(value = "ids") List<Long> ids) { | ||||
|         customerService.receiveCustomer(ids, getLoginUserId()); | ||||
|         customerService.receiveCustomer(ids, getLoginUserId(), Boolean.TRUE); | ||||
|         return success(true); | ||||
|     } | ||||
|  | ||||
| @@ -180,18 +190,8 @@ public class CrmCustomerController { | ||||
|     @Operation(summary = "分配公海给对应负责人") | ||||
|     @PreAuthorize("@ss.hasPermission('crm:customer:distribute')") | ||||
|     public CommonResult<Boolean> distributeCustomer(@Valid @RequestBody CrmCustomerDistributeReqVO distributeReqVO) { | ||||
|         customerService.receiveCustomer(distributeReqVO.getIds(), distributeReqVO.getOwnerUserId()); | ||||
|         customerService.receiveCustomer(distributeReqVO.getIds(), distributeReqVO.getOwnerUserId(), Boolean.FALSE); | ||||
|         return success(true); | ||||
|     } | ||||
|  | ||||
|     // TODO 芋艿:这个接口要调整下 | ||||
|     //@GetMapping("/query-all-list") | ||||
|     //@Operation(summary = "查询客户列表") | ||||
|     //@PreAuthorize("@ss.hasPermission('crm:customer:all')") | ||||
|     //public CommonResult<List<CrmCustomerQueryAllRespVO>> queryAll() { | ||||
|     //    List<CrmCustomerDO> crmCustomerDOList = customerService.getCustomerList(); | ||||
|     //    List<CrmCustomerQueryAllRespVO> data = CrmCustomerConvert.INSTANCE.convertQueryAll(crmCustomerDOList); | ||||
|     //    return success(data); | ||||
|     //} | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -0,0 +1,20 @@ | ||||
| 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; | ||||
|  | ||||
| } | ||||
| @@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; | ||||
| import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO; | ||||
| import org.apache.ibatis.annotations.Mapper; | ||||
|  | ||||
| import java.util.Collection; | ||||
| import java.util.List; | ||||
|  | ||||
| /** | ||||
| @@ -28,6 +29,12 @@ public interface CrmPermissionMapper extends BaseMapperX<CrmPermissionDO> { | ||||
|                 .eq(CrmPermissionDO::getBizId, bizId)); | ||||
|     } | ||||
|  | ||||
|     default List<CrmPermissionDO> selectByBizTypeAndBizIds(Integer bizType, Collection<Long> bizIds) { | ||||
|         return selectList(new LambdaQueryWrapperX<CrmPermissionDO>() | ||||
|                 .eq(CrmPermissionDO::getBizType, bizType) | ||||
|                 .in(CrmPermissionDO::getBizId, bizIds)); | ||||
|     } | ||||
|  | ||||
|     default List<CrmPermissionDO> selectListByBizTypeAndUserId(Integer bizType, Long userId) { | ||||
|         return selectList(new LambdaQueryWrapperX<CrmPermissionDO>() | ||||
|                 .eq(CrmPermissionDO::getBizType, bizType) | ||||
|   | ||||
| @@ -18,12 +18,10 @@ import org.aspectj.lang.annotation.Aspect; | ||||
| import org.aspectj.lang.annotation.Before; | ||||
| import org.springframework.stereotype.Component; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.*; | ||||
|  | ||||
| import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | ||||
| import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.anyMatch; | ||||
| import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; | ||||
| import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; | ||||
| import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CRM_PERMISSION_DENIED; | ||||
|  | ||||
| @@ -46,16 +44,29 @@ public class CrmPermissionAspect { | ||||
|         Map<String, Object> expressionValues = parseExpressions(joinPoint, crmPermission); | ||||
|         Integer bizType = StrUtil.isEmpty(crmPermission.bizTypeValue()) ? | ||||
|                 crmPermission.bizType()[0].getType() : (Integer) expressionValues.get(crmPermission.bizTypeValue()); // 模块类型 | ||||
|         Long bizId = (Long) expressionValues.get(crmPermission.bizId()); // 模块数据编号 | ||||
|         // 处理兼容多个 bizId 的情况 | ||||
|         Object object = expressionValues.get(crmPermission.bizId());// 模块数据编号 | ||||
|         Set<Long> bizIds = new HashSet<>(); | ||||
|         if (object instanceof Collection<?>) { | ||||
|             bizIds.addAll(convertSet((Collection<?>) object, item -> Long.parseLong(item.toString()))); | ||||
|         } else { | ||||
|             bizIds.add(Long.parseLong(object.toString())); | ||||
|         } | ||||
|         Integer permissionLevel = crmPermission.level().getLevel(); // 需要的权限级别 | ||||
|         List<CrmPermissionDO> permissionList = crmPermissionService.getPermissionListByBiz(bizType, bizIds); | ||||
|         Map<Long, List<CrmPermissionDO>> multiMap = convertMultiMap(permissionList, CrmPermissionDO::getBizId); | ||||
|         bizIds.forEach(bizId -> { | ||||
|             validatePermission(bizType, multiMap.get(bizId), permissionLevel); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|         // 1.1 如果是超级管理员则直接通过 | ||||
|     private void validatePermission(Integer bizType, List<CrmPermissionDO> bizPermissions, Integer permissionLevel) { | ||||
|         // 1. 如果是超级管理员则直接通过 | ||||
|         if (CrmPermissionUtils.isCrmAdmin()) { | ||||
|             return; | ||||
|         } | ||||
|         // 1.2 获取数据权限 | ||||
|         List<CrmPermissionDO> bizPermissions = crmPermissionService.getPermissionListByBiz(bizType, bizId); | ||||
|         if (CollUtil.isEmpty(bizPermissions)) { // 没有数据权限的情况 | ||||
|         // 1.1 没有数据权限的情况 | ||||
|         if (CollUtil.isEmpty(bizPermissions)) { | ||||
|             // 公海数据如果没有团队成员大家也因该有读权限才对 | ||||
|             if (CrmPermissionLevelEnum.isRead(permissionLevel)) { | ||||
|                 return; | ||||
| @@ -63,7 +74,7 @@ public class CrmPermissionAspect { | ||||
|  | ||||
|             // 没有数据权限的情况下超出了读权限直接报错,避免后面校验空指针 | ||||
|             throw exception(CRM_PERMISSION_DENIED, CrmBizTypeEnum.getNameByType(bizType)); | ||||
|         } else { // 有数据权限但是没有负责人的情况 | ||||
|         } else { // 1.2 有数据权限但是没有负责人的情况 | ||||
|             if (!anyMatch(bizPermissions, item -> CrmPermissionLevelEnum.isOwner(item.getLevel()))) { | ||||
|                 if (CrmPermissionLevelEnum.isRead(permissionLevel)) { | ||||
|                     return; | ||||
|   | ||||
| @@ -86,7 +86,7 @@ public interface CrmCustomerService { | ||||
|      * 锁定/解锁客户 | ||||
|      * | ||||
|      * @param lockReqVO 更新信息 | ||||
|      * @param userId 用户编号 | ||||
|      * @param userId    用户编号 | ||||
|      */ | ||||
|     void lockCustomer(@Valid CrmCustomerLockReqVO lockReqVO, Long userId); | ||||
|  | ||||
| @@ -104,15 +104,8 @@ public interface CrmCustomerService { | ||||
|      * | ||||
|      * @param ids         要领取的客户编号数组 | ||||
|      * @param ownerUserId 负责人 | ||||
|      * @param isReceive   是/否领取 | ||||
|      */ | ||||
|     void receiveCustomer(List<Long> ids, Long ownerUserId); | ||||
|  | ||||
|     /** | ||||
|      * 获取客户列表 | ||||
|      * | ||||
|      * @return 客户列表 | ||||
|      * @author zyna | ||||
|      */ | ||||
|     List<CrmCustomerDO> getCustomerList(); | ||||
|     void receiveCustomer(List<Long> ids, Long ownerUserId, Boolean isReceive); | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -16,9 +16,11 @@ import cn.iocoder.yudao.module.crm.dal.mysql.customer.CrmCustomerMapper; | ||||
| 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; | ||||
| import cn.iocoder.yudao.module.crm.framework.permission.core.util.CrmPermissionUtils; | ||||
| import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; | ||||
| import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; | ||||
| import cn.iocoder.yudao.module.system.api.user.AdminUserApi; | ||||
| import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; | ||||
| import com.mzt.logapi.context.LogRecordContext; | ||||
| import com.mzt.logapi.service.impl.DiffParseFunction; | ||||
| import com.mzt.logapi.starter.annotation.LogRecord; | ||||
| @@ -35,8 +37,7 @@ import java.util.List; | ||||
|  | ||||
| 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.LogRecordConstants.CRM_CUSTOMER; | ||||
| import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.TRANSFER_CUSTOMER_LOG_SUCCESS; | ||||
| import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*; | ||||
| import static cn.iocoder.yudao.module.crm.enums.customer.CrmCustomerLimitConfigTypeEnum.CUSTOMER_LOCK_LIMIT; | ||||
| import static cn.iocoder.yudao.module.crm.enums.customer.CrmCustomerLimitConfigTypeEnum.CUSTOMER_OWNER_LIMIT; | ||||
| import static java.util.Collections.singletonList; | ||||
| @@ -63,8 +64,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | ||||
|  | ||||
|     @Override | ||||
|     @Transactional(rollbackFor = Exception.class) | ||||
|     @LogRecord(type = CRM_CUSTOMER, subType = "创建客户", bizNo = "{{#customerId}}", success = "创建了客户") | ||||
|     // TODO @puhui999:创建了客户【客户名】,要记录进去;不然在展示操作日志的全列表,看不清楚是哪个客户哈; | ||||
|     @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) { | ||||
|         createReqVO.setId(null); | ||||
|         // 1. 校验拥有客户是否到达上限 | ||||
| @@ -81,14 +81,14 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | ||||
|         permissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType()) | ||||
|                 .setBizId(customer.getId()).setUserId(userId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); // 设置当前操作的人为负责人 | ||||
|  | ||||
|         // 4. 记录操作日志 | ||||
|         LogRecordContext.putVariable("customerId", customer.getId()); | ||||
|         // 4. 记录操作日志上下文 | ||||
|         LogRecordContext.putVariable("customer", customer); | ||||
|         return customer.getId(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     @Transactional(rollbackFor = Exception.class) | ||||
|     @LogRecord(type = CRM_CUSTOMER, subType = "更新客户", bizNo = "{{#updateReqVO.id}}", success = "更新了客户{_DIFF{#updateReqVO}}", extra = "{{#extra}}") | ||||
|     @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) | ||||
|     public void updateCustomer(CrmCustomerSaveReqVO updateReqVO) { | ||||
|         Assert.notNull(updateReqVO.getId(), "客户编号不能为空"); | ||||
| @@ -101,17 +101,18 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | ||||
|         CrmCustomerDO updateObj = CrmCustomerConvert.INSTANCE.convert(updateReqVO); | ||||
|         customerMapper.updateById(updateObj); | ||||
|  | ||||
|         // 3. 记录操作日志 | ||||
|         // 3. 记录操作日志上下文 | ||||
|         LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldCustomer, CrmCustomerSaveReqVO.class)); | ||||
|         LogRecordContext.putVariable("customerName", oldCustomer.getName()); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     @Transactional(rollbackFor = Exception.class) | ||||
|     @LogRecord(type = CRM_CUSTOMER, subType = "删除客户", bizNo = "{{#id}}", 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) | ||||
|     public void deleteCustomer(Long id) { | ||||
|         // 校验存在 | ||||
|         validateCustomerExists(id); | ||||
|         CrmCustomerDO customer = validateCustomerExists(id); | ||||
|         // TODO @puhui999:如果有联系人、商机,则不允许删除; | ||||
|  | ||||
|         // 删除 | ||||
| @@ -119,16 +120,144 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | ||||
|         // 删除数据权限 | ||||
|         permissionService.deletePermission(CrmBizTypeEnum.CRM_CUSTOMER.getType(), id); | ||||
|         // TODO @puhui999:删除跟进记录 | ||||
|  | ||||
|         // 记录操作日志上下文 | ||||
|         LogRecordContext.putVariable("customerName", customer.getName()); | ||||
|     } | ||||
|  | ||||
|     private CrmCustomerDO validateCustomerExists(Long id) { | ||||
|         CrmCustomerDO customerDO = customerMapper.selectById(id); | ||||
|         if (customerDO == null) { | ||||
|     @Override | ||||
|     @Transactional(rollbackFor = Exception.class) | ||||
|     @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) | ||||
|     public void transferCustomer(CrmCustomerTransferReqVO reqVO, Long userId) { | ||||
|         // 1.1 校验客户是否存在 | ||||
|         CrmCustomerDO customer = validateCustomerExists(reqVO.getId()); | ||||
|         // 1.2 校验拥有客户是否到达上限 | ||||
|         validateCustomerExceedOwnerLimit(reqVO.getNewOwnerUserId(), 1); | ||||
|  | ||||
|         // 2.1 数据权限转移 | ||||
|         permissionService.transferPermission( | ||||
|                 CrmCustomerConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType())); | ||||
|         // 2.2 转移后重新设置负责人 | ||||
|         customerMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId()); | ||||
|  | ||||
|         // 3. TODO 记录转移日志 | ||||
|         // 记录操作日志上下文 | ||||
|         LogRecordContext.putVariable("crmCustomer", customer); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     @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) | ||||
|     public void lockCustomer(CrmCustomerLockReqVO lockReqVO, Long userId) { | ||||
|         // 1.1 校验当前客户是否存在 | ||||
|         CrmCustomerDO customer = validateCustomerExists(lockReqVO.getId()); | ||||
|         // 1.2 校验当前是否重复操作锁定/解锁状态 | ||||
|         if (customer.getLockStatus().equals(lockReqVO.getLockStatus())) { | ||||
|             throw exception(customer.getLockStatus() ? CUSTOMER_LOCK_FAIL_IS_LOCK : CUSTOMER_UNLOCK_FAIL_IS_UNLOCK); | ||||
|         } | ||||
|         // 1.3 校验锁定上限。 | ||||
|         if (lockReqVO.getLockStatus()) { | ||||
|             validateCustomerExceedLockLimit(userId); | ||||
|         } | ||||
|  | ||||
|         // 2. 更新锁定状态 | ||||
|         customerMapper.updateById(BeanUtils.toBean(lockReqVO, CrmCustomerDO.class)); | ||||
|  | ||||
|         // 3. 记录操作日志上下文 | ||||
|         LogRecordContext.putVariable("crmCustomer", customer); | ||||
|     } | ||||
|  | ||||
|     // ==================== 公海相关操作 ==================== | ||||
|  | ||||
|     @Override | ||||
|     @Transactional(rollbackFor = Exception.class) | ||||
|     @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) | ||||
|     public void putCustomerPool(Long id) { | ||||
|         // 1. 校验存在 | ||||
|         CrmCustomerDO customer = customerMapper.selectById(id); | ||||
|         if (customer == null) { | ||||
|             throw exception(CUSTOMER_NOT_EXISTS); | ||||
|         } | ||||
|         return customerDO; | ||||
|         // 1.2. 校验是否为公海数据 | ||||
|         validateCustomerOwnerExists(customer, true); | ||||
|         // 1.3. 校验客户是否锁定 | ||||
|         validateCustomerIsLocked(customer, true); | ||||
|  | ||||
|         // 2. 设置负责人为 NULL | ||||
|         int updateOwnerUserIncr = customerMapper.updateOwnerUserIdById(customer.getId(), null); | ||||
|         if (updateOwnerUserIncr == 0) { | ||||
|             throw exception(CUSTOMER_UPDATE_OWNER_USER_FAIL); | ||||
|         } | ||||
|         // 3. 删除负责人数据权限 | ||||
|         permissionService.deletePermission(CrmBizTypeEnum.CRM_CUSTOMER.getType(), customer.getId(), | ||||
|                 CrmPermissionLevelEnum.OWNER.getLevel()); | ||||
|         // TODO @puhui999:联系人的负责人,也要设置为 null;这块和领取是对应的;因为领取后,负责人也要关联过来; | ||||
|  | ||||
|         // 记录操作日志上下文 | ||||
|         LogRecordContext.putVariable("customerName", customer.getName()); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     @Transactional(rollbackFor = Exception.class) | ||||
|     public void receiveCustomer(List<Long> ids, Long ownerUserId, Boolean isReceive) { | ||||
|         if (!isReceive && !CrmPermissionUtils.isCrmAdmin()) { // 只有管理员可以分配 | ||||
|             throw exception(CRM_PERMISSION_DENIED, CrmBizTypeEnum.CRM_CUSTOMER.getName()); | ||||
|         } | ||||
|  | ||||
|         // 1.1 校验存在 | ||||
|         List<CrmCustomerDO> customers = customerMapper.selectBatchIds(ids); | ||||
|         if (customers.size() != ids.size()) { | ||||
|             throw exception(CUSTOMER_NOT_EXISTS); | ||||
|         } | ||||
|         // 1.2. 校验负责人是否存在 | ||||
|         adminUserApi.validateUserList(singletonList(ownerUserId)); | ||||
|         // 1.3. 校验状态 | ||||
|         customers.forEach(customer -> { | ||||
|             // 校验是否已有负责人 | ||||
|             validateCustomerOwnerExists(customer, false); | ||||
|             // 校验是否锁定 | ||||
|             validateCustomerIsLocked(customer, false); | ||||
|             // 校验成交状态 | ||||
|             validateCustomerDeal(customer); | ||||
|         }); | ||||
|         // 1.4  校验负责人是否到达上限 | ||||
|         validateCustomerExceedOwnerLimit(ownerUserId, customers.size()); | ||||
|  | ||||
|         // 2.1 领取公海数据 | ||||
|         List<CrmCustomerDO> updateCustomers = new ArrayList<>(); | ||||
|         List<CrmPermissionCreateReqBO> createPermissions = new ArrayList<>(); | ||||
|         customers.forEach(customer -> { | ||||
|             // 2.1. 设置负责人 | ||||
|             updateCustomers.add(new CrmCustomerDO().setId(customer.getId()).setOwnerUserId(ownerUserId)); | ||||
|             // 2.2. 创建负责人数据权限 | ||||
|             createPermissions.add(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType()) | ||||
|                     .setBizId(customer.getId()).setUserId(ownerUserId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); | ||||
|         }); | ||||
|         // 2.2 更新客户负责人 | ||||
|         customerMapper.updateBatch(updateCustomers); | ||||
|         // 2.3 创建负责人数据权限 | ||||
|         permissionService.createPermissionBatch(createPermissions); | ||||
|         // TODO @芋艿:要不要处理关联的联系人??? | ||||
|  | ||||
|         // 3. 记录操作日志 | ||||
|         AdminUserRespDTO user = null; | ||||
|         if (!isReceive) { | ||||
|             user = adminUserApi.getUser(ownerUserId); | ||||
|         } | ||||
|         for (CrmCustomerDO customer : customers) { | ||||
|             receiveCustomerLog(customer, user == null ? null : user.getNickname()); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @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) { | ||||
|  | ||||
|     } | ||||
|  | ||||
|     //======================= 查询相关 ======================= | ||||
|  | ||||
|     @Override | ||||
|     @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#id", level = CrmPermissionLevelEnum.READ) | ||||
|     public CrmCustomerDO getCustomer(Long id) { | ||||
| @@ -148,6 +277,8 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | ||||
|         return customerMapper.selectPage(pageReqVO, userId); | ||||
|     } | ||||
|  | ||||
|     //======================= 校验相关 ======================= | ||||
|  | ||||
|     /** | ||||
|      * 校验客户是否存在 | ||||
|      * | ||||
| @@ -158,47 +289,38 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | ||||
|         validateCustomerExists(customerId); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     @Transactional(rollbackFor = Exception.class) | ||||
|     @LogRecord(type = CRM_CUSTOMER, subType = "转移客户", bizNo = "{{#reqVO.id}}", success = TRANSFER_CUSTOMER_LOG_SUCCESS) | ||||
|     @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#reqVO.id", level = CrmPermissionLevelEnum.OWNER) | ||||
|     public void transferCustomer(CrmCustomerTransferReqVO reqVO, Long userId) { | ||||
|         // 1.1 校验客户是否存在 | ||||
|         CrmCustomerDO customer = validateCustomerExists(reqVO.getId()); | ||||
|         // 1.2 校验拥有客户是否到达上限 | ||||
|         validateCustomerExceedOwnerLimit(reqVO.getNewOwnerUserId(), 1); | ||||
|  | ||||
|         // 2.1 数据权限转移 | ||||
|         permissionService.transferPermission( | ||||
|                 CrmCustomerConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType())); | ||||
|         // 2.2 转移后重新设置负责人 | ||||
|         customerMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId()); | ||||
|  | ||||
|         // 3. TODO 记录转移日志 | ||||
|         LogRecordContext.putVariable("crmCustomer", customer); | ||||
|     private void validateCustomerOwnerExists(CrmCustomerDO customer, Boolean pool) { | ||||
|         if (customer == null) { // 防御一下 | ||||
|             throw exception(CUSTOMER_NOT_EXISTS); | ||||
|         } | ||||
|         // 校验是否为公海数据 | ||||
|         if (pool && customer.getOwnerUserId() == null) { | ||||
|             throw exception(CUSTOMER_IN_POOL, customer.getName()); | ||||
|         } | ||||
|         // 负责人已存在 | ||||
|         if (customer.getOwnerUserId() != null) { | ||||
|             throw exception(CUSTOMER_OWNER_EXISTS, customer.getName()); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     // TODO @puhui999:看看这个能不能根据条件,写操作日志; | ||||
|     // TODO 如果是 锁定,则 subType 为 锁定客户;success 为 将客户【】锁定 | ||||
|     // TODO 如果是 解锁,则 subType 为 解锁客户;success 为 将客户【】解锁 | ||||
|     @LogRecord(type = CRM_CUSTOMER, subType = "锁定/解锁客户", bizNo = "{{#updateReqVO.id}}", success = "锁定了客户") | ||||
|     // TODO @puhui999:数据权限 | ||||
|     public void lockCustomer(CrmCustomerLockReqVO lockReqVO, Long userId) { | ||||
|         // 1.1 校验当前客户是否存在 | ||||
|         validateCustomerExists(lockReqVO.getId()); | ||||
|         // 1.2 校验当前是否重复操作锁定/解锁状态 | ||||
|         CrmCustomerDO customer = customerMapper.selectById(lockReqVO.getId()); | ||||
|         if (customer.getLockStatus().equals(lockReqVO.getLockStatus())) { | ||||
|             throw exception(customer.getLockStatus() ? CUSTOMER_LOCK_FAIL_IS_LOCK : CUSTOMER_UNLOCK_FAIL_IS_UNLOCK); | ||||
|         } | ||||
|         // 1.3 校验锁定上限。 | ||||
|         if (lockReqVO.getLockStatus()) { | ||||
|             validateCustomerExceedLockLimit(userId); | ||||
|     private CrmCustomerDO validateCustomerExists(Long id) { | ||||
|         CrmCustomerDO customerDO = customerMapper.selectById(id); | ||||
|         if (customerDO == null) { | ||||
|             throw exception(CUSTOMER_NOT_EXISTS); | ||||
|         } | ||||
|         return customerDO; | ||||
|     } | ||||
|  | ||||
|         // 2. 更新锁定状态 | ||||
|         customerMapper.updateById(BeanUtils.toBean(lockReqVO, CrmCustomerDO.class)); | ||||
|     private void validateCustomerIsLocked(CrmCustomerDO customer, Boolean pool) { | ||||
|         if (customer.getLockStatus()) { | ||||
|             throw exception(pool ? CUSTOMER_LOCKED_PUT_POOL_FAIL : CUSTOMER_LOCKED, customer.getName()); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void validateCustomerDeal(CrmCustomerDO customer) { | ||||
|         if (customer.getDealStatus()) { | ||||
|             throw exception(CUSTOMER_ALREADY_DEAL); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -242,106 +364,4 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     @Transactional(rollbackFor = Exception.class) | ||||
|     @LogRecord(type = CRM_CUSTOMER, subType = "客户放入公海", bizNo = "{{#id}}", success = "将客户放入了公海") | ||||
|     // TODO @puhui999:将客户【】放入了公海 | ||||
|     @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#id", level = CrmPermissionLevelEnum.OWNER) | ||||
|     public void putCustomerPool(Long id) { | ||||
|         // 1. 校验存在 | ||||
|         CrmCustomerDO customer = customerMapper.selectById(id); | ||||
|         if (customer == null) { | ||||
|             throw exception(CUSTOMER_NOT_EXISTS); | ||||
|         } | ||||
|         // 1.2. 校验是否为公海数据 | ||||
|         validateCustomerOwnerExists(customer, true); | ||||
|         // 1.3. 校验客户是否锁定 | ||||
|         validateCustomerIsLocked(customer, true); | ||||
|  | ||||
|         // 2. 设置负责人为 NULL | ||||
|         int updateOwnerUserIncr = customerMapper.updateOwnerUserIdById(customer.getId(), null); | ||||
|         if (updateOwnerUserIncr == 0) { | ||||
|             throw exception(CUSTOMER_UPDATE_OWNER_USER_FAIL); | ||||
|         } | ||||
|         // 3. 删除负责人数据权限 | ||||
|         permissionService.deletePermission(CrmBizTypeEnum.CRM_CUSTOMER.getType(), customer.getId(), | ||||
|                 CrmPermissionLevelEnum.OWNER.getLevel()); | ||||
|         // TODO @puhui999:联系人的负责人,也要设置为 null;这块和领取是对应的;因为领取后,负责人也要关联过来; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     @Transactional(rollbackFor = Exception.class) | ||||
|     // TODO @puhui999:权限校验 | ||||
|  | ||||
|     // TODO @puhui999:如果是分配,操作日志是 “将客户【】分配给【】” | ||||
|     // TODO @puhui999:如果是领取,操作日志是“领取客户【】”; | ||||
|     // TODO @puhui999:如果是多条,则需要记录多条操作日志;不然 bizId 不好关联 | ||||
|     public void receiveCustomer(List<Long> ids, Long ownerUserId) { | ||||
|         // 1.1 校验存在 | ||||
|         List<CrmCustomerDO> customers = customerMapper.selectBatchIds(ids); | ||||
|         if (customers.size() != ids.size()) { | ||||
|             throw exception(CUSTOMER_NOT_EXISTS); | ||||
|         } | ||||
|         // 1.2. 校验负责人是否存在 | ||||
|         adminUserApi.validateUserList(singletonList(ownerUserId)); | ||||
|         // 1.3. 校验状态 | ||||
|         customers.forEach(customer -> { | ||||
|             // 校验是否已有负责人 | ||||
|             validateCustomerOwnerExists(customer, false); | ||||
|             // 校验是否锁定 | ||||
|             validateCustomerIsLocked(customer, false); | ||||
|             // 校验成交状态 | ||||
|             validateCustomerDeal(customer); | ||||
|         }); | ||||
|         // 1.4  校验负责人是否到达上限 | ||||
|         validateCustomerExceedOwnerLimit(ownerUserId, customers.size()); | ||||
|  | ||||
|         // 2.1 领取公海数据 | ||||
|         List<CrmCustomerDO> updateCustomers = new ArrayList<>(); | ||||
|         List<CrmPermissionCreateReqBO> createPermissions = new ArrayList<>(); | ||||
|         customers.forEach(customer -> { | ||||
|             // 2.1. 设置负责人 | ||||
|             updateCustomers.add(new CrmCustomerDO().setId(customer.getId()).setOwnerUserId(ownerUserId)); | ||||
|             // 2.2. 创建负责人数据权限 | ||||
|             createPermissions.add(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType()) | ||||
|                     .setBizId(customer.getId()).setUserId(ownerUserId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); | ||||
|         }); | ||||
|         // 2.2 更新客户负责人 | ||||
|         customerMapper.updateBatch(updateCustomers); | ||||
|         // 2.3 创建负责人数据权限 | ||||
|         permissionService.createPermissionBatch(createPermissions); | ||||
|         // TODO @芋艿:要不要处理关联的联系人??? | ||||
|     } | ||||
|  | ||||
|     private void validateCustomerOwnerExists(CrmCustomerDO customer, Boolean pool) { | ||||
|         if (customer == null) { // 防御一下 | ||||
|             throw exception(CUSTOMER_NOT_EXISTS); | ||||
|         } | ||||
|         // 校验是否为公海数据 | ||||
|         if (pool && customer.getOwnerUserId() == null) { | ||||
|             throw exception(CUSTOMER_IN_POOL, customer.getName()); | ||||
|         } | ||||
|         // 负责人已存在 | ||||
|         if (customer.getOwnerUserId() != null) { | ||||
|             throw exception(CUSTOMER_OWNER_EXISTS, customer.getName()); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void validateCustomerIsLocked(CrmCustomerDO customer, Boolean pool) { | ||||
|         if (customer.getLockStatus()) { | ||||
|             throw exception(pool ? CUSTOMER_LOCKED_PUT_POOL_FAIL : CUSTOMER_LOCKED, customer.getName()); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void validateCustomerDeal(CrmCustomerDO customer) { | ||||
|         if (customer.getDealStatus()) { | ||||
|             throw exception(CUSTOMER_ALREADY_DEAL); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public List<CrmCustomerDO> getCustomerList() { | ||||
|         return customerMapper.selectList(); | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -90,6 +90,15 @@ public interface CrmPermissionService { | ||||
|      */ | ||||
|     List<CrmPermissionDO> getPermissionListByBiz(Integer bizType, Long bizId); | ||||
|  | ||||
|     /** | ||||
|      * 获取数据权限列表,通过 数据类型 x 某个数据 | ||||
|      * | ||||
|      * @param bizType 数据类型,关联 {@link CrmBizTypeEnum} | ||||
|      * @param bizIds  数据编号,关联 {@link CrmBizTypeEnum} 对应模块 DO#getId() | ||||
|      * @return Crm 数据权限列表 | ||||
|      */ | ||||
|     List<CrmPermissionDO> getPermissionListByBiz(Integer bizType, Collection<Long> bizIds); | ||||
|  | ||||
|     /** | ||||
|      * 获取用户参与的模块数据列表 | ||||
|      * | ||||
|   | ||||
| @@ -187,6 +187,11 @@ public class CrmPermissionServiceImpl implements CrmPermissionService { | ||||
|         return crmPermissionMapper.selectByBizTypeAndBizId(bizType, bizId); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public List<CrmPermissionDO> getPermissionListByBiz(Integer bizType, Collection<Long> bizIds) { | ||||
|         return crmPermissionMapper.selectByBizTypeAndBizIds(bizType, bizIds); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public List<CrmPermissionDO> getPermissionListByBizTypeAndUserId(Integer bizType, Long userId) { | ||||
|         return crmPermissionMapper.selectListByBizTypeAndUserId(bizType, userId); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 puhui999
					puhui999