CRM-数据权限:完善 review 提到的问题

This commit is contained in:
puhui999 2023-12-11 12:02:41 +08:00
parent 23df8633f4
commit e4d3175f06
31 changed files with 169 additions and 123 deletions

View File

@ -22,7 +22,8 @@ public enum CrmBizTypeEnum implements IntArrayValuable {
CRM_CONTACT(3, "联系人"),
CRM_BUSINESS(4, "商机"),
CRM_CONTRACT(5, "合同"),
CRM_PRODUCT(6, "产品")
CRM_PRODUCT(6, "产品"),
CRM_RECEIVABLE(7, "回款")
;
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CrmBizTypeEnum::getType).toArray();

View File

@ -122,7 +122,7 @@ public class CrmBusinessController {
@Operation(summary = "获得商机分页,基于指定客户")
public CommonResult<PageResult<CrmBusinessRespVO>> getBusinessPageByCustomer(@Valid CrmBusinessPageReqVO pageReqVO) {
Assert.notNull(pageReqVO.getCustomerId(), "客户编号不能为空");
PageResult<CrmBusinessDO> pageResult = businessService.getBusinessPageByCustomer(pageReqVO, getLoginUserId());
PageResult<CrmBusinessDO> pageResult = businessService.getBusinessPageByCustomerId(pageReqVO);
// 处理客户名称回显
// TODO @ljlleo可以使用 CollectionUtils.convertSet 替代常用的 stream 操作更简洁一点下面几个也是哈
Set<Long> customerIds = pageResult.getList().stream()

View File

@ -24,7 +24,4 @@ public class CrmBusinessPageReqVO extends PageParam {
@InEnum(CrmSceneTypeEnum.class)
private Integer sceneType; // 场景类型 null 时则表示全部
@Schema(description = "是否为公海数据", requiredMode = Schema.RequiredMode.REQUIRED, example = "false")
private Boolean pool; // null 则表示为不是公海数据
}

View File

@ -125,7 +125,7 @@ public class CrmContactController {
@Operation(summary = "获得联系人分页,基于指定客户")
public CommonResult<PageResult<CrmContactRespVO>> getContactPageByCustomer(@Valid CrmContactPageReqVO pageVO) {
Assert.notNull(pageVO.getCustomerId(), "客户编号不能为空");
PageResult<CrmContactDO> pageResult = contactService.getContactPageByCustomerId(pageVO, getLoginUserId());
PageResult<CrmContactDO> pageResult = contactService.getContactPageByCustomerId(pageVO);
return success(convertDetailContactPage(pageResult));
}

View File

@ -39,7 +39,4 @@ public class CrmContactPageReqVO extends PageParam {
@InEnum(CrmSceneTypeEnum.class)
private Integer sceneType; // 场景类型 null 时则表示全部
@Schema(description = "是否为公海数据", requiredMode = Schema.RequiredMode.REQUIRED, example = "false")
private Boolean pool; // null 则表示为不是公海数据
}

View File

@ -95,7 +95,7 @@ public class CrmContractController {
@Operation(summary = "获得联系人分页,基于指定客户")
public CommonResult<PageResult<ContractRespVO>> getContractPageByCustomer(@Valid CrmContractPageReqVO pageVO) {
Assert.notNull(pageVO.getCustomerId(), "客户编号不能为空");
PageResult<CrmContractDO> pageResult = contractService.getContractPageByCustomer(pageVO, getLoginUserId());
PageResult<CrmContractDO> pageResult = contractService.getContractPageByCustomerId(pageVO);
return success(convertDetailContractPage(pageResult));
}

View File

@ -30,7 +30,4 @@ public class CrmContractPageReqVO extends PageParam {
@InEnum(CrmSceneTypeEnum.class)
private Integer sceneType; // 场景类型 null 时则表示全部
@Schema(description = "是否为公海数据", requiredMode = Schema.RequiredMode.REQUIRED, example = "false")
private Boolean pool; // null 则表示为不是公海数据 TODO @puhui999合同没有公海目前只有客户线索有公海其它都没
}

View File

@ -36,6 +36,7 @@ import java.util.Map;
import java.util.stream.Stream;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertListByFlatMap;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
@ -94,7 +95,7 @@ public class CrmReceivableController {
@Operation(summary = "获得回款分页")
@PreAuthorize("@ss.hasPermission('crm:receivable:query')")
public CommonResult<PageResult<CrmReceivableRespVO>> getReceivablePage(@Valid CrmReceivablePageReqVO pageReqVO) {
PageResult<CrmReceivableDO> pageResult = receivableService.getReceivablePage(pageReqVO);
PageResult<CrmReceivableDO> pageResult = receivableService.getReceivablePage(pageReqVO, getLoginUserId());
return success(convertDetailReceivablePage(pageResult));
}
@ -102,7 +103,7 @@ public class CrmReceivableController {
@Operation(summary = "获得回款分页,基于指定客户")
public CommonResult<PageResult<CrmReceivableRespVO>> getReceivablePageByCustomer(@Valid CrmReceivablePageReqVO pageReqVO) {
Assert.notNull(pageReqVO.getCustomerId(), "客户编号不能为空");
PageResult<CrmReceivableDO> pageResult = receivableService.getReceivablePageByCustomer(pageReqVO);
PageResult<CrmReceivableDO> pageResult = receivableService.getReceivablePageByCustomerId(pageReqVO);
return success(convertDetailReceivablePage(pageResult));
}
@ -113,7 +114,8 @@ public class CrmReceivableController {
@OperateLog(type = EXPORT)
public void exportReceivableExcel(@Valid CrmReceivablePageReqVO exportReqVO,
HttpServletResponse response) throws IOException {
PageResult<CrmReceivableDO> pageResult = receivableService.getReceivablePage(exportReqVO);
exportReqVO.setPageSize(PAGE_SIZE_NONE);
PageResult<CrmReceivableDO> pageResult = receivableService.getReceivablePage(exportReqVO, getLoginUserId());
// 导出 Excel
ExcelUtils.write(response, "回款.xls", "数据", CrmReceivableRespVO.class,
convertDetailReceivablePage(pageResult).getList());

View File

@ -25,7 +25,4 @@ public class CrmReceivablePlanPageReqVO extends PageParam {
@InEnum(CrmSceneTypeEnum.class)
private Integer sceneType; // 场景类型 null 时则表示全部
@Schema(description = "是否为公海数据", requiredMode = Schema.RequiredMode.REQUIRED, example = "false")
private Boolean pool; // null 则表示为不是公海数据
}

View File

@ -27,7 +27,4 @@ public class CrmReceivablePageReqVO extends PageParam {
@InEnum(CrmSceneTypeEnum.class)
private Integer sceneType; // 场景类型 null 时则表示全部
@Schema(description = "是否为公海数据", requiredMode = Schema.RequiredMode.REQUIRED, example = "false")
private Boolean pool; // null 则表示为不是公海数据
}

View File

@ -9,7 +9,6 @@ import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferRe
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
import java.util.List;
@ -48,10 +47,7 @@ public interface ContactConvert {
List<CrmContactSimpleRespVO> convertAllList(List<CrmContactDO> list);
@Mappings({
@Mapping(target = "bizId", source = "reqVO.id"),
@Mapping(target = "newOwnerUserId", source = "reqVO.id")
})
@Mapping(target = "bizId", source = "reqVO.id")
CrmPermissionTransferReqBO convert(CrmContactTransferReqVO reqVO, Long userId);
/**

View File

@ -8,7 +8,6 @@ import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferRe
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
import java.util.List;
@ -39,10 +38,7 @@ public interface ContractConvert {
List<CrmContractExcelVO> convertList02(List<CrmContractDO> list);
@Mappings({
@Mapping(target = "bizId", source = "reqVO.id"),
@Mapping(target = "newOwnerUserId", source = "reqVO.id")
})
@Mapping(target = "bizId", source = "reqVO.id")
CrmPermissionTransferReqBO convert(CrmContractTransferReqVO reqVO, Long userId);
default PageResult<ContractRespVO> convertPage(PageResult<CrmContractDO> pageResult, Map<Long, AdminUserRespDTO> userMap,

View File

@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.crm.dal.mysql.business;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessPageReqVO;
import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
@ -27,14 +28,20 @@ public interface CrmBusinessMapper extends BaseMapperX<CrmBusinessDO> {
.set(CrmBusinessDO::getOwnerUserId, ownerUserId));
}
default PageResult<CrmBusinessDO> selectPageByCustomerId(CrmBusinessPageReqVO pageReqVO) {
return selectPage(pageReqVO, new LambdaQueryWrapperX<CrmBusinessDO>()
.eq(CrmBusinessDO::getCustomerId, pageReqVO.getCustomerId()) // 指定客户编号
.likeIfPresent(CrmBusinessDO::getName, pageReqVO.getName())
.orderByDesc(CrmBusinessDO::getId));
}
default PageResult<CrmBusinessDO> selectPage(CrmBusinessPageReqVO pageReqVO, Long userId) {
MPJLambdaWrapperX<CrmBusinessDO> query = new MPJLambdaWrapperX<>();
// 拼接数据权限的查询条件
CrmQueryWrapperUtils.builderPageQuery(query, CrmBizTypeEnum.CRM_BUSINESS.getType(), CrmBusinessDO::getId,
userId, pageReqVO.getSceneType(), pageReqVO.getPool());
CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_BUSINESS.getType(), CrmBusinessDO::getId,
userId, pageReqVO.getSceneType(), Boolean.FALSE);
// 拼接自身的查询条件
query.selectAll(CrmBusinessDO.class)
.eqIfPresent(CrmBusinessDO::getCustomerId, pageReqVO.getCustomerId()) // 指定客户编号
.likeIfPresent(CrmBusinessDO::getName, pageReqVO.getName())
.orderByDesc(CrmBusinessDO::getId);
return selectJoinPage(pageReqVO, CrmBusinessDO.class, query);
@ -43,7 +50,7 @@ public interface CrmBusinessMapper extends BaseMapperX<CrmBusinessDO> {
default List<CrmBusinessDO> selectBatchIds(Collection<Long> ids, Long userId) {
MPJLambdaWrapperX<CrmBusinessDO> query = new MPJLambdaWrapperX<>();
// 拼接数据权限的查询条件
CrmQueryWrapperUtils.builderListQueryBatch(query, CrmBizTypeEnum.CRM_BUSINESS.getType(), ids, userId);
CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_BUSINESS.getType(), ids, userId);
return selectJoinList(CrmBusinessDO.class, query);
}

View File

@ -30,7 +30,7 @@ public interface CrmClueMapper extends BaseMapperX<CrmClueDO> {
default PageResult<CrmClueDO> selectPage(CrmCluePageReqVO pageReqVO, Long userId) {
MPJLambdaWrapperX<CrmClueDO> query = new MPJLambdaWrapperX<>();
// 拼接数据权限的查询条件
CrmQueryWrapperUtils.builderPageQuery(query, CrmBizTypeEnum.CRM_LEADS.getType(), CrmClueDO::getId,
CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_LEADS.getType(), CrmClueDO::getId,
userId, pageReqVO.getSceneType(), pageReqVO.getPool());
// 拼接自身的查询条件
query.selectAll(CrmClueDO.class)
@ -44,7 +44,7 @@ public interface CrmClueMapper extends BaseMapperX<CrmClueDO> {
default List<CrmClueDO> selectBatchIds(Collection<Long> ids, Long userId) {
MPJLambdaWrapperX<CrmClueDO> query = new MPJLambdaWrapperX<>();
// 拼接数据权限的查询条件
CrmQueryWrapperUtils.builderListQueryBatch(query, CrmBizTypeEnum.CRM_LEADS.getType(), ids, userId);
CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_LEADS.getType(), ids, userId);
return selectJoinList(CrmClueDO.class, query);
}

View File

@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.crm.dal.mysql.contact;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactPageReqVO;
import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO;
@ -27,14 +28,25 @@ public interface CrmContactMapper extends BaseMapperX<CrmContactDO> {
.set(CrmContactDO::getOwnerUserId, ownerUserId));
}
default PageResult<CrmContactDO> selectPageByCustomerId(CrmContactPageReqVO pageVO) {
return selectPage(pageVO, new LambdaQueryWrapperX<CrmContactDO>()
.eq(CrmContactDO::getCustomerId, pageVO.getCustomerId()) // 指定客户编号
.likeIfPresent(CrmContactDO::getName, pageVO.getName())
.eqIfPresent(CrmContactDO::getMobile, pageVO.getMobile())
.eqIfPresent(CrmContactDO::getTelephone, pageVO.getTelephone())
.eqIfPresent(CrmContactDO::getEmail, pageVO.getEmail())
.eqIfPresent(CrmContactDO::getQq, pageVO.getQq())
.eqIfPresent(CrmContactDO::getWechat, pageVO.getWechat())
.orderByDesc(CrmContactDO::getId));
}
default PageResult<CrmContactDO> selectPage(CrmContactPageReqVO pageReqVO, Long userId) {
MPJLambdaWrapperX<CrmContactDO> query = new MPJLambdaWrapperX<>();
// 拼接数据权限的查询条件
CrmQueryWrapperUtils.builderPageQuery(query, CrmBizTypeEnum.CRM_CONTACT.getType(), CrmContactDO::getId,
userId, pageReqVO.getSceneType(), pageReqVO.getPool());
CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CONTACT.getType(), CrmContactDO::getId,
userId, pageReqVO.getSceneType(), Boolean.FALSE);
// 拼接自身的查询条件
query.selectAll(CrmContactDO.class)
.eqIfPresent(CrmContactDO::getCustomerId, pageReqVO.getCustomerId()) // 指定客户编号
.likeIfPresent(CrmContactDO::getName, pageReqVO.getName())
.eqIfPresent(CrmContactDO::getMobile, pageReqVO.getMobile())
.eqIfPresent(CrmContactDO::getTelephone, pageReqVO.getTelephone())
@ -48,7 +60,7 @@ public interface CrmContactMapper extends BaseMapperX<CrmContactDO> {
default List<CrmContactDO> selectBatchIds(Collection<Long> ids, Long userId) {
MPJLambdaWrapperX<CrmContactDO> query = new MPJLambdaWrapperX<>();
// 拼接数据权限的查询条件
CrmQueryWrapperUtils.builderListQueryBatch(query, CrmBizTypeEnum.CRM_CONTACT.getType(), ids, userId);
CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CONTACT.getType(), ids, userId);
return selectJoinList(CrmContactDO.class, query);
}

View File

@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.crm.dal.mysql.contract;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageReqVO;
import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
@ -27,13 +28,22 @@ public interface CrmContractMapper extends BaseMapperX<CrmContractDO> {
.set(CrmContractDO::getOwnerUserId, ownerUserId));
}
default PageResult<CrmContractDO> selectPageByCustomerId(CrmContractPageReqVO pageReqVO) {
return selectPage(pageReqVO, new LambdaQueryWrapperX<CrmContractDO>()
.eq(CrmContractDO::getCustomerId, pageReqVO.getCustomerId())
.likeIfPresent(CrmContractDO::getNo, pageReqVO.getNo())
.likeIfPresent(CrmContractDO::getName, pageReqVO.getName())
.eqIfPresent(CrmContractDO::getCustomerId, pageReqVO.getCustomerId())
.eqIfPresent(CrmContractDO::getBusinessId, pageReqVO.getBusinessId())
.orderByDesc(CrmContractDO::getId));
}
default PageResult<CrmContractDO> selectPage(CrmContractPageReqVO pageReqVO, Long userId) {
MPJLambdaWrapperX<CrmContractDO> mpjLambdaWrapperX = new MPJLambdaWrapperX<>();
// 构建数据权限连表条件
CrmQueryWrapperUtils.builderPageQuery(mpjLambdaWrapperX, CrmBizTypeEnum.CRM_CONTACT.getType(), CrmContractDO::getId,
userId, pageReqVO.getSceneType(), pageReqVO.getPool());
CrmQueryWrapperUtils.appendPermissionCondition(mpjLambdaWrapperX, CrmBizTypeEnum.CRM_CONTACT.getType(), CrmContractDO::getId,
userId, pageReqVO.getSceneType(), Boolean.FALSE);
mpjLambdaWrapperX.selectAll(CrmContractDO.class)
.eqIfPresent(CrmContractDO::getCustomerId, pageReqVO.getCustomerId())
.likeIfPresent(CrmContractDO::getNo, pageReqVO.getNo())
.likeIfPresent(CrmContractDO::getName, pageReqVO.getName())
.eqIfPresent(CrmContractDO::getCustomerId, pageReqVO.getCustomerId())
@ -45,7 +55,7 @@ public interface CrmContractMapper extends BaseMapperX<CrmContractDO> {
default List<CrmContractDO> selectBatchIds(Collection<Long> ids, Long userId) {
MPJLambdaWrapperX<CrmContractDO> mpjLambdaWrapperX = new MPJLambdaWrapperX<>();
// 构建数据权限连表条件
CrmQueryWrapperUtils.builderListQueryBatch(mpjLambdaWrapperX, CrmBizTypeEnum.CRM_CONTACT.getType(), ids, userId);
CrmQueryWrapperUtils.appendPermissionCondition(mpjLambdaWrapperX, CrmBizTypeEnum.CRM_CONTACT.getType(), ids, userId);
return selectJoinList(CrmContractDO.class, mpjLambdaWrapperX);
}

View File

@ -30,7 +30,7 @@ public interface CrmCustomerMapper extends BaseMapperX<CrmCustomerDO> {
default PageResult<CrmCustomerDO> selectPage(CrmCustomerPageReqVO pageReqVO, Long userId) {
MPJLambdaWrapperX<CrmCustomerDO> query = new MPJLambdaWrapperX<>();
// 拼接数据权限的查询条件
CrmQueryWrapperUtils.builderPageQuery(query, CrmBizTypeEnum.CRM_CUSTOMER.getType(), CrmCustomerDO::getId,
CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CUSTOMER.getType(), CrmCustomerDO::getId,
userId, pageReqVO.getSceneType(), pageReqVO.getPool());
// 拼接自身的查询条件
query.selectAll(CrmCustomerDO.class)
@ -45,7 +45,7 @@ public interface CrmCustomerMapper extends BaseMapperX<CrmCustomerDO> {
default List<CrmCustomerDO> selectBatchIds(Collection<Long> ids, Long userId) {
MPJLambdaWrapperX<CrmCustomerDO> query = new MPJLambdaWrapperX<>();
// 拼接数据权限的查询条件
CrmQueryWrapperUtils.builderListQueryBatch(query, CrmBizTypeEnum.CRM_CUSTOMER.getType(), ids, userId);
CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CUSTOMER.getType(), ids, userId);
return selectJoinList(CrmCustomerDO.class, query);
}

View File

@ -46,4 +46,10 @@ public interface CrmPermissionMapper extends BaseMapperX<CrmPermissionDO> {
.eq(CrmPermissionDO::getId, id).eq(CrmPermissionDO::getUserId, userId));
}
default int deletePermission(Integer bizType, Long bizId) {
return delete(new LambdaQueryWrapperX<CrmPermissionDO>()
.eq(CrmPermissionDO::getBizType, bizType)
.eq(CrmPermissionDO::getBizId, bizId));
}
}

View File

@ -3,10 +3,17 @@ package cn.iocoder.yudao.module.crm.dal.mysql.receivable;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivablePageReqVO;
import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivableDO;
import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
import cn.iocoder.yudao.module.crm.util.CrmQueryWrapperUtils;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.apache.ibatis.annotations.Mapper;
import java.util.Collection;
import java.util.List;
/**
* 回款 Mapper
*
@ -15,15 +22,13 @@ import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface CrmReceivableMapper extends BaseMapperX<CrmReceivableDO> {
default PageResult<CrmReceivableDO> selectPage(CrmReceivablePageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<CrmReceivableDO>()
.eqIfPresent(CrmReceivableDO::getNo, reqVO.getNo())
.eqIfPresent(CrmReceivableDO::getPlanId, reqVO.getPlanId())
.eqIfPresent(CrmReceivableDO::getCustomerId, reqVO.getCustomerId())
.orderByDesc(CrmReceivableDO::getId));
default int updateOwnerUserIdById(Long id, Long ownerUserId) {
return update(new LambdaUpdateWrapper<CrmReceivableDO>()
.eq(CrmReceivableDO::getId, id)
.set(CrmReceivableDO::getOwnerUserId, ownerUserId));
}
default PageResult<CrmReceivableDO> selectPageByCustomer(CrmReceivablePageReqVO reqVO) {
default PageResult<CrmReceivableDO> selectPageByCustomerId(CrmReceivablePageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<CrmReceivableDO>()
.eq(CrmReceivableDO::getCustomerId, reqVO.getCustomerId()) // 必须传递
.eqIfPresent(CrmReceivableDO::getNo, reqVO.getNo())
@ -31,4 +36,24 @@ public interface CrmReceivableMapper extends BaseMapperX<CrmReceivableDO> {
.orderByDesc(CrmReceivableDO::getId));
}
default PageResult<CrmReceivableDO> selectPage(CrmReceivablePageReqVO pageReqVO, Long userId) {
MPJLambdaWrapperX<CrmReceivableDO> query = new MPJLambdaWrapperX<>();
// 拼接数据权限的查询条件
CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_RECEIVABLE.getType(), CrmReceivableDO::getId,
userId, pageReqVO.getSceneType(), Boolean.FALSE);
// 拼接自身的查询条件
query.selectAll(CrmReceivableDO.class)
.eqIfPresent(CrmReceivableDO::getNo, pageReqVO.getNo())
.eqIfPresent(CrmReceivableDO::getPlanId, pageReqVO.getPlanId())
.orderByDesc(CrmReceivableDO::getId);
return selectJoinPage(pageReqVO, CrmReceivableDO.class, query);
}
default List<CrmReceivableDO> selectBatchIds(Collection<Long> ids, Long userId) {
MPJLambdaWrapperX<CrmReceivableDO> query = new MPJLambdaWrapperX<>();
// 拼接数据权限的查询条件
CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_RECEIVABLE.getType(), ids, userId);
return selectJoinList(CrmReceivableDO.class, query);
}
}

View File

@ -75,10 +75,9 @@ public interface CrmBusinessService {
* 数据权限基于 {@link CrmCustomerDO} 读取
*
* @param pageReqVO 分页查询
* @param userId 用户编号
* @return 联系人分页
*/
PageResult<CrmBusinessDO> getBusinessPageByCustomer(CrmBusinessPageReqVO pageReqVO, Long userId);
PageResult<CrmBusinessDO> getBusinessPageByCustomerId(CrmBusinessPageReqVO pageReqVO);
/**
* 商机转移

View File

@ -111,11 +111,9 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
}
@Override
public PageResult<CrmBusinessDO> getBusinessPageByCustomer(CrmBusinessPageReqVO pageReqVO, Long userId) {
// 校验客户存在 TODO @puhui999这里不校验
customerService.validateCustomer(pageReqVO.getCustomerId());
// TODO @puhui999感觉这里貌似不太复用用 selectPage因为他可能没商机权限只是因为能看 customer所以可以看到列表
return businessMapper.selectPage(pageReqVO, userId);
@CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#pageReqVO.customerId", level = CrmPermissionLevelEnum.READ)
public PageResult<CrmBusinessDO> getBusinessPageByCustomerId(CrmBusinessPageReqVO pageReqVO) {
return businessMapper.selectPageByCustomerId(pageReqVO);
}
@Override
@ -127,7 +125,6 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
// 2.1 数据权限转移
crmPermissionService.transferPermission(
CrmBusinessConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_BUSINESS.getType()));
// 2.2 设置新的负责人
businessMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId());

View File

@ -5,6 +5,7 @@ import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactCreateR
import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactPageReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactUpdateReqVO;
import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO;
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
import jakarta.validation.Valid;
import java.util.Collection;
@ -71,12 +72,11 @@ public interface CrmContactService {
/**
* 获得联系人分页
*
* 数据权限基于 {@link CrmContactDO}
* 数据权限基于 {@link CrmCustomerDO}
*
* @param pageVO 分页查询
* @param userId 用户编号
* @return 联系人分页
*/
PageResult<CrmContactDO> getContactPageByCustomerId(CrmContactPageReqVO pageVO, Long userId);
PageResult<CrmContactDO> getContactPageByCustomerId(CrmContactPageReqVO pageVO);
}

View File

@ -134,11 +134,9 @@ public class CrmContactServiceImpl implements CrmContactService {
}
@Override
public PageResult<CrmContactDO> getContactPageByCustomerId(CrmContactPageReqVO pageVO, Long userId) {
// 校验用户存在
customerService.validateCustomer(pageVO.getCustomerId());
// TODO @puhui999getBusinessPageByCustomer 同理
return contactMapper.selectPage(pageVO, userId);
@CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#pageVO.customerId", level = CrmPermissionLevelEnum.READ)
public PageResult<CrmContactDO> getContactPageByCustomerId(CrmContactPageReqVO pageVO) {
return contactMapper.selectPageByCustomerId(pageVO);
}
}

View File

@ -75,12 +75,9 @@ public interface CrmContractService {
* 数据权限基于 {@link CrmCustomerDO} 读取
*
* @param pageReqVO 分页查询
* @param userId 用户编号
* @return 联系人分页
*/
default PageResult<CrmContractDO> getContractPageByCustomer(CrmContractPageReqVO pageReqVO, Long userId) {
return getContractPage(pageReqVO, userId);
}
PageResult<CrmContractDO> getContractPageByCustomerId(CrmContractPageReqVO pageReqVO);
/**
* 合同转移

View File

@ -104,6 +104,12 @@ public class CrmContractServiceImpl implements CrmContractService {
return contractMapper.selectPage(pageReqVO, userId);
}
@Override
@CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#pageReqVO.customerId", level = CrmPermissionLevelEnum.READ)
public PageResult<CrmContractDO> getContractPageByCustomerId(CrmContractPageReqVO pageReqVO) {
return contractMapper.selectPageByCustomerId(pageReqVO);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void transferContract(CrmContractTransferReqVO reqVO, Long userId) {

View File

@ -114,7 +114,6 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
*/
@Override
public void validateCustomer(Long customerId) {
// TODO puhui999: 不返回客户不走校验应该可行
// 校验客户是否存在
if (customerId == null) {
throw exception(CUSTOMER_NOT_EXISTS);

View File

@ -139,14 +139,11 @@ public class CrmPermissionServiceImpl implements CrmPermissionService {
@Override
public void deletePermission(Integer bizType, Long bizId) {
// TODO @puhui999这种直接写条件删除不需要先查询再删除
List<CrmPermissionDO> permissionList = crmPermissionMapper.selectByBizTypeAndBizId(bizType, bizId);
if (CollUtil.isEmpty(permissionList)) {
return;
}
// 删除数据权限
crmPermissionMapper.deleteBatchIds(convertSet(permissionList, CrmPermissionDO::getId));
int deletedCol = crmPermissionMapper.deletePermission(bizType, bizId);
if (deletedCol == 0) {
throw exception(CRM_PERMISSION_NOT_EXISTS);
}
}
@Override

View File

@ -6,8 +6,8 @@ import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.Crm
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableUpdateReqVO;
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivableDO;
import jakarta.validation.Valid;
import java.util.Collection;
import java.util.List;
@ -62,9 +62,10 @@ public interface CrmReceivableService {
* 数据权限基于 {@link CrmReceivableDO} 读取
*
* @param pageReqVO 分页查询
* @param userId 用户编号
* @return 回款分页
*/
PageResult<CrmReceivableDO> getReceivablePage(CrmReceivablePageReqVO pageReqVO);
PageResult<CrmReceivableDO> getReceivablePage(CrmReceivablePageReqVO pageReqVO, Long userId);
/**
* 获得回款分页基于指定客户
@ -74,6 +75,6 @@ public interface CrmReceivableService {
* @param pageReqVO 分页查询
* @return 回款分页
*/
PageResult<CrmReceivableDO> getReceivablePageByCustomer(CrmReceivablePageReqVO pageReqVO);
PageResult<CrmReceivableDO> getReceivablePageByCustomerId(CrmReceivablePageReqVO pageReqVO);
}

View File

@ -20,10 +20,10 @@ import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
import cn.iocoder.yudao.module.crm.framework.core.annotations.CrmPermission;
import cn.iocoder.yudao.module.crm.service.contract.CrmContractService;
import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import jakarta.annotation.Resource;
import java.util.Collection;
import java.util.List;
@ -129,16 +129,15 @@ public class CrmReceivableServiceImpl implements CrmReceivableService {
return receivableMapper.selectBatchIds(ids);
}
// TODO @芋艿数据权限
@Override
public PageResult<CrmReceivableDO> getReceivablePage(CrmReceivablePageReqVO pageReqVO) {
return receivableMapper.selectPage(pageReqVO);
public PageResult<CrmReceivableDO> getReceivablePage(CrmReceivablePageReqVO pageReqVO, Long userId) {
return receivableMapper.selectPage(pageReqVO, userId);
}
@Override
@CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#pageReqVO.customerId", level = CrmPermissionLevelEnum.READ)
public PageResult<CrmReceivableDO> getReceivablePageByCustomer(CrmReceivablePageReqVO pageReqVO) {
return receivableMapper.selectPageByCustomer(pageReqVO);
public PageResult<CrmReceivableDO> getReceivablePageByCustomerId(CrmReceivablePageReqVO pageReqVO) {
return receivableMapper.selectPageByCustomerId(pageReqVO);
}
}

View File

@ -6,6 +6,7 @@ import cn.hutool.extra.spring.SpringUtil;
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.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
@ -17,7 +18,7 @@ import java.util.List;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
/**
* CRM 分页查询工具类
* CRM 查询工具类
*
* @author HUIHUI
*/
@ -26,17 +27,16 @@ public class CrmQueryWrapperUtils {
/**
* 构造 CRM 数据类型数据分页查询条件
*
* @param query 连表查询对象
* @param bizType 数据类型 {@link CrmBizTypeEnum}
* @param bizId 数据编号
* @param userId 用户编号
* @param sceneType 场景类型
* @param pool 公海
* @param query 连表查询对象
* @param bizType 数据类型 {@link CrmBizTypeEnum}
* @param bizId 数据编号
* @param userId 用户编号
* @param sceneType 场景类型
* @param pool 公海
*/
// TODO @puhui999bizId 直接传递会不会简单点
// TODO @puhui999builderPageQuery 应该不仅仅适合于分页查询应该适用于所有的查询可以改成 appendPermissionCondition
public static <T extends MPJLambdaWrapper<?>, S> void builderPageQuery(T query, Integer bizType, SFunction<S, ?> bizId,
Long userId, Integer sceneType, Boolean pool) {
// TODO @puhui999bizId 直接传递会不会简单点 回复还是需要 SFunction 因为分页连表时不知道 bizId 是多少
public static <T extends MPJLambdaWrapper<?>, S> void appendPermissionCondition(T query, Integer bizType, SFunction<S, ?> bizId,
Long userId, Integer sceneType, Boolean pool) {
// 1. 构建数据权限连表条件
if (ObjUtil.notEqual(validateAdminUser(userId), Boolean.TRUE)) { // 管理员不需要数据权限
query.innerJoin(CrmPermissionDO.class, on ->
@ -48,9 +48,13 @@ public class CrmQueryWrapperUtils {
query.eq("owner_user_id", userId);
}
// 2.2 场景二我参与的数据
// TODO @puhui999参与指的是有读写权限噢可以把 1. 的合并到 2.2 因为 2.1 不需要
if (CrmSceneTypeEnum.isInvolved(sceneType)) {
query.ne("owner_user_id", userId);
query
.ne("owner_user_id", userId)
.and(q -> q.eq(CrmPermissionDO::getLevel, CrmPermissionLevelEnum.READ.getLevel())
.or()
.eq(CrmPermissionDO::getLevel, CrmPermissionLevelEnum.WRITE.getLevel()));
}
// 2.3 场景三下属负责的数据
if (CrmSceneTypeEnum.isSubordinate(sceneType)) {
@ -61,7 +65,7 @@ public class CrmQueryWrapperUtils {
}
}
// 2. 拼接公海的查询条件
// 3. 拼接公海的查询条件
if (ObjUtil.equal(pool, Boolean.TRUE)) { // 情况一公海
query.isNull("owner_user_id");
} else { // 情况二不是公海
@ -72,28 +76,27 @@ public class CrmQueryWrapperUtils {
/**
* 构造 CRM 数据类型批量数据查询条件
*
* @param query 连表查询对象
* @param bizType 数据类型 {@link CrmBizTypeEnum}
* @param bizIds 数据编号
* @param userId 用户编号
* @param query 连表查询对象
* @param bizType 数据类型 {@link CrmBizTypeEnum}
* @param bizIds 数据编号
* @param userId 用户编号
*/
// TODO @puhui999可以改成 appendPermissionCondition
// TODO @puhui999S 是不是可以删除
public static <T extends MPJLambdaWrapper<?>, S> void builderListQueryBatch(T query, Integer bizType, Collection<Long> bizIds, Long userId) {
// TODO @puhui999这里先 if return 简单点
if (ObjUtil.notEqual(validateAdminUser(userId), Boolean.TRUE)) { // 管理员不需要数据权限
query.innerJoin(CrmPermissionDO.class, on ->
on.eq(CrmPermissionDO::getBizType, bizType).in(CrmPermissionDO::getBizId, bizIds)
.in(CollUtil.isNotEmpty(bizIds), CrmPermissionDO::getUserId, userId));
public static <T extends MPJLambdaWrapper<?>> void appendPermissionCondition(T query, Integer bizType, Collection<Long> bizIds, Long userId) {
if (ObjUtil.equal(validateAdminUser(userId), Boolean.TRUE)) {// 管理员不需要数据权限
return;
}
query.innerJoin(CrmPermissionDO.class, on ->
on.eq(CrmPermissionDO::getBizType, bizType).in(CrmPermissionDO::getBizId, bizIds)
.in(CollUtil.isNotEmpty(bizIds), CrmPermissionDO::getUserId, userId));
}
// TODO @puhui999需要加个变量不用每次都拿哈
private static AdminUserApi getAdminUserApi() {
return SpringUtil.getBean(AdminUserApi.class);
return AdminUserApiHolder.ADMIN_USER_API;
}
// TODO @puhui999需要实现
/**
* 校验用户是否是管理员
*
@ -104,4 +107,15 @@ public class CrmQueryWrapperUtils {
return false;
}
/**
* 静态内部类实现 AdminUserApi 单例获取
*
* @author HUIHUI
*/
private static class AdminUserApiHolder {
private static final AdminUserApi ADMIN_USER_API = SpringUtil.getBean(AdminUserApi.class);
}
}

View File

@ -7,12 +7,11 @@ import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.Crm
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableUpdateReqVO;
import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivableDO;
import cn.iocoder.yudao.module.crm.dal.mysql.receivable.CrmReceivableMapper;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.Import;
import jakarta.annotation.Resource;
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
@ -133,7 +132,7 @@ public class CrmCrmReceivableServiceImplTest extends BaseDbUnitTest {
reqVO.setCustomerId(null);
// 调用
PageResult<CrmReceivableDO> pageResult = receivableService.getReceivablePage(reqVO);
PageResult<CrmReceivableDO> pageResult = receivableService.getReceivablePage(reqVO, 1L);
// 断言
assertEquals(1, pageResult.getTotal());
assertEquals(1, pageResult.getList().size());