Merge branch 'feature/REQ-1696' into 'master'

Feature/req 1696

See merge request universal/infrastructure/backend/tyr!15
This commit is contained in:
谭杰 2023-12-20 05:58:19 +00:00
commit 6f8816420a
16 changed files with 294 additions and 49 deletions

View File

@ -0,0 +1,28 @@
package cn.axzo.tyr.client.common.enums;
import com.baomidou.mybatisplus.annotation.EnumValue;
import com.fasterxml.jackson.annotation.JsonValue;
import lombok.Getter;
/**
* 产品默认授权方式类型
* @author tanjie@axzo.cn
* @date 2022/7/5 18:14
*/
@Getter
public enum ProductAuthTypeEnum {
CREATE_WORKSPACE(1, "创建工作台"),
APPRO_QUA(2, "资质审核"),
;
@Getter
@EnumValue
@JsonValue
public final Integer code;
public final String desc;
ProductAuthTypeEnum(Integer code, String desc){
this.code = code;
this.desc = desc;
}
}

View File

@ -74,4 +74,18 @@ public interface TyrSaasRoleUserApi {
@PostMapping("/api/saas-role-user/page")
ApiPageResult<SaasRoleUserDTO> pageQuery(@RequestBody @Valid RoleUserParam param);
/**
* 根据id删除用户角色关联关系
* @return
*/
@PostMapping("/api/saas-role-user/remove-role-user-relation")
ApiResult removeRoleUserRelation(@RequestBody @Valid List<Long> ids);
/**
* 获取分包负责人等特殊角色
* @return
*/
@PostMapping("/api/saas-role-user/get-special-role")
ApiResult<List<Long>> getSpecialRole();
}

View File

@ -6,6 +6,7 @@ import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
* 产品新增模型
@ -45,4 +46,25 @@ public class ProductAddReq {
* 上下架状态 1:上架, 0:下架
*/
private Integer status;
/**
* 产品默认授权方式
* 1:创建工作台
* 2:资质认证
*/
private Integer authType;
/**
* 资质序列/单位类型(数组多选)
* cn.axzo.basics.common.constant.enums.OrganizationalUnitTypeEnum
* 1:总包单位
* 2:建设单位
* 3:监理单位
* 4:劳务分包
* 5:专业分包
*/
private List<Integer> ouTypes;
}

View File

@ -39,7 +39,9 @@ public class ProductSearchListReq{
/**
* 1总包企业产品 2:总包项目产品 3:政企产品 4:分包企业产品 5:班组产品
* 从数据库里面看,这个字段废弃了,新增的都是0
*/
@Deprecated
private Integer productType;
/**
@ -47,4 +49,17 @@ public class ProductSearchListReq{
*/
private Integer commonProduct;
/**
* 产品默认授权方式
* 1:创建工作台
* 2:资质认证
*/
private Integer authType;
/**
* 资质序列/单位类型(数组多选)
* cn.axzo.basics.common.constant.enums.OrganizationalUnitTypeEnum
*/
private List<Integer> ouTypes;
}

View File

@ -9,6 +9,7 @@ import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
* 产品更新模型
@ -50,4 +51,22 @@ public class ProductUpdateReq {
*/
private Integer status;
/**
* 产品默认授权方式
* 1:创建工作台
* 2:资质认证
*/
private Integer authType;
/**
* 资质序列/单位类型(数组多选)
* cn.axzo.basics.common.constant.enums.OrganizationalUnitTypeEnum
* 1:总包单位
* 2:建设单位
* 3:监理单位
* 4:劳务分包
* 5:专业分包
*/
private List<Integer> ouTypes;
}

View File

@ -7,6 +7,7 @@ import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.util.Date;
import java.util.List;
/**
* 产品模型
@ -78,4 +79,22 @@ public class ProductVO {
*/
private Date updateAt;
/**
* 产品默认授权方式
* 1:创建工作台
* 2:资质认证
*/
private Integer authType;
/**
* 资质序列/单位类型(数组多选)
* cn.axzo.basics.common.constant.enums.OrganizationalUnitTypeEnum
* 1:总包单位
* 2:建设单位
* 3:监理单位
* 4:劳务分包
* 5:专业分包
*/
private List<Integer> ouTypes;
}

View File

@ -62,6 +62,12 @@ public class QuerySaasRoleReq {
*/
private Boolean includePermissionGroup;
/**
* 是否包含分包负责人等特殊角色
* @return
*/
private Boolean includeSpecialRole;
public QuerySaasRoleReq buildDefault() {
if (this.workspaceId == null) {
this.workspaceId = new ArrayList<>();

View File

@ -31,7 +31,9 @@ public class RoleUserParam extends PageRequest {
/**
* personId
* 模型里面把personId删除了,用身份id查
*/
@Deprecated
private Long personId;
/**

View File

@ -1,16 +1,20 @@
package cn.axzo.tyr.server.controller.roleuser;
import cn.axzo.basics.common.util.AssertUtil;
import cn.axzo.framework.domain.web.result.ApiPageResult;
import cn.axzo.framework.domain.web.result.ApiResult;
import cn.axzo.pokonyan.config.mybatisplus.BaseEntity;
import cn.axzo.tyr.client.feign.TyrSaasRoleUserApi;
import cn.axzo.tyr.client.model.roleuser.dto.SaasRoleUserDTO;
import cn.axzo.tyr.client.model.roleuser.dto.SuperAminInfoResp;
import cn.axzo.tyr.client.model.roleuser.req.*;
import cn.axzo.tyr.server.repository.dao.SaasRoleUserRelationDao;
import cn.axzo.tyr.server.service.SaasRoleUserRelationService;
import cn.axzo.tyr.server.service.SaasRoleUserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@ -28,6 +32,8 @@ import java.util.List;
public class RoleUserController implements TyrSaasRoleUserApi {
private final SaasRoleUserService saasRoleUserService;
private final SaasRoleUserRelationService saasRoleUserRelationService;
private final SaasRoleUserRelationDao saasRoleUserRelationDao;
@Override
public ApiResult<Void> saveOrUpdate(@Valid RoleUserReq req) {
saasRoleUserService.saveOrUpdate(req);
@ -77,6 +83,27 @@ public class RoleUserController implements TyrSaasRoleUserApi {
return ApiResult.ok(saasRoleUserService.batchSuperAdminList(param));
}
/**
* 根据id删除用户角色关联关系
* @return
*/
public ApiResult removeRoleUserRelation(@RequestBody @Valid List<Long> ids){
AssertUtil.isTrue(!CollectionUtils.isEmpty(ids),"用户角色关联id不能为空");
saasRoleUserRelationDao.lambdaUpdate()
.in(BaseEntity::getId,ids)
.setSql(" is_delete = id")
.update();
return ApiResult.ok();
}
/**
* 获取分包负责人等特殊角色
* @return
*/
public ApiResult<List<Long>> getSpecialRole() {
return ApiResult.ok(saasRoleUserService.getSpecialRole());
}
@Override
public ApiPageResult<SaasRoleUserDTO> pageQuery(RoleUserParam param) {
return ApiPageResult.ok(saasRoleUserRelationService.pageQuery(param));

View File

@ -6,8 +6,14 @@ import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.apache.commons.lang3.StringUtils;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* saas-产品表(SaasProduct)表实体类
@ -63,6 +69,19 @@ public class ProductModule extends BaseEntity<ProductModule> {
*/
private String remark;
/**
* 产品默认授权方式
* 1:创建工作台
* 2:资质认证
*/
private Integer authType;
/**
* 资质序列/单位类型(数组多选逗号隔开1,2,3,4,5)
* cn.axzo.basics.common.constant.enums.OrganizationalUnitTypeEnum
*/
private String ouType;
/**
* 获取主键值
*
@ -72,5 +91,14 @@ public class ProductModule extends BaseEntity<ProductModule> {
protected Serializable pkVal() {
return this.id;
}
public List<Integer> parseOuType() {
if (StringUtils.isNotBlank(this.ouType)) {
return Arrays.asList(this.ouType.split(",")).stream().map(e -> Integer.valueOf(e.trim())).collect(Collectors.toList());
} else {
// 避免下游空指针
return new ArrayList<>();
}
}
}

View File

@ -29,7 +29,7 @@ public interface RoleService {
List<SaasRoleVO> queryByIdentityIdType(Long identityId, Integer identityType,Long workspaceId,Long ouId, Boolean includePermissionGroup);
List<SaasRoleVO> getByIds(List<Long> roleIds, Integer isCommon, List<Long> workspaceId, List<Long> ouId, Boolean includePermissionGroup);
List<SaasRoleVO> getByIds(List<Long> roleIds, Integer isCommon, List<Long> workspaceId, List<Long> ouId, Boolean includePermissionGroup,Boolean includeSpecialRole);
List<SaasRoleVO> query(QuerySaasRoleReq req);

View File

@ -14,7 +14,9 @@ import java.util.Set;
*/
public interface SaasRoleUserService {
void saveOrUpdate( RoleUserReq req);
List<Long> getSpecialRole();
void saveOrUpdate(RoleUserReq req);
/**
* 是超管

View File

@ -13,16 +13,19 @@ import cn.axzo.tyr.client.model.product.ProductVO;
import cn.axzo.tyr.server.repository.entity.ProductModule;
import cn.axzo.tyr.server.repository.dao.ProductModuleDao;
import cn.axzo.tyr.server.service.ProductService;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import io.swagger.models.auth.In;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.util.Integers;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.*;
import java.util.stream.Collectors;
/**
* 产品相关 Service 接口实现
@ -38,12 +41,31 @@ public class ProductServiceImpl implements ProductService {
@Override
public ApiResult<List<ProductVO>> list(ProductSearchListReq req) {
List<ProductModule> list = productModuleDao.lambdaQuery()
.in(!CollectionUtils.isEmpty(req.getIds()), ProductModule::getId, req.getIds())
.like(StringUtils.hasLength(req.getName()), ProductModule::getProductName, req.getName())
.eq(Objects.nonNull(req.getDictWorkspaceTypeId()), ProductModule::getDictWorkspaceTypeId, req.getDictWorkspaceTypeId())
.eq(Objects.nonNull(req.getStatus()), ProductModule::getStatus, req.getStatus())
.list();
LambdaQueryChainWrapper<ProductModule> eq = productModuleDao.lambdaQuery()
.in(!CollectionUtils.isEmpty(req.getIds()), ProductModule::getId, req.getIds())
.like(StringUtils.hasLength(req.getName()), ProductModule::getProductName, req.getName())
.eq(Objects.nonNull(req.getDictWorkspaceTypeId()), ProductModule::getDictWorkspaceTypeId, req.getDictWorkspaceTypeId())
.eq(Objects.nonNull(req.getStatus()), ProductModule::getStatus, req.getStatus())
.eq(Objects.nonNull(req.getProductType()),ProductModule::getProductType,req.getProductType())
.eq(Objects.nonNull(req.getAuthType()),ProductModule::getAuthType,req.getAuthType())
.eq(ProductModule::getIsDelete, 0);
StringBuilder condition = new StringBuilder();
if (org.apache.commons.collections.CollectionUtils.isNotEmpty(req.getOuTypes())) {
condition = new StringBuilder();
for (Integer value : req.getOuTypes()) {
condition.append(" FIND_IN_SET('" + value + "', ou_type) OR");
}
}
if(!CollectionUtils.isEmpty(req.getOuTypes())){
eq.last(" AND (" + condition.substring(0, condition.length() - 2) + ")");
}
List<ProductModule> list = eq.list();
ArrayList<ProductVO> result = new ArrayList<>();
list.forEach(e -> {
ProductVO product = BeanMapper.copyBean(e, ProductVO.class);
product.setOuTypes(e.parseOuType());
result.add(product);
});
return ApiResult.ok(BeanMapper.copyList(list, ProductVO.class));
}
@ -61,7 +83,10 @@ public class ProductServiceImpl implements ProductService {
@Override
public ApiResult<ProductVO> getById(Long id) {
return ApiResult.ok(BeanMapper.copyBean(productModuleDao.getById(id), ProductVO.class));
ProductModule byId = productModuleDao.getById(id);
ProductVO productVO = BeanMapper.copyBean(byId, ProductVO.class);
productVO.setOuTypes(byId.parseOuType());
return ApiResult.ok(productVO);
}
@Override
@ -72,6 +97,10 @@ public class ProductServiceImpl implements ProductService {
.oneOpt();
AssertUtil.isTrue(!optProduct.isPresent(), "产品名称在相同工作台类型下不允许重复");
ProductModule productModule = BeanMapper.copyBean(req, ProductModule.class);
// 拼接ouType
if (!CollectionUtils.isEmpty(req.getOuTypes())) {
productModule.setOuType(org.apache.commons.lang3.StringUtils.join(req.getOuTypes(),","));
}
productModuleDao.save(productModule);
return ApiResult.ok(BeanMapper.copyBean(productModule, ProductVO.class));
}
@ -85,6 +114,10 @@ public class ProductServiceImpl implements ProductService {
AssertUtil.isTrue(!optProduct.isPresent() || Objects.equals(req.getId(), optProduct.get().getId()), "产品名称在相同工作台类型下不允许重复");
ProductModule productModule = productModuleDao.getById(req.getId());
BeanMapper.copyBeanIgnoreNull(req, () -> productModule);
// 拼接ouType
if (!CollectionUtils.isEmpty(req.getOuTypes())) {
productModule.setOuType(org.apache.commons.lang3.StringUtils.join(req.getOuTypes(),","));
}
productModuleDao.updateById(productModule);
return ApiResult.ok(BeanMapper.copyBeanIgnoreNull(productModule, ProductVO.class));
}

View File

@ -81,16 +81,18 @@ public class RoleServiceImpl implements RoleService {
@Autowired
SaasRoleUserRelationDao saasRoleUserRelationDao;
@Autowired
RoleUserService roleUserService;
@Override
public List<SaasRoleVO> queryByIdentityIdType(Long identityId, Integer identityType, Long workspaceId, Long ouId, Boolean includePermissionGroup) {
// 查询人关联的角色id
List<Long> roleIds = roleUserRelationDao.query(identityId, identityType, workspaceId, ouId).stream().map(SaasRoleUserRelation::getRoleId).collect(Collectors.toList());
if (CollectionUtils.isEmpty(roleIds)) {
return new ArrayList<>();
}
return getByIds(roleIds, null, null, null, includePermissionGroup);
}
@Override
public List<SaasRoleVO> queryByIdentityIdType(Long identityId, Integer identityType, Long workspaceId, Long ouId, Boolean includePermissionGroup) {
// 查询人关联的角色id
List<Long> roleIds = roleUserRelationDao.query(identityId, identityType, workspaceId, ouId).stream().map(SaasRoleUserRelation::getRoleId).collect(Collectors.toList());
if (CollectionUtils.isEmpty(roleIds)) {
return new ArrayList<>();
}
return getByIds(roleIds, null, null,null, includePermissionGroup,null);
}
/**
* 根据id查询权限详情包含权限组合权限集(底层基础方法)
@ -98,13 +100,20 @@ public class RoleServiceImpl implements RoleService {
* @return
*/
@Override
public List<SaasRoleVO> getByIds(List<Long> roleIds, Integer isCommon, List<Long> workspaceId, List<Long> ouId, Boolean includePermissionGroup) {
if (includePermissionGroup == null) {
includePermissionGroup = false;
}
if (CollectionUtils.isEmpty(roleIds)) {
return new ArrayList<>();
}
public List<SaasRoleVO> getByIds(List<Long> roleIds, Integer isCommon, List<Long> workspaceId, List<Long> ouId, Boolean includePermissionGroup,Boolean includeSpecialRole) {
if (CollectionUtils.isEmpty(roleIds)) {
return new ArrayList<>();
}
if (includePermissionGroup == null) {
includePermissionGroup = false;
}
if (includeSpecialRole == null) {
includeSpecialRole = true;
}
if (!includeSpecialRole) {
List<Long> specialRole = roleUserService.getSpecialRole();
roleIds = roleIds.stream().filter(e -> !specialRole.contains(e)).collect(Collectors.toList());
}
// 查询角色信息
List<SaasRole> roles = saasRoleDao.lambdaQuery().in(BaseEntity::getId, roleIds).list();
// 查询权限集
@ -186,18 +195,18 @@ public class RoleServiceImpl implements RoleService {
if (CollectionUtils.isEmpty(groupRelation)) {
return new ArrayList<>();
}
}
// 查询角色
List<SaasRole> list = saasRoleDao.lambdaQuery()
.in(CollectionUtils.isNotEmpty(req.getIds()), BaseEntity::getId, req.getIds())
.in(CollectionUtils.isNotEmpty(groupRelation), BaseEntity::getId, groupRelation.stream().map(SaasRoleGroupRelation::getRoleId).collect(Collectors.toList()))
.in(CollectionUtils.isNotEmpty(req.getRoleType()), SaasRole::getRoleType, req.getRoleType())
.in(CollectionUtils.isEmpty(req.getIds()) && CollectionUtils.isNotEmpty(req.getWorkspaceId()), SaasRole::getWorkspaceId, req.getWorkspaceId())
.in(CollectionUtils.isEmpty(req.getIds()) && CollectionUtils.isNotEmpty(req.getOuId()), SaasRole::getOwnerOuId, req.getOuId())
.orderByDesc(BaseEntity::getId)
.list();
return getByIds(list.stream().map(BaseEntity::getId).collect(Collectors.toList()), req.getIsCommon(), req.getWorkspaceId(), req.getOuId(), req.getIncludePermissionGroup());
}
}
// 查询角色
List<SaasRole> list = saasRoleDao.lambdaQuery()
.in(CollectionUtils.isNotEmpty(req.getIds()), BaseEntity::getId, req.getIds())
.in(CollectionUtils.isNotEmpty(groupRelation), BaseEntity::getId, groupRelation.stream().map(SaasRoleGroupRelation::getRoleId).collect(Collectors.toList()))
.in(CollectionUtils.isNotEmpty(req.getRoleType()), SaasRole::getRoleType, req.getRoleType())
.in(CollectionUtils.isEmpty(req.getIds()) && CollectionUtils.isNotEmpty(req.getWorkspaceId()),SaasRole::getWorkspaceId,req.getWorkspaceId())
.in(CollectionUtils.isEmpty(req.getIds()) && CollectionUtils.isNotEmpty(req.getOuId()),SaasRole::getOwnerOuId,req.getOuId())
.orderByDesc(BaseEntity::getId)
.list();
return getByIds(list.stream().map(BaseEntity::getId).collect(Collectors.toList()), req.getIsCommon(),req.getWorkspaceId(),req.getOuId(),req.getIncludePermissionGroup(),req.getIncludeSpecialRole());
}
@Override
public List<QueryBatchByIdentityIdTypeRes> queryBatchByIdentityIdType(List<QueryByIdentityIdTypeReq> req) {

View File

@ -22,14 +22,12 @@ import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapp
import com.google.common.collect.Lists;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;
/**
@ -42,14 +40,33 @@ import java.util.stream.Collectors;
@Slf4j
@RequiredArgsConstructor
@Service
@RefreshScope
public class RoleUserService implements SaasRoleUserService {
private final SaasRoleUserRelationDao roleUserRelationDao;
private final SaasRoleDao saasRoleDao;
@Override
@Transactional(rollbackFor = Exception.class)
public void saveOrUpdate(RoleUserReq req) {
// 单位类型默认角色关系,后面可以座位管理员的逻辑进行迭代
@Value("#{${participateUnitDefaultRoleId:{}}}")
public Map<Integer,Long> participateUnitDefaultRoleId;
/**
* 获取分包负责人等特殊角色
* @return
*/
@Override
public List<Long> getSpecialRole() {
if (participateUnitDefaultRoleId != null && participateUnitDefaultRoleId.size() > 0) {
return participateUnitDefaultRoleId.values().stream().collect(Collectors.toList());
}else{
return new ArrayList<>();
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public void saveOrUpdate(RoleUserReq req) {
Set<Long> updateRoleIds = req.getUpdateRoleIds();
// 角色校验(不能将角色修改为管理员角色)
@ -70,6 +87,10 @@ public class RoleUserService implements SaasRoleUserService {
List<Long> adminRole = existsRole.stream().filter(e -> RoleTypeEnum.getRoleType(e.getRoleType()).isAdminRole()).mapToLong(SaasRole::getId).boxed().collect(Collectors.toList());
// 排除管理员角色(普通角色) 这里用过滤的方式是为了防止脏数据产生(saas_role_user_relation表有用户数据但是角色表已经被删除)
notAdminRole = existsRoleUser.stream().mapToLong(SaasRoleUserRelation::getRoleId).boxed().filter(roleId -> !adminRole.contains(roleId)).collect(Collectors.toList());
// 排除分包负责人等角色
if (CollectionUtils.isNotEmpty(notAdminRole) && participateUnitDefaultRoleId != null && participateUnitDefaultRoleId.size() > 0) {
notAdminRole = notAdminRole.stream().filter(e-> !participateUnitDefaultRoleId.values().contains(e)).collect(Collectors.toList());
}
}
BaseWorkspaceModel workspaceModel = BaseWorkspaceModel.builder()
.workspaceId(req.getWorkspaceId()).ouId(req.getOuId())

View File

@ -615,7 +615,7 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService {
//查询角色及权限
watch.start("roleService.getByIds");
List<SaasRoleVO> rolePermissions = roleService.getByIds(roleIds,
null, Lists.newArrayList(workspaceId), Lists.newArrayList(ouId), true);
null, Lists.newArrayList(workspaceId), Lists.newArrayList(ouId), true,null);
watch.stop();
//计算角色实际的权限 - 匹配请求的权限 --> 实际拥有权限的角色
watch.start("filterMatchFeature");