CRM:完善数据分页查询条件构造 CrmQueryWrapperUtils
This commit is contained in:
parent
3bab9748db
commit
3e91ac73c4
@ -0,0 +1,27 @@
|
||||
package cn.iocoder.yudao.module.crm.enums.permission;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* Crm 数据权限角色枚举
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum CrmPermissionRoleCodeEnum {
|
||||
|
||||
CRM_ADMIN("crm_admin", "CRM 管理员");
|
||||
|
||||
/**
|
||||
* 角色标识
|
||||
*/
|
||||
private String code;
|
||||
/**
|
||||
* 角色名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
### 请求 /transfer
|
||||
PUT {{baseUrl}}/crm/customer/transfer
|
||||
Content-Type: application/json
|
||||
Content-Type: application/-id: {{adminTenentId}}json
|
||||
Authorization: Bearer {{token}}
|
||||
tenant-id: {{adminTenentId}}
|
||||
tenant
|
||||
|
||||
{
|
||||
"id": 10,
|
||||
|
@ -3,8 +3,10 @@ package cn.iocoder.yudao.module.crm.controller.admin.customer;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
||||
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
|
||||
import cn.iocoder.yudao.framework.operatelogv2.core.vo.OperateLogV2PageReqVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.*;
|
||||
import cn.iocoder.yudao.module.crm.convert.customer.CrmCustomerConvert;
|
||||
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
|
||||
@ -12,6 +14,7 @@ import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
|
||||
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
||||
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
|
||||
import cn.iocoder.yudao.module.system.api.logger.OperateLogApi;
|
||||
import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2PageReqDTO;
|
||||
import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2RespDTO;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||
@ -135,23 +138,14 @@ public class CrmCustomerController {
|
||||
return success(true);
|
||||
}
|
||||
|
||||
// TODO @puhui999:operate-log-list 或者 operate-log-page 如果分页
|
||||
@GetMapping("/operate-log")
|
||||
@GetMapping("/operate-log-page")
|
||||
@Operation(summary = "获得客户操作日志")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('crm:customer:query')")
|
||||
// TODO @puhui999:最好有读权限;方法名改成 getCustomerOperateLog
|
||||
public CommonResult<List<OperateLogV2RespDTO>> getOperateLog(@RequestParam("id") Long id) {
|
||||
// 1. 获取客户
|
||||
// TODO @puhui999:这个校验可以去掉哈;
|
||||
CrmCustomerDO customer = customerService.getCustomer(id);
|
||||
if (customer == null) {
|
||||
return success(null);
|
||||
}
|
||||
|
||||
// 2. 获取操作日志
|
||||
// TODO @puhui999:操作日志,返回可能要分页哈;
|
||||
return success(operateLogApi.getOperateLogByModuleAndBizId(CRM_CUSTOMER, id));
|
||||
public CommonResult<PageResult<OperateLogV2RespDTO>> getCustomerOperateLog(OperateLogV2PageReqVO reqVO) {
|
||||
reqVO.setPageSize(PAGE_SIZE_NONE); // 不分页
|
||||
reqVO.setBizType(CRM_CUSTOMER);
|
||||
return success(operateLogApi.getOperateLogPage(BeanUtils.toBean(reqVO, OperateLogV2PageReqDTO.class)));
|
||||
}
|
||||
|
||||
// TODO @Joey:单独建一个属于自己业务的 ReqVO;因为前端如果模拟请求,是不是可以更新其它字段了;
|
||||
|
@ -38,11 +38,8 @@ public interface CrmBusinessMapper extends BaseMapperX<CrmBusinessDO> {
|
||||
default PageResult<CrmBusinessDO> selectPage(CrmBusinessPageReqVO pageReqVO, Long userId) {
|
||||
MPJLambdaWrapperX<CrmBusinessDO> query = new MPJLambdaWrapperX<>();
|
||||
// 拼接数据权限的查询条件
|
||||
boolean condition = CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_BUSINESS.getType(),
|
||||
CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_BUSINESS.getType(),
|
||||
CrmBusinessDO::getId, userId, pageReqVO.getSceneType(), Boolean.FALSE);
|
||||
if (!condition) {
|
||||
return PageResult.empty();
|
||||
}
|
||||
// 拼接自身的查询条件
|
||||
query.selectAll(CrmBusinessDO.class)
|
||||
.likeIfPresent(CrmBusinessDO::getName, pageReqVO.getName())
|
||||
|
@ -30,11 +30,8 @@ public interface CrmClueMapper extends BaseMapperX<CrmClueDO> {
|
||||
default PageResult<CrmClueDO> selectPage(CrmCluePageReqVO pageReqVO, Long userId) {
|
||||
MPJLambdaWrapperX<CrmClueDO> query = new MPJLambdaWrapperX<>();
|
||||
// 拼接数据权限的查询条件
|
||||
boolean condition = CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_LEADS.getType(),
|
||||
CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_LEADS.getType(),
|
||||
CrmClueDO::getId, userId, pageReqVO.getSceneType(), pageReqVO.getPool());
|
||||
if (!condition) {
|
||||
return PageResult.empty();
|
||||
}
|
||||
// 拼接自身的查询条件
|
||||
query.selectAll(CrmClueDO.class)
|
||||
.likeIfPresent(CrmClueDO::getName, pageReqVO.getName())
|
||||
|
@ -43,11 +43,8 @@ public interface CrmContactMapper extends BaseMapperX<CrmContactDO> {
|
||||
default PageResult<CrmContactDO> selectPage(CrmContactPageReqVO pageReqVO, Long userId) {
|
||||
MPJLambdaWrapperX<CrmContactDO> query = new MPJLambdaWrapperX<>();
|
||||
// 拼接数据权限的查询条件
|
||||
boolean condition = CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CONTACT.getType(),
|
||||
CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CONTACT.getType(),
|
||||
CrmContactDO::getId, userId, pageReqVO.getSceneType(), Boolean.FALSE);
|
||||
if (!condition) {
|
||||
return PageResult.empty();
|
||||
}
|
||||
// 拼接自身的查询条件
|
||||
query.selectAll(CrmContactDO.class)
|
||||
.likeIfPresent(CrmContactDO::getName, pageReqVO.getName())
|
||||
|
@ -41,11 +41,8 @@ public interface CrmContractMapper extends BaseMapperX<CrmContractDO> {
|
||||
default PageResult<CrmContractDO> selectPage(CrmContractPageReqVO pageReqVO, Long userId) {
|
||||
MPJLambdaWrapperX<CrmContractDO> mpjLambdaWrapperX = new MPJLambdaWrapperX<>();
|
||||
// 拼接数据权限的查询条件
|
||||
boolean condition = CrmQueryWrapperUtils.appendPermissionCondition(mpjLambdaWrapperX, CrmBizTypeEnum.CRM_CONTACT.getType(),
|
||||
CrmQueryWrapperUtils.appendPermissionCondition(mpjLambdaWrapperX, CrmBizTypeEnum.CRM_CONTACT.getType(),
|
||||
CrmContractDO::getId, userId, pageReqVO.getSceneType(), Boolean.FALSE);
|
||||
if (!condition) {
|
||||
return PageResult.empty();
|
||||
}
|
||||
// 拼接自身的查询条件
|
||||
mpjLambdaWrapperX.selectAll(CrmContractDO.class)
|
||||
.likeIfPresent(CrmContractDO::getNo, pageReqVO.getNo())
|
||||
|
@ -30,11 +30,8 @@ public interface CrmCustomerMapper extends BaseMapperX<CrmCustomerDO> {
|
||||
default PageResult<CrmCustomerDO> selectPage(CrmCustomerPageReqVO pageReqVO, Long userId) {
|
||||
MPJLambdaWrapperX<CrmCustomerDO> query = new MPJLambdaWrapperX<>();
|
||||
// 拼接数据权限的查询条件
|
||||
boolean condition = CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CUSTOMER.getType(),
|
||||
CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CUSTOMER.getType(),
|
||||
CrmCustomerDO::getId, userId, pageReqVO.getSceneType(), pageReqVO.getPool());
|
||||
if (!condition) {
|
||||
return PageResult.empty();
|
||||
}
|
||||
// 拼接自身的查询条件
|
||||
query.selectAll(CrmCustomerDO.class)
|
||||
.likeIfPresent(CrmCustomerDO::getName, pageReqVO.getName())
|
||||
|
@ -39,11 +39,8 @@ public interface CrmReceivableMapper extends BaseMapperX<CrmReceivableDO> {
|
||||
default PageResult<CrmReceivableDO> selectPage(CrmReceivablePageReqVO pageReqVO, Long userId) {
|
||||
MPJLambdaWrapperX<CrmReceivableDO> query = new MPJLambdaWrapperX<>();
|
||||
// 拼接数据权限的查询条件
|
||||
boolean condition = CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_RECEIVABLE.getType(),
|
||||
CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_RECEIVABLE.getType(),
|
||||
CrmReceivableDO::getId, userId, pageReqVO.getSceneType(), Boolean.FALSE);
|
||||
if (!condition) {
|
||||
return PageResult.empty();
|
||||
}
|
||||
// 拼接自身的查询条件
|
||||
query.selectAll(CrmReceivableDO.class)
|
||||
.eqIfPresent(CrmReceivableDO::getNo, pageReqVO.getNo())
|
||||
|
@ -38,11 +38,8 @@ public interface CrmReceivablePlanMapper extends BaseMapperX<CrmReceivablePlanDO
|
||||
default PageResult<CrmReceivablePlanDO> selectPage(CrmReceivablePlanPageReqVO pageReqVO, Long userId) {
|
||||
MPJLambdaWrapperX<CrmReceivablePlanDO> query = new MPJLambdaWrapperX<>();
|
||||
// 拼接数据权限的查询条件
|
||||
boolean condition = CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_RECEIVABLE_PLAN.getType(),
|
||||
CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_RECEIVABLE_PLAN.getType(),
|
||||
CrmReceivablePlanDO::getId, userId, pageReqVO.getSceneType(), Boolean.FALSE);
|
||||
if (!condition) {
|
||||
return PageResult.empty();
|
||||
}
|
||||
// 拼接自身的查询条件
|
||||
query.selectAll(CrmReceivablePlanDO.class)
|
||||
.eqIfPresent(CrmReceivablePlanDO::getCustomerId, pageReqVO.getCustomerId())
|
||||
|
@ -7,9 +7,12 @@ import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO;
|
||||
import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
|
||||
import cn.iocoder.yudao.module.crm.enums.common.CrmSceneTypeEnum;
|
||||
import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
|
||||
import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionRoleCodeEnum;
|
||||
import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
|
||||
import com.github.yulichang.autoconfigure.MybatisPlusJoinProperties;
|
||||
import com.github.yulichang.wrapper.MPJLambdaWrapper;
|
||||
|
||||
import java.util.Collection;
|
||||
@ -33,46 +36,41 @@ public class CrmQueryWrapperUtils {
|
||||
* @param userId 用户编号
|
||||
* @param sceneType 场景类型
|
||||
* @param pool 公海
|
||||
* @return 是否 (是:需要执行查询,否:不需要查询调用方法直接返回空)
|
||||
*/
|
||||
// TODO @puhui999:bizId 直接传递会不会简单点 回复:还是需要 SFunction 因为分页连表时不知道 bizId 是多少;是不是把 bizId 传入就好啦?
|
||||
public static <T extends MPJLambdaWrapper<?>, S> boolean appendPermissionCondition(T query, Integer bizType, SFunction<S, ?> bizId,
|
||||
Long userId, Integer sceneType, Boolean pool) {
|
||||
public static <T extends MPJLambdaWrapper<?>, S> void appendPermissionCondition(T query, Integer bizType, SFunction<S, ?> bizId,
|
||||
Long userId, Integer sceneType, Boolean pool) {
|
||||
final String ownerUserIdField = SingletonManager.getMybatisPlusJoinProperties().getTableAlias() + ".owner_user_id";
|
||||
// 1. 构建数据权限连表条件
|
||||
if (ObjUtil.notEqual(validateAdminUser(userId), Boolean.TRUE)) { // 管理员不需要数据权限
|
||||
if (ObjUtil.notEqual(validateAdminUser(userId), Boolean.TRUE) && ObjUtil.notEqual(pool, Boolean.TRUE)) { // 管理员,公海不需要数据权限
|
||||
query.innerJoin(CrmPermissionDO.class, on -> on.eq(CrmPermissionDO::getBizType, bizType)
|
||||
.eq(CrmPermissionDO::getBizId, bizId)
|
||||
.eq(CrmPermissionDO::getBizId, bizId) // 只能使用 SFunction 如果传 id 解析出来的 sql 不对
|
||||
.eq(CrmPermissionDO::getUserId, userId));
|
||||
}
|
||||
// 2.1 场景一:我负责的数据
|
||||
if (CrmSceneTypeEnum.isOwner(sceneType)) {
|
||||
query.eq("owner_user_id", userId);
|
||||
query.eq(ownerUserIdField, userId);
|
||||
}
|
||||
// 2.2 场景二:我参与的数据
|
||||
if (CrmSceneTypeEnum.isInvolved(sceneType)) {
|
||||
query.ne("owner_user_id", userId)
|
||||
// TODO @puhui999:IN 是不是更合适哈;
|
||||
.and(q -> q.eq(CrmPermissionDO::getLevel, CrmPermissionLevelEnum.READ.getLevel())
|
||||
.or()
|
||||
.eq(CrmPermissionDO::getLevel, CrmPermissionLevelEnum.WRITE.getLevel()));
|
||||
query.ne(ownerUserIdField, userId)
|
||||
.in(CrmPermissionDO::getLevel, CrmPermissionLevelEnum.READ.getLevel(), CrmPermissionLevelEnum.WRITE.getLevel());
|
||||
}
|
||||
// 2.3 场景三:下属负责的数据
|
||||
if (CrmSceneTypeEnum.isSubordinate(sceneType)) {
|
||||
// TODO @puhui999:要不如果没有下属,拼一个 owner_user_id in null,不返回结果就好啦;
|
||||
List<AdminUserRespDTO> subordinateUsers = getAdminUserApi().getUserListBySubordinate(userId);
|
||||
List<AdminUserRespDTO> subordinateUsers = SingletonManager.getAdminUserApi().getUserListBySubordinate(userId);
|
||||
if (CollUtil.isEmpty(subordinateUsers)) {
|
||||
return false;
|
||||
query.eq(ownerUserIdField, -1); // 不返回任何结果
|
||||
} else {
|
||||
query.in(ownerUserIdField, convertSet(subordinateUsers, AdminUserRespDTO::getId));
|
||||
}
|
||||
query.in("owner_user_id", convertSet(subordinateUsers, AdminUserRespDTO::getId));
|
||||
}
|
||||
|
||||
// 3. 拼接公海的查询条件
|
||||
if (ObjUtil.equal(pool, Boolean.TRUE)) { // 情况一:公海
|
||||
query.isNull("owner_user_id");
|
||||
query.isNull(ownerUserIdField);
|
||||
} else { // 情况二:不是公海
|
||||
query.isNotNull("owner_user_id");
|
||||
query.isNotNull(ownerUserIdField);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -93,38 +91,38 @@ public class CrmQueryWrapperUtils {
|
||||
.in(CollUtil.isNotEmpty(bizIds), CrmPermissionDO::getUserId, userId));
|
||||
}
|
||||
|
||||
private static AdminUserApi getAdminUserApi() {
|
||||
return AdminUserApiHolder.ADMIN_USER_API;
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验用户是否是管理员
|
||||
* 校验用户是否是 CRM 管理员
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @return 是/否
|
||||
*/
|
||||
private static boolean validateAdminUser(Long userId) {
|
||||
// TODO 查询权限配置表用户的角色信息
|
||||
// TODO @puhui999:查询用户的角色;CRM_ADMIN("crm_admin", "CRM 管理员"),
|
||||
//CrmPermissionConfig permissionConfig = crmPermissionConfigService.getPermissionConfigByUserId(userId);
|
||||
//if (permissionConfig == null) {
|
||||
// return false;
|
||||
//}
|
||||
//// 校验是否为管理员
|
||||
//if (permissionConfig.getIsAdmin()){
|
||||
// return true;
|
||||
//}
|
||||
return false;
|
||||
return SingletonManager.getPermissionApi().hasAnyRoles(userId, CrmPermissionRoleCodeEnum.CRM_ADMIN.getCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* 静态内部类实现 AdminUserApi 单例获取
|
||||
* 静态内部类实现单例获取
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
private static class AdminUserApiHolder {
|
||||
private static class SingletonManager {
|
||||
|
||||
private static final AdminUserApi ADMIN_USER_API = SpringUtil.getBean(AdminUserApi.class);
|
||||
private static final PermissionApi PERMISSION_API = SpringUtil.getBean(PermissionApi.class);
|
||||
private static final MybatisPlusJoinProperties MYBATIS_PLUS_JOIN_PROPERTIES = SpringUtil.getBean(MybatisPlusJoinProperties.class);
|
||||
|
||||
public static AdminUserApi getAdminUserApi() {
|
||||
return ADMIN_USER_API;
|
||||
}
|
||||
|
||||
public static PermissionApi getPermissionApi() {
|
||||
return PERMISSION_API;
|
||||
}
|
||||
|
||||
public static MybatisPlusJoinProperties getMybatisPlusJoinProperties() {
|
||||
return MYBATIS_PLUS_JOIN_PROPERTIES;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -188,6 +188,7 @@ logging:
|
||||
cn.iocoder.yudao.module.trade.dal.mysql: debug
|
||||
cn.iocoder.yudao.module.promotion.dal.mysql: debug
|
||||
cn.iocoder.yudao.module.statistics.dal.mysql: debug
|
||||
cn.iocoder.yudao.module.crm.dal.mysql: debug
|
||||
|
||||
debug: false
|
||||
|
||||
|
@ -79,7 +79,17 @@ mybatis-plus:
|
||||
password: XDV71a+xqStEA3WH # 加解密的秘钥,可使用 https://www.imaegoo.com/2020/aes-key-generator/ 网站生成
|
||||
|
||||
mybatis-plus-join:
|
||||
banner: false # 关闭控制台的 Banner 打印
|
||||
#是否打印 mybatis plus join banner 默认true
|
||||
banner: false
|
||||
#全局启用副表逻辑删除(默认true) 关闭后关联查询不会加副表逻辑删除
|
||||
sub-table-logic: true
|
||||
#拦截器MappedStatement缓存(默认true)
|
||||
ms-cache: true
|
||||
#表别名(默认 t)
|
||||
table-alias: t
|
||||
#副表逻辑删除条件的位置,支持where、on
|
||||
#默认ON (1.4.7.2及之前版本默认为where)
|
||||
logic-del-type: on
|
||||
|
||||
# Spring Data Redis 配置
|
||||
spring:
|
||||
|
Loading…
Reference in New Issue
Block a user