Commit d0df0e8e161ec9df00db23916181465daca83a25

Authored by YunaiV
1 parent 0253846f

📖 CRM:【客户】优化锁定客户的逻辑实现

Showing 12 changed files with 128 additions and 103 deletions
yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/ErrorCodeConstants.java
... ... @@ -39,12 +39,10 @@ public interface ErrorCodeConstants {
39 39 ErrorCode CUSTOMER_IN_POOL = new ErrorCode(1_020_006_004, "客户【{}】放入公海失败,原因:已经是公海客户");
40 40 ErrorCode CUSTOMER_LOCKED_PUT_POOL_FAIL = new ErrorCode(1_020_006_005, "客户【{}】放入公海失败,原因:客户已锁定");
41 41 ErrorCode CUSTOMER_UPDATE_OWNER_USER_FAIL = new ErrorCode(1_020_006_006, "更新客户【{}】负责人失败, 原因:系统异常");
42   -
43   - ErrorCode CUSTOMER_UNLOCK_STATUS_NO_REPETITION = new ErrorCode(1_020_006_001, "无需重复操作锁定/解锁状态");
44   -
45   - ErrorCode CUSTOMER_NO_DEPARTMENT_FOUND = new ErrorCode(1_020_006_002, "操作失败,请先绑定部门再进行操作");
46   -
47   - ErrorCode CUSTOMER_EXCEED_LOCK_LIMIT = new ErrorCode(1_020_006_003, "操作失败,超出锁定规则上限");
  42 + ErrorCode CUSTOMER_LOCK_FAIL_IS_LOCK = new ErrorCode(1_020_006_007, "锁定客户失败,它已经处于锁定状态");
  43 + ErrorCode CUSTOMER_UNLOCK_FAIL_IS_UNLOCK = new ErrorCode(1_020_006_008, "锁定客户失败,它已经处于未锁定状态");
  44 + ErrorCode CUSTOMER_LOCK_EXCEED_LIMIT = new ErrorCode(1_020_006_009, "锁定客户失败,超出锁定规则上限");
  45 + ErrorCode CUSTOMER_OWNER_EXCEED_LIMIT = new ErrorCode(1_020_006_010, "操作失败,超出客户数拥有上限");
48 46  
49 47 // ========== 权限管理 1_020_007_000 ==========
50 48 ErrorCode CRM_PERMISSION_NOT_EXISTS = new ErrorCode(1_020_007_000, "数据权限不存在");
... ...
yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/customer/CrmCustomerLimitConfigTypeEnum.java
... ... @@ -18,19 +18,19 @@ public enum CrmCustomerLimitConfigTypeEnum implements IntArrayValuable {
18 18 /**
19 19 * 拥有客户数限制
20 20 */
21   - CUSTOMER_QUANTITY_LIMIT(1, "拥有客户数限制"),
  21 + CUSTOMER_OWNER_LIMIT(1, "拥有客户数限制"),
22 22 /**
23 23 * 锁定客户数限制
24 24 */
25 25 CUSTOMER_LOCK_LIMIT(2, "锁定客户数限制"),
26 26 ;
27 27  
28   - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CrmCustomerLimitConfigTypeEnum::getCode).toArray();
  28 + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CrmCustomerLimitConfigTypeEnum::getType).toArray();
29 29  
30 30 /**
31 31 * 状态
32 32 */
33   - private final Integer code;
  33 + private final Integer type;
34 34 /**
35 35 * 状态名
36 36 */
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java
... ... @@ -154,13 +154,12 @@ public class CrmCustomerController {
154 154 return success(operateLogApi.getOperateLogPage(BeanUtils.toBean(reqVO, OperateLogV2PageReqDTO.class)));
155 155 }
156 156  
157   - // TODO @Joey:单独建一个属于自己业务的 ReqVO;因为前端如果模拟请求,是不是可以更新其它字段了;
158 157 @PutMapping("/lock")
159 158 @Operation(summary = "锁定/解锁客户")
160 159 @OperateLog(enable = false) // TODO 关闭原有日志记录
161 160 @PreAuthorize("@ss.hasPermission('crm:customer:update')")
162 161 public CommonResult<Boolean> lockCustomer(@Valid @RequestBody CrmCustomerLockReqVO lockReqVO) {
163   - customerService.lockCustomer(lockReqVO);
  162 + customerService.lockCustomer(lockReqVO, getLoginUserId());
164 163 return success(true);
165 164 }
166 165  
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/CrmCustomerLockReqVO.java
... ... @@ -13,6 +13,4 @@ public class CrmCustomerLockReqVO {
13 13 @Schema(description = "客户锁定状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
14 14 private Boolean lockStatus;
15 15  
16   -
17   -
18 16 }
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/limitconfig/CrmCustomerLimitConfigCreateReqVO.java
... ... @@ -5,16 +5,10 @@ import lombok.Data;
5 5 import lombok.EqualsAndHashCode;
6 6 import lombok.ToString;
7 7  
8   -import java.util.List;
9   -
10 8 @Schema(description = "管理后台 - 客户限制配置创建 Request VO")
11 9 @Data
12 10 @EqualsAndHashCode(callSuper = true)
13 11 @ToString(callSuper = true)
14 12 public class CrmCustomerLimitConfigCreateReqVO extends CrmCustomerLimitConfigBaseVO {
15 13  
16   -
17   - @Schema(description = "规则适用人群")
18   - private Long userId;
19   -
20 14 }
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/customer/CrmCustomerConvert.java
... ... @@ -12,7 +12,6 @@ import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
12 12 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
13 13 import org.mapstruct.Mapper;
14 14 import org.mapstruct.Mapping;
15   -import org.mapstruct.Mappings;
16 15 import org.mapstruct.factory.Mappers;
17 16  
18 17 import java.util.List;
... ... @@ -79,6 +78,4 @@ public interface CrmCustomerConvert {
79 78  
80 79 List<CrmCustomerQueryAllRespVO> convertQueryAll(List<CrmCustomerDO> crmCustomerDO);
81 80  
82   - CrmCustomerDO convert(CrmCustomerLockReqVO lockReqVO);
83   -
84 81 }
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/customer/CrmCustomerLimitConfigMapper.java
... ... @@ -3,13 +3,11 @@ package cn.iocoder.yudao.module.crm.dal.mysql.customer;
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
6   -import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.limitconfig.CrmCustomerLimitConfigCreateReqVO;
7 6 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.limitconfig.CrmCustomerLimitConfigPageReqVO;
8 7 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerLimitConfigDO;
9 8 import org.apache.ibatis.annotations.Mapper;
10 9  
11   -import java.util.Arrays;
12   -import java.util.stream.Collectors;
  10 +import java.util.List;
13 11  
14 12 /**
15 13 * 客户限制配置 Mapper
... ... @@ -25,16 +23,15 @@ public interface CrmCustomerLimitConfigMapper extends BaseMapperX&lt;CrmCustomerLim
25 23 .orderByDesc(CrmCustomerLimitConfigDO::getId));
26 24 }
27 25  
28   - default CrmCustomerLimitConfigDO selectByLimitConfig(CrmCustomerLimitConfigCreateReqVO reqVO){
29   - LambdaQueryWrapperX<CrmCustomerLimitConfigDO> queryWrapper = new LambdaQueryWrapperX<>();
30   - queryWrapper.apply("FIND_IN_SET({0}, user_ids) > 0", reqVO.getUserId());
31   - queryWrapper.eq(CrmCustomerLimitConfigDO::getType, reqVO.getType());
32   - // 将部门ID列表转换成逗号分隔的字符串
33   - String deptIdsString = reqVO.getDeptIds().stream()
34   - .map(String::valueOf)
35   - .collect(Collectors.joining(","));
36   - queryWrapper.apply("FIND_IN_SET({0}, dept_ids) > 0", deptIdsString);
37   - return selectOne(queryWrapper);
  26 + default List<CrmCustomerLimitConfigDO> selectListByTypeAndUserIdAndDeptId(
  27 + Integer type, Long userId, Long deptId) {
  28 + LambdaQueryWrapperX<CrmCustomerLimitConfigDO> query = new LambdaQueryWrapperX<CrmCustomerLimitConfigDO>()
  29 + .eq(CrmCustomerLimitConfigDO::getType, type);
  30 + query.apply("FIND_IN_SET({0}, user_ids) > 0", userId);
  31 + if (deptId != null) {
  32 + query.apply("FIND_IN_SET({0}, dept_ids) > 0", deptId);
  33 + }
  34 + return selectList(query);
38 35 }
39 36  
40 37 }
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/customer/CrmCustomerMapper.java
... ... @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.crm.dal.mysql.customer;
2 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  5 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
5 6 import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
6 7 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerPageReqVO;
7 8 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
... ... @@ -9,6 +10,7 @@ import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
9 10 import cn.iocoder.yudao.module.crm.util.CrmQueryWrapperUtils;
10 11 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
11 12 import org.apache.ibatis.annotations.Mapper;
  13 +import org.springframework.lang.Nullable;
12 14  
13 15 import java.util.Collection;
14 16 import java.util.List;
... ... @@ -21,6 +23,18 @@ import java.util.List;
21 23 @Mapper
22 24 public interface CrmCustomerMapper extends BaseMapperX<CrmCustomerDO> {
23 25  
  26 + default Long selectCountByLockStatusAndOwnerUserId(Boolean lockStatus, Long ownerUserId) {
  27 + return selectCount(new LambdaUpdateWrapper<CrmCustomerDO>()
  28 + .eq(CrmCustomerDO::getLockStatus, lockStatus)
  29 + .eq(CrmCustomerDO::getOwnerUserId, ownerUserId));
  30 + }
  31 +
  32 + default Long selectCountByDealStatusAndOwnerUserId(@Nullable Boolean dealStatus, Long ownerUserId) {
  33 + return selectCount(new LambdaQueryWrapperX<CrmCustomerDO>()
  34 + .eqIfPresent(CrmCustomerDO::getDealStatus, dealStatus)
  35 + .eq(CrmCustomerDO::getOwnerUserId, ownerUserId));
  36 + }
  37 +
24 38 default int updateOwnerUserIdById(Long id, Long ownerUserId) {
25 39 return update(new LambdaUpdateWrapper<CrmCustomerDO>()
26 40 .eq(CrmCustomerDO::getId, id)
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerLimitConfigService.java
... ... @@ -5,9 +5,10 @@ import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.limitconfig.CrmC
5 5 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.limitconfig.CrmCustomerLimitConfigPageReqVO;
6 6 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.limitconfig.CrmCustomerLimitConfigUpdateReqVO;
7 7 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerLimitConfigDO;
8   -
9 8 import jakarta.validation.Valid;
10 9  
  10 +import java.util.List;
  11 +
11 12 /**
12 13 * 客户限制配置 Service 接口
13 14 *
... ... @@ -54,8 +55,11 @@ public interface CrmCustomerLimitConfigService {
54 55 PageResult<CrmCustomerLimitConfigDO> getCustomerLimitConfigPage(CrmCustomerLimitConfigPageReqVO pageReqVO);
55 56  
56 57 /**
57   - * 查询当前登录人客户限制配置
  58 + * 查询用户对应的配置列表
  59 + *
  60 + * @param type 类型
  61 + * @param userId 用户类型
58 62 */
59   - CrmCustomerLimitConfigDO selectByLimitConfig(CrmCustomerLimitConfigCreateReqVO configReqVO);
  63 + List<CrmCustomerLimitConfigDO> getCustomerLimitConfigListByUserId(Integer type, Long userId);
60 64  
61 65 }
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerLimitConfigServiceImpl.java
1 1 package cn.iocoder.yudao.module.crm.service.customer;
2 2  
  3 +import cn.hutool.core.lang.Assert;
3 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 5 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.limitconfig.CrmCustomerLimitConfigCreateReqVO;
5 6 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.limitconfig.CrmCustomerLimitConfigPageReqVO;
... ... @@ -9,12 +10,14 @@ import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerLimitConfi
9 10 import cn.iocoder.yudao.module.crm.dal.mysql.customer.CrmCustomerLimitConfigMapper;
10 11 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
11 12 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
  13 +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
12 14 import org.springframework.stereotype.Service;
13 15 import org.springframework.validation.annotation.Validated;
14 16  
15 17 import jakarta.annotation.Resource;
16 18  
17 19 import java.util.Collection;
  20 +import java.util.List;
18 21  
19 22 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
20 23 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CUSTOMER_LIMIT_CONFIG_NOT_EXISTS;
... ... @@ -30,6 +33,7 @@ public class CrmCustomerLimitConfigServiceImpl implements CrmCustomerLimitConfig
30 33  
31 34 @Resource
32 35 private CrmCustomerLimitConfigMapper customerLimitConfigMapper;
  36 +
33 37 @Resource
34 38 private DeptApi deptApi;
35 39 @Resource
... ... @@ -91,8 +95,10 @@ public class CrmCustomerLimitConfigServiceImpl implements CrmCustomerLimitConfig
91 95 }
92 96  
93 97 @Override
94   - public CrmCustomerLimitConfigDO selectByLimitConfig(CrmCustomerLimitConfigCreateReqVO configReqVO) {
95   - return customerLimitConfigMapper.selectByLimitConfig(configReqVO);
  98 + public List<CrmCustomerLimitConfigDO> getCustomerLimitConfigListByUserId(Integer type, Long userId) {
  99 + AdminUserRespDTO user = adminUserApi.getUser(userId);
  100 + Assert.notNull(user, "用户({})不存在", userId);
  101 + return customerLimitConfigMapper.selectListByTypeAndUserIdAndDeptId(type, userId, user.getDeptId());
96 102 }
97 103  
98 104 }
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerService.java
... ... @@ -83,8 +83,9 @@ public interface CrmCustomerService {
83 83 * 锁定/解锁客户
84 84 *
85 85 * @param lockReqVO 更新信息
  86 + * @param userId 用户编号
86 87 */
87   - void lockCustomer(@Valid CrmCustomerLockReqVO lockReqVO);
  88 + void lockCustomer(@Valid CrmCustomerLockReqVO lockReqVO, Long userId);
88 89  
89 90 // ==================== 公海相关操作 ====================
90 91  
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java
... ... @@ -2,13 +2,9 @@ package cn.iocoder.yudao.module.crm.service.customer;
2 2  
3 3 import cn.hutool.core.collection.CollUtil;
4 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
5 6 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
6   -import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerCreateReqVO;
7   -import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerPageReqVO;
8   -import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerTransferReqVO;
9   -import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerUpdateReqVO;
10 7 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.*;
11   -import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.limitconfig.CrmCustomerLimitConfigCreateReqVO;
12 8 import cn.iocoder.yudao.module.crm.convert.customer.CrmCustomerConvert;
13 9 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
14 10 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerLimitConfigDO;
... ... @@ -19,11 +15,9 @@ import cn.iocoder.yudao.module.crm.framework.permission.core.annotations.CrmPerm
19 15 import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService;
20 16 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO;
21 17 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
22   -import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
23 18 import com.mzt.logapi.context.LogRecordContext;
24 19 import com.mzt.logapi.service.impl.DiffParseFunction;
25 20 import com.mzt.logapi.starter.annotation.LogRecord;
26   -import com.mzt.logapi.starter.annotation.LogRecord;
27 21 import jakarta.annotation.Resource;
28 22 import org.springframework.stereotype.Service;
29 23 import org.springframework.transaction.annotation.Transactional;
... ... @@ -33,13 +27,11 @@ import java.time.LocalDateTime;
33 27 import java.util.*;
34 28  
35 29 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
36   -import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
37 30 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*;
38 31 import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.CRM_CUSTOMER;
39 32 import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.TRANSFER_CUSTOMER_LOG_SUCCESS;
40   -import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CUSTOMER_EXCEED_LOCK_LIMIT;
41 33 import static cn.iocoder.yudao.module.crm.enums.customer.CrmCustomerLimitConfigTypeEnum.CUSTOMER_LOCK_LIMIT;
42   -import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.CRM_CUSTOMER;
  34 +import static cn.iocoder.yudao.module.crm.enums.customer.CrmCustomerLimitConfigTypeEnum.CUSTOMER_OWNER_LIMIT;
43 35 import static java.util.Collections.singletonList;
44 36  
45 37 /**
... ... @@ -55,29 +47,32 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
55 47 private CrmCustomerMapper customerMapper;
56 48  
57 49 @Resource
58   - private CrmPermissionService crmPermissionService;
  50 + private CrmPermissionService permissionService;
59 51 @Resource
60   - private CrmCustomerLimitConfigService crmCustomerLimitConfigService;
  52 + private CrmCustomerLimitConfigService customerLimitConfigService;
61 53  
62 54 @Resource
63 55 private AdminUserApi adminUserApi;
64 56  
65 57 @Override
66 58 @Transactional(rollbackFor = Exception.class)
67   - @LogRecord(type = CRM_CUSTOMER, subType = "创建客户", bizNo = "{{#customerId}}", success = "创建了客户") // TODO @puhui999:客户名字,要记录进去;不然在展示操作日志的全列表,看不清楚是哪个客户哈;
  59 + @LogRecord(type = CRM_CUSTOMER, subType = "创建客户", bizNo = "{{#customerId}}", success = "创建了客户") // TODO @puhui999:创建了客户【客户名】,要记录进去;不然在展示操作日志的全列表,看不清楚是哪个客户哈;
68 60 public Long createCustomer(CrmCustomerCreateReqVO createReqVO, Long userId) {
69   - // 插入客户
  61 + // 1. 校验拥有客户是否到达上限
  62 + validateCustomerExceedOwnerLimit(createReqVO.getOwnerUserId(), 1);
  63 +
  64 + // 2. 插入客户
70 65 CrmCustomerDO customer = CrmCustomerConvert.INSTANCE.convert(createReqVO)
71 66 .setLockStatus(false).setDealStatus(false)
72 67 .setContactLastTime(LocalDateTime.now());
73 68 // TODO @puhui999:可能要加个 receiveTime 字段,记录最后接收时间
74 69 customerMapper.insert(customer);
75 70  
76   - // 创建数据权限
77   - crmPermissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType())
  71 + // 3. 创建数据权限
  72 + permissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType())
78 73 .setBizId(customer.getId()).setUserId(userId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); // 设置当前操作的人为负责人
79 74  
80   - // 记录操作日志
  75 + // 4. 记录操作日志
81 76 LogRecordContext.putVariable("customerId", customer.getId());
82 77 return customer.getId();
83 78 }
... ... @@ -88,14 +83,14 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
88 83 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE)
89 84 public void updateCustomer(CrmCustomerUpdateReqVO updateReqVO) {
90 85 // TODO @puhui999:更新的时候,要把 updateReqVO 负责人设置为空,避免修改。
91   - // 校验存在
  86 + // 1. 校验存在
92 87 CrmCustomerDO oldCustomer = validateCustomerExists(updateReqVO.getId());
93 88  
94   - // 更新
  89 + // 2. 更新客户
95 90 CrmCustomerDO updateObj = CrmCustomerConvert.INSTANCE.convert(updateReqVO);
96 91 customerMapper.updateById(updateObj);
97 92  
98   - // 记录操作日志
  93 + // 3. 记录操作日志
99 94 LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldCustomer, CrmCustomerUpdateReqVO.class));
100 95 // TODO 扩展信息测试 @puhui999:看着没啥问题,可以删除啦;
101 96 HashMap<String, Object> extra = new HashMap<>();
... ... @@ -114,7 +109,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
114 109 // 删除
115 110 customerMapper.deleteById(id);
116 111 // 删除数据权限
117   - crmPermissionService.deletePermission(CrmBizTypeEnum.CRM_CUSTOMER.getType(), id);
  112 + permissionService.deletePermission(CrmBizTypeEnum.CRM_CUSTOMER.getType(), id);
118 113 }
119 114  
120 115 private CrmCustomerDO validateCustomerExists(Long id) {
... ... @@ -159,63 +154,83 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
159 154 @LogRecord(type = CRM_CUSTOMER, subType = "客户转移", bizNo = "{{#reqVO.id}}", success = TRANSFER_CUSTOMER_LOG_SUCCESS)
160 155 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#reqVO.id", level = CrmPermissionLevelEnum.OWNER)
161 156 public void transferCustomer(CrmCustomerTransferReqVO reqVO, Long userId) {
162   - // 1. 校验客户是否存在
163   - CrmCustomerDO customerDO = validateCustomerExists(reqVO.getId());
  157 + // 1.1 校验客户是否存在
  158 + CrmCustomerDO customer = validateCustomerExists(reqVO.getId());
  159 + // 1.2 校验拥有客户是否到达上限
  160 + validateCustomerExceedOwnerLimit(reqVO.getNewOwnerUserId(), 1);
164 161  
165 162 // 2.1 数据权限转移
166   - crmPermissionService.transferPermission(
  163 + permissionService.transferPermission(
167 164 CrmCustomerConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType()));
168 165 // 2.2 转移后重新设置负责人
169 166 customerMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId());
170 167  
171 168 // 3. TODO 记录转移日志
172   - LogRecordContext.putVariable("crmCustomer", customerDO);
  169 + LogRecordContext.putVariable("crmCustomer", customer);
173 170 }
174 171  
175 172 @Override
  173 + // TODO @puhui999:看看这个能不能根据条件,写操作日志;
  174 + // TODO 如果是 锁定,则 subType 为 锁定客户;success 为 将客户【】锁定
  175 + // TODO 如果是 解锁,则 subType 为 解锁客户;success 为 将客户【】解锁
176 176 @LogRecord(type = CRM_CUSTOMER, subType = "锁定/解锁客户", bizNo = "{{#updateReqVO.id}}", success = "锁定了客户")
177   - public void lockCustomer(CrmCustomerLockReqVO lockReqVO) {
178   - // 校验当前客户是否存在
  177 + // TODO @puhui999:数据权限
  178 + public void lockCustomer(CrmCustomerLockReqVO lockReqVO, Long userId) {
  179 + // 1.1 校验当前客户是否存在
179 180 validateCustomerExists(lockReqVO.getId());
180   -
181   - CrmCustomerDO customerDO = customerMapper.selectById(lockReqVO.getId());
182   -
183   - // 校验当前是否重复操作锁定/解锁状态
184   - if (customerDO.getLockStatus().equals(lockReqVO.getLockStatus())) {
185   - throw exception(CUSTOMER_UNLOCK_STATUS_NO_REPETITION);
  181 + // 1.2 校验当前是否重复操作锁定/解锁状态
  182 + CrmCustomerDO customer = customerMapper.selectById(lockReqVO.getId());
  183 + if (customer.getLockStatus().equals(lockReqVO.getLockStatus())) {
  184 + throw exception(customer.getLockStatus() ? CUSTOMER_LOCK_FAIL_IS_LOCK : CUSTOMER_UNLOCK_FAIL_IS_UNLOCK);
186 185 }
187   -
188   - // 获取当前登录信息,开始校验锁定上限
189   - AdminUserRespDTO userRespDTO = adminUserApi.getUser(getLoginUserId());
190   -
191   - if (userRespDTO.getDeptId() == null || userRespDTO.getId() == null) {
192   - // 如有入参为空,提示业务异常
193   - throw exception(CUSTOMER_NO_DEPARTMENT_FOUND);
  186 + // 1.3 校验锁定上限。
  187 + if (lockReqVO.getLockStatus()) {
  188 + validateCustomerExceedLockLimit(userId);
194 189 }
195 190  
196   - // 开始校验规则限制
197   - List<Long> userDeptIds = Collections.singletonList(userRespDTO.getDeptId());
198   -
199   - CrmCustomerLimitConfigCreateReqVO configReqVO = new CrmCustomerLimitConfigCreateReqVO();
200   - configReqVO.setUserId(userRespDTO.getId());
201   - configReqVO.setDeptIds(userDeptIds);
202   - configReqVO.setType(CUSTOMER_LOCK_LIMIT.getCode());
203   -
204   - CrmCustomerLimitConfigDO crmCustomerLimitConfigDO = crmCustomerLimitConfigService.selectByLimitConfig(configReqVO);
205   -
206   - // 统计当前用户已锁定客户数量
207   - List<CrmCustomerDO> crmCustomerDOS = customerMapper.selectList("owner_user_id", getLoginUserId());
208   - long customerLockCount = crmCustomerDOS.stream().filter(CrmCustomerDO::getLockStatus).count();
  191 + // 2. 更新锁定状态
  192 + customerMapper.updateById(BeanUtils.toBean(lockReqVO, CrmCustomerDO.class));
  193 + }
209 194  
210   - // 锁定操作的时候校验当前用户可锁定客户的上限
211   - if (crmCustomerLimitConfigDO != null && lockReqVO.getLockStatus() && customerLockCount >= crmCustomerLimitConfigDO.getMaxCount()) {
212   - // 超出锁定数量上限,提示业务异常
213   - throw exception(CUSTOMER_EXCEED_LOCK_LIMIT);
  195 + /**
  196 + * 校验用户拥有的客户数量,是否到达上限
  197 + *
  198 + * @param userId 用户编号
  199 + * @param newCount 附加数量
  200 + */
  201 + private void validateCustomerExceedOwnerLimit(Long userId, int newCount) {
  202 + List<CrmCustomerLimitConfigDO> limitConfigs = customerLimitConfigService.getCustomerLimitConfigListByUserId(
  203 + CUSTOMER_OWNER_LIMIT.getType(), userId);
  204 + if (CollUtil.isEmpty(limitConfigs)) {
  205 + return;
214 206 }
  207 + Long ownerCount = customerMapper.selectCountByDealStatusAndOwnerUserId(null, userId);
  208 + Long dealOwnerCount = customerMapper.selectCountByDealStatusAndOwnerUserId(true, userId);
  209 + limitConfigs.forEach(limitConfig -> {
  210 + long nowCount = limitConfig.getDealCountEnabled() ? ownerCount : ownerCount - dealOwnerCount;
  211 + if (nowCount + newCount > limitConfig.getMaxCount()) {
  212 + throw exception(CUSTOMER_OWNER_EXCEED_LIMIT);
  213 + }
  214 + });
  215 + }
215 216  
216   - // 更新
217   - CrmCustomerDO updateObj = CrmCustomerConvert.INSTANCE.convert(lockReqVO);
218   - customerMapper.updateById(updateObj);
  217 + /**
  218 + * 校验用户锁定的客户数量,是否到达上限
  219 + *
  220 + * @param userId 用户编号
  221 + */
  222 + private void validateCustomerExceedLockLimit(Long userId) {
  223 + List<CrmCustomerLimitConfigDO> limitConfigs = customerLimitConfigService.getCustomerLimitConfigListByUserId(
  224 + CUSTOMER_LOCK_LIMIT.getType(), userId);
  225 + if (CollUtil.isEmpty(limitConfigs)) {
  226 + return;
  227 + }
  228 + Long lockCount = customerMapper.selectCountByLockStatusAndOwnerUserId(true, userId);
  229 + Integer maxCount = CollectionUtils.getMaxValue(limitConfigs, CrmCustomerLimitConfigDO::getMaxCount);
  230 + assert maxCount != null;
  231 + if (lockCount >= maxCount) {
  232 + throw exception(CUSTOMER_LOCK_EXCEED_LIMIT);
  233 + }
219 234 }
220 235  
221 236 @Override
... ... @@ -239,7 +254,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
239 254 throw exception(CUSTOMER_UPDATE_OWNER_USER_FAIL);
240 255 }
241 256 // 3. 删除负责人数据权限
242   - crmPermissionService.deletePermission(CrmBizTypeEnum.CRM_CUSTOMER.getType(), customer.getId(),
  257 + permissionService.deletePermission(CrmBizTypeEnum.CRM_CUSTOMER.getType(), customer.getId(),
243 258 CrmPermissionLevelEnum.OWNER.getLevel());
244 259 }
245 260  
... ... @@ -262,6 +277,8 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
262 277 // 校验成交状态
263 278 validateCustomerDeal(customer);
264 279 });
  280 + // 1.4 校验负责人是否到达上限
  281 + validateCustomerExceedOwnerLimit(ownerUserId, customers.size());
265 282  
266 283 // 2. 领取公海数据
267 284 List<CrmCustomerDO> updateCustomers = new ArrayList<>();
... ... @@ -277,7 +294,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
277 294 // 3.1 更新客户负责人
278 295 customerMapper.updateBatch(updateCustomers);
279 296 // 3.2 创建负责人数据权限
280   - crmPermissionService.createPermissionBatch(createPermissions);
  297 + permissionService.createPermissionBatch(createPermissions);
281 298 }
282 299  
283 300 private void validateCustomerOwnerExists(CrmCustomerDO customer, Boolean pool) {
... ...