feat: 系统用户可切换租户

pull/9/head
Carina 3 years ago
parent 2ed4916f8e
commit a44f34b8d1

@ -18,10 +18,7 @@ package org.opsli.api.web.system.user;
import org.opsli.api.base.result.ResultVo;
import org.opsli.api.wrapper.system.menu.MenuModel;
import org.opsli.api.wrapper.system.role.RoleModel;
import org.opsli.api.wrapper.system.user.UserInfo;
import org.opsli.api.wrapper.system.user.UserModel;
import org.opsli.api.wrapper.system.user.UserOrgRefWebModel;
import org.opsli.api.wrapper.system.user.UserPassword;
import org.opsli.api.wrapper.system.user.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
@ -108,7 +105,7 @@ public interface UserApi {
* @return ResultVo
*/
@PostMapping("/updatePasswordById")
ResultVo<?> updatePasswordById(@RequestBody UserPassword userPassword);
ResultVo<?> updatePasswordById(@RequestBody ToUserPassword userPassword);
/**
* ID
@ -244,6 +241,21 @@ public interface UserApi {
void importTemplate(HttpServletResponse response);
/**
*
* @param tenantId ID
* @return ResultVo
*/
@PostMapping("/switchTenant")
ResultVo<?> switchTenant(String tenantId);
/**
*
* @return ResultVo
*/
@PostMapping("/switchOneself")
ResultVo<?> switchOneself();
/**
* username
* @param username

@ -52,14 +52,6 @@ public class RoleModel extends ApiWrapper {
@ValidatorLenMax(50)
private String roleName;
/** 是否内置数据 0否 1是*/
@ApiModelProperty(value = "是否内置数据 0否 1是")
@ExcelProperty(value = "是否内置数据", order = 3)
@ExcelInfo(dictType = "no_yes")
@Validator({ValidatorType.IS_NOT_NULL})
@ValidatorLenMax(1)
private String izLock;
/** 标签 */
@ApiModelProperty(value = "标签")
@ExcelProperty(value = "标签", order = 4)

@ -0,0 +1,67 @@
/**
* Copyright 2020 OPSLI https://www.opsli.com
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.opsli.api.wrapper.system.user;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.opsli.common.annotation.validator.Validator;
import org.opsli.common.annotation.validator.ValidatorLenMax;
import org.opsli.common.annotation.validator.ValidatorLenMin;
import org.opsli.common.enums.ValidatorType;
import java.io.Serializable;
/**
*
*
* @author Parker
* @date 2020-09-16 17:33
*/
@Data
@EqualsAndHashCode(callSuper = false)
@ExcelIgnoreUnannotated
public class ToUserPassword implements Serializable {
private static final long serialVersionUID = 1L;
/** User Id */
@ApiModelProperty(value = "用户Id")
private String userId;
/** 新密码 */
@ApiModelProperty(value = "新密码")
@Validator({ValidatorType.IS_NOT_NULL, ValidatorType.IS_SECURITY_PASSWORD})
@ValidatorLenMin(6)
@ValidatorLenMax(50)
private String newPassword;
/** 盐值,密码秘钥 前端不可改*/
@ApiModelProperty(value = "盐值,密码秘钥 前端不可改")
@ExcelIgnore
@ValidatorLenMax(50)
private String salt;
/** 登录密码强度 前端不可改 */
@ApiModelProperty(value = "登录密码强度 前端不可改")
@ExcelIgnore
@ValidatorLenMin(1)
@ValidatorLenMax(1)
private String passwordLevel;
}

@ -15,7 +15,9 @@
*/
package org.opsli.api.wrapper.system.user;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
@ -103,4 +105,16 @@ public class UserInfo extends ApiWrapper {
@ApiModelProperty(value = "多租户ID")
private String tenantId;
/** 允许切换租户0 不允许 1 允许) */
@ApiModelProperty(value = "是否允许切换运营商")
private String enableSwitchTenant;
/** 切换后的租户id*/
@ApiModelProperty(value = "切换后的租户id")
private String switchTenantId;
/** 切换后的租户管理员*/
@ApiModelProperty(value = "切换后的租户管理员")
private String switchTenantUserId;
}

@ -43,7 +43,7 @@ public class UserModel extends ApiWrapper {
@ExcelIgnore
@Validator({ValidatorType.IS_NOT_NULL, ValidatorType.IS_GENERAL})
@ValidatorLenMax(32)
@ValidatorLenMin(5)
@ValidatorLenMin(4)
private String username;
/** 登录密码 */
@ -163,5 +163,4 @@ public class UserModel extends ApiWrapper {
@ExcelIgnore
private String switchTenantUserId;
}

@ -37,6 +37,10 @@ import org.opsli.plugins.excel.annotation.ExcelInfo;
@EqualsAndHashCode(callSuper = false)
public class UserWebModel extends ApiWrapper {
/** 角色名称 */
@ApiModelProperty(value = "角色名称")
@ExcelIgnore
private String roleNames;
/** 登录账户 */
@ApiModelProperty(value = "登录账户")
@ -137,4 +141,8 @@ public class UserWebModel extends ApiWrapper {
@ValidatorLenMax(20)
private String tenantId;
/** 允许切换租户0 不允许 1 允许) */
@ApiModelProperty(value = "是否允许切换运营商")
private String enableSwitchTenant;
}

@ -28,10 +28,8 @@ import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.*;
import org.opsli.api.wrapper.system.org.SysOrgModel;
import org.opsli.api.wrapper.system.user.UserOrgRefModel;
import org.opsli.common.constants.MyBatisConstants;
import org.opsli.core.utils.UserTokenUtil;
import org.opsli.core.utils.UserUtil;
import org.springframework.stereotype.Component;
@ -147,7 +145,7 @@ public class MybatisAutoFillInterceptor implements Interceptor {
// 如果创建人 为空则进行默认赋值
Object createValue = ReflectUtil.getFieldValue(arg, f.getName());
if(StringUtils.isBlank(Convert.toStr(createValue))){
BeanUtil.setProperty(arg, MyBatisConstants.FIELD_CREATE_BY, UserTokenUtil.getUserIdByToken());
BeanUtil.setProperty(arg, MyBatisConstants.FIELD_CREATE_BY, UserUtil.getUser().getId());
}
break;
// 更新人
@ -155,7 +153,7 @@ public class MybatisAutoFillInterceptor implements Interceptor {
// 如果更新人 为空则进行默认赋值
Object updateValue = ReflectUtil.getFieldValue(arg, f.getName());
if(StringUtils.isBlank(Convert.toStr(updateValue))){
BeanUtil.setProperty(arg, MyBatisConstants.FIELD_UPDATE_BY, UserTokenUtil.getUserIdByToken());
BeanUtil.setProperty(arg, MyBatisConstants.FIELD_UPDATE_BY, UserUtil.getUser().getId());
}
break;
// 创建日期
@ -180,7 +178,7 @@ public class MybatisAutoFillInterceptor implements Interceptor {
// 如果租户ID 为空则进行默认赋值
Object tenantValue = ReflectUtil.getFieldValue(arg, f.getName());
if(StringUtils.isBlank(Convert.toStr(tenantValue))){
BeanUtil.setProperty(arg, MyBatisConstants.FIELD_TENANT, UserTokenUtil.getTenantIdByToken());
BeanUtil.setProperty(arg, MyBatisConstants.FIELD_TENANT, UserUtil.getTenantId());
}
break;
// 组织机构设置
@ -189,7 +187,7 @@ public class MybatisAutoFillInterceptor implements Interceptor {
Object orgValue = ReflectUtil.getFieldValue(arg, f.getName());
if(StringUtils.isBlank(Convert.toStr(orgValue))){
UserOrgRefModel userOrgRefModel =
UserUtil.getUserDefOrgByUserId(UserTokenUtil.getUserIdByToken());
UserUtil.getUserDefOrgByUserId(UserUtil.getUser().getId());
if(null != userOrgRefModel){
String orgIds = userOrgRefModel.getOrgIds();
BeanUtil.setProperty(arg, MyBatisConstants.FIELD_ORG_GROUP, orgIds);
@ -257,7 +255,7 @@ public class MybatisAutoFillInterceptor implements Interceptor {
// 如果更新人 为空则进行默认赋值
Object updateValue = ReflectUtil.getFieldValue(arg, f.getName());
if(StringUtils.isBlank(Convert.toStr(updateValue))){
BeanUtil.setProperty(arg, MyBatisConstants.FIELD_UPDATE_BY, UserTokenUtil.getUserIdByToken());
BeanUtil.setProperty(arg, MyBatisConstants.FIELD_UPDATE_BY, UserUtil.getUser().getId());
}
break;
// 更新日期

@ -107,9 +107,7 @@ public class QueryDataPermsHandler implements QueryBuilderChain{
// 1. 当前用户
UserModel currUser = UserUtil.getUser();
String userId = StringUtils.isNotEmpty(currUser.getSwitchTenantUserId())
? currUser.getSwitchTenantUserId()
: currUser.getId();
String userId = currUser.getId();
// 2. 当前用户 组织机构集合

@ -62,9 +62,7 @@ public class QueryTenantHandler implements QueryBuilderChain{
UserModel currUser = UserUtil.getUser();
// 切换运营商后 组织ID 不同
String tenantId = StringUtils.isNotEmpty(currUser.getSwitchTenantId())
? currUser.getSwitchTenantId()
: currUser.getTenantId();
String tenantId = currUser.getTenantId();
wrapper.eq(FieldUtil.humpToUnderline(MyBatisConstants.FIELD_TENANT), tenantId);
}
@ -84,9 +82,7 @@ public class QueryTenantHandler implements QueryBuilderChain{
UserModel currUser = UserUtil.getUser();
// 切换运营商后 组织ID 不同
String tenantId = StringUtils.isNotEmpty(currUser.getSwitchTenantId())
? currUser.getSwitchTenantId()
: currUser.getTenantId();
String tenantId = currUser.getTenantId();
String fieldName = webQueryConf.get(MyBatisConstants.FIELD_TENANT);
if(StringUtils.isEmpty(fieldName)){
@ -94,6 +90,7 @@ public class QueryTenantHandler implements QueryBuilderChain{
}
wrapper.eq(fieldName, tenantId);
}
return wrapper;
}

@ -42,11 +42,20 @@ public class WebQueryConf {
* @param fieldFn
* @param value
*/
public void pub(FieldUtil.SFunction<T, ?> fieldFn, String value){
public <T> void pub(FieldUtil.SFunction<T, ?> fieldFn, String value){
String fileName = FieldUtil.getFileName(fieldFn);
queryMap.putIfAbsent(fileName, value);
}
/**
*
* @param fileName
* @param value
*/
public void pub(String fileName, String value){
queryMap.putIfAbsent(fileName, value);
}
/**
*
* @param field

@ -108,6 +108,34 @@ public class UserUtil {
// Token失效请重新登录
throw new TokenException(TokenMsg.EXCEPTION_TOKEN_LOSE_EFFICACY);
}
return user;
}
/**
*
* @return UserModel
*/
public static UserModel getUserBySource(){
// 判断 工具类是否初始化完成
ThrowExceptionUtil.isThrowException(!IS_INIT,
CoreMsg.OTHER_EXCEPTION_UTILS_INIT);
String token = TokenThreadLocal.get();
// 如果还是没获取到token 则抛出异常
if(StringUtils.isEmpty(token)){
// Token失效请重新登录
throw new TokenException(TokenMsg.EXCEPTION_TOKEN_LOSE_EFFICACY);
}
String userId = UserTokenUtil.getUserIdByToken(token);
UserModel user = getUserBySource(userId);
if(user == null){
// Token失效请重新登录
throw new TokenException(TokenMsg.EXCEPTION_TOKEN_LOSE_EFFICACY);
}
return user;
}
@ -117,6 +145,25 @@ public class UserUtil {
* @return UserModel
*/
public static UserModel getUser(String userId){
return getUser(userId, false);
}
/**
* ID ()
* @param userId ID
* @return UserModel
*/
public static UserModel getUserBySource(String userId){
return getUser(userId, true);
}
/**
* ID
* @param userId ID
* @param isRecursion
* @return UserModel
*/
private static UserModel getUser(String userId, boolean isRecursion){
// 判断 工具类是否初始化完成
ThrowExceptionUtil.isThrowException(!IS_INIT,
CoreMsg.OTHER_EXCEPTION_UTILS_INIT);
@ -127,6 +174,14 @@ public class UserUtil {
// 先从缓存里拿
UserModel userModel = CacheUtil.getTimed(UserModel.class, cacheKey);
if (userModel != null){
// 如果不是递归触发 可进入一次
if(!isRecursion){
// 如果是 切换租户权限 则进行新一轮判断
// 注意不要陷入递归死循环 只保障循环一次
if (StringUtils.isNotBlank(userModel.getSwitchTenantUserId())){
userModel = getUser(userModel.getSwitchTenantUserId(), true);
}
}
return userModel;
}
@ -176,6 +231,15 @@ public class UserUtil {
return null;
}
// 如果不是递归触发 可进入一次
if(!isRecursion){
// 如果是 切换租户权限 则进行新一轮判断
// 注意不要陷入递归死循环 只保障循环一次
if (StringUtils.isNotBlank(userModel.getSwitchTenantUserId())){
userModel = getUser(userModel.getSwitchTenantUserId(), true);
}
}
return userModel;
}
@ -253,6 +317,13 @@ public class UserUtil {
ThrowExceptionUtil.isThrowException(!IS_INIT,
CoreMsg.OTHER_EXCEPTION_UTILS_INIT);
// 处理 切换租户
UserModel currUser = getUser(userId);
if (null != currUser &&
StringUtils.isNotBlank(currUser.getSwitchTenantUserId())){
userId = currUser.getSwitchTenantUserId();
}
// 缓存Key
String cacheKey = PREFIX_ID_ROLES + userId;
@ -321,6 +392,13 @@ public class UserUtil {
ThrowExceptionUtil.isThrowException(!IS_INIT,
CoreMsg.OTHER_EXCEPTION_UTILS_INIT);
// 处理 切换租户
UserModel currUser = getUser(userId);
if (null != currUser &&
StringUtils.isNotBlank(currUser.getSwitchTenantUserId())){
userId = currUser.getSwitchTenantUserId();
}
// 缓存Key
String cacheKey = PREFIX_ID_PERMISSIONS + userId;
@ -388,6 +466,13 @@ public class UserUtil {
ThrowExceptionUtil.isThrowException(!IS_INIT,
CoreMsg.OTHER_EXCEPTION_UTILS_INIT);
// 处理 切换租户
UserModel currUser = getUser(userId);
if (null != currUser &&
StringUtils.isNotBlank(currUser.getSwitchTenantUserId())){
userId = currUser.getSwitchTenantUserId();
}
// 缓存Key
String cacheKey = PREFIX_ID_ORGS + userId;
@ -469,6 +554,13 @@ public class UserUtil {
ThrowExceptionUtil.isThrowException(!IS_INIT,
CoreMsg.OTHER_EXCEPTION_UTILS_INIT);
// 处理 切换租户
UserModel currUser = getUser(userId);
if (null != currUser &&
StringUtils.isNotBlank(currUser.getSwitchTenantUserId())){
userId = currUser.getSwitchTenantUserId();
}
// 缓存Key
String cacheKey = PREFIX_ID_MENUS + userId;
@ -538,6 +630,13 @@ public class UserUtil {
ThrowExceptionUtil.isThrowException(!IS_INIT,
CoreMsg.OTHER_EXCEPTION_UTILS_INIT);
// 处理 切换租户
UserModel currUser = getUser(userId);
if (null != currUser &&
StringUtils.isNotBlank(currUser.getSwitchTenantUserId())){
userId = currUser.getSwitchTenantUserId();
}
// 缓存Key
String cacheKey = PREFIX_ID_DEF_ROLE + userId;
@ -603,6 +702,13 @@ public class UserUtil {
ThrowExceptionUtil.isThrowException(!IS_INIT,
CoreMsg.OTHER_EXCEPTION_UTILS_INIT);
// 处理 切换租户
UserModel currUser = getUser(userId);
if (null != currUser &&
StringUtils.isNotBlank(currUser.getSwitchTenantUserId())){
userId = currUser.getSwitchTenantUserId();
}
// 缓存Key
String cacheKey = PREFIX_ID_DEF_ORG + userId;
@ -718,8 +824,10 @@ public class UserUtil {
return true;
}
UserModel userModelById = CacheUtil.getTimed(UserModel.class, PREFIX_ID + user.getId());
UserModel userModelByUsername = CacheUtil.getTimed(UserModel.class, PREFIX_USERNAME + user.getUsername());
UserModel userModelById = CacheUtil.getTimed(
UserModel.class, PREFIX_ID + user.getId());
UserModel userModelByUsername = CacheUtil.getTimed(
UserModel.class, PREFIX_USERNAME + user.getUsername());
boolean hasNilFlagById = CacheUtil.hasNilFlag(PREFIX_ID + user.getId());
boolean hasNilFlagByName = CacheUtil.hasNilFlag(PREFIX_USERNAME + user.getUsername());

@ -39,9 +39,6 @@ public class SysRole extends BaseEntity {
/** 角色名称 */
private String roleName;
/** 是否内置数据 0否 1是 */
private String izLock;
/** 标签 */
private String label;

@ -15,10 +15,8 @@
*/
package org.opsli.modulars.system.role.mapper;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.opsli.modulars.system.role.entity.SysRole;

@ -23,7 +23,6 @@ import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.opsli.api.base.result.ResultVo;
import org.opsli.api.web.system.role.RoleMenuRefApi;
import org.opsli.api.wrapper.system.role.RoleMenuRefModel;
import org.opsli.api.wrapper.system.role.RoleModel;
import org.opsli.api.wrapper.system.user.UserModel;
import org.opsli.common.annotation.ApiRestController;
import org.opsli.common.annotation.EnableLog;
@ -34,7 +33,6 @@ import org.opsli.core.utils.UserUtil;
import org.opsli.modulars.system.SystemMsg;
import org.opsli.modulars.system.menu.entity.SysMenu;
import org.opsli.modulars.system.role.service.IRoleMenuRefService;
import org.opsli.modulars.system.role.service.IRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
@ -53,15 +51,10 @@ import java.util.stream.Collectors;
@ApiRestController("/system/role/perms")
public class RoleMenuRefRestController implements RoleMenuRefApi {
/** 内置数据 */
private static final String LOCK_DATA = "1";
/** 配置类 */
@Autowired
protected GlobalProperties globalProperties;
@Autowired
private IRoleService iRoleService;
@Autowired
private IRoleMenuRefService iRoleMenuRefService;
@ -114,16 +107,6 @@ public class RoleMenuRefRestController implements RoleMenuRefApi {
return ResultVo.error("设置权限失败");
}
RoleModel roleModel = iRoleService.get(model.getRoleId());
// 内置数据 只有超级管理员可以修改
if(roleModel != null && LOCK_DATA.equals(roleModel.getIzLock()) ){
UserModel user = UserUtil.getUser();
if(!StringUtils.equals(UserUtil.SUPER_ADMIN, user.getUsername())){
throw new ServiceException(SystemMsg.EXCEPTION_LOCK_DATA);
}
}
boolean ret = iRoleMenuRefService.setPerms(model.getRoleId(),
model.getPermsIds());
if(ret){

@ -21,25 +21,17 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.opsli.api.base.result.ResultVo;
import org.opsli.api.web.system.role.RoleApi;
import org.opsli.api.wrapper.system.role.RoleModel;
import org.opsli.api.wrapper.system.user.UserModel;
import org.opsli.common.annotation.ApiRestController;
import org.opsli.common.annotation.EnableLog;
import org.opsli.common.annotation.RequiresPermissionsCus;
import org.opsli.common.constants.MyBatisConstants;
import org.opsli.common.exception.ServiceException;
import org.opsli.common.utils.FieldUtil;
import org.opsli.core.base.controller.BaseRestController;
import org.opsli.core.persistence.Page;
import org.opsli.core.persistence.querybuilder.GenQueryBuilder;
import org.opsli.core.persistence.querybuilder.QueryBuilder;
import org.opsli.core.persistence.querybuilder.WebQueryBuilder;
import org.opsli.core.utils.UserUtil;
import org.opsli.modulars.system.SystemMsg;
import org.opsli.modulars.system.role.entity.SysRole;
import org.opsli.modulars.system.role.service.IRoleService;
import org.springframework.web.multipart.MultipartHttpServletRequest;
@ -47,7 +39,6 @@ import org.springframework.web.multipart.MultipartHttpServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.List;
/**
@ -62,9 +53,6 @@ import java.util.List;
public class RoleRestController extends BaseRestController<SysRole, RoleModel, IRoleService>
implements RoleApi {
/** 内置数据 */
private static final String LOCK_DATA = "1";
/**
*
* @param model
@ -131,18 +119,6 @@ public class RoleRestController extends BaseRestController<SysRole, RoleModel, I
// 演示模式 不允许操作
super.demoError();
if(model != null){
RoleModel roleModel = IService.get(model.getId());
// 内置数据 只有超级管理员可以修改
if(roleModel != null && LOCK_DATA.equals(roleModel.getIzLock()) ){
UserModel user = UserUtil.getUser();
if(!StringUtils.equals(UserUtil.SUPER_ADMIN, user.getUsername())){
throw new ServiceException(SystemMsg.EXCEPTION_LOCK_DATA);
}
}
}
// 调用修改方法
IService.update(model);
return ResultVo.success("修改角色成功");
@ -162,15 +138,6 @@ public class RoleRestController extends BaseRestController<SysRole, RoleModel, I
// 演示模式 不允许操作
super.demoError();
RoleModel roleModel = IService.get(id);
// 内置数据 只有超级管理员可以修改
if(roleModel != null && LOCK_DATA.equals(roleModel.getIzLock()) ){
UserModel user = UserUtil.getUser();
if(!StringUtils.equals(UserUtil.SUPER_ADMIN, user.getUsername())){
throw new ServiceException(SystemMsg.EXCEPTION_LOCK_DATA);
}
}
IService.delete(id);
return ResultVo.success("删除角色成功");
}
@ -190,25 +157,6 @@ public class RoleRestController extends BaseRestController<SysRole, RoleModel, I
super.demoError();
String[] idArray = Convert.toStrArray(ids);
if(idArray != null){
QueryBuilder<SysRole> queryBuilder = new GenQueryBuilder<>();
QueryWrapper<SysRole> wrapper = queryBuilder.build();
List<String> idList = Convert.toList(String.class,idArray);
wrapper.in(MyBatisConstants.FIELD_ID, idList);
List<SysRole> roleList = IService.findList(wrapper);
for (SysRole sysRole : roleList) {
// 内置数据 只有超级管理员可以修改
if(sysRole != null && LOCK_DATA.equals(sysRole.getIzLock()) ){
UserModel user = UserUtil.getUser();
if(!StringUtils.equals(UserUtil.SUPER_ADMIN, user.getUsername())){
throw new ServiceException(SystemMsg.EXCEPTION_LOCK_DATA);
}
}
}
}
IService.deleteAll(idArray);
return ResultVo.success("批量删除角色成功");
}

@ -82,6 +82,9 @@ public class SysUser extends BaseEntity {
/** 是否租户管理员 */
private String izTenantAdmin;
/** 允许切换租户0 不允许 1 允许) */
private String enableSwitchTenant;
// ========================================
/** 逻辑删除字段 */

@ -32,6 +32,8 @@ import org.opsli.core.base.entity.BaseEntity;
@EqualsAndHashCode(callSuper = false)
public class SysUserWeb extends BaseEntity {
/** 角色名称 */
private String roleNames;
/** 登录账户 */
private String username;
@ -76,6 +78,9 @@ public class SysUserWeb extends BaseEntity {
@TableField(updateStrategy = FieldStrategy.IGNORED)
private String sign;
/** 允许切换租户0 不允许 1 允许) */
private String enableSwitchTenant;
// ========================================
/** 逻辑删除字段 */

@ -19,6 +19,7 @@
a.login_ip as loginIp,
a.remark as remark,
a.tenant_id as tenantId,
a.enable_switch_tenant as enableSwitchTenant,
a.create_by as createBy,
a.create_time as createTime,
@ -29,16 +30,19 @@
</sql>
<sql id="joinsColumns">
GROUP_CONCAT(r.role_name) as roleNames,
</sql>
<sql id="joins">
left join sys_user_org_ref b on b.user_id = a.id
left join sys_user_role_ref c on c.user_id = a.id
left join sys_role r on r.id = c.role_id
</sql>
<select id="findList" parameterType="SysUser" resultType="SysUserWeb">
select
<include refid="columns"></include>
<include refid="joinsColumns"></include>
<include refid="columns"></include>
from
sys_user a
<include refid="joins"></include>

@ -15,6 +15,7 @@
*/
package org.opsli.modulars.system.user.service;
import org.opsli.api.wrapper.system.user.ToUserPassword;
import org.opsli.api.wrapper.system.user.UserModel;
import org.opsli.api.wrapper.system.user.UserPassword;
import org.opsli.api.wrapper.system.user.UserWebModel;
@ -41,11 +42,18 @@ public interface IUserService extends CrudServiceInterface<SysUser, UserModel> {
/**
*
*
* @param userPassword
* @return boolean
*/
boolean updatePassword(UserPassword userPassword);
boolean updatePasswordByCheckOld(UserPassword userPassword);
/**
*
* @param userPassword
* @return boolean
*/
boolean updatePasswordByNotCheckOld(ToUserPassword userPassword);
/**
*
@ -85,4 +93,11 @@ public interface IUserService extends CrudServiceInterface<SysUser, UserModel> {
* @return Page<T>
*/
Page<SysUserWeb, UserWebModel> findPageByCus(Page<SysUserWeb, UserWebModel> page);
/**
*
* @param page
* @return Page<T>
*/
Page<SysUserWeb, UserWebModel> findPageByTenant(Page<SysUserWeb, UserWebModel> page);
}

@ -198,8 +198,7 @@ public class UserRoleRefServiceImpl extends ServiceImpl<UserRoleRefMapper, SysUs
@Override
public List<String> getUserIdListByRoleIds(String[] roleIds) {
QueryWrapper<SysUserRoleRef> queryWrapper = new QueryWrapper<>();
queryWrapper.eq(
FieldUtil.humpToUnderline(MyBatisConstants.FIELD_DELETE_LOGIC), DictType.NO_YES_NO.getValue());
queryWrapper.eq("b.deleted", DictType.NO_YES_NO.getValue());
queryWrapper.in("role_id", Convert.toList(roleIds));
List<String> users = mapper.getUserIdList(queryWrapper);
@ -214,8 +213,7 @@ public class UserRoleRefServiceImpl extends ServiceImpl<UserRoleRefMapper, SysUs
@Override
public List<String> getUserIdListByTenantIdAndAllData(String tenantId) {
QueryWrapper<SysUserRoleRef> queryWrapper = new QueryWrapper<>();
queryWrapper.eq(
FieldUtil.humpToUnderline(MyBatisConstants.FIELD_DELETE_LOGIC), DictType.NO_YES_NO.getValue());
queryWrapper.eq("b.deleted", DictType.NO_YES_NO.getValue());
queryWrapper.eq("c.tenantId", tenantId);
queryWrapper.eq("c.data_scope", "3");

@ -24,10 +24,7 @@ import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.opsli.api.wrapper.system.options.OptionsModel;
import org.opsli.api.wrapper.system.user.UserModel;
import org.opsli.api.wrapper.system.user.UserPassword;
import org.opsli.api.wrapper.system.user.UserRoleRefModel;
import org.opsli.api.wrapper.system.user.UserWebModel;
import org.opsli.api.wrapper.system.user.*;
import org.opsli.common.constants.MyBatisConstants;
import org.opsli.common.enums.DictType;
import org.opsli.common.exception.ServiceException;
@ -39,6 +36,7 @@ import org.opsli.core.msg.CoreMsg;
import org.opsli.core.persistence.Page;
import org.opsli.core.persistence.querybuilder.GenQueryBuilder;
import org.opsli.core.persistence.querybuilder.QueryBuilder;
import org.opsli.core.persistence.querybuilder.conf.WebQueryConf;
import org.opsli.core.utils.OptionsUtil;
import org.opsli.core.utils.UserUtil;
import org.opsli.modulars.system.SystemMsg;
@ -90,7 +88,7 @@ public class UserServiceImpl extends CrudServiceImpl<UserMapper, SysUser, UserMo
if(!UserUtil.isHasUpdateTenantPerms(UserUtil.getUser())){
model.setTenantId(null);
model.setIzTenantAdmin(null);
model.setEnableSwitchTenant(null);
model.setEnableSwitchTenant(DictType.NO_YES_NO.getValue());
}
}
@ -469,7 +467,7 @@ public class UserServiceImpl extends CrudServiceImpl<UserMapper, SysUser, UserMo
@Override
@Transactional(rollbackFor = Exception.class)
public boolean updatePassword(UserPassword userPassword) {
public boolean updatePasswordByCheckOld(UserPassword userPassword) {
UserModel userModel = super.get(userPassword.getUserId());
// 如果为空则 不修改密码
if(userModel == null){
@ -515,6 +513,42 @@ public class UserServiceImpl extends CrudServiceImpl<UserMapper, SysUser, UserMo
return ret;
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean updatePasswordByNotCheckOld(ToUserPassword toUserPassword) {
UserModel userModel = super.get(toUserPassword.getUserId());
// 如果为空则 不修改密码
if(userModel == null){
return false;
}
// 设置随机新盐值
toUserPassword.setSalt(
RandomUtil.randomString(20)
);
// 获得密码强度
toUserPassword.setPasswordLevel(
CheckStrength.getPasswordLevel(toUserPassword.getNewPassword()).getCode()
);
// 处理密码
toUserPassword.setNewPassword(
UserUtil.handlePassword(toUserPassword.getNewPassword(),
toUserPassword.getSalt())
);
// 修改密码
boolean ret = mapper.updatePassword(
WrapperUtil.transformInstance(toUserPassword, UserPassword.class)
);
if(ret){
// 刷新用户缓存
this.clearCache(Collections.singletonList(userModel));
}
return ret;
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean resetPassword(UserPassword userPassword) {
@ -590,16 +624,9 @@ public class UserServiceImpl extends CrudServiceImpl<UserMapper, SysUser, UserMo
private List<SysUserWeb> findListByCus(QueryWrapper<SysUserWeb> queryWrapper) {
// 如果没有租户修改能力 则默认增加租户限制
if(!UserUtil.isHasUpdateTenantPerms(UserUtil.getUser())){
// 数据处理责任链
queryWrapper = super.addHandler(SysUserWeb.class, queryWrapper);
}
// 逻辑删除 查询未删除数据
queryWrapper.eq(
FieldUtil.humpToUnderline(MyBatisConstants.FIELD_DELETE_LOGIC), DictType.NO_YES_NO.getValue());
queryWrapper.eq("a.deleted", DictType.NO_YES_NO.getValue());
// 按照ID 分组
queryWrapper.groupBy("a.id","b.user_id");
return mapper.findList(queryWrapper);
@ -620,9 +647,15 @@ public class UserServiceImpl extends CrudServiceImpl<UserMapper, SysUser, UserMo
// 不能查看自身
queryWrapper.notIn("username", currUser.getUsername());
// 添加过滤权限
WebQueryConf conf = new WebQueryConf();
conf.pub(SysUserWeb::getTenantId, "a.tenant_id");
// 数据处理责任链
queryWrapper = super.addHandler(SysUserWeb.class, conf, queryWrapper);
page.pageHelperBegin();
try{
List<SysUserWeb> list = this.findListByCus(page.getQueryWrapper());
List<SysUserWeb> list = this.findListByCus(queryWrapper);
PageInfo<SysUserWeb> pageInfo = new PageInfo<>(list);
List<UserWebModel> es = WrapperUtil.transformInstance(pageInfo.getList(), UserWebModel.class);
page.instance(pageInfo, es);
@ -633,6 +666,35 @@ public class UserServiceImpl extends CrudServiceImpl<UserMapper, SysUser, UserMo
}
@Override
public Page<SysUserWeb, UserWebModel> findPageByTenant(Page<SysUserWeb, UserWebModel> page) {
UserModel currUser = UserUtil.getUser();
QueryWrapper<SysUserWeb> queryWrapper = page.getQueryWrapper();
// 如果不是超级管理员则 无法看到超级管理员账户
if(!UserUtil.SUPER_ADMIN.equals(currUser.getUsername())){
queryWrapper.notIn("username", UserUtil.SUPER_ADMIN);
page.setQueryWrapper(queryWrapper);
}
// 不能查看自身
queryWrapper.notIn("username", currUser.getUsername());
// 只查看 为租户管理员的用户
queryWrapper.eq("iz_tenant_admin", DictType.NO_YES_YES.getValue());
page.pageHelperBegin();
try{
List<SysUserWeb> list = this.findListByCus(queryWrapper);
PageInfo<SysUserWeb> pageInfo = new PageInfo<>(list);
List<UserWebModel> es = WrapperUtil.transformInstance(pageInfo.getList(), UserWebModel.class);
page.instance(pageInfo, es);
} finally {
page.pageHelperEnd();
}
return page;
}
/**
*

@ -30,7 +30,6 @@ import org.opsli.api.base.result.ResultVo;
import org.opsli.api.web.system.user.UserApi;
import org.opsli.api.wrapper.system.menu.MenuModel;
import org.opsli.api.wrapper.system.options.OptionsModel;
import org.opsli.api.wrapper.system.role.RoleModel;
import org.opsli.api.wrapper.system.tenant.TenantModel;
import org.opsli.api.wrapper.system.user.*;
import org.opsli.common.annotation.ApiRestController;
@ -45,15 +44,14 @@ import org.opsli.common.utils.WrapperUtil;
import org.opsli.core.base.controller.BaseRestController;
import org.opsli.core.msg.TokenMsg;
import org.opsli.core.persistence.Page;
import org.opsli.core.persistence.querybuilder.GenQueryBuilder;
import org.opsli.core.persistence.querybuilder.QueryBuilder;
import org.opsli.core.persistence.querybuilder.WebQueryBuilder;
import org.opsli.core.persistence.querybuilder.conf.WebQueryConf;
import org.opsli.core.utils.OptionsUtil;
import org.opsli.core.utils.OrgUtil;
import org.opsli.core.utils.TenantUtil;
import org.opsli.core.utils.UserUtil;
import org.opsli.modulars.system.SystemMsg;
import org.opsli.modulars.system.tenant.entity.SysTenant;
import org.opsli.modulars.system.user.entity.SysUser;
import org.opsli.modulars.system.user.entity.SysUserWeb;
import org.opsli.modulars.system.user.service.IUserRoleRefService;
@ -62,7 +60,6 @@ import org.opsli.plugins.oss.OssStorageFactory;
import org.opsli.plugins.oss.service.BaseOssStorageService;
import org.opsli.plugins.oss.service.OssStorageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
@ -96,8 +93,8 @@ public class UserRestController extends BaseRestController<SysUser, UserModel, I
@ApiOperation(value = "当前登陆用户信息", notes = "当前登陆用户信息")
@Override
public ResultVo<UserInfo> getInfo(HttpServletRequest request) {
UserModel user = UserUtil.getUser();
return this.getInfoById(user.getId());
UserModel currUser = UserUtil.getUserBySource();
return this.getInfoById(currUser.getId());
}
/**
@ -107,20 +104,31 @@ public class UserRestController extends BaseRestController<SysUser, UserModel, I
@ApiOperation(value = "当前登陆用户信息 By Id", notes = "当前登陆用户信息 By Id")
@Override
public ResultVo<UserInfo> getInfoById(String userId) {
UserModel user = UserUtil.getUser(userId);
if(user == null){
UserModel currUser = UserUtil.getUserBySource(userId);
if(currUser == null){
throw new TokenException(TokenMsg.EXCEPTION_TOKEN_LOSE_EFFICACY);
}
List<String> userRolesByUserId = UserUtil.getUserRolesByUserId(user.getId());
List<String> userAllPermsByUserId = UserUtil.getUserAllPermsByUserId(user.getId());
// 判断是否是 切换租户状态
String userIdTemp = currUser.getId();
if(StringUtils.isNotBlank(currUser.getSwitchTenantUserId())){
UserModel switchUser = UserUtil.getUser(currUser.getSwitchTenantUserId());
if(switchUser == null){
// 不允许切换租户
throw new ServiceException(SystemMsg.EXCEPTION_USER_SWITCH_NOT_ALLOWED);
}
userIdTemp = switchUser.getId();
}
List<String> userRolesByUserId = UserUtil.getUserRolesByUserId(userIdTemp);
List<String> userAllPermsByUserId = UserUtil.getUserAllPermsByUserId(userIdTemp);
UserInfo userInfo = WrapperUtil.transformInstance(user, UserInfo.class);
UserInfo userInfo = WrapperUtil.transformInstance(currUser, UserInfo.class);
userInfo.setRoles(userRolesByUserId);
userInfo.setPerms(userAllPermsByUserId);
// 判断是否是超级管理员
if(StringUtils.equals(UserUtil.SUPER_ADMIN, user.getUsername())){
if(StringUtils.equals(UserUtil.SUPER_ADMIN, currUser.getUsername())){
userInfo.setIzSuperAdmin(true);
}
@ -175,9 +183,9 @@ public class UserRestController extends BaseRestController<SysUser, UserModel, I
// 演示模式 不允许操作
super.demoError();
UserModel user = UserUtil.getUser();
UserModel user = UserUtil.getUserBySource();
userPassword.setUserId(user.getId());
IService.updatePassword(userPassword);
IService.updatePasswordByCheckOld(userPassword);
return ResultVo.success();
}
@ -204,7 +212,7 @@ public class UserRestController extends BaseRestController<SysUser, UserModel, I
BaseOssStorageService.FileAttr fileAttr = ossStorageService.upload(
files.get(0).getInputStream(), "jpg");
UserModel user = UserUtil.getUser();
UserModel user = UserUtil.getUserBySource();
// 更新头像至数据库
UserModel userModel = new UserModel();
userModel.setId(user.getId());
@ -231,11 +239,11 @@ public class UserRestController extends BaseRestController<SysUser, UserModel, I
@RequiresPermissions("system_user_updatePassword")
@EnableLog
@Override
public ResultVo<?> updatePasswordById(UserPassword userPassword) {
public ResultVo<?> updatePasswordById(ToUserPassword userPassword) {
// 演示模式 不允许操作
super.demoError();
IService.updatePassword(userPassword);
IService.updatePasswordByNotCheckOld(userPassword);
return ResultVo.success();
}
@ -325,7 +333,7 @@ public class UserRestController extends BaseRestController<SysUser, UserModel, I
String orgIdGroup,
HttpServletRequest request) {
QueryBuilder<SysUserWeb> queryBuilder = new WebQueryBuilder<>(
SysUserWeb.class, request.getParameterMap());
SysUserWeb.class, request.getParameterMap(), "a.update_time");
Page<SysUserWeb, UserWebModel> page = new Page<>(pageNo, pageSize);
QueryWrapper<SysUserWeb> queryWrapper = queryBuilder.build();
@ -347,7 +355,7 @@ public class UserRestController extends BaseRestController<SysUser, UserModel, I
}
/**
*
*
* @param pageNo
* @param pageSize
* @param request request
@ -358,16 +366,18 @@ public class UserRestController extends BaseRestController<SysUser, UserModel, I
@Override
public ResultVo<?> findPageByTenant(Integer pageNo, Integer pageSize,
HttpServletRequest request) {
// 转换字段
WebQueryConf conf = new WebQueryConf();
conf.pub(SysUserWeb::getTenantId, "a.tenant_id");
QueryBuilder<SysUserWeb> queryBuilder = new WebQueryBuilder<>(
SysUserWeb.class, request.getParameterMap());
SysUserWeb.class, request.getParameterMap(),"a.update_time", conf);
Page<SysUserWeb, UserWebModel> page = new Page<>(pageNo, pageSize);
QueryWrapper<SysUserWeb> queryWrapper = queryBuilder.build();
// 只查看 为租户管理员的用户
queryWrapper.eq("iz_tenant_admin", DictType.NO_YES_YES.getValue());
page.setQueryWrapper(queryWrapper);
page = IService.findPageByCus(page);
page.setQueryWrapper(queryBuilder.build());
page = IService.findPageByTenant(page);
// 密码防止分页泄露处理
for (UserWebModel userModel : page.getList()) {
userModel.setSecretKey(null);
@ -418,7 +428,7 @@ public class UserRestController extends BaseRestController<SysUser, UserModel, I
@EnableLog
@Override
public ResultVo<?> updateSelf(UserModel model) {
UserModel currUser = UserUtil.getUser();
UserModel currUser = UserUtil.getUserBySource();
if(!StringUtils.equals(currUser.getId(), model.getId())){
// 非法参数 防止其他用户 通过该接口 修改非自身用户数据
throw new ServiceException(SystemMsg.EXCEPTION_USER_ILLEGAL_PARAMETER);
@ -534,9 +544,9 @@ public class UserRestController extends BaseRestController<SysUser, UserModel, I
* @return ResultVo
*/
@ApiOperation(value = "切换租户", notes = "切换租户")
@GetMapping("/switchTenant")
@Override
public ResultVo<?> switchTenant(String tenantId) {
UserModel currUser = UserUtil.getUser();
UserModel currUser = UserUtil.getUserBySource();
if (!DictType.NO_YES_YES.getValue().equals(currUser.getEnableSwitchTenant())){
// 不允许切换租户
throw new ServiceException(SystemMsg.EXCEPTION_USER_SWITCH_NOT_ALLOWED);
@ -597,9 +607,13 @@ public class UserRestController extends BaseRestController<SysUser, UserModel, I
* @return ResultVo
*/
@ApiOperation(value = "切换回自己账户", notes = "切换回自己账户")
@GetMapping("/switchOneself")
@Override
public ResultVo<?> switchOneself() {
UserModel currUser = UserUtil.getUser();
UserModel currUser = UserUtil.getUserBySource();
if (!DictType.NO_YES_YES.getValue().equals(currUser.getEnableSwitchTenant())){
// 不允许切换租户
throw new ServiceException(SystemMsg.EXCEPTION_USER_SWITCH_NOT_ALLOWED);
}
currUser.setSwitchTenantId(null);
currUser.setSwitchTenantUserId(null);

Loading…
Cancel
Save