diff --git a/opsli-api/src/main/java/org/opsli/api/web/system/menu/MenuApi.java b/opsli-api/src/main/java/org/opsli/api/web/system/menu/MenuApi.java index 162aa1b..ded669d 100644 --- a/opsli-api/src/main/java/org/opsli/api/web/system/menu/MenuApi.java +++ b/opsli-api/src/main/java/org/opsli/api/web/system/menu/MenuApi.java @@ -59,6 +59,7 @@ public interface MenuApi { /** * 懒加载列表菜单 + * * @param parentId 父节点ID * @return ResultVo */ @@ -84,10 +85,12 @@ public interface MenuApi { /** * 根据 获得用户 菜单 - 权限 + * + * @param label 标签 * @return ResultVo */ @GetMapping("/getMenuAndPermsTree") - ResultVo getMenuAndPermsTree(); + ResultVo getMenuAndPermsTree(String label); /** * 获得集合 diff --git a/opsli-api/src/main/java/org/opsli/api/wrapper/system/menu/MenuModel.java b/opsli-api/src/main/java/org/opsli/api/wrapper/system/menu/MenuModel.java index 520e6bb..c286e96 100644 --- a/opsli-api/src/main/java/org/opsli/api/wrapper/system/menu/MenuModel.java +++ b/opsli-api/src/main/java/org/opsli/api/wrapper/system/menu/MenuModel.java @@ -103,4 +103,10 @@ public class MenuModel extends ApiWrapper { @Validator({ValidatorType.IS_NOT_NULL}) private String alwaysShow; + /** 标签 */ + @ApiModelProperty(value = "标签") + @ExcelIgnore + @Validator({ValidatorType.IS_NOT_NULL}) + private String label; + } diff --git a/opsli-api/src/main/java/org/opsli/api/wrapper/system/role/RoleModel.java b/opsli-api/src/main/java/org/opsli/api/wrapper/system/role/RoleModel.java index ce5f408..204e678 100644 --- a/opsli-api/src/main/java/org/opsli/api/wrapper/system/role/RoleModel.java +++ b/opsli-api/src/main/java/org/opsli/api/wrapper/system/role/RoleModel.java @@ -60,10 +60,18 @@ public class RoleModel extends ApiWrapper { @ValidatorLenMax(1) private String izLock; + /** 标签 */ + @ApiModelProperty(value = "标签") + @ExcelProperty(value = "标签", order = 4) + @ExcelInfo(dictType = "menu_role_type") + @Validator({ValidatorType.IS_NOT_NULL}) + @ValidatorLenMax(1) + private String label; + /** 授权数据范围 */ @ApiModelProperty(value = "授权数据范围") - @ExcelProperty(value = "授权数据范围", order = 4) + @ExcelProperty(value = "授权数据范围", order = 5) @ExcelInfo(dictType = "role_data_scope") @Validator({ValidatorType.IS_NOT_NULL}) @ValidatorLenMax(5) @@ -71,7 +79,7 @@ public class RoleModel extends ApiWrapper { /** 备注 */ @ApiModelProperty(value = "备注") - @ExcelProperty(value = "备注", order = 5) + @ExcelProperty(value = "备注", order = 6) @ExcelInfo @ValidatorLenMax(255) private String remark; diff --git a/opsli-api/src/main/java/org/opsli/api/wrapper/system/user/UserInfo.java b/opsli-api/src/main/java/org/opsli/api/wrapper/system/user/UserInfo.java index 6b432b3..5dbd050 100644 --- a/opsli-api/src/main/java/org/opsli/api/wrapper/system/user/UserInfo.java +++ b/opsli-api/src/main/java/org/opsli/api/wrapper/system/user/UserInfo.java @@ -99,4 +99,8 @@ public class UserInfo extends ApiWrapper { @ApiModelProperty(value = "密码强度") private String passwordLevel; + /** 多租户字段 */ + @ApiModelProperty(value = "多租户ID") + private String tenantId; + } diff --git a/opsli-api/src/main/java/org/opsli/api/wrapper/system/user/UserModel.java b/opsli-api/src/main/java/org/opsli/api/wrapper/system/user/UserModel.java index d934960..113b8d8 100644 --- a/opsli-api/src/main/java/org/opsli/api/wrapper/system/user/UserModel.java +++ b/opsli-api/src/main/java/org/opsli/api/wrapper/system/user/UserModel.java @@ -148,7 +148,20 @@ public class UserModel extends ApiWrapper { @ValidatorLenMax(1) private String izExistOrg; + /** 允许切换租户(0 不允许 1 允许) */ + @ApiModelProperty(value = "是否允许切换运营商") + @ExcelIgnore + private String enableSwitchTenant; + + /** 切换后的租户id*/ + @JsonIgnore + @ExcelIgnore + private String switchTenantId; + /** 切换后的租户管理员*/ + @JsonIgnore + @ExcelIgnore + private String switchTenantUserId; } diff --git a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/enums/DictType.java b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/enums/DictType.java index 962ccd8..217ac27 100644 --- a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/enums/DictType.java +++ b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/enums/DictType.java @@ -28,6 +28,10 @@ public enum DictType { NO_YES_NO("no_yes","0", "否"), NO_YES_YES("no_yes","1", "是"), + /** 菜单 标签 */ + MENU_LABEL_SYSTEM("menu_role_type","0", "系统模块"), + MENU_LABEL_FUNCTION("menu_role_type","1", "功能模块"), + /** 菜单 */ MENU_MENU("menu_type","1", "菜单"), MENU_BUTTON("menu_type","2", "按钮"), diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/persistence/querybuilder/chain/QueryDataPermsHandler.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/persistence/querybuilder/chain/QueryDataPermsHandler.java index 2e892e1..e6eaabe 100644 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/persistence/querybuilder/chain/QueryDataPermsHandler.java +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/persistence/querybuilder/chain/QueryDataPermsHandler.java @@ -107,8 +107,13 @@ public class QueryDataPermsHandler implements QueryBuilderChain{ // 1. 当前用户 UserModel currUser = UserUtil.getUser(); + String userId = StringUtils.isNotEmpty(currUser.getSwitchTenantUserId()) + ? currUser.getSwitchTenantUserId() + : currUser.getId(); + + // 2. 当前用户 组织机构集合 - List userOrgRefModelList = UserUtil.getOrgListByUserId(currUser.getId()); + List userOrgRefModelList = UserUtil.getOrgListByUserId(userId); List orgIdGroupList = Lists.newArrayListWithCapacity(userOrgRefModelList.size()); for (UserOrgRefModel userOrgRefModel : userOrgRefModelList) { orgIdGroupList.add(userOrgRefModel.getOrgIds()); @@ -123,7 +128,7 @@ public class QueryDataPermsHandler implements QueryBuilderChain{ conditionType = ConditionType.ALL; }else{ // 如果不是超级管理员 则获得当前用户的默认角色下的 授权数据权限类型 - RoleModel defRole = UserUtil.getUserDefRoleByUserId(currUser.getId()); + RoleModel defRole = UserUtil.getUserDefRoleByUserId(userId); if(null != defRole){ conditionType = ConditionType.getConditionType(defRole.getDataScope()); } @@ -164,7 +169,7 @@ public class QueryDataPermsHandler implements QueryBuilderChain{ }); }else { // 查自身 - wra.eq(FieldUtil.humpToUnderline(MyBatisConstants.FIELD_CREATE_BY), currUser.getId()); + wra.eq(FieldUtil.humpToUnderline(MyBatisConstants.FIELD_CREATE_BY), userId); } }); } diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/persistence/querybuilder/chain/QueryTenantHandler.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/persistence/querybuilder/chain/QueryTenantHandler.java index 20727ed..a9cfc9f 100644 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/persistence/querybuilder/chain/QueryTenantHandler.java +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/persistence/querybuilder/chain/QueryTenantHandler.java @@ -59,14 +59,14 @@ public class QueryTenantHandler implements QueryBuilderChain{ // 自身责任 -- 判断多租户 boolean tenantFlag = ReflectUtil.hasField(entityClazz, MyBatisConstants.FIELD_TENANT); if(tenantFlag) { - String tenantId = UserUtil.getTenantId(); - //UserModel user = UserUtil.getUser(); - // 超级管理员可以操作 无租户限制, 其余用户全部有租户限制 -// if(!UserUtil.SUPER_ADMIN.equals(user.getUsername()) && -// StringUtils.isNotEmpty(tenantId) -// ){ - wrapper.eq(FieldUtil.humpToUnderline(MyBatisConstants.FIELD_TENANT), tenantId); - //} + UserModel currUser = UserUtil.getUser(); + + // 切换运营商后 组织ID 不同 + String tenantId = StringUtils.isNotEmpty(currUser.getSwitchTenantId()) + ? currUser.getSwitchTenantId() + : currUser.getTenantId(); + + wrapper.eq(FieldUtil.humpToUnderline(MyBatisConstants.FIELD_TENANT), tenantId); } return wrapper; } @@ -81,19 +81,18 @@ public class QueryTenantHandler implements QueryBuilderChain{ // 自身责任 -- 判断多租户 boolean tenantFlag = ReflectUtil.hasField(entityClazz, MyBatisConstants.FIELD_TENANT); if(tenantFlag) { - String tenantId = UserUtil.getTenantId(); - //UserModel user = UserUtil.getUser(); - // 超级管理员可以操作 无租户限制, 其余用户全部有租户限制 -// if(!UserUtil.SUPER_ADMIN.equals(user.getUsername()) && -// StringUtils.isNotEmpty(tenantId) -// ){ + UserModel currUser = UserUtil.getUser(); + + // 切换运营商后 组织ID 不同 + String tenantId = StringUtils.isNotEmpty(currUser.getSwitchTenantId()) + ? currUser.getSwitchTenantId() + : currUser.getTenantId(); - String fieldName = webQueryConf.get(MyBatisConstants.FIELD_TENANT); - if(StringUtils.isEmpty(fieldName)){ - fieldName = FieldUtil.humpToUnderline(MyBatisConstants.FIELD_TENANT); - } - wrapper.eq(fieldName, tenantId); - //} + String fieldName = webQueryConf.get(MyBatisConstants.FIELD_TENANT); + if(StringUtils.isEmpty(fieldName)){ + fieldName = FieldUtil.humpToUnderline(MyBatisConstants.FIELD_TENANT); + } + wrapper.eq(fieldName, tenantId); } return wrapper; } diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/TenantUtil.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/TenantUtil.java index 940e7b4..b1cff05 100644 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/TenantUtil.java +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/TenantUtil.java @@ -44,6 +44,9 @@ public class TenantUtil { /** 前缀 */ public static final String PREFIX_CODE = "tenant:id:"; + /** 超级管理员 租户ID */ + public static final String SUPER_ADMIN_TENANT_ID = "0"; + /** 租户 Api */ private static TenantApi tenantApi; diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/UserUtil.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/UserUtil.java index d2162c3..841d413 100644 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/UserUtil.java +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/UserUtil.java @@ -659,6 +659,51 @@ public class UserUtil { // ============== 刷新缓存 ============== + /** + * 获得当前系统登陆用户 + * @return UserModel + */ + public static boolean updateUser(UserModel user){ + if(null == user){ + return false; + } + + // 先清空缓存 + boolean flag = refreshUser(user); + if(!flag){ + return false; + } + + // 缓存Key + String cacheKey = PREFIX_ID + user.getId(); + try { + // 存入缓存 + CacheUtil.put(cacheKey, user); + }catch (Exception e){ + log.error(e.getMessage(), e); + } + + try { + // 分布式加锁 + if(!DistributedLockUtil.lock(cacheKey)){ + // 无法申领分布式锁 + log.error(CoreMsg.REDIS_EXCEPTION_LOCK.getMessage()); + return false; + } + + // 存入缓存 + flag = CacheUtil.put(cacheKey, user); + }catch (Exception e){ + flag = false; + log.error(e.getMessage(), e); + }finally { + // 释放锁 + DistributedLockUtil.unlock(cacheKey); + } + + return flag; + } + /** * 刷新用户 - 删就完了 * @param user 用户 @@ -984,7 +1029,7 @@ public class UserUtil { // 如果是超级管理员 则不进行租户处理 默认为0 if(StringUtils.equals(SUPER_ADMIN, user.getUsername())){ - return "0"; + return TenantUtil.SUPER_ADMIN_TENANT_ID; } return user.getTenantId(); } diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/SystemMsg.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/SystemMsg.java index 6494307..6e6153c 100644 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/SystemMsg.java +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/SystemMsg.java @@ -49,6 +49,7 @@ public enum SystemMsg implements BaseMsg { EXCEPTION_ROLE_UNIQUE(20200,"角色编号或名称重复,该角色已存在!"), EXCEPTION_ROLE_ID_NOT_NULL(20201,"角色Id不可为空"), EXCEPTION_ROLE_PERMS_ERROR(20202,"角色权限设置失败"), + EXCEPTION_ROLE_USED(20203,"角色删除失败, 被删除角色正在被其他用户使用"), @@ -68,7 +69,8 @@ public enum SystemMsg implements BaseMsg { EXCEPTION_USER_ILLEGAL_PARAMETER(20311,"非法参数"), EXCEPTION_USER_HANDLE_SELF(20312,"不可操作自身"), EXCEPTION_USER_HANDLE_SUPER_ADMIN(20313,"不可操作超管账号"), - + EXCEPTION_USER_SWITCH_TENANT_NOT_HAS_ADMIN(20314,"此租户不存在管理员,不能切换"), + EXCEPTION_USER_SWITCH_NOT_ALLOWED(20315,"不允许切换租户"), /** * 租户 diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/menu/entity/SysMenu.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/menu/entity/SysMenu.java index dfe86bf..9c35988 100644 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/menu/entity/SysMenu.java +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/menu/entity/SysMenu.java @@ -70,6 +70,9 @@ public class SysMenu extends BaseEntity { /** 是否总是显示 0为否 1为是 */ private String alwaysShow; + /** 标签 */ + private String label; + // ======================================== /** 逻辑删除字段 */ diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/menu/web/MenuRestController.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/menu/web/MenuRestController.java index 0c9f686..44fa6a8 100644 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/menu/web/MenuRestController.java +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/menu/web/MenuRestController.java @@ -101,11 +101,11 @@ public class MenuRestController extends BaseRestController getMenuAndPermsTree() { + public ResultVo getMenuAndPermsTree(String label) { UserModel user = UserUtil.getUser(); // 获得当前用户菜单 - List menuModelList = iUserRoleRefService.getMenuAllListByUserId(user.getId()); + List menuModelList = iUserRoleRefService.getMenuAllListByUserId(user.getId(), label); // 这里有坑 如果 为 菜单数据 且 组件(Component)地址为空 不会跳转到主页 也不报错 // 修复菜单问题导致无法跳转主页 @@ -200,6 +200,9 @@ public class MenuRestController extends BaseRestController userIdList = + iUserRoleRefService.getUserIdListByTenantIdAndAllData(UserUtil.getTenantId()); + // 清除缓存 + this.clearCache(userIdList); return super.insert(model); } @@ -337,4 +353,32 @@ public class SysOrgServiceImpl extends CrudServiceImpl userIdList){ + if(CollUtil.isNotEmpty(userIdList)){ + int cacheCount = 0; + for (String userId : userIdList) { + cacheCount += 2; + boolean tmp; + // 清空当期用户缓存 组织 + tmp = UserUtil.refreshUserOrgs(userId); + if(tmp){ + cacheCount--; + } + tmp = UserUtil.refreshUserDefOrg(userId); + if(tmp){ + cacheCount--; + } + } + // 判断删除状态 + if(cacheCount != 0){ + // 删除缓存失败 + throw new ServiceException(CoreMsg.CACHE_DEL_EXCEPTION); + } + } + } } diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/role/entity/SysRole.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/role/entity/SysRole.java index c5b1e78..90a83f5 100644 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/role/entity/SysRole.java +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/role/entity/SysRole.java @@ -42,6 +42,9 @@ public class SysRole extends BaseEntity { /** 是否内置数据 0否 1是 */ private String izLock; + /** 标签 */ + private String label; + /** 授权数据范围 */ private String dataScope; diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/role/service/impl/RoleServiceImpl.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/role/service/impl/RoleServiceImpl.java index 6e478c3..05cd2e1 100644 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/role/service/impl/RoleServiceImpl.java +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/role/service/impl/RoleServiceImpl.java @@ -15,7 +15,9 @@ */ package org.opsli.modulars.system.role.service.impl; +import cn.hutool.core.collection.CollUtil; import cn.hutool.core.convert.Convert; +import cn.hutool.core.util.ArrayUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.google.common.collect.Lists; import org.apache.commons.lang3.StringUtils; @@ -25,6 +27,7 @@ import org.opsli.common.constants.MyBatisConstants; import org.opsli.common.exception.ServiceException; import org.opsli.common.utils.FieldUtil; import org.opsli.core.base.service.impl.CrudServiceImpl; +import org.opsli.core.msg.CoreMsg; import org.opsli.core.persistence.querybuilder.GenQueryBuilder; import org.opsli.core.persistence.querybuilder.QueryBuilder; import org.opsli.core.persistence.querybuilder.chain.QueryDataPermsHandler; @@ -35,6 +38,7 @@ import org.opsli.modulars.system.role.entity.SysRole; import org.opsli.modulars.system.role.mapper.RoleMapper; import org.opsli.modulars.system.role.service.IRoleMenuRefService; import org.opsli.modulars.system.role.service.IRoleService; +import org.opsli.modulars.system.user.service.IUserRoleRefService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -56,6 +60,8 @@ public class RoleServiceImpl extends CrudServiceImpl models) { List roleIds = Lists.newArrayList(); for (RoleModel model : models) { roleIds.add(model.getId()); } + // 删除角色下 权限 iRoleMenuRefService.delPermsByRoleIds(roleIds); return super.deleteAll(models); @@ -214,6 +249,43 @@ public class RoleServiceImpl extends CrudServiceImpl userIdList = iUserRoleRefService.getUserIdListByRoleIds(roleIds); + if(CollUtil.isNotEmpty(userIdList)){ + int cacheCount = 0; + for (String userId : userIdList) { + cacheCount += 4; + boolean tmp; + // 清空当期用户缓存角色、权限、菜单 + tmp = UserUtil.refreshUserRoles(userId); + if(tmp){ + cacheCount--; + } + tmp = UserUtil.refreshUserAllPerms(userId); + if(tmp){ + cacheCount--; + } + tmp = UserUtil.refreshUserMenus(userId); + if(tmp){ + cacheCount--; + } + tmp = UserUtil.refreshUserDefRole(userId); + if(tmp){ + cacheCount--; + } + } + // 判断删除状态 + if(cacheCount != 0){ + // 删除缓存失败 + throw new ServiceException(CoreMsg.CACHE_DEL_EXCEPTION); + } + } + } } diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/user/mapper/UserRoleRefMapper.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/user/mapper/UserRoleRefMapper.java index 6c85833..2dfca85 100644 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/user/mapper/UserRoleRefMapper.java +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/user/mapper/UserRoleRefMapper.java @@ -15,8 +15,11 @@ */ package org.opsli.modulars.system.user.mapper; +import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.toolkit.Constants; import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; import org.opsli.modulars.system.menu.entity.SysMenu; import org.opsli.modulars.system.user.entity.SysUserRoleRef; @@ -67,11 +70,12 @@ public interface UserRoleRefMapper extends BaseMapper { List findMenuAllListByUserId(String userId); /** - * 根据角色ID 获得当前用户Id集合 - * @param roleId 角色ID + * 根据条件 获得当前用户Id集合 + * + * @param wrapper wrapper * @return List */ - List getUserIdListByRoleId(String roleId); + List getUserIdList(@Param(Constants.WRAPPER) Wrapper wrapper); /** * 根据菜单ID 获得当前用户Id集合 diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/user/mapper/xml/UserRoleRefMapper.xml b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/user/mapper/xml/UserRoleRefMapper.xml index f3e351b..ab1f463 100644 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/user/mapper/xml/UserRoleRefMapper.xml +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/user/mapper/xml/UserRoleRefMapper.xml @@ -66,6 +66,8 @@ and c.type in ( '1', '3' ) and c.deleted = '0' and c.hidden = '0' + + and c.label like '%1%' @@ -95,16 +97,13 @@ and c.hidden = '0' - select a.user_id - from - sys_user_role_ref a + from sys_user_role_ref a join sys_user b on a.user_id = b.id - - b.deleted = 0 - and a.role_id = #{roleId} - + join sys_role c on a.role_id = c.id + ${ew.customSqlSegment}