commit
9f1b92abd9
@ -0,0 +1,31 @@
|
|||||||
|
package cn.iocoder.yudao.module.crm.enums.common;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum PermissionTypeEnum implements IntArrayValuable {
|
||||||
|
|
||||||
|
READONLY(1, "只读"),
|
||||||
|
READ_AND_WRITE(2, "读写");
|
||||||
|
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PermissionTypeEnum::getType).toArray();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 类型
|
||||||
|
*/
|
||||||
|
private final Integer type;
|
||||||
|
/**
|
||||||
|
* 类型名
|
||||||
|
*/
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int[] array() {
|
||||||
|
return ARRAYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
package cn.iocoder.yudao.module.crm.enums.common;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Crm 负责人转移后原负责人的处理方式
|
||||||
|
*
|
||||||
|
* @author HUIHUI
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum TransferTypeEnum implements IntArrayValuable {
|
||||||
|
|
||||||
|
REMOVE(1, "移除"),
|
||||||
|
TEAM(2, "转为团队成员");
|
||||||
|
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TransferTypeEnum::getType).toArray();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 类型
|
||||||
|
*/
|
||||||
|
private final Integer type;
|
||||||
|
/**
|
||||||
|
* 类型名
|
||||||
|
*/
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int[] array() {
|
||||||
|
return ARRAYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
PUT {{baseUrl}}/crm/business/transfer
|
||||||
|
Content-Type: application/json
|
||||||
|
Authorization: Bearer {{token}}
|
||||||
|
tenant-id: {{adminTenentId}}
|
||||||
|
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"ownerUserId": 2,
|
||||||
|
"transferType": 2,
|
||||||
|
"permissionType": 2
|
||||||
|
}
|
||||||
@ -1,20 +0,0 @@
|
|||||||
package cn.iocoder.yudao.module.crm.controller.admin.business.vo;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
|
|
||||||
@Schema(description = "管理后台 - 商机转移 Request VO")
|
|
||||||
@Data
|
|
||||||
public class CrmBusinessTransferReqVO {
|
|
||||||
|
|
||||||
@Schema(description = "商机编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
|
|
||||||
@NotNull(message = "联系人编号不能为空")
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
@Schema(description = "新负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
|
|
||||||
@NotNull(message = "新负责人的用户编号不能为空")
|
|
||||||
private Long ownerUserId;
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
package cn.iocoder.yudao.module.crm.controller.admin.business.vo;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||||
|
import cn.iocoder.yudao.module.crm.enums.common.PermissionTypeEnum;
|
||||||
|
import cn.iocoder.yudao.module.crm.enums.common.TransferTypeEnum;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
@Schema(description = "管理后台 - 商机转移 Request VO")
|
||||||
|
@Data
|
||||||
|
public class CrmTransferBusinessReqVO {
|
||||||
|
|
||||||
|
@Schema(description = "商机编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
|
||||||
|
@NotNull(message = "联系人编号不能为空")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Schema(description = "新负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
|
||||||
|
@NotNull(message = "新负责人的用户编号不能为空")
|
||||||
|
private Long ownerUserId;
|
||||||
|
|
||||||
|
@Schema(description = "原负责人移除方式", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
|
||||||
|
@InEnum(TransferTypeEnum.class)
|
||||||
|
@NotNull(message = "原负责人移除方式不能为空")
|
||||||
|
private Integer transferType;
|
||||||
|
|
||||||
|
@Schema(description = "权限类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
|
||||||
|
@InEnum(PermissionTypeEnum.class)
|
||||||
|
@NotNull(message = "权限类型不能为空")
|
||||||
|
private Integer permissionType;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
package cn.iocoder.yudao.module.crm.controller.admin.customer.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
@Schema(description = "管理后台 - 客户转移 Request VO")
|
||||||
|
@Data
|
||||||
|
public class CrmTransferCustomerReqVO {
|
||||||
|
|
||||||
|
@Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
|
||||||
|
@NotNull(message = "客户编号不能为空")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Schema(description = "新负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
|
||||||
|
@NotNull(message = "新负责人的用户编号不能为空")
|
||||||
|
private Long ownerUserId;
|
||||||
|
|
||||||
|
@Schema(description = "原负责人移除方式", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
|
||||||
|
@NotNull(message = "原负责人移除方式不能为空")
|
||||||
|
private Integer transferType;
|
||||||
|
|
||||||
|
@Schema(description = "权限类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
|
||||||
|
@NotNull(message = "权限类型不能为空")
|
||||||
|
private Integer permissionType;
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
package cn.iocoder.yudao.module.crm.convert.permission;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO;
|
||||||
|
import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateBO;
|
||||||
|
import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionUpdateBO;
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Crm 数据权限 Convert
|
||||||
|
*
|
||||||
|
* @author Wanwan
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface CrmPermissionConvert {
|
||||||
|
|
||||||
|
CrmPermissionConvert INSTANCE = Mappers.getMapper(CrmPermissionConvert.class);
|
||||||
|
|
||||||
|
CrmPermissionDO convert(CrmPermissionCreateBO createBO);
|
||||||
|
|
||||||
|
CrmPermissionDO convert(CrmPermissionUpdateBO updateBO);
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,57 @@
|
|||||||
|
package cn.iocoder.yudao.module.crm.dal.dataobject.permission;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.type.JsonLongSetTypeHandler;
|
||||||
|
import cn.iocoder.yudao.module.crm.framework.enums.CrmEnum;
|
||||||
|
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.*;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* crm 数据权限 DO
|
||||||
|
*
|
||||||
|
* @author HUIHUI
|
||||||
|
*/
|
||||||
|
@TableName("crm_receivable")
|
||||||
|
@KeySequence("crm_receivable_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class CrmPermissionDO extends BaseDO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ID
|
||||||
|
*/
|
||||||
|
@TableId
|
||||||
|
private Long id;
|
||||||
|
/**
|
||||||
|
* 数据类型 关联 {@link CrmEnum}
|
||||||
|
*/
|
||||||
|
private Integer crmType;
|
||||||
|
/**
|
||||||
|
* 数据编号 关联 {@link CrmEnum} 对应模块 DO#getId()
|
||||||
|
*/
|
||||||
|
private Long crmDataId;
|
||||||
|
/**
|
||||||
|
* 负责人的用户编号 关联 AdminUser#id
|
||||||
|
*/
|
||||||
|
private Long ownerUserId;
|
||||||
|
/**
|
||||||
|
* 只读权限的用户编号数组
|
||||||
|
*/
|
||||||
|
@TableField(typeHandler = JsonLongSetTypeHandler.class)
|
||||||
|
private Set<Long> roUserIds;
|
||||||
|
/**
|
||||||
|
* 读写权限的用户编号数组
|
||||||
|
*/
|
||||||
|
@TableField(typeHandler = JsonLongSetTypeHandler.class)
|
||||||
|
private Set<Long> rwUserIds;
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
package cn.iocoder.yudao.module.crm.dal.mysql.permission;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||||
|
import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* crm 数据权限 mapper
|
||||||
|
*
|
||||||
|
* @author HUIHUI
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface CrmPermissionMapper extends BaseMapperX<CrmPermissionDO> {
|
||||||
|
|
||||||
|
default CrmPermissionDO selectByCrmTypeAndCrmDataId(Integer crmType, Long crmDataId) {
|
||||||
|
return selectOne(new LambdaQueryWrapperX<CrmPermissionDO>()
|
||||||
|
.eq(CrmPermissionDO::getCrmType, crmType).eq(CrmPermissionDO::getCrmDataId, crmDataId));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
package cn.iocoder.yudao.module.crm.dal.mysql.permission;
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
package cn.iocoder.yudao.module.crm.framework.core.annotations;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.crm.framework.enums.CrmEnum;
|
||||||
|
import cn.iocoder.yudao.module.crm.framework.enums.OperationTypeEnum;
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
|
||||||
|
import static java.lang.annotation.ElementType.METHOD;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Crm 数据操作权限校验 AOP 注解
|
||||||
|
*
|
||||||
|
* @author HUIHUI
|
||||||
|
*/
|
||||||
|
@Target({METHOD, ANNOTATION_TYPE})
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
public @interface CrmPermission {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* crm 类型
|
||||||
|
*/
|
||||||
|
CrmEnum crmType();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 操作类型
|
||||||
|
*/
|
||||||
|
OperationTypeEnum operationType();
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,93 @@
|
|||||||
|
package cn.iocoder.yudao.module.crm.framework.core.aop;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
import cn.hutool.core.util.ObjUtil;
|
||||||
|
import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
|
||||||
|
import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO;
|
||||||
|
import cn.iocoder.yudao.module.crm.framework.core.annotations.CrmPermission;
|
||||||
|
import cn.iocoder.yudao.module.crm.framework.enums.OperationTypeEnum;
|
||||||
|
import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.aspectj.lang.JoinPoint;
|
||||||
|
import org.aspectj.lang.annotation.Aspect;
|
||||||
|
import org.aspectj.lang.annotation.Before;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
|
import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
|
||||||
|
import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CRM_PERMISSION_DENIED;
|
||||||
|
import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CRM_PERMISSION_MODEL_NOT_EXISTS;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Crm 数据权限校验 AOP 切面
|
||||||
|
*
|
||||||
|
* @author HUIHUI
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@Aspect
|
||||||
|
@Slf4j
|
||||||
|
public class CrmPermissionAspect {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private CrmPermissionService crmPermissionService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得用户编号
|
||||||
|
*
|
||||||
|
* @return 用户编号
|
||||||
|
*/
|
||||||
|
private static Long getUserId() {
|
||||||
|
return WebFrameworkUtils.getLoginUserId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before("@annotation(crmPermission)")
|
||||||
|
public void doBefore(JoinPoint joinPoint, CrmPermission crmPermission) {
|
||||||
|
try {
|
||||||
|
Integer crmType = crmPermission.crmType().getType();
|
||||||
|
Integer operationType = crmPermission.operationType().getType();
|
||||||
|
Long id = (Long) joinPoint.getArgs()[0];// 获取操作数据的编号
|
||||||
|
|
||||||
|
// 1. 获取数据权限
|
||||||
|
CrmPermissionDO permission = crmPermissionService.getCrmPermissionByCrmTypeAndCrmDataId(crmType, id);
|
||||||
|
if (permission == null) {
|
||||||
|
// 不存在说明数据也不存在
|
||||||
|
throw exception(CRM_PERMISSION_MODEL_NOT_EXISTS, crmPermission.crmType().getName());
|
||||||
|
}
|
||||||
|
// 1.2. 校验是否为公海数据
|
||||||
|
if (permission.getOwnerUserId() == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 1.3. 校验当前负责人是不是自己
|
||||||
|
if (ObjUtil.equal(permission.getOwnerUserId(), getUserId())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 1.4 TODO 校验是否为超级管理员
|
||||||
|
|
||||||
|
// 2. 校验是否有读权限
|
||||||
|
if (OperationTypeEnum.isRead(operationType)) {
|
||||||
|
// 校验该数据当前用户是否可读
|
||||||
|
boolean isRead = CollUtil.contains(permission.getRoUserIds(), item -> ObjUtil.equal(item, getUserId()))
|
||||||
|
|| CollUtil.contains(permission.getRwUserIds(), item -> ObjUtil.equal(item, getUserId()));
|
||||||
|
if (isRead) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 校验是否有编辑权限
|
||||||
|
if (OperationTypeEnum.isEdit(operationType)) {
|
||||||
|
// 校验该数据当前用户是否可读写
|
||||||
|
if (CollUtil.contains(permission.getRwUserIds(), item -> ObjUtil.equal(item, getUserId()))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 没通过结束,报错 {}操作失败,原因:没有权限
|
||||||
|
throw exception(CRM_PERMISSION_DENIED, crmPermission.crmType().getName());
|
||||||
|
} catch (Exception ex) {
|
||||||
|
log.error("[doBefore][crmPermission({}) 数据校验错误]", toJsonString(crmPermission), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
package cn.iocoder.yudao.module.crm.framework.core;
|
||||||
@ -0,0 +1,40 @@
|
|||||||
|
package cn.iocoder.yudao.module.crm.framework.enums;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.ObjUtil;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Crm 类型枚举
|
||||||
|
*
|
||||||
|
* @author HUIHUI
|
||||||
|
*/
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Getter
|
||||||
|
public enum CrmEnum {
|
||||||
|
|
||||||
|
CRM_LEADS(1, "线索"),
|
||||||
|
CRM_CUSTOMER(2, "客户"),
|
||||||
|
CRM_CONTACTS(3, "联系人"),
|
||||||
|
CRM_BUSINESS(5, "商机"),
|
||||||
|
CRM_CONTRACT(6, "合同");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 类型
|
||||||
|
*/
|
||||||
|
private final Integer type;
|
||||||
|
/**
|
||||||
|
* 名称
|
||||||
|
*/
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
public static String getNameByType(Integer type) {
|
||||||
|
for (CrmEnum crmEnum : CrmEnum.values()) {
|
||||||
|
if (ObjUtil.equal(crmEnum.type, type)) {
|
||||||
|
return crmEnum.name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,38 @@
|
|||||||
|
package cn.iocoder.yudao.module.crm.framework.enums;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.ObjUtil;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Crm 数据操作类型枚举
|
||||||
|
*
|
||||||
|
* @author HUIHUI
|
||||||
|
*/
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Getter
|
||||||
|
public enum OperationTypeEnum {
|
||||||
|
|
||||||
|
DELETE(1, "删除"),
|
||||||
|
UPDATE(2, "修改"),
|
||||||
|
READ(3, "查询");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 类型
|
||||||
|
*/
|
||||||
|
private final Integer type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 名称
|
||||||
|
*/
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
public static boolean isRead(Integer type) {
|
||||||
|
return ObjUtil.equal(type, READ.getType());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isEdit(Integer type) {
|
||||||
|
return ObjUtil.equal(type, UPDATE.getType()) || ObjUtil.equal(type, DELETE.getType());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,57 @@
|
|||||||
|
package cn.iocoder.yudao.module.crm.service.permission;
|
||||||
|
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO;
|
||||||
|
import cn.iocoder.yudao.module.crm.framework.enums.CrmEnum;
|
||||||
|
import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateBO;
|
||||||
|
import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionUpdateBO;
|
||||||
|
import cn.iocoder.yudao.module.crm.service.permission.bo.TransferCrmPermissionBO;
|
||||||
|
|
||||||
|
import javax.validation.Valid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* crm 数据权限 Service 接口
|
||||||
|
*
|
||||||
|
* @author HUIHUI
|
||||||
|
*/
|
||||||
|
public interface CrmPermissionService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建数据权限
|
||||||
|
*
|
||||||
|
* @param createBO 创建信息
|
||||||
|
* @return 编号
|
||||||
|
*/
|
||||||
|
Long createCrmPermission(@Valid CrmPermissionCreateBO createBO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新数据权限
|
||||||
|
*
|
||||||
|
* @param updateBO 更新信息
|
||||||
|
*/
|
||||||
|
void updateCrmPermission(@Valid CrmPermissionUpdateBO updateBO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除数据权限
|
||||||
|
*
|
||||||
|
* @param id 编号
|
||||||
|
*/
|
||||||
|
void deleteCrmPermission(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得数据权限
|
||||||
|
*
|
||||||
|
* @param crmType 数据类型 关联 {@link CrmEnum}
|
||||||
|
* @param crmDataId 数据编号 关联 {@link CrmEnum} 对应模块 DO#getId()
|
||||||
|
* @return 数据权限
|
||||||
|
*/
|
||||||
|
CrmPermissionDO getCrmPermissionByCrmTypeAndCrmDataId(Integer crmType, Long crmDataId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据权限转移
|
||||||
|
*
|
||||||
|
* @param transferCrmPermissionBO 数据权限转移请求
|
||||||
|
*/
|
||||||
|
void transferCrmPermission(@Valid TransferCrmPermissionBO transferCrmPermissionBO);
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,121 @@
|
|||||||
|
package cn.iocoder.yudao.module.crm.service.permission;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
import cn.hutool.core.util.ObjUtil;
|
||||||
|
import cn.iocoder.yudao.module.crm.convert.permission.CrmPermissionConvert;
|
||||||
|
import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO;
|
||||||
|
import cn.iocoder.yudao.module.crm.dal.mysql.permission.CrmPermissionMapper;
|
||||||
|
import cn.iocoder.yudao.module.crm.enums.common.PermissionTypeEnum;
|
||||||
|
import cn.iocoder.yudao.module.crm.enums.common.TransferTypeEnum;
|
||||||
|
import cn.iocoder.yudao.module.crm.framework.enums.CrmEnum;
|
||||||
|
import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateBO;
|
||||||
|
import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionUpdateBO;
|
||||||
|
import cn.iocoder.yudao.module.crm.service.permission.bo.TransferCrmPermissionBO;
|
||||||
|
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||||
|
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
|
import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* crm 数据权限 Service 接口实现类
|
||||||
|
*
|
||||||
|
* @author HUIHUI
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@Validated
|
||||||
|
public class CrmPermissionServiceImpl implements CrmPermissionService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private CrmPermissionMapper crmPermissionMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private AdminUserApi adminUserApi;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public Long createCrmPermission(CrmPermissionCreateBO createBO) {
|
||||||
|
CrmPermissionDO createDO = CrmPermissionConvert.INSTANCE.convert(createBO);
|
||||||
|
crmPermissionMapper.insert(createDO);
|
||||||
|
return createDO.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void updateCrmPermission(CrmPermissionUpdateBO updateBO) {
|
||||||
|
validateCrmPermissionExists(updateBO.getId());
|
||||||
|
|
||||||
|
CrmPermissionDO updateDO = CrmPermissionConvert.INSTANCE.convert(updateBO);
|
||||||
|
crmPermissionMapper.updateById(updateDO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void deleteCrmPermission(Long id) {
|
||||||
|
validateCrmPermissionExists(id);
|
||||||
|
|
||||||
|
crmPermissionMapper.deleteById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateCrmPermissionExists(Long id) {
|
||||||
|
if (crmPermissionMapper.selectById(id) == null) {
|
||||||
|
throw exception(CRM_PERMISSION_NOT_EXISTS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CrmPermissionDO getCrmPermissionByCrmTypeAndCrmDataId(Integer crmType, Long crmDataId) {
|
||||||
|
return crmPermissionMapper.selectByCrmTypeAndCrmDataId(crmType, crmDataId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void transferCrmPermission(TransferCrmPermissionBO transferCrmPermissionBO) {
|
||||||
|
// 1 校验商机是否存在
|
||||||
|
CrmPermissionDO permission = getCrmPermissionByCrmTypeAndCrmDataId(transferCrmPermissionBO.getCrmType(),
|
||||||
|
transferCrmPermissionBO.getCrmDataId());
|
||||||
|
String crmName = CrmEnum.getNameByType(transferCrmPermissionBO.getCrmType());
|
||||||
|
if (permission == null) {
|
||||||
|
throw exception(CRM_PERMISSION_MODEL_NOT_EXISTS, crmName);
|
||||||
|
}
|
||||||
|
// 1.2 校验转移对象是否已经是该负责人
|
||||||
|
if (ObjUtil.equal(permission.getOwnerUserId(), permission.getOwnerUserId())) {
|
||||||
|
throw exception(CRM_PERMISSION_MODEL_TRANSFER_FAIL_OWNER_USER_NOT_EXISTS, crmName);
|
||||||
|
}
|
||||||
|
// 1.3 校验新负责人是否存在
|
||||||
|
AdminUserRespDTO user = adminUserApi.getUser(permission.getOwnerUserId());
|
||||||
|
if (user == null) {
|
||||||
|
throw exception(CRM_PERMISSION_MODEL_TRANSFER_FAIL_OWNER_USER_EXISTS, crmName);
|
||||||
|
}
|
||||||
|
// TODO 校验是否为超级管理员 || 1.4
|
||||||
|
// 1.4 校验是否有写权限
|
||||||
|
if (!CollUtil.contains(permission.getRwUserIds(), id -> ObjUtil.equal(id, transferCrmPermissionBO.getUserId()))) {
|
||||||
|
throw exception(CRM_PERMISSION_DENIED, crmName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2 权限转移
|
||||||
|
CrmPermissionDO updateCrmPermission = new CrmPermissionDO().setId(permission.getId())
|
||||||
|
.setOwnerUserId(transferCrmPermissionBO.getOwnerUserId());
|
||||||
|
if (ObjUtil.equal(TransferTypeEnum.TEAM.getType(), transferCrmPermissionBO.getTransferType())) {
|
||||||
|
if (ObjUtil.equal(PermissionTypeEnum.READONLY.getType(), transferCrmPermissionBO.getPermissionType())) {
|
||||||
|
Set<Long> roUserIds = permission.getRoUserIds();
|
||||||
|
roUserIds.add(permission.getOwnerUserId()); // 老负责人加入团队有只读权限
|
||||||
|
updateCrmPermission.setRoUserIds(roUserIds);
|
||||||
|
}
|
||||||
|
if (ObjUtil.equal(PermissionTypeEnum.READ_AND_WRITE.getType(), transferCrmPermissionBO.getPermissionType())) {
|
||||||
|
Set<Long> rwUserIds = permission.getRwUserIds();
|
||||||
|
rwUserIds.add(permission.getOwnerUserId()); // 老负责人加入团队有读写权限
|
||||||
|
updateCrmPermission.setRoUserIds(rwUserIds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
crmPermissionMapper.updateById(updateCrmPermission);
|
||||||
|
|
||||||
|
// 3. TODO 记录机转移日志
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,40 @@
|
|||||||
|
package cn.iocoder.yudao.module.crm.service.permission.bo;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.crm.framework.enums.CrmEnum;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* crm 数据权限 Create BO
|
||||||
|
*
|
||||||
|
* @author HUIHUI
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class CrmPermissionCreateBO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Crm 类型 关联 {@link CrmEnum}
|
||||||
|
*/
|
||||||
|
@NotNull(message = "Crm 类型不能为空")
|
||||||
|
private Integer crmType;
|
||||||
|
/**
|
||||||
|
* 数据编号 关联 {@link CrmEnum} 对应模块 DO#getId()
|
||||||
|
*/
|
||||||
|
@NotNull(message = "Crm 数据编号不能为空")
|
||||||
|
private Long crmDataId;
|
||||||
|
/**
|
||||||
|
* 负责人的用户编号 关联 AdminUser#id, null 则为公海数据
|
||||||
|
*/
|
||||||
|
private Long ownerUserId;
|
||||||
|
/**
|
||||||
|
* 只读权限的用户编号数组
|
||||||
|
*/
|
||||||
|
private Set<Long> roUserIds;
|
||||||
|
/**
|
||||||
|
* 读写权限的用户编号数组
|
||||||
|
*/
|
||||||
|
private Set<Long> rwUserIds;
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,47 @@
|
|||||||
|
package cn.iocoder.yudao.module.crm.service.permission.bo;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO;
|
||||||
|
import cn.iocoder.yudao.module.crm.framework.enums.CrmEnum;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* crm 数据权限 Update BO
|
||||||
|
*
|
||||||
|
* @author HUIHUI
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class CrmPermissionUpdateBO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据权限编号 {@link CrmPermissionDO#getId()}
|
||||||
|
*/
|
||||||
|
@NotNull(message = "Crm 数据权限编号不能为空")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Crm 类型 关联 {@link CrmEnum}
|
||||||
|
*/
|
||||||
|
@NotNull(message = "Crm 类型不能为空")
|
||||||
|
private Integer crmType;
|
||||||
|
/**
|
||||||
|
* 数据编号 关联 {@link CrmEnum} 对应模块 DO#getId()
|
||||||
|
*/
|
||||||
|
@NotNull(message = "Crm 数据编号不能为空")
|
||||||
|
private Long crmDataId;
|
||||||
|
/**
|
||||||
|
* 负责人的用户编号 关联 AdminUser#id, null 则为公海数据
|
||||||
|
*/
|
||||||
|
private Long ownerUserId;
|
||||||
|
/**
|
||||||
|
* 只读权限的用户编号数组
|
||||||
|
*/
|
||||||
|
private Set<Long> roUserIds;
|
||||||
|
/**
|
||||||
|
* 读写权限的用户编号数组
|
||||||
|
*/
|
||||||
|
private Set<Long> rwUserIds;
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,48 @@
|
|||||||
|
package cn.iocoder.yudao.module.crm.service.permission.bo;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.crm.enums.common.PermissionTypeEnum;
|
||||||
|
import cn.iocoder.yudao.module.crm.enums.common.TransferTypeEnum;
|
||||||
|
import cn.iocoder.yudao.module.crm.framework.enums.CrmEnum;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据权限转移 BO
|
||||||
|
*
|
||||||
|
* @author HUIHUI
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class TransferCrmPermissionBO {
|
||||||
|
|
||||||
|
@NotNull(message = "用户编号不能为空")
|
||||||
|
private Long userId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Crm 类型 关联 {@link CrmEnum}
|
||||||
|
*/
|
||||||
|
@NotNull(message = "Crm 类型不能为空")
|
||||||
|
private Integer crmType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据编号 关联 {@link CrmEnum} 对应模块 DO#getId()
|
||||||
|
*/
|
||||||
|
@NotNull(message = "Crm 数据编号不能为空")
|
||||||
|
private Long crmDataId;
|
||||||
|
|
||||||
|
@NotNull(message = "新负责人的用户编号不能为空")
|
||||||
|
private Long ownerUserId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 原负责人移除方式, 关联 {@link TransferTypeEnum}
|
||||||
|
*/
|
||||||
|
@NotNull(message = "原负责人移除方式不能为空")
|
||||||
|
private Integer transferType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 权限类型, 关联 {@link PermissionTypeEnum}
|
||||||
|
*/
|
||||||
|
@NotNull(message = "权限类型不能为空")
|
||||||
|
private Integer permissionType;
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue