Commit d8bb55fc0bb955218c5d5c3029e82c0709074eaa
1 parent
ea4b4b89
CRM-客户:完善操作日志
Showing
10 changed files
with
245 additions
and
156 deletions
yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/ErrorCodeConstants.java
| @@ -40,7 +40,7 @@ public interface ErrorCodeConstants { | @@ -40,7 +40,7 @@ public interface ErrorCodeConstants { | ||
| 40 | ErrorCode CUSTOMER_LOCKED_PUT_POOL_FAIL = new ErrorCode(1_020_006_005, "客户【{}】放入公海失败,原因:客户已锁定"); | 40 | ErrorCode CUSTOMER_LOCKED_PUT_POOL_FAIL = new ErrorCode(1_020_006_005, "客户【{}】放入公海失败,原因:客户已锁定"); |
| 41 | ErrorCode CUSTOMER_UPDATE_OWNER_USER_FAIL = new ErrorCode(1_020_006_006, "更新客户【{}】负责人失败, 原因:系统异常"); | 41 | ErrorCode CUSTOMER_UPDATE_OWNER_USER_FAIL = new ErrorCode(1_020_006_006, "更新客户【{}】负责人失败, 原因:系统异常"); |
| 42 | ErrorCode CUSTOMER_LOCK_FAIL_IS_LOCK = new ErrorCode(1_020_006_007, "锁定客户失败,它已经处于锁定状态"); | 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, "锁定客户失败,它已经处于未锁定状态"); | 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, "锁定客户失败,超出锁定规则上限"); | 44 | ErrorCode CUSTOMER_LOCK_EXCEED_LIMIT = new ErrorCode(1_020_006_009, "锁定客户失败,超出锁定规则上限"); |
| 45 | ErrorCode CUSTOMER_OWNER_EXCEED_LIMIT = new ErrorCode(1_020_006_010, "操作失败,超出客户数拥有上限"); | 45 | ErrorCode CUSTOMER_OWNER_EXCEED_LIMIT = new ErrorCode(1_020_006_010, "操作失败,超出客户数拥有上限"); |
| 46 | 46 |
yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/LogRecordConstants.java
| @@ -2,32 +2,56 @@ package cn.iocoder.yudao.module.crm.enums; | @@ -2,32 +2,56 @@ package cn.iocoder.yudao.module.crm.enums; | ||
| 2 | 2 | ||
| 3 | /** | 3 | /** |
| 4 | * CRM 操作日志枚举 | 4 | * CRM 操作日志枚举 |
| 5 | + * 目的:统一管理,也减少 Service 里各种“复杂”字符串 | ||
| 5 | * | 6 | * |
| 6 | * @author HUIHUI | 7 | * @author HUIHUI |
| 7 | */ | 8 | */ |
| 8 | public interface LogRecordConstants { | 9 | public interface LogRecordConstants { |
| 9 | 10 | ||
| 10 | - //======================= 客户模块类型 ======================= | ||
| 11 | - // TODO puhui999: 确保模块命名方式为 module + 子模块名称的方式。统一定义模块名称是为了方便查询各自记录的操作日志,列如说:查询客户【张三的操作日志】就可以 module + bizId | ||
| 12 | - String CRM_LEADS = "CRM 线索"; | ||
| 13 | - String CRM_CUSTOMER = "CRM 客户"; | ||
| 14 | - String CRM_CONTACT = "CRM 联系人"; | ||
| 15 | - String CRM_BUSINESS = "CRM 商机"; | ||
| 16 | - String CRM_CONTRACT = "CRM 合同"; | ||
| 17 | - String CRM_PRODUCT = "CRM 产品"; | ||
| 18 | - String CRM_RECEIVABLE = "CRM 回款"; | ||
| 19 | - String CRM_RECEIVABLE_PLAN = "CRM 回款计划"; | 11 | + // ======================= CRM_LEADS 线索 ======================= |
| 20 | 12 | ||
| 21 | - //======================= 客户转移操作日志 ======================= | 13 | + String CRM_LEADS_TYPE = "CRM 线索"; |
| 22 | 14 | ||
| 23 | - String TRANSFER_CUSTOMER_LOG_SUCCESS = "把客户【{{#crmCustomer.name}}】的负责人从【{getAdminUserById{#crmCustomer.ownerUserId}}】变更为了【{getAdminUserById{#reqVO.newOwnerUserId}}】"; | 15 | + // ======================= CRM_CUSTOMER 客户 ======================= |
| 24 | 16 | ||
| 25 | - // TODO @puhui999:这里格式是不是可以这样;目的是:统一管理,也减少 Service 里各种“复杂”字符串 | ||
| 26 | - // ======================= Customer 客户 ======================= | ||
| 27 | - String CUSTOMER_TYPE = "CRM 客户"; | ||
| 28 | - String CUSTOMER_CREATE_SUB_TYPE = "创建客户"; | ||
| 29 | - String CUSTOMER_CREATE_SUCCESS = "更新了客户{_DIFF{#updateReqVO}}"; | 17 | + String CRM_CUSTOMER_TYPE = "CRM 客户"; |
| 18 | + String CRM_CUSTOMER_CREATE_SUB_TYPE = "创建客户"; | ||
| 19 | + String CRM_CUSTOMER_CREATE_SUCCESS = "创建了客户{{#customer.name}}"; | ||
| 20 | + String CRM_CUSTOMER_UPDATE_SUB_TYPE = "更新客户"; | ||
| 21 | + String CRM_CUSTOMER_UPDATE_SUCCESS = "更新了客户【{{#customerName}}】{_DIFF{#updateReqVO}}"; | ||
| 22 | + String CRM_CUSTOMER_DELETE_SUB_TYPE = "删除客户"; | ||
| 23 | + String CRM_CUSTOMER_DELETE_SUCCESS = "删除了客户【{{#customerName}}】"; | ||
| 24 | + String CRM_CUSTOMER_TRANSFER_SUB_TYPE = "转移客户"; | ||
| 25 | + String CRM_CUSTOMER_TRANSFER_SUCCESS = "将客户【{{#crmCustomer.name}}】的负责人从【{getAdminUserById{#crmCustomer.ownerUserId}}】变更为了【{getAdminUserById{#reqVO.newOwnerUserId}}】"; | ||
| 26 | + String CRM_CUSTOMER_LOCK_SUB_TYPE = "{{#crmCustomer.lockStatus ? '锁定客户' : '解锁客户'}}"; | ||
| 27 | + String CRM_CUSTOMER_LOCK_SUCCESS = "{{#crmCustomer.lockStatus ? '将客户【#crmCustomer.name】锁定' : '将客户【#crmCustomer.name】解锁'}}"; | ||
| 28 | + String CRM_CUSTOMER_POOL_SUB_TYPE = "客户放入公海"; | ||
| 29 | + String CRM_CUSTOMER_POOL_SUCCESS = "将客户【{{#customerName}}】放入了公海"; | ||
| 30 | + String CRM_CUSTOMER_RECEIVE_SUB_TYPE = "{{#ownerUserName != null ? '分配客户' : '领取客户'}}"; | ||
| 31 | + String CRM_CUSTOMER_RECEIVE_SUCCESS = "{{#ownerUserName != null ? '将客户【#customer.name】分配给【#ownerUserName】' : '领取客户【#customer.name】'}}"; | ||
| 30 | 32 | ||
| 31 | - String CUSTOMER_UPDATE_SUB_TYPE = "更新客户"; | 33 | + // ======================= CRM_CONTACT 联系人 ======================= |
| 34 | + | ||
| 35 | + String CRM_CONTACT_TYPE = "CRM 联系人"; | ||
| 36 | + | ||
| 37 | + // ======================= CRM_BUSINESS 商机 ======================= | ||
| 38 | + | ||
| 39 | + String CRM_BUSINESS_TYPE = "CRM 商机"; | ||
| 40 | + | ||
| 41 | + // ======================= CRM_CONTRACT 合同 ======================= | ||
| 42 | + | ||
| 43 | + String CRM_CONTRACT_TYPE = "CRM 合同"; | ||
| 44 | + | ||
| 45 | + // ======================= CRM_PRODUCT 产品 ======================= | ||
| 46 | + | ||
| 47 | + String CRM_PRODUCT_TYPE = "CRM 产品"; | ||
| 48 | + | ||
| 49 | + // ======================= CRM_RECEIVABLE 回款 ======================= | ||
| 50 | + | ||
| 51 | + String CRM_RECEIVABLE_TYPE = "CRM 回款"; | ||
| 52 | + | ||
| 53 | + // ======================= CRM_RECEIVABLE_PLAN 回款计划 ======================= | ||
| 54 | + | ||
| 55 | + String CRM_RECEIVABLE_PLAN_TYPE = "CRM 回款计划"; | ||
| 32 | 56 | ||
| 33 | } | 57 | } |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java
| @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.crm.controller.admin.customer; | @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.crm.controller.admin.customer; | ||
| 3 | import cn.hutool.core.collection.CollUtil; | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; | 4 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 6 | +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | ||
| 6 | import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; | 7 | import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; |
| 7 | import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; | 8 | import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; |
| 8 | import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.*; | 9 | import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.*; |
| @@ -38,7 +39,7 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils. | @@ -38,7 +39,7 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils. | ||
| 38 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSetByFlatMap; | 39 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSetByFlatMap; |
| 39 | import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; | 40 | import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; |
| 40 | import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; | 41 | import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; |
| 41 | -import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.CRM_CUSTOMER; | 42 | +import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.CRM_CUSTOMER_TYPE; |
| 42 | 43 | ||
| 43 | @Tag(name = "管理后台 - CRM 客户") | 44 | @Tag(name = "管理后台 - CRM 客户") |
| 44 | @RestController | 45 | @RestController |
| @@ -115,6 +116,15 @@ public class CrmCustomerController { | @@ -115,6 +116,15 @@ public class CrmCustomerController { | ||
| 115 | return success(CrmCustomerConvert.INSTANCE.convertPage(pageResult, userMap, deptMap)); | 116 | return success(CrmCustomerConvert.INSTANCE.convertPage(pageResult, userMap, deptMap)); |
| 116 | } | 117 | } |
| 117 | 118 | ||
| 119 | + @GetMapping(value = {"/list-all-simple"}) | ||
| 120 | + @Operation(summary = "获取客户精简信息列表", description = "只包含有读权限的客户,主要用于前端的下拉选项") | ||
| 121 | + public CommonResult<List<CrmCustomerSimpleRespVO>> getSimpleDeptList() { | ||
| 122 | + CrmCustomerPageReqVO reqVO = new CrmCustomerPageReqVO(); | ||
| 123 | + reqVO.setPageSize(PAGE_SIZE_NONE); // 不分页 | ||
| 124 | + List<CrmCustomerDO> list = customerService.getCustomerPage(reqVO, getLoginUserId()).getList(); | ||
| 125 | + return success(BeanUtils.toBean(list, CrmCustomerSimpleRespVO.class)); | ||
| 126 | + } | ||
| 127 | + | ||
| 118 | @GetMapping("/export-excel") | 128 | @GetMapping("/export-excel") |
| 119 | @Operation(summary = "导出客户 Excel") | 129 | @Operation(summary = "导出客户 Excel") |
| 120 | @PreAuthorize("@ss.hasPermission('crm:customer:export')") | 130 | @PreAuthorize("@ss.hasPermission('crm:customer:export')") |
| @@ -143,7 +153,7 @@ public class CrmCustomerController { | @@ -143,7 +153,7 @@ public class CrmCustomerController { | ||
| 143 | public CommonResult<PageResult<OperateLogV2RespDTO>> getCustomerOperateLog(@RequestParam("id") Long id) { | 153 | public CommonResult<PageResult<OperateLogV2RespDTO>> getCustomerOperateLog(@RequestParam("id") Long id) { |
| 144 | OperateLogV2PageReqDTO reqDTO = new OperateLogV2PageReqDTO(); | 154 | OperateLogV2PageReqDTO reqDTO = new OperateLogV2PageReqDTO(); |
| 145 | reqDTO.setPageSize(PAGE_SIZE_NONE); // 不分页 | 155 | reqDTO.setPageSize(PAGE_SIZE_NONE); // 不分页 |
| 146 | - reqDTO.setBizType(CRM_CUSTOMER); | 156 | + reqDTO.setBizType(CRM_CUSTOMER_TYPE); |
| 147 | reqDTO.setBizId(id); | 157 | reqDTO.setBizId(id); |
| 148 | return success(operateLogApi.getOperateLogPage(reqDTO)); | 158 | return success(operateLogApi.getOperateLogPage(reqDTO)); |
| 149 | } | 159 | } |
| @@ -172,7 +182,7 @@ public class CrmCustomerController { | @@ -172,7 +182,7 @@ public class CrmCustomerController { | ||
| 172 | @Parameter(name = "ids", description = "编号数组", required = true, example = "1,2,3") | 182 | @Parameter(name = "ids", description = "编号数组", required = true, example = "1,2,3") |
| 173 | @PreAuthorize("@ss.hasPermission('crm:customer:receive')") | 183 | @PreAuthorize("@ss.hasPermission('crm:customer:receive')") |
| 174 | public CommonResult<Boolean> receiveCustomer(@RequestParam(value = "ids") List<Long> ids) { | 184 | public CommonResult<Boolean> receiveCustomer(@RequestParam(value = "ids") List<Long> ids) { |
| 175 | - customerService.receiveCustomer(ids, getLoginUserId()); | 185 | + customerService.receiveCustomer(ids, getLoginUserId(), Boolean.TRUE); |
| 176 | return success(true); | 186 | return success(true); |
| 177 | } | 187 | } |
| 178 | 188 | ||
| @@ -180,18 +190,8 @@ public class CrmCustomerController { | @@ -180,18 +190,8 @@ public class CrmCustomerController { | ||
| 180 | @Operation(summary = "分配公海给对应负责人") | 190 | @Operation(summary = "分配公海给对应负责人") |
| 181 | @PreAuthorize("@ss.hasPermission('crm:customer:distribute')") | 191 | @PreAuthorize("@ss.hasPermission('crm:customer:distribute')") |
| 182 | public CommonResult<Boolean> distributeCustomer(@Valid @RequestBody CrmCustomerDistributeReqVO distributeReqVO) { | 192 | public CommonResult<Boolean> distributeCustomer(@Valid @RequestBody CrmCustomerDistributeReqVO distributeReqVO) { |
| 183 | - customerService.receiveCustomer(distributeReqVO.getIds(), distributeReqVO.getOwnerUserId()); | 193 | + customerService.receiveCustomer(distributeReqVO.getIds(), distributeReqVO.getOwnerUserId(), Boolean.FALSE); |
| 184 | return success(true); | 194 | return success(true); |
| 185 | } | 195 | } |
| 186 | 196 | ||
| 187 | - // TODO 芋艿:这个接口要调整下 | ||
| 188 | - //@GetMapping("/query-all-list") | ||
| 189 | - //@Operation(summary = "查询客户列表") | ||
| 190 | - //@PreAuthorize("@ss.hasPermission('crm:customer:all')") | ||
| 191 | - //public CommonResult<List<CrmCustomerQueryAllRespVO>> queryAll() { | ||
| 192 | - // List<CrmCustomerDO> crmCustomerDOList = customerService.getCustomerList(); | ||
| 193 | - // List<CrmCustomerQueryAllRespVO> data = CrmCustomerConvert.INSTANCE.convertQueryAll(crmCustomerDOList); | ||
| 194 | - // return success(data); | ||
| 195 | - //} | ||
| 196 | - | ||
| 197 | } | 197 | } |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/CrmCustomerSimpleRespVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.crm.controller.admin.customer.vo; | ||
| 2 | + | ||
| 3 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 4 | +import lombok.AllArgsConstructor; | ||
| 5 | +import lombok.Data; | ||
| 6 | +import lombok.NoArgsConstructor; | ||
| 7 | + | ||
| 8 | +@Schema(description = "管理后台 - 客户精简信息 Response VO") | ||
| 9 | +@Data | ||
| 10 | +@NoArgsConstructor | ||
| 11 | +@AllArgsConstructor | ||
| 12 | +public class CrmCustomerSimpleRespVO { | ||
| 13 | + | ||
| 14 | + @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") | ||
| 15 | + private Long id; | ||
| 16 | + | ||
| 17 | + @Schema(description = "客户名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道") | ||
| 18 | + private String name; | ||
| 19 | + | ||
| 20 | +} |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/permission/CrmPermissionMapper.java
| @@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; | @@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; | ||
| 5 | import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO; | 5 | import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO; |
| 6 | import org.apache.ibatis.annotations.Mapper; | 6 | import org.apache.ibatis.annotations.Mapper; |
| 7 | 7 | ||
| 8 | +import java.util.Collection; | ||
| 8 | import java.util.List; | 9 | import java.util.List; |
| 9 | 10 | ||
| 10 | /** | 11 | /** |
| @@ -28,6 +29,12 @@ public interface CrmPermissionMapper extends BaseMapperX<CrmPermissionDO> { | @@ -28,6 +29,12 @@ public interface CrmPermissionMapper extends BaseMapperX<CrmPermissionDO> { | ||
| 28 | .eq(CrmPermissionDO::getBizId, bizId)); | 29 | .eq(CrmPermissionDO::getBizId, bizId)); |
| 29 | } | 30 | } |
| 30 | 31 | ||
| 32 | + default List<CrmPermissionDO> selectByBizTypeAndBizIds(Integer bizType, Collection<Long> bizIds) { | ||
| 33 | + return selectList(new LambdaQueryWrapperX<CrmPermissionDO>() | ||
| 34 | + .eq(CrmPermissionDO::getBizType, bizType) | ||
| 35 | + .in(CrmPermissionDO::getBizId, bizIds)); | ||
| 36 | + } | ||
| 37 | + | ||
| 31 | default List<CrmPermissionDO> selectListByBizTypeAndUserId(Integer bizType, Long userId) { | 38 | default List<CrmPermissionDO> selectListByBizTypeAndUserId(Integer bizType, Long userId) { |
| 32 | return selectList(new LambdaQueryWrapperX<CrmPermissionDO>() | 39 | return selectList(new LambdaQueryWrapperX<CrmPermissionDO>() |
| 33 | .eq(CrmPermissionDO::getBizType, bizType) | 40 | .eq(CrmPermissionDO::getBizType, bizType) |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/permission/core/aop/CrmPermissionAspect.java
| @@ -18,12 +18,10 @@ import org.aspectj.lang.annotation.Aspect; | @@ -18,12 +18,10 @@ import org.aspectj.lang.annotation.Aspect; | ||
| 18 | import org.aspectj.lang.annotation.Before; | 18 | import org.aspectj.lang.annotation.Before; |
| 19 | import org.springframework.stereotype.Component; | 19 | import org.springframework.stereotype.Component; |
| 20 | 20 | ||
| 21 | -import java.util.ArrayList; | ||
| 22 | -import java.util.List; | ||
| 23 | -import java.util.Map; | 21 | +import java.util.*; |
| 24 | 22 | ||
| 25 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | 23 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 26 | -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.anyMatch; | 24 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; |
| 27 | import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; | 25 | import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; |
| 28 | import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CRM_PERMISSION_DENIED; | 26 | import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CRM_PERMISSION_DENIED; |
| 29 | 27 | ||
| @@ -46,16 +44,29 @@ public class CrmPermissionAspect { | @@ -46,16 +44,29 @@ public class CrmPermissionAspect { | ||
| 46 | Map<String, Object> expressionValues = parseExpressions(joinPoint, crmPermission); | 44 | Map<String, Object> expressionValues = parseExpressions(joinPoint, crmPermission); |
| 47 | Integer bizType = StrUtil.isEmpty(crmPermission.bizTypeValue()) ? | 45 | Integer bizType = StrUtil.isEmpty(crmPermission.bizTypeValue()) ? |
| 48 | crmPermission.bizType()[0].getType() : (Integer) expressionValues.get(crmPermission.bizTypeValue()); // 模块类型 | 46 | crmPermission.bizType()[0].getType() : (Integer) expressionValues.get(crmPermission.bizTypeValue()); // 模块类型 |
| 49 | - Long bizId = (Long) expressionValues.get(crmPermission.bizId()); // 模块数据编号 | 47 | + // 处理兼容多个 bizId 的情况 |
| 48 | + Object object = expressionValues.get(crmPermission.bizId());// 模块数据编号 | ||
| 49 | + Set<Long> bizIds = new HashSet<>(); | ||
| 50 | + if (object instanceof Collection<?>) { | ||
| 51 | + bizIds.addAll(convertSet((Collection<?>) object, item -> Long.parseLong(item.toString()))); | ||
| 52 | + } else { | ||
| 53 | + bizIds.add(Long.parseLong(object.toString())); | ||
| 54 | + } | ||
| 50 | Integer permissionLevel = crmPermission.level().getLevel(); // 需要的权限级别 | 55 | Integer permissionLevel = crmPermission.level().getLevel(); // 需要的权限级别 |
| 56 | + List<CrmPermissionDO> permissionList = crmPermissionService.getPermissionListByBiz(bizType, bizIds); | ||
| 57 | + Map<Long, List<CrmPermissionDO>> multiMap = convertMultiMap(permissionList, CrmPermissionDO::getBizId); | ||
| 58 | + bizIds.forEach(bizId -> { | ||
| 59 | + validatePermission(bizType, multiMap.get(bizId), permissionLevel); | ||
| 60 | + }); | ||
| 61 | + } | ||
| 51 | 62 | ||
| 52 | - // 1.1 如果是超级管理员则直接通过 | 63 | + private void validatePermission(Integer bizType, List<CrmPermissionDO> bizPermissions, Integer permissionLevel) { |
| 64 | + // 1. 如果是超级管理员则直接通过 | ||
| 53 | if (CrmPermissionUtils.isCrmAdmin()) { | 65 | if (CrmPermissionUtils.isCrmAdmin()) { |
| 54 | return; | 66 | return; |
| 55 | } | 67 | } |
| 56 | - // 1.2 获取数据权限 | ||
| 57 | - List<CrmPermissionDO> bizPermissions = crmPermissionService.getPermissionListByBiz(bizType, bizId); | ||
| 58 | - if (CollUtil.isEmpty(bizPermissions)) { // 没有数据权限的情况 | 68 | + // 1.1 没有数据权限的情况 |
| 69 | + if (CollUtil.isEmpty(bizPermissions)) { | ||
| 59 | // 公海数据如果没有团队成员大家也因该有读权限才对 | 70 | // 公海数据如果没有团队成员大家也因该有读权限才对 |
| 60 | if (CrmPermissionLevelEnum.isRead(permissionLevel)) { | 71 | if (CrmPermissionLevelEnum.isRead(permissionLevel)) { |
| 61 | return; | 72 | return; |
| @@ -63,7 +74,7 @@ public class CrmPermissionAspect { | @@ -63,7 +74,7 @@ public class CrmPermissionAspect { | ||
| 63 | 74 | ||
| 64 | // 没有数据权限的情况下超出了读权限直接报错,避免后面校验空指针 | 75 | // 没有数据权限的情况下超出了读权限直接报错,避免后面校验空指针 |
| 65 | throw exception(CRM_PERMISSION_DENIED, CrmBizTypeEnum.getNameByType(bizType)); | 76 | throw exception(CRM_PERMISSION_DENIED, CrmBizTypeEnum.getNameByType(bizType)); |
| 66 | - } else { // 有数据权限但是没有负责人的情况 | 77 | + } else { // 1.2 有数据权限但是没有负责人的情况 |
| 67 | if (!anyMatch(bizPermissions, item -> CrmPermissionLevelEnum.isOwner(item.getLevel()))) { | 78 | if (!anyMatch(bizPermissions, item -> CrmPermissionLevelEnum.isOwner(item.getLevel()))) { |
| 68 | if (CrmPermissionLevelEnum.isRead(permissionLevel)) { | 79 | if (CrmPermissionLevelEnum.isRead(permissionLevel)) { |
| 69 | return; | 80 | return; |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerService.java
| @@ -86,7 +86,7 @@ public interface CrmCustomerService { | @@ -86,7 +86,7 @@ public interface CrmCustomerService { | ||
| 86 | * 锁定/解锁客户 | 86 | * 锁定/解锁客户 |
| 87 | * | 87 | * |
| 88 | * @param lockReqVO 更新信息 | 88 | * @param lockReqVO 更新信息 |
| 89 | - * @param userId 用户编号 | 89 | + * @param userId 用户编号 |
| 90 | */ | 90 | */ |
| 91 | void lockCustomer(@Valid CrmCustomerLockReqVO lockReqVO, Long userId); | 91 | void lockCustomer(@Valid CrmCustomerLockReqVO lockReqVO, Long userId); |
| 92 | 92 | ||
| @@ -104,15 +104,8 @@ public interface CrmCustomerService { | @@ -104,15 +104,8 @@ public interface CrmCustomerService { | ||
| 104 | * | 104 | * |
| 105 | * @param ids 要领取的客户编号数组 | 105 | * @param ids 要领取的客户编号数组 |
| 106 | * @param ownerUserId 负责人 | 106 | * @param ownerUserId 负责人 |
| 107 | + * @param isReceive 是/否领取 | ||
| 107 | */ | 108 | */ |
| 108 | - void receiveCustomer(List<Long> ids, Long ownerUserId); | ||
| 109 | - | ||
| 110 | - /** | ||
| 111 | - * 获取客户列表 | ||
| 112 | - * | ||
| 113 | - * @return 客户列表 | ||
| 114 | - * @author zyna | ||
| 115 | - */ | ||
| 116 | - List<CrmCustomerDO> getCustomerList(); | 109 | + void receiveCustomer(List<Long> ids, Long ownerUserId, Boolean isReceive); |
| 117 | 110 | ||
| 118 | } | 111 | } |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java
| @@ -16,9 +16,11 @@ import cn.iocoder.yudao.module.crm.dal.mysql.customer.CrmCustomerMapper; | @@ -16,9 +16,11 @@ import cn.iocoder.yudao.module.crm.dal.mysql.customer.CrmCustomerMapper; | ||
| 16 | import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; | 16 | import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; |
| 17 | import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; | 17 | import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; |
| 18 | import cn.iocoder.yudao.module.crm.framework.permission.core.annotations.CrmPermission; | 18 | import cn.iocoder.yudao.module.crm.framework.permission.core.annotations.CrmPermission; |
| 19 | +import cn.iocoder.yudao.module.crm.framework.permission.core.util.CrmPermissionUtils; | ||
| 19 | import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; | 20 | import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; |
| 20 | import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; | 21 | import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; |
| 21 | import cn.iocoder.yudao.module.system.api.user.AdminUserApi; | 22 | import cn.iocoder.yudao.module.system.api.user.AdminUserApi; |
| 23 | +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; | ||
| 22 | import com.mzt.logapi.context.LogRecordContext; | 24 | import com.mzt.logapi.context.LogRecordContext; |
| 23 | import com.mzt.logapi.service.impl.DiffParseFunction; | 25 | import com.mzt.logapi.service.impl.DiffParseFunction; |
| 24 | import com.mzt.logapi.starter.annotation.LogRecord; | 26 | import com.mzt.logapi.starter.annotation.LogRecord; |
| @@ -35,8 +37,7 @@ import java.util.List; | @@ -35,8 +37,7 @@ import java.util.List; | ||
| 35 | 37 | ||
| 36 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | 38 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 37 | import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*; | 39 | import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*; |
| 38 | -import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.CRM_CUSTOMER; | ||
| 39 | -import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.TRANSFER_CUSTOMER_LOG_SUCCESS; | 40 | +import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*; |
| 40 | import static cn.iocoder.yudao.module.crm.enums.customer.CrmCustomerLimitConfigTypeEnum.CUSTOMER_LOCK_LIMIT; | 41 | import static cn.iocoder.yudao.module.crm.enums.customer.CrmCustomerLimitConfigTypeEnum.CUSTOMER_LOCK_LIMIT; |
| 41 | import static cn.iocoder.yudao.module.crm.enums.customer.CrmCustomerLimitConfigTypeEnum.CUSTOMER_OWNER_LIMIT; | 42 | import static cn.iocoder.yudao.module.crm.enums.customer.CrmCustomerLimitConfigTypeEnum.CUSTOMER_OWNER_LIMIT; |
| 42 | import static java.util.Collections.singletonList; | 43 | import static java.util.Collections.singletonList; |
| @@ -63,8 +64,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | @@ -63,8 +64,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | ||
| 63 | 64 | ||
| 64 | @Override | 65 | @Override |
| 65 | @Transactional(rollbackFor = Exception.class) | 66 | @Transactional(rollbackFor = Exception.class) |
| 66 | - @LogRecord(type = CRM_CUSTOMER, subType = "创建客户", bizNo = "{{#customerId}}", success = "创建了客户") | ||
| 67 | - // TODO @puhui999:创建了客户【客户名】,要记录进去;不然在展示操作日志的全列表,看不清楚是哪个客户哈; | 67 | + @LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_CREATE_SUB_TYPE, bizNo = "{{#customer.id}}", success = CRM_CUSTOMER_CREATE_SUCCESS) |
| 68 | public Long createCustomer(CrmCustomerSaveReqVO createReqVO, Long userId) { | 68 | public Long createCustomer(CrmCustomerSaveReqVO createReqVO, Long userId) { |
| 69 | createReqVO.setId(null); | 69 | createReqVO.setId(null); |
| 70 | // 1. 校验拥有客户是否到达上限 | 70 | // 1. 校验拥有客户是否到达上限 |
| @@ -81,14 +81,14 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | @@ -81,14 +81,14 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | ||
| 81 | permissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType()) | 81 | permissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType()) |
| 82 | .setBizId(customer.getId()).setUserId(userId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); // 设置当前操作的人为负责人 | 82 | .setBizId(customer.getId()).setUserId(userId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); // 设置当前操作的人为负责人 |
| 83 | 83 | ||
| 84 | - // 4. 记录操作日志 | ||
| 85 | - LogRecordContext.putVariable("customerId", customer.getId()); | 84 | + // 4. 记录操作日志上下文 |
| 85 | + LogRecordContext.putVariable("customer", customer); | ||
| 86 | return customer.getId(); | 86 | return customer.getId(); |
| 87 | } | 87 | } |
| 88 | 88 | ||
| 89 | @Override | 89 | @Override |
| 90 | @Transactional(rollbackFor = Exception.class) | 90 | @Transactional(rollbackFor = Exception.class) |
| 91 | - @LogRecord(type = CRM_CUSTOMER, subType = "更新客户", bizNo = "{{#updateReqVO.id}}", success = "更新了客户{_DIFF{#updateReqVO}}", extra = "{{#extra}}") | 91 | + @LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_UPDATE_SUB_TYPE, bizNo = "{{#updateReqVO.id}}", success = CRM_CUSTOMER_UPDATE_SUCCESS) |
| 92 | @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE) | 92 | @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE) |
| 93 | public void updateCustomer(CrmCustomerSaveReqVO updateReqVO) { | 93 | public void updateCustomer(CrmCustomerSaveReqVO updateReqVO) { |
| 94 | Assert.notNull(updateReqVO.getId(), "客户编号不能为空"); | 94 | Assert.notNull(updateReqVO.getId(), "客户编号不能为空"); |
| @@ -101,17 +101,18 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | @@ -101,17 +101,18 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | ||
| 101 | CrmCustomerDO updateObj = CrmCustomerConvert.INSTANCE.convert(updateReqVO); | 101 | CrmCustomerDO updateObj = CrmCustomerConvert.INSTANCE.convert(updateReqVO); |
| 102 | customerMapper.updateById(updateObj); | 102 | customerMapper.updateById(updateObj); |
| 103 | 103 | ||
| 104 | - // 3. 记录操作日志 | 104 | + // 3. 记录操作日志上下文 |
| 105 | LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldCustomer, CrmCustomerSaveReqVO.class)); | 105 | LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldCustomer, CrmCustomerSaveReqVO.class)); |
| 106 | + LogRecordContext.putVariable("customerName", oldCustomer.getName()); | ||
| 106 | } | 107 | } |
| 107 | 108 | ||
| 108 | @Override | 109 | @Override |
| 109 | @Transactional(rollbackFor = Exception.class) | 110 | @Transactional(rollbackFor = Exception.class) |
| 110 | - @LogRecord(type = CRM_CUSTOMER, subType = "删除客户", bizNo = "{{#id}}", success = "删除了客户") | 111 | + @LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_DELETE_SUB_TYPE, bizNo = "{{#id}}", success = CRM_CUSTOMER_DELETE_SUCCESS) |
| 111 | @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#id", level = CrmPermissionLevelEnum.OWNER) | 112 | @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#id", level = CrmPermissionLevelEnum.OWNER) |
| 112 | public void deleteCustomer(Long id) { | 113 | public void deleteCustomer(Long id) { |
| 113 | // 校验存在 | 114 | // 校验存在 |
| 114 | - validateCustomerExists(id); | 115 | + CrmCustomerDO customer = validateCustomerExists(id); |
| 115 | // TODO @puhui999:如果有联系人、商机,则不允许删除; | 116 | // TODO @puhui999:如果有联系人、商机,则不允许删除; |
| 116 | 117 | ||
| 117 | // 删除 | 118 | // 删除 |
| @@ -119,48 +120,14 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | @@ -119,48 +120,14 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | ||
| 119 | // 删除数据权限 | 120 | // 删除数据权限 |
| 120 | permissionService.deletePermission(CrmBizTypeEnum.CRM_CUSTOMER.getType(), id); | 121 | permissionService.deletePermission(CrmBizTypeEnum.CRM_CUSTOMER.getType(), id); |
| 121 | // TODO @puhui999:删除跟进记录 | 122 | // TODO @puhui999:删除跟进记录 |
| 122 | - } | ||
| 123 | - | ||
| 124 | - private CrmCustomerDO validateCustomerExists(Long id) { | ||
| 125 | - CrmCustomerDO customerDO = customerMapper.selectById(id); | ||
| 126 | - if (customerDO == null) { | ||
| 127 | - throw exception(CUSTOMER_NOT_EXISTS); | ||
| 128 | - } | ||
| 129 | - return customerDO; | ||
| 130 | - } | ||
| 131 | - | ||
| 132 | - @Override | ||
| 133 | - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#id", level = CrmPermissionLevelEnum.READ) | ||
| 134 | - public CrmCustomerDO getCustomer(Long id) { | ||
| 135 | - return customerMapper.selectById(id); | ||
| 136 | - } | ||
| 137 | - | ||
| 138 | - @Override | ||
| 139 | - public List<CrmCustomerDO> getCustomerList(Collection<Long> ids) { | ||
| 140 | - if (CollUtil.isEmpty(ids)) { | ||
| 141 | - return Collections.emptyList(); | ||
| 142 | - } | ||
| 143 | - return customerMapper.selectBatchIds(ids); | ||
| 144 | - } | ||
| 145 | 123 | ||
| 146 | - @Override | ||
| 147 | - public PageResult<CrmCustomerDO> getCustomerPage(CrmCustomerPageReqVO pageReqVO, Long userId) { | ||
| 148 | - return customerMapper.selectPage(pageReqVO, userId); | ||
| 149 | - } | ||
| 150 | - | ||
| 151 | - /** | ||
| 152 | - * 校验客户是否存在 | ||
| 153 | - * | ||
| 154 | - * @param customerId 客户 id | ||
| 155 | - */ | ||
| 156 | - @Override | ||
| 157 | - public void validateCustomer(Long customerId) { | ||
| 158 | - validateCustomerExists(customerId); | 124 | + // 记录操作日志上下文 |
| 125 | + LogRecordContext.putVariable("customerName", customer.getName()); | ||
| 159 | } | 126 | } |
| 160 | 127 | ||
| 161 | @Override | 128 | @Override |
| 162 | @Transactional(rollbackFor = Exception.class) | 129 | @Transactional(rollbackFor = Exception.class) |
| 163 | - @LogRecord(type = CRM_CUSTOMER, subType = "转移客户", bizNo = "{{#reqVO.id}}", success = TRANSFER_CUSTOMER_LOG_SUCCESS) | 130 | + @LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_TRANSFER_SUB_TYPE, bizNo = "{{#reqVO.id}}", success = CRM_CUSTOMER_TRANSFER_SUCCESS) |
| 164 | @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#reqVO.id", level = CrmPermissionLevelEnum.OWNER) | 131 | @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#reqVO.id", level = CrmPermissionLevelEnum.OWNER) |
| 165 | public void transferCustomer(CrmCustomerTransferReqVO reqVO, Long userId) { | 132 | public void transferCustomer(CrmCustomerTransferReqVO reqVO, Long userId) { |
| 166 | // 1.1 校验客户是否存在 | 133 | // 1.1 校验客户是否存在 |
| @@ -175,20 +142,17 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | @@ -175,20 +142,17 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | ||
| 175 | customerMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId()); | 142 | customerMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId()); |
| 176 | 143 | ||
| 177 | // 3. TODO 记录转移日志 | 144 | // 3. TODO 记录转移日志 |
| 145 | + // 记录操作日志上下文 | ||
| 178 | LogRecordContext.putVariable("crmCustomer", customer); | 146 | LogRecordContext.putVariable("crmCustomer", customer); |
| 179 | } | 147 | } |
| 180 | 148 | ||
| 181 | @Override | 149 | @Override |
| 182 | - // TODO @puhui999:看看这个能不能根据条件,写操作日志; | ||
| 183 | - // TODO 如果是 锁定,则 subType 为 锁定客户;success 为 将客户【】锁定 | ||
| 184 | - // TODO 如果是 解锁,则 subType 为 解锁客户;success 为 将客户【】解锁 | ||
| 185 | - @LogRecord(type = CRM_CUSTOMER, subType = "锁定/解锁客户", bizNo = "{{#updateReqVO.id}}", success = "锁定了客户") | ||
| 186 | - // TODO @puhui999:数据权限 | 150 | + @LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_LOCK_SUB_TYPE, bizNo = "{{#lockReqVO.id}}", success = CRM_CUSTOMER_LOCK_SUCCESS) |
| 151 | + @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#lockReqVO.id", level = CrmPermissionLevelEnum.OWNER) | ||
| 187 | public void lockCustomer(CrmCustomerLockReqVO lockReqVO, Long userId) { | 152 | public void lockCustomer(CrmCustomerLockReqVO lockReqVO, Long userId) { |
| 188 | // 1.1 校验当前客户是否存在 | 153 | // 1.1 校验当前客户是否存在 |
| 189 | - validateCustomerExists(lockReqVO.getId()); | 154 | + CrmCustomerDO customer = validateCustomerExists(lockReqVO.getId()); |
| 190 | // 1.2 校验当前是否重复操作锁定/解锁状态 | 155 | // 1.2 校验当前是否重复操作锁定/解锁状态 |
| 191 | - CrmCustomerDO customer = customerMapper.selectById(lockReqVO.getId()); | ||
| 192 | if (customer.getLockStatus().equals(lockReqVO.getLockStatus())) { | 156 | if (customer.getLockStatus().equals(lockReqVO.getLockStatus())) { |
| 193 | throw exception(customer.getLockStatus() ? CUSTOMER_LOCK_FAIL_IS_LOCK : CUSTOMER_UNLOCK_FAIL_IS_UNLOCK); | 157 | throw exception(customer.getLockStatus() ? CUSTOMER_LOCK_FAIL_IS_LOCK : CUSTOMER_UNLOCK_FAIL_IS_UNLOCK); |
| 194 | } | 158 | } |
| @@ -199,53 +163,16 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | @@ -199,53 +163,16 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | ||
| 199 | 163 | ||
| 200 | // 2. 更新锁定状态 | 164 | // 2. 更新锁定状态 |
| 201 | customerMapper.updateById(BeanUtils.toBean(lockReqVO, CrmCustomerDO.class)); | 165 | customerMapper.updateById(BeanUtils.toBean(lockReqVO, CrmCustomerDO.class)); |
| 202 | - } | ||
| 203 | 166 | ||
| 204 | - /** | ||
| 205 | - * 校验用户拥有的客户数量,是否到达上限 | ||
| 206 | - * | ||
| 207 | - * @param userId 用户编号 | ||
| 208 | - * @param newCount 附加数量 | ||
| 209 | - */ | ||
| 210 | - private void validateCustomerExceedOwnerLimit(Long userId, int newCount) { | ||
| 211 | - List<CrmCustomerLimitConfigDO> limitConfigs = customerLimitConfigService.getCustomerLimitConfigListByUserId( | ||
| 212 | - CUSTOMER_OWNER_LIMIT.getType(), userId); | ||
| 213 | - if (CollUtil.isEmpty(limitConfigs)) { | ||
| 214 | - return; | ||
| 215 | - } | ||
| 216 | - Long ownerCount = customerMapper.selectCountByDealStatusAndOwnerUserId(null, userId); | ||
| 217 | - Long dealOwnerCount = customerMapper.selectCountByDealStatusAndOwnerUserId(true, userId); | ||
| 218 | - limitConfigs.forEach(limitConfig -> { | ||
| 219 | - long nowCount = limitConfig.getDealCountEnabled() ? ownerCount : ownerCount - dealOwnerCount; | ||
| 220 | - if (nowCount + newCount > limitConfig.getMaxCount()) { | ||
| 221 | - throw exception(CUSTOMER_OWNER_EXCEED_LIMIT); | ||
| 222 | - } | ||
| 223 | - }); | 167 | + // 3. 记录操作日志上下文 |
| 168 | + LogRecordContext.putVariable("crmCustomer", customer); | ||
| 224 | } | 169 | } |
| 225 | 170 | ||
| 226 | - /** | ||
| 227 | - * 校验用户锁定的客户数量,是否到达上限 | ||
| 228 | - * | ||
| 229 | - * @param userId 用户编号 | ||
| 230 | - */ | ||
| 231 | - private void validateCustomerExceedLockLimit(Long userId) { | ||
| 232 | - List<CrmCustomerLimitConfigDO> limitConfigs = customerLimitConfigService.getCustomerLimitConfigListByUserId( | ||
| 233 | - CUSTOMER_LOCK_LIMIT.getType(), userId); | ||
| 234 | - if (CollUtil.isEmpty(limitConfigs)) { | ||
| 235 | - return; | ||
| 236 | - } | ||
| 237 | - Long lockCount = customerMapper.selectCountByLockStatusAndOwnerUserId(true, userId); | ||
| 238 | - Integer maxCount = CollectionUtils.getMaxValue(limitConfigs, CrmCustomerLimitConfigDO::getMaxCount); | ||
| 239 | - assert maxCount != null; | ||
| 240 | - if (lockCount >= maxCount) { | ||
| 241 | - throw exception(CUSTOMER_LOCK_EXCEED_LIMIT); | ||
| 242 | - } | ||
| 243 | - } | 171 | + // ==================== 公海相关操作 ==================== |
| 244 | 172 | ||
| 245 | @Override | 173 | @Override |
| 246 | @Transactional(rollbackFor = Exception.class) | 174 | @Transactional(rollbackFor = Exception.class) |
| 247 | - @LogRecord(type = CRM_CUSTOMER, subType = "客户放入公海", bizNo = "{{#id}}", success = "将客户放入了公海") | ||
| 248 | - // TODO @puhui999:将客户【】放入了公海 | 175 | + @LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_POOL_SUB_TYPE, bizNo = "{{#id}}", success = CRM_CUSTOMER_POOL_SUCCESS) |
| 249 | @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#id", level = CrmPermissionLevelEnum.OWNER) | 176 | @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#id", level = CrmPermissionLevelEnum.OWNER) |
| 250 | public void putCustomerPool(Long id) { | 177 | public void putCustomerPool(Long id) { |
| 251 | // 1. 校验存在 | 178 | // 1. 校验存在 |
| @@ -267,16 +194,18 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | @@ -267,16 +194,18 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | ||
| 267 | permissionService.deletePermission(CrmBizTypeEnum.CRM_CUSTOMER.getType(), customer.getId(), | 194 | permissionService.deletePermission(CrmBizTypeEnum.CRM_CUSTOMER.getType(), customer.getId(), |
| 268 | CrmPermissionLevelEnum.OWNER.getLevel()); | 195 | CrmPermissionLevelEnum.OWNER.getLevel()); |
| 269 | // TODO @puhui999:联系人的负责人,也要设置为 null;这块和领取是对应的;因为领取后,负责人也要关联过来; | 196 | // TODO @puhui999:联系人的负责人,也要设置为 null;这块和领取是对应的;因为领取后,负责人也要关联过来; |
| 197 | + | ||
| 198 | + // 记录操作日志上下文 | ||
| 199 | + LogRecordContext.putVariable("customerName", customer.getName()); | ||
| 270 | } | 200 | } |
| 271 | 201 | ||
| 272 | @Override | 202 | @Override |
| 273 | @Transactional(rollbackFor = Exception.class) | 203 | @Transactional(rollbackFor = Exception.class) |
| 274 | - // TODO @puhui999:权限校验 | 204 | + public void receiveCustomer(List<Long> ids, Long ownerUserId, Boolean isReceive) { |
| 205 | + if (!isReceive && !CrmPermissionUtils.isCrmAdmin()) { // 只有管理员可以分配 | ||
| 206 | + throw exception(CRM_PERMISSION_DENIED, CrmBizTypeEnum.CRM_CUSTOMER.getName()); | ||
| 207 | + } | ||
| 275 | 208 | ||
| 276 | - // TODO @puhui999:如果是分配,操作日志是 “将客户【】分配给【】” | ||
| 277 | - // TODO @puhui999:如果是领取,操作日志是“领取客户【】”; | ||
| 278 | - // TODO @puhui999:如果是多条,则需要记录多条操作日志;不然 bizId 不好关联 | ||
| 279 | - public void receiveCustomer(List<Long> ids, Long ownerUserId) { | ||
| 280 | // 1.1 校验存在 | 209 | // 1.1 校验存在 |
| 281 | List<CrmCustomerDO> customers = customerMapper.selectBatchIds(ids); | 210 | List<CrmCustomerDO> customers = customerMapper.selectBatchIds(ids); |
| 282 | if (customers.size() != ids.size()) { | 211 | if (customers.size() != ids.size()) { |
| @@ -311,6 +240,53 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | @@ -311,6 +240,53 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | ||
| 311 | // 2.3 创建负责人数据权限 | 240 | // 2.3 创建负责人数据权限 |
| 312 | permissionService.createPermissionBatch(createPermissions); | 241 | permissionService.createPermissionBatch(createPermissions); |
| 313 | // TODO @芋艿:要不要处理关联的联系人??? | 242 | // TODO @芋艿:要不要处理关联的联系人??? |
| 243 | + | ||
| 244 | + // 3. 记录操作日志 | ||
| 245 | + AdminUserRespDTO user = null; | ||
| 246 | + if (!isReceive) { | ||
| 247 | + user = adminUserApi.getUser(ownerUserId); | ||
| 248 | + } | ||
| 249 | + for (CrmCustomerDO customer : customers) { | ||
| 250 | + receiveCustomerLog(customer, user == null ? null : user.getNickname()); | ||
| 251 | + } | ||
| 252 | + } | ||
| 253 | + | ||
| 254 | + @LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_RECEIVE_SUB_TYPE, bizNo = "{{#customer.id}}", success = CRM_CUSTOMER_RECEIVE_SUCCESS) | ||
| 255 | + public void receiveCustomerLog(CrmCustomerDO customer, String ownerUserName) { | ||
| 256 | + | ||
| 257 | + } | ||
| 258 | + | ||
| 259 | + //======================= 查询相关 ======================= | ||
| 260 | + | ||
| 261 | + @Override | ||
| 262 | + @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#id", level = CrmPermissionLevelEnum.READ) | ||
| 263 | + public CrmCustomerDO getCustomer(Long id) { | ||
| 264 | + return customerMapper.selectById(id); | ||
| 265 | + } | ||
| 266 | + | ||
| 267 | + @Override | ||
| 268 | + public List<CrmCustomerDO> getCustomerList(Collection<Long> ids) { | ||
| 269 | + if (CollUtil.isEmpty(ids)) { | ||
| 270 | + return Collections.emptyList(); | ||
| 271 | + } | ||
| 272 | + return customerMapper.selectBatchIds(ids); | ||
| 273 | + } | ||
| 274 | + | ||
| 275 | + @Override | ||
| 276 | + public PageResult<CrmCustomerDO> getCustomerPage(CrmCustomerPageReqVO pageReqVO, Long userId) { | ||
| 277 | + return customerMapper.selectPage(pageReqVO, userId); | ||
| 278 | + } | ||
| 279 | + | ||
| 280 | + //======================= 校验相关 ======================= | ||
| 281 | + | ||
| 282 | + /** | ||
| 283 | + * 校验客户是否存在 | ||
| 284 | + * | ||
| 285 | + * @param customerId 客户 id | ||
| 286 | + */ | ||
| 287 | + @Override | ||
| 288 | + public void validateCustomer(Long customerId) { | ||
| 289 | + validateCustomerExists(customerId); | ||
| 314 | } | 290 | } |
| 315 | 291 | ||
| 316 | private void validateCustomerOwnerExists(CrmCustomerDO customer, Boolean pool) { | 292 | private void validateCustomerOwnerExists(CrmCustomerDO customer, Boolean pool) { |
| @@ -327,6 +303,14 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | @@ -327,6 +303,14 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | ||
| 327 | } | 303 | } |
| 328 | } | 304 | } |
| 329 | 305 | ||
| 306 | + private CrmCustomerDO validateCustomerExists(Long id) { | ||
| 307 | + CrmCustomerDO customerDO = customerMapper.selectById(id); | ||
| 308 | + if (customerDO == null) { | ||
| 309 | + throw exception(CUSTOMER_NOT_EXISTS); | ||
| 310 | + } | ||
| 311 | + return customerDO; | ||
| 312 | + } | ||
| 313 | + | ||
| 330 | private void validateCustomerIsLocked(CrmCustomerDO customer, Boolean pool) { | 314 | private void validateCustomerIsLocked(CrmCustomerDO customer, Boolean pool) { |
| 331 | if (customer.getLockStatus()) { | 315 | if (customer.getLockStatus()) { |
| 332 | throw exception(pool ? CUSTOMER_LOCKED_PUT_POOL_FAIL : CUSTOMER_LOCKED, customer.getName()); | 316 | throw exception(pool ? CUSTOMER_LOCKED_PUT_POOL_FAIL : CUSTOMER_LOCKED, customer.getName()); |
| @@ -339,9 +323,45 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | @@ -339,9 +323,45 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | ||
| 339 | } | 323 | } |
| 340 | } | 324 | } |
| 341 | 325 | ||
| 342 | - @Override | ||
| 343 | - public List<CrmCustomerDO> getCustomerList() { | ||
| 344 | - return customerMapper.selectList(); | 326 | + /** |
| 327 | + * 校验用户拥有的客户数量,是否到达上限 | ||
| 328 | + * | ||
| 329 | + * @param userId 用户编号 | ||
| 330 | + * @param newCount 附加数量 | ||
| 331 | + */ | ||
| 332 | + private void validateCustomerExceedOwnerLimit(Long userId, int newCount) { | ||
| 333 | + List<CrmCustomerLimitConfigDO> limitConfigs = customerLimitConfigService.getCustomerLimitConfigListByUserId( | ||
| 334 | + CUSTOMER_OWNER_LIMIT.getType(), userId); | ||
| 335 | + if (CollUtil.isEmpty(limitConfigs)) { | ||
| 336 | + return; | ||
| 337 | + } | ||
| 338 | + Long ownerCount = customerMapper.selectCountByDealStatusAndOwnerUserId(null, userId); | ||
| 339 | + Long dealOwnerCount = customerMapper.selectCountByDealStatusAndOwnerUserId(true, userId); | ||
| 340 | + limitConfigs.forEach(limitConfig -> { | ||
| 341 | + long nowCount = limitConfig.getDealCountEnabled() ? ownerCount : ownerCount - dealOwnerCount; | ||
| 342 | + if (nowCount + newCount > limitConfig.getMaxCount()) { | ||
| 343 | + throw exception(CUSTOMER_OWNER_EXCEED_LIMIT); | ||
| 344 | + } | ||
| 345 | + }); | ||
| 346 | + } | ||
| 347 | + | ||
| 348 | + /** | ||
| 349 | + * 校验用户锁定的客户数量,是否到达上限 | ||
| 350 | + * | ||
| 351 | + * @param userId 用户编号 | ||
| 352 | + */ | ||
| 353 | + private void validateCustomerExceedLockLimit(Long userId) { | ||
| 354 | + List<CrmCustomerLimitConfigDO> limitConfigs = customerLimitConfigService.getCustomerLimitConfigListByUserId( | ||
| 355 | + CUSTOMER_LOCK_LIMIT.getType(), userId); | ||
| 356 | + if (CollUtil.isEmpty(limitConfigs)) { | ||
| 357 | + return; | ||
| 358 | + } | ||
| 359 | + Long lockCount = customerMapper.selectCountByLockStatusAndOwnerUserId(true, userId); | ||
| 360 | + Integer maxCount = CollectionUtils.getMaxValue(limitConfigs, CrmCustomerLimitConfigDO::getMaxCount); | ||
| 361 | + assert maxCount != null; | ||
| 362 | + if (lockCount >= maxCount) { | ||
| 363 | + throw exception(CUSTOMER_LOCK_EXCEED_LIMIT); | ||
| 364 | + } | ||
| 345 | } | 365 | } |
| 346 | 366 | ||
| 347 | } | 367 | } |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionService.java
| @@ -91,6 +91,15 @@ public interface CrmPermissionService { | @@ -91,6 +91,15 @@ public interface CrmPermissionService { | ||
| 91 | List<CrmPermissionDO> getPermissionListByBiz(Integer bizType, Long bizId); | 91 | List<CrmPermissionDO> getPermissionListByBiz(Integer bizType, Long bizId); |
| 92 | 92 | ||
| 93 | /** | 93 | /** |
| 94 | + * 获取数据权限列表,通过 数据类型 x 某个数据 | ||
| 95 | + * | ||
| 96 | + * @param bizType 数据类型,关联 {@link CrmBizTypeEnum} | ||
| 97 | + * @param bizIds 数据编号,关联 {@link CrmBizTypeEnum} 对应模块 DO#getId() | ||
| 98 | + * @return Crm 数据权限列表 | ||
| 99 | + */ | ||
| 100 | + List<CrmPermissionDO> getPermissionListByBiz(Integer bizType, Collection<Long> bizIds); | ||
| 101 | + | ||
| 102 | + /** | ||
| 94 | * 获取用户参与的模块数据列表 | 103 | * 获取用户参与的模块数据列表 |
| 95 | * | 104 | * |
| 96 | * @param bizType 模块类型 | 105 | * @param bizType 模块类型 |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionServiceImpl.java
| @@ -188,6 +188,11 @@ public class CrmPermissionServiceImpl implements CrmPermissionService { | @@ -188,6 +188,11 @@ public class CrmPermissionServiceImpl implements CrmPermissionService { | ||
| 188 | } | 188 | } |
| 189 | 189 | ||
| 190 | @Override | 190 | @Override |
| 191 | + public List<CrmPermissionDO> getPermissionListByBiz(Integer bizType, Collection<Long> bizIds) { | ||
| 192 | + return crmPermissionMapper.selectByBizTypeAndBizIds(bizType, bizIds); | ||
| 193 | + } | ||
| 194 | + | ||
| 195 | + @Override | ||
| 191 | public List<CrmPermissionDO> getPermissionListByBizTypeAndUserId(Integer bizType, Long userId) { | 196 | public List<CrmPermissionDO> getPermissionListByBizTypeAndUserId(Integer bizType, Long userId) { |
| 192 | return crmPermissionMapper.selectListByBizTypeAndUserId(bizType, userId); | 197 | return crmPermissionMapper.selectListByBizTypeAndUserId(bizType, userId); |
| 193 | } | 198 | } |