mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-10-31 10:18:42 +08:00 
			
		
		
		
	CRM-客户:完善操作日志
This commit is contained in:
		| @@ -40,7 +40,7 @@ public interface ErrorCodeConstants { | |||||||
|     ErrorCode CUSTOMER_LOCKED_PUT_POOL_FAIL = new ErrorCode(1_020_006_005, "客户【{}】放入公海失败,原因:客户已锁定"); |     ErrorCode CUSTOMER_LOCKED_PUT_POOL_FAIL = new ErrorCode(1_020_006_005, "客户【{}】放入公海失败,原因:客户已锁定"); | ||||||
|     ErrorCode CUSTOMER_UPDATE_OWNER_USER_FAIL = new ErrorCode(1_020_006_006, "更新客户【{}】负责人失败, 原因:系统异常"); |     ErrorCode CUSTOMER_UPDATE_OWNER_USER_FAIL = new ErrorCode(1_020_006_006, "更新客户【{}】负责人失败, 原因:系统异常"); | ||||||
|     ErrorCode CUSTOMER_LOCK_FAIL_IS_LOCK = new ErrorCode(1_020_006_007, "锁定客户失败,它已经处于锁定状态"); |     ErrorCode CUSTOMER_LOCK_FAIL_IS_LOCK = new ErrorCode(1_020_006_007, "锁定客户失败,它已经处于锁定状态"); | ||||||
|     ErrorCode CUSTOMER_UNLOCK_FAIL_IS_UNLOCK = new ErrorCode(1_020_006_008, "锁定客户失败,它已经处于未锁定状态"); |     ErrorCode CUSTOMER_UNLOCK_FAIL_IS_UNLOCK = new ErrorCode(1_020_006_008, "解锁客户失败,它已经处于未锁定状态"); | ||||||
|     ErrorCode CUSTOMER_LOCK_EXCEED_LIMIT = new ErrorCode(1_020_006_009, "锁定客户失败,超出锁定规则上限"); |     ErrorCode CUSTOMER_LOCK_EXCEED_LIMIT = new ErrorCode(1_020_006_009, "锁定客户失败,超出锁定规则上限"); | ||||||
|     ErrorCode CUSTOMER_OWNER_EXCEED_LIMIT = new ErrorCode(1_020_006_010, "操作失败,超出客户数拥有上限"); |     ErrorCode CUSTOMER_OWNER_EXCEED_LIMIT = new ErrorCode(1_020_006_010, "操作失败,超出客户数拥有上限"); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -2,32 +2,56 @@ package cn.iocoder.yudao.module.crm.enums; | |||||||
|  |  | ||||||
| /** | /** | ||||||
|  * CRM 操作日志枚举 |  * CRM 操作日志枚举 | ||||||
|  |  * 目的:统一管理,也减少 Service 里各种“复杂”字符串 | ||||||
|  * |  * | ||||||
|  * @author HUIHUI |  * @author HUIHUI | ||||||
|  */ |  */ | ||||||
| public interface LogRecordConstants { | public interface LogRecordConstants { | ||||||
|  |  | ||||||
|     //======================= 客户模块类型 ======================= |     // ======================= CRM_LEADS 线索 ======================= | ||||||
|     // TODO puhui999: 确保模块命名方式为 module + 子模块名称的方式。统一定义模块名称是为了方便查询各自记录的操作日志,列如说:查询客户【张三的操作日志】就可以 module + bizId |  | ||||||
|     String CRM_LEADS = "CRM 线索"; |  | ||||||
|     String CRM_CUSTOMER = "CRM 客户"; |  | ||||||
|     String CRM_CONTACT = "CRM 联系人"; |  | ||||||
|     String CRM_BUSINESS = "CRM 商机"; |  | ||||||
|     String CRM_CONTRACT = "CRM 合同"; |  | ||||||
|     String CRM_PRODUCT = "CRM 产品"; |  | ||||||
|     String CRM_RECEIVABLE = "CRM 回款"; |  | ||||||
|     String CRM_RECEIVABLE_PLAN = "CRM 回款计划"; |  | ||||||
|  |  | ||||||
|     //======================= 客户转移操作日志 ======================= |     String CRM_LEADS_TYPE = "CRM 线索"; | ||||||
|  |  | ||||||
|     String TRANSFER_CUSTOMER_LOG_SUCCESS = "把客户【{{#crmCustomer.name}}】的负责人从【{getAdminUserById{#crmCustomer.ownerUserId}}】变更为了【{getAdminUserById{#reqVO.newOwnerUserId}}】"; |     // ======================= CRM_CUSTOMER 客户 ======================= | ||||||
|  |  | ||||||
|     // TODO @puhui999:这里格式是不是可以这样;目的是:统一管理,也减少 Service 里各种“复杂”字符串 |     String CRM_CUSTOMER_TYPE = "CRM 客户"; | ||||||
|     // ======================= Customer 客户 ======================= |     String CRM_CUSTOMER_CREATE_SUB_TYPE = "创建客户"; | ||||||
|     String CUSTOMER_TYPE = "CRM 客户"; |     String CRM_CUSTOMER_CREATE_SUCCESS = "创建了客户{{#customer.name}}"; | ||||||
|     String CUSTOMER_CREATE_SUB_TYPE = "创建客户"; |     String CRM_CUSTOMER_UPDATE_SUB_TYPE = "更新客户"; | ||||||
|     String CUSTOMER_CREATE_SUCCESS = "更新了客户{_DIFF{#updateReqVO}}"; |     String CRM_CUSTOMER_UPDATE_SUCCESS = "更新了客户【{{#customerName}}】{_DIFF{#updateReqVO}}"; | ||||||
|  |     String CRM_CUSTOMER_DELETE_SUB_TYPE = "删除客户"; | ||||||
|  |     String CRM_CUSTOMER_DELETE_SUCCESS = "删除了客户【{{#customerName}}】"; | ||||||
|  |     String CRM_CUSTOMER_TRANSFER_SUB_TYPE = "转移客户"; | ||||||
|  |     String CRM_CUSTOMER_TRANSFER_SUCCESS = "将客户【{{#crmCustomer.name}}】的负责人从【{getAdminUserById{#crmCustomer.ownerUserId}}】变更为了【{getAdminUserById{#reqVO.newOwnerUserId}}】"; | ||||||
|  |     String CRM_CUSTOMER_LOCK_SUB_TYPE = "{{#crmCustomer.lockStatus ? '锁定客户' : '解锁客户'}}"; | ||||||
|  |     String CRM_CUSTOMER_LOCK_SUCCESS = "{{#crmCustomer.lockStatus ? '将客户【#crmCustomer.name】锁定' : '将客户【#crmCustomer.name】解锁'}}"; | ||||||
|  |     String CRM_CUSTOMER_POOL_SUB_TYPE = "客户放入公海"; | ||||||
|  |     String CRM_CUSTOMER_POOL_SUCCESS = "将客户【{{#customerName}}】放入了公海"; | ||||||
|  |     String CRM_CUSTOMER_RECEIVE_SUB_TYPE = "{{#ownerUserName != null ? '分配客户' : '领取客户'}}"; | ||||||
|  |     String CRM_CUSTOMER_RECEIVE_SUCCESS = "{{#ownerUserName != null ? '将客户【#customer.name】分配给【#ownerUserName】' : '领取客户【#customer.name】'}}"; | ||||||
|  |  | ||||||
|     String CUSTOMER_UPDATE_SUB_TYPE = "更新客户"; |     // ======================= CRM_CONTACT 联系人 ======================= | ||||||
|  |  | ||||||
|  |     String CRM_CONTACT_TYPE = "CRM 联系人"; | ||||||
|  |  | ||||||
|  |     // ======================= CRM_BUSINESS 商机 ======================= | ||||||
|  |  | ||||||
|  |     String CRM_BUSINESS_TYPE = "CRM 商机"; | ||||||
|  |  | ||||||
|  |     // ======================= CRM_CONTRACT 合同 ======================= | ||||||
|  |  | ||||||
|  |     String CRM_CONTRACT_TYPE = "CRM 合同"; | ||||||
|  |  | ||||||
|  |     // ======================= CRM_PRODUCT 产品 ======================= | ||||||
|  |  | ||||||
|  |     String CRM_PRODUCT_TYPE = "CRM 产品"; | ||||||
|  |  | ||||||
|  |     // ======================= CRM_RECEIVABLE 回款 ======================= | ||||||
|  |  | ||||||
|  |     String CRM_RECEIVABLE_TYPE = "CRM 回款"; | ||||||
|  |  | ||||||
|  |     // ======================= CRM_RECEIVABLE_PLAN 回款计划 ======================= | ||||||
|  |  | ||||||
|  |     String CRM_RECEIVABLE_PLAN_TYPE = "CRM 回款计划"; | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.crm.controller.admin.customer; | |||||||
| import cn.hutool.core.collection.CollUtil; | import cn.hutool.core.collection.CollUtil; | ||||||
| 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.framework.common.util.object.BeanUtils; | ||||||
| import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; | import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; | ||||||
| import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; | import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; | ||||||
| import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.*; | 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.common.util.collection.CollectionUtils.convertSetByFlatMap; | ||||||
| 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_CUSTOMER; | import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.CRM_CUSTOMER_TYPE; | ||||||
|  |  | ||||||
| @Tag(name = "管理后台 - CRM 客户") | @Tag(name = "管理后台 - CRM 客户") | ||||||
| @RestController | @RestController | ||||||
| @@ -115,6 +116,15 @@ public class CrmCustomerController { | |||||||
|         return success(CrmCustomerConvert.INSTANCE.convertPage(pageResult, userMap, deptMap)); |         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") |     @GetMapping("/export-excel") | ||||||
|     @Operation(summary = "导出客户 Excel") |     @Operation(summary = "导出客户 Excel") | ||||||
|     @PreAuthorize("@ss.hasPermission('crm:customer:export')") |     @PreAuthorize("@ss.hasPermission('crm:customer:export')") | ||||||
| @@ -143,7 +153,7 @@ public class CrmCustomerController { | |||||||
|     public CommonResult<PageResult<OperateLogV2RespDTO>> getCustomerOperateLog(@RequestParam("id") Long id) { |     public CommonResult<PageResult<OperateLogV2RespDTO>> getCustomerOperateLog(@RequestParam("id") Long id) { | ||||||
|         OperateLogV2PageReqDTO reqDTO = new OperateLogV2PageReqDTO(); |         OperateLogV2PageReqDTO reqDTO = new OperateLogV2PageReqDTO(); | ||||||
|         reqDTO.setPageSize(PAGE_SIZE_NONE); // 不分页 |         reqDTO.setPageSize(PAGE_SIZE_NONE); // 不分页 | ||||||
|         reqDTO.setBizType(CRM_CUSTOMER); |         reqDTO.setBizType(CRM_CUSTOMER_TYPE); | ||||||
|         reqDTO.setBizId(id); |         reqDTO.setBizId(id); | ||||||
|         return success(operateLogApi.getOperateLogPage(reqDTO)); |         return success(operateLogApi.getOperateLogPage(reqDTO)); | ||||||
|     } |     } | ||||||
| @@ -172,7 +182,7 @@ public class CrmCustomerController { | |||||||
|     @Parameter(name = "ids", description = "编号数组", required = true, example = "1,2,3") |     @Parameter(name = "ids", description = "编号数组", required = true, example = "1,2,3") | ||||||
|     @PreAuthorize("@ss.hasPermission('crm:customer:receive')") |     @PreAuthorize("@ss.hasPermission('crm:customer:receive')") | ||||||
|     public CommonResult<Boolean> receiveCustomer(@RequestParam(value = "ids") List<Long> ids) { |     public CommonResult<Boolean> receiveCustomer(@RequestParam(value = "ids") List<Long> ids) { | ||||||
|         customerService.receiveCustomer(ids, getLoginUserId()); |         customerService.receiveCustomer(ids, getLoginUserId(), Boolean.TRUE); | ||||||
|         return success(true); |         return success(true); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -180,18 +190,8 @@ public class CrmCustomerController { | |||||||
|     @Operation(summary = "分配公海给对应负责人") |     @Operation(summary = "分配公海给对应负责人") | ||||||
|     @PreAuthorize("@ss.hasPermission('crm:customer:distribute')") |     @PreAuthorize("@ss.hasPermission('crm:customer:distribute')") | ||||||
|     public CommonResult<Boolean> distributeCustomer(@Valid @RequestBody CrmCustomerDistributeReqVO distributeReqVO) { |     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); |         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 cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO; | ||||||
| import org.apache.ibatis.annotations.Mapper; | import org.apache.ibatis.annotations.Mapper; | ||||||
|  |  | ||||||
|  | import java.util.Collection; | ||||||
| import java.util.List; | import java.util.List; | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @@ -28,6 +29,12 @@ public interface CrmPermissionMapper extends BaseMapperX<CrmPermissionDO> { | |||||||
|                 .eq(CrmPermissionDO::getBizId, bizId)); |                 .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) { |     default List<CrmPermissionDO> selectListByBizTypeAndUserId(Integer bizType, Long userId) { | ||||||
|         return selectList(new LambdaQueryWrapperX<CrmPermissionDO>() |         return selectList(new LambdaQueryWrapperX<CrmPermissionDO>() | ||||||
|                 .eq(CrmPermissionDO::getBizType, bizType) |                 .eq(CrmPermissionDO::getBizType, bizType) | ||||||
|   | |||||||
| @@ -18,12 +18,10 @@ import org.aspectj.lang.annotation.Aspect; | |||||||
| import org.aspectj.lang.annotation.Before; | import org.aspectj.lang.annotation.Before; | ||||||
| import org.springframework.stereotype.Component; | import org.springframework.stereotype.Component; | ||||||
|  |  | ||||||
| import java.util.ArrayList; | import java.util.*; | ||||||
| import java.util.List; |  | ||||||
| import java.util.Map; |  | ||||||
|  |  | ||||||
| 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.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.framework.common.util.json.JsonUtils.toJsonString; | ||||||
| import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CRM_PERMISSION_DENIED; | 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); |         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()); // 模块类型 | ||||||
|         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(); // 需要的权限级别 |         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()) { |         if (CrmPermissionUtils.isCrmAdmin()) { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|         // 1.2 获取数据权限 |         // 1.1 没有数据权限的情况 | ||||||
|         List<CrmPermissionDO> bizPermissions = crmPermissionService.getPermissionListByBiz(bizType, bizId); |         if (CollUtil.isEmpty(bizPermissions)) { | ||||||
|         if (CollUtil.isEmpty(bizPermissions)) { // 没有数据权限的情况 |  | ||||||
|             // 公海数据如果没有团队成员大家也因该有读权限才对 |             // 公海数据如果没有团队成员大家也因该有读权限才对 | ||||||
|             if (CrmPermissionLevelEnum.isRead(permissionLevel)) { |             if (CrmPermissionLevelEnum.isRead(permissionLevel)) { | ||||||
|                 return; |                 return; | ||||||
| @@ -63,7 +74,7 @@ public class CrmPermissionAspect { | |||||||
|  |  | ||||||
|             // 没有数据权限的情况下超出了读权限直接报错,避免后面校验空指针 |             // 没有数据权限的情况下超出了读权限直接报错,避免后面校验空指针 | ||||||
|             throw exception(CRM_PERMISSION_DENIED, CrmBizTypeEnum.getNameByType(bizType)); |             throw exception(CRM_PERMISSION_DENIED, CrmBizTypeEnum.getNameByType(bizType)); | ||||||
|         } else { // 有数据权限但是没有负责人的情况 |         } else { // 1.2 有数据权限但是没有负责人的情况 | ||||||
|             if (!anyMatch(bizPermissions, item -> CrmPermissionLevelEnum.isOwner(item.getLevel()))) { |             if (!anyMatch(bizPermissions, item -> CrmPermissionLevelEnum.isOwner(item.getLevel()))) { | ||||||
|                 if (CrmPermissionLevelEnum.isRead(permissionLevel)) { |                 if (CrmPermissionLevelEnum.isRead(permissionLevel)) { | ||||||
|                     return; |                     return; | ||||||
|   | |||||||
| @@ -86,7 +86,7 @@ public interface CrmCustomerService { | |||||||
|      * 锁定/解锁客户 |      * 锁定/解锁客户 | ||||||
|      * |      * | ||||||
|      * @param lockReqVO 更新信息 |      * @param lockReqVO 更新信息 | ||||||
|      * @param userId 用户编号 |      * @param userId    用户编号 | ||||||
|      */ |      */ | ||||||
|     void lockCustomer(@Valid CrmCustomerLockReqVO lockReqVO, Long userId); |     void lockCustomer(@Valid CrmCustomerLockReqVO lockReqVO, Long userId); | ||||||
|  |  | ||||||
| @@ -104,15 +104,8 @@ public interface CrmCustomerService { | |||||||
|      * |      * | ||||||
|      * @param ids         要领取的客户编号数组 |      * @param ids         要领取的客户编号数组 | ||||||
|      * @param ownerUserId 负责人 |      * @param ownerUserId 负责人 | ||||||
|  |      * @param isReceive   是/否领取 | ||||||
|      */ |      */ | ||||||
|     void receiveCustomer(List<Long> ids, Long ownerUserId); |     void receiveCustomer(List<Long> ids, Long ownerUserId, Boolean isReceive); | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 获取客户列表 |  | ||||||
|      * |  | ||||||
|      * @return 客户列表 |  | ||||||
|      * @author zyna |  | ||||||
|      */ |  | ||||||
|     List<CrmCustomerDO> getCustomerList(); |  | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -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.common.CrmBizTypeEnum; | ||||||
| import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; | 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.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.CrmPermissionService; | ||||||
| import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; | 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.AdminUserApi; | ||||||
|  | import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; | ||||||
| import com.mzt.logapi.context.LogRecordContext; | import com.mzt.logapi.context.LogRecordContext; | ||||||
| import com.mzt.logapi.service.impl.DiffParseFunction; | import com.mzt.logapi.service.impl.DiffParseFunction; | ||||||
| import com.mzt.logapi.starter.annotation.LogRecord; | 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.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_CUSTOMER; | import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*; | ||||||
| import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.TRANSFER_CUSTOMER_LOG_SUCCESS; |  | ||||||
| import static cn.iocoder.yudao.module.crm.enums.customer.CrmCustomerLimitConfigTypeEnum.CUSTOMER_LOCK_LIMIT; | 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 cn.iocoder.yudao.module.crm.enums.customer.CrmCustomerLimitConfigTypeEnum.CUSTOMER_OWNER_LIMIT; | ||||||
| import static java.util.Collections.singletonList; | import static java.util.Collections.singletonList; | ||||||
| @@ -63,8 +64,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | |||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     @Transactional(rollbackFor = Exception.class) |     @Transactional(rollbackFor = Exception.class) | ||||||
|     @LogRecord(type = CRM_CUSTOMER, subType = "创建客户", bizNo = "{{#customerId}}", success = "创建了客户") |     @LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_CREATE_SUB_TYPE, bizNo = "{{#customer.id}}", success = CRM_CUSTOMER_CREATE_SUCCESS) | ||||||
|     // TODO @puhui999:创建了客户【客户名】,要记录进去;不然在展示操作日志的全列表,看不清楚是哪个客户哈; |  | ||||||
|     public Long createCustomer(CrmCustomerSaveReqVO createReqVO, Long userId) { |     public Long createCustomer(CrmCustomerSaveReqVO createReqVO, Long userId) { | ||||||
|         createReqVO.setId(null); |         createReqVO.setId(null); | ||||||
|         // 1. 校验拥有客户是否到达上限 |         // 1. 校验拥有客户是否到达上限 | ||||||
| @@ -81,14 +81,14 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | |||||||
|         permissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType()) |         permissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType()) | ||||||
|                 .setBizId(customer.getId()).setUserId(userId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); // 设置当前操作的人为负责人 |                 .setBizId(customer.getId()).setUserId(userId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); // 设置当前操作的人为负责人 | ||||||
|  |  | ||||||
|         // 4. 记录操作日志 |         // 4. 记录操作日志上下文 | ||||||
|         LogRecordContext.putVariable("customerId", customer.getId()); |         LogRecordContext.putVariable("customer", customer); | ||||||
|         return customer.getId(); |         return customer.getId(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     @Transactional(rollbackFor = Exception.class) |     @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) |     @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(), "客户编号不能为空"); | ||||||
| @@ -101,17 +101,18 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | |||||||
|         CrmCustomerDO updateObj = CrmCustomerConvert.INSTANCE.convert(updateReqVO); |         CrmCustomerDO updateObj = CrmCustomerConvert.INSTANCE.convert(updateReqVO); | ||||||
|         customerMapper.updateById(updateObj); |         customerMapper.updateById(updateObj); | ||||||
|  |  | ||||||
|         // 3. 记录操作日志 |         // 3. 记录操作日志上下文 | ||||||
|         LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldCustomer, CrmCustomerSaveReqVO.class)); |         LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldCustomer, CrmCustomerSaveReqVO.class)); | ||||||
|  |         LogRecordContext.putVariable("customerName", oldCustomer.getName()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     @Transactional(rollbackFor = Exception.class) |     @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) |     @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#id", level = CrmPermissionLevelEnum.OWNER) | ||||||
|     public void deleteCustomer(Long id) { |     public void deleteCustomer(Long id) { | ||||||
|         // 校验存在 |         // 校验存在 | ||||||
|         validateCustomerExists(id); |         CrmCustomerDO customer = validateCustomerExists(id); | ||||||
|         // TODO @puhui999:如果有联系人、商机,则不允许删除; |         // TODO @puhui999:如果有联系人、商机,则不允许删除; | ||||||
|  |  | ||||||
|         // 删除 |         // 删除 | ||||||
| @@ -119,16 +120,144 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | |||||||
|         // 删除数据权限 |         // 删除数据权限 | ||||||
|         permissionService.deletePermission(CrmBizTypeEnum.CRM_CUSTOMER.getType(), id); |         permissionService.deletePermission(CrmBizTypeEnum.CRM_CUSTOMER.getType(), id); | ||||||
|         // TODO @puhui999:删除跟进记录 |         // TODO @puhui999:删除跟进记录 | ||||||
|  |  | ||||||
|  |         // 记录操作日志上下文 | ||||||
|  |         LogRecordContext.putVariable("customerName", customer.getName()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private CrmCustomerDO validateCustomerExists(Long id) { |     @Override | ||||||
|         CrmCustomerDO customerDO = customerMapper.selectById(id); |     @Transactional(rollbackFor = Exception.class) | ||||||
|         if (customerDO == null) { |     @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); |             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 |     @Override | ||||||
|     @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#id", level = CrmPermissionLevelEnum.READ) |     @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#id", level = CrmPermissionLevelEnum.READ) | ||||||
|     public CrmCustomerDO getCustomer(Long id) { |     public CrmCustomerDO getCustomer(Long id) { | ||||||
| @@ -148,6 +277,8 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | |||||||
|         return customerMapper.selectPage(pageReqVO, userId); |         return customerMapper.selectPage(pageReqVO, userId); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     //======================= 校验相关 ======================= | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * 校验客户是否存在 |      * 校验客户是否存在 | ||||||
|      * |      * | ||||||
| @@ -158,47 +289,38 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | |||||||
|         validateCustomerExists(customerId); |         validateCustomerExists(customerId); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     private void validateCustomerOwnerExists(CrmCustomerDO customer, Boolean pool) { | ||||||
|     @Transactional(rollbackFor = Exception.class) |         if (customer == null) { // 防御一下 | ||||||
|     @LogRecord(type = CRM_CUSTOMER, subType = "转移客户", bizNo = "{{#reqVO.id}}", success = TRANSFER_CUSTOMER_LOG_SUCCESS) |             throw exception(CUSTOMER_NOT_EXISTS); | ||||||
|     @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#reqVO.id", level = CrmPermissionLevelEnum.OWNER) |         } | ||||||
|     public void transferCustomer(CrmCustomerTransferReqVO reqVO, Long userId) { |         // 校验是否为公海数据 | ||||||
|         // 1.1 校验客户是否存在 |         if (pool && customer.getOwnerUserId() == null) { | ||||||
|         CrmCustomerDO customer = validateCustomerExists(reqVO.getId()); |             throw exception(CUSTOMER_IN_POOL, customer.getName()); | ||||||
|         // 1.2 校验拥有客户是否到达上限 |         } | ||||||
|         validateCustomerExceedOwnerLimit(reqVO.getNewOwnerUserId(), 1); |         // 负责人已存在 | ||||||
|  |         if (customer.getOwnerUserId() != null) { | ||||||
|         // 2.1 数据权限转移 |             throw exception(CUSTOMER_OWNER_EXISTS, customer.getName()); | ||||||
|         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 |     private CrmCustomerDO validateCustomerExists(Long id) { | ||||||
|     // TODO @puhui999:看看这个能不能根据条件,写操作日志; |         CrmCustomerDO customerDO = customerMapper.selectById(id); | ||||||
|     // TODO 如果是 锁定,则 subType 为 锁定客户;success 为 将客户【】锁定 |         if (customerDO == null) { | ||||||
|     // TODO 如果是 解锁,则 subType 为 解锁客户;success 为 将客户【】解锁 |             throw exception(CUSTOMER_NOT_EXISTS); | ||||||
|     @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); |  | ||||||
|         } |         } | ||||||
|  |         return customerDO; | ||||||
|  |     } | ||||||
|  |  | ||||||
|         // 2. 更新锁定状态 |     private void validateCustomerIsLocked(CrmCustomerDO customer, Boolean pool) { | ||||||
|         customerMapper.updateById(BeanUtils.toBean(lockReqVO, CrmCustomerDO.class)); |         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); |     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); |         return crmPermissionMapper.selectByBizTypeAndBizId(bizType, bizId); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public List<CrmPermissionDO> getPermissionListByBiz(Integer bizType, Collection<Long> bizIds) { | ||||||
|  |         return crmPermissionMapper.selectByBizTypeAndBizIds(bizType, bizIds); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public List<CrmPermissionDO> getPermissionListByBizTypeAndUserId(Integer bizType, Long userId) { |     public List<CrmPermissionDO> getPermissionListByBizTypeAndUserId(Integer bizType, Long userId) { | ||||||
|         return crmPermissionMapper.selectListByBizTypeAndUserId(bizType, userId); |         return crmPermissionMapper.selectListByBizTypeAndUserId(bizType, userId); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 puhui999
					puhui999