mirror of
https://github.com/mfish-qf/mfish-nocode.git
synced 2026-09-24 15:45:53 +08:00
feat: 增加通用数据权限控制,通过@DataScope@DataScopes注解方式进行数据权限控制 #(258)
This commit is contained in:
+5
@@ -38,6 +38,11 @@ public class RemoteOrgFallback implements FallbackFactory<RemoteOrgService> {
|
||||
public Result<PageResult<UserInfo>> queryUserByCode(String origin, String code, String account, String nickname, String phone, ReqPage reqPage) {
|
||||
return Result.fail("错误:根据编码获取组织下用户失败" + cause.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<List<String>> getOrgIdsByFixCode(String origin, String tenantId, String codes, String direction) {
|
||||
return Result.fail("错误:根据固定编码获取组织id失败" + cause.getMessage());
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package cn.com.mfish.common.oauth.api.fallback;
|
||||
|
||||
import cn.com.mfish.common.core.web.Result;
|
||||
import cn.com.mfish.common.oauth.api.remote.RemoteRoleService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.cloud.openfeign.FallbackFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @description: 角色远程调用失败处理
|
||||
* @author: mfish
|
||||
* @date: 2024/4/29
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class RemoteRoleFallback implements FallbackFactory<RemoteRoleService> {
|
||||
@Override
|
||||
public RemoteRoleService create(Throwable cause) {
|
||||
log.error("角色服务调用失败:{}", cause.getMessage());
|
||||
return (origin, tenantId, codes) -> Result.fail("错误:获取角色id失败" + cause.getMessage());
|
||||
}
|
||||
}
|
||||
+5
@@ -55,6 +55,11 @@ public class RemoteUserFallback implements FallbackFactory<RemoteUserService> {
|
||||
public Result<List<SsoOrg>> getOrgs(String origin, String userId, String direction) {
|
||||
return Result.fail("错误:获取用户组织失败" + cause.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<List<String>> getOrgIds(String origin, String userId, String tenantId, String direction) {
|
||||
return Result.fail("错误:获取用户组织ID失败" + cause.getMessage());
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
+3
@@ -33,4 +33,7 @@ public interface RemoteOrgService {
|
||||
|
||||
@GetMapping("/org/user/{code}")
|
||||
Result<PageResult<UserInfo>> queryUserByCode(@RequestHeader(RPCConstants.REQ_ORIGIN) String origin, @PathVariable("code") String code, @RequestParam("account") String account, @RequestParam("nickname") String nickname, @RequestParam("phone") String phone, @SpringQueryMap ReqPage reqPage);
|
||||
|
||||
@GetMapping("/org/ids")
|
||||
Result<List<String>> getOrgIdsByFixCode(@RequestHeader(RPCConstants.REQ_ORIGIN) String origin, @RequestParam("tenantId") String tenantId, @RequestParam("codes") String codes, @RequestParam("direction") String direction);
|
||||
}
|
||||
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package cn.com.mfish.common.oauth.api.remote;
|
||||
|
||||
import cn.com.mfish.common.core.constants.RPCConstants;
|
||||
import cn.com.mfish.common.core.constants.ServiceConstants;
|
||||
import cn.com.mfish.common.core.web.Result;
|
||||
import cn.com.mfish.common.oauth.api.fallback.RemoteRoleFallback;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestHeader;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @description: 角色远程接口
|
||||
* @author: mfish
|
||||
* @date: 2024/4/29
|
||||
*/
|
||||
@FeignClient(contextId = "remoteRoleService", value = ServiceConstants.OAUTH_SERVICE, fallbackFactory = RemoteRoleFallback.class)
|
||||
public interface RemoteRoleService {
|
||||
|
||||
@GetMapping("/ids/{codes}")
|
||||
Result<List<String>> getRoleIdsByCode(@RequestHeader(RPCConstants.REQ_ORIGIN) String origin, @RequestParam("tenantId") String tenantId, @RequestParam("codes") String codes);
|
||||
}
|
||||
+12
@@ -80,4 +80,16 @@ public interface RemoteUserService {
|
||||
*/
|
||||
@GetMapping("/user/orgs/{userId}")
|
||||
Result<List<SsoOrg>> getOrgs(@RequestHeader(RPCConstants.REQ_ORIGIN) String origin, @PathVariable("userId") String userId, @RequestParam("direction") String direction);
|
||||
|
||||
/**
|
||||
* 获取用户相关组织id
|
||||
*
|
||||
* @param origin 来源
|
||||
* @param userId 用户id
|
||||
* @param tenantId 租户id
|
||||
* @param direction 查询方向
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/orgIds/{userId}")
|
||||
Result<List<String>> getOrgIds(@RequestHeader(RPCConstants.REQ_ORIGIN) String origin, @PathVariable("userId") String userId, @RequestParam("tenantId") String tenantId, @RequestParam("direction") String direction);
|
||||
}
|
||||
@@ -43,7 +43,7 @@ public class DictController {
|
||||
* @param reqDict
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "字典-分页列表查询", description = "字典-分页列表查询")
|
||||
@Operation(summary = "字典-分页列表查询", description = "字典-分页列表查询")
|
||||
@GetMapping
|
||||
@RequiresPermissions("sys:dict:query")
|
||||
public Result<PageResult<Dict>> queryPageList(ReqDict reqDict, ReqPage reqPage) {
|
||||
@@ -57,6 +57,7 @@ public class DictController {
|
||||
* @param reqPage
|
||||
* @return
|
||||
*/
|
||||
|
||||
private List<Dict> queryList(ReqDict reqDict, ReqPage reqPage) {
|
||||
PageHelper.startPage(reqPage.getPageNum(), reqPage.getPageSize());
|
||||
LambdaQueryWrapper<Dict> queryWrapper = new LambdaQueryWrapper<Dict>()
|
||||
@@ -74,7 +75,7 @@ public class DictController {
|
||||
* @return
|
||||
*/
|
||||
@Log(title = "字典-添加", operateType = OperateType.INSERT)
|
||||
@Operation(summary = "字典-添加", description = "字典-添加")
|
||||
@Operation(summary = "字典-添加", description = "字典-添加")
|
||||
@PostMapping
|
||||
@RequiresPermissions("sys:dict:insert")
|
||||
public Result<Dict> add(@RequestBody Dict dict) {
|
||||
@@ -95,7 +96,7 @@ public class DictController {
|
||||
* @return
|
||||
*/
|
||||
@Log(title = "字典-编辑", operateType = OperateType.UPDATE)
|
||||
@Operation(summary = "字典-编辑", description = "字典-编辑")
|
||||
@Operation(summary = "字典-编辑", description = "字典-编辑")
|
||||
@PutMapping
|
||||
@RequiresPermissions("sys:dict:update")
|
||||
public Result<Dict> edit(@RequestBody Dict dict) {
|
||||
@@ -132,7 +133,7 @@ public class DictController {
|
||||
* @return
|
||||
*/
|
||||
@Log(title = "字典-通过id删除", operateType = OperateType.DELETE)
|
||||
@Operation(summary = "字典-通过id删除", description = "字典-通过id删除")
|
||||
@Operation(summary = "字典-通过id删除", description = "字典-通过id删除")
|
||||
@DeleteMapping("/{id}")
|
||||
@RequiresPermissions("sys:dict:delete")
|
||||
public Result<Boolean> delete(@Parameter(name = "id", description = "唯一性ID") @PathVariable String id) {
|
||||
@@ -145,7 +146,7 @@ public class DictController {
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "字典-通过id查询", description = "字典-通过id查询")
|
||||
@Operation(summary = "字典-通过id查询", description = "字典-通过id查询")
|
||||
@GetMapping("/{id}")
|
||||
@RequiresPermissions("sys:dict:query")
|
||||
public Result<Dict> queryById(@Parameter(name = "id", description = "唯一性ID") @PathVariable String id) {
|
||||
@@ -155,11 +156,12 @@ public class DictController {
|
||||
|
||||
/**
|
||||
* 导出
|
||||
*
|
||||
* @param reqDict
|
||||
* @param reqPage
|
||||
* @throws IOException
|
||||
*/
|
||||
@Operation(summary = "导出字典", description = "导出字典")
|
||||
@Operation(summary = "导出字典", description = "导出字典")
|
||||
@GetMapping("/export")
|
||||
@RequiresPermissions("sys:dict:query")
|
||||
public void export(ReqDict reqDict, ReqPage reqPage) throws IOException {
|
||||
|
||||
+3
-4
@@ -14,17 +14,16 @@ import cn.com.mfish.common.dblink.entity.DataSourceOptions;
|
||||
import cn.com.mfish.common.dblink.page.BoundSql;
|
||||
import cn.com.mfish.common.dblink.page.MfPageHelper;
|
||||
import cn.com.mfish.common.dblink.query.QueryHandler;
|
||||
import cn.com.mfish.common.dblink.service.DbConnectService;
|
||||
import cn.com.mfish.common.dblink.service.TableService;
|
||||
import cn.com.mfish.sys.api.entity.DbConnect;
|
||||
import cn.com.mfish.sys.api.entity.FieldInfo;
|
||||
import cn.com.mfish.sys.api.entity.TableInfo;
|
||||
import cn.com.mfish.common.dblink.service.DbConnectService;
|
||||
import cn.com.mfish.common.dblink.service.TableService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
@@ -41,4 +41,9 @@ public class BootOrgService implements RemoteOrgService {
|
||||
, new ReqOrgUser().setAccount(account).setNickname(nickname).setPhone(phone), reqPage)
|
||||
, "组织下用户查询成功");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<List<String>> getOrgIdsByFixCode(String origin, String tenantId, String codes, String direction) {
|
||||
return ssoOrgService.getOrgIdsByFixCode(tenantId, List.of(codes.split(",")), TreeDirection.getDirection(direction));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package cn.com.mfish.common.api;
|
||||
|
||||
import cn.com.mfish.common.core.web.Result;
|
||||
import cn.com.mfish.common.oauth.api.remote.RemoteRoleService;
|
||||
import cn.com.mfish.common.oauth.service.SsoRoleService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @description: 角色远程接口的本地实现
|
||||
* @author: mfish
|
||||
* @date: 2024/4/29
|
||||
*/
|
||||
@Service("remoteRoleService")
|
||||
public class BootRoleService implements RemoteRoleService {
|
||||
@Resource
|
||||
SsoRoleService ssoRoleService;
|
||||
|
||||
@Override
|
||||
public Result<List<String>> getRoleIdsByCode(String origin, String tenantId, String codes) {
|
||||
return ssoRoleService.getRoleIdsByCode(tenantId, List.of(codes.split(",")));
|
||||
}
|
||||
}
|
||||
@@ -65,4 +65,9 @@ public class BootUserService implements RemoteUserService {
|
||||
public Result<List<SsoOrg>> getOrgs(String origin, String userId, String direction) {
|
||||
return ssoUserService.getOrgs(userId, direction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<List<String>> getOrgIds(String origin, String userId, String tenantId, String direction) {
|
||||
return ssoUserService.getOrgIds(tenantId, userId, direction);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-3
@@ -1,4 +1,4 @@
|
||||
package cn.com.mfish.common.ds.scope;
|
||||
package cn.com.mfish.common.core.scope;
|
||||
|
||||
/**
|
||||
* @description: 数据范围处理
|
||||
@@ -6,6 +6,5 @@ package cn.com.mfish.common.ds.scope;
|
||||
* @date: 2024/4/26
|
||||
*/
|
||||
public interface DataScopeHandle {
|
||||
|
||||
String sqlChange(String sql, String table, String fieldName, String value);
|
||||
String buildCondition(String fieldName, String[] values);
|
||||
}
|
||||
+1
-5
@@ -76,11 +76,7 @@ public class AuthInfoUtils {
|
||||
* @return
|
||||
*/
|
||||
public static String getCurrentUserId() {
|
||||
String userId = getAttr(RPCConstants.REQ_USER_ID);
|
||||
// if (StringUtils.isEmpty(userId)) {
|
||||
// throw new OAuthValidateException("错误:未获取到当前用户id");
|
||||
// }
|
||||
return userId;
|
||||
return getAttr(RPCConstants.REQ_USER_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+17
-12
@@ -1,5 +1,6 @@
|
||||
package cn.com.mfish.common.core.utils;
|
||||
|
||||
import cn.com.mfish.common.core.constants.ServiceConstants;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
||||
@@ -64,16 +65,20 @@ public final class SpringBeanFactory implements BeanFactoryPostProcessor {
|
||||
return beanFactory.getType(name);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * 获取FeignClient的bean
|
||||
// *
|
||||
// * @param name
|
||||
// * @param tClass
|
||||
// * @param <T>
|
||||
// * @return
|
||||
// */
|
||||
// public static <T> T getFeignBean(String name, Class<T> tClass) {
|
||||
// FeignContext feignContext = beanFactory.getBean(FeignContext.class);
|
||||
// return feignContext.getInstance(name, tClass);
|
||||
// }
|
||||
/**
|
||||
* 获取远程服务
|
||||
* @param clazz 远程服务类型
|
||||
* @return 远程服务bean
|
||||
* @param <T>
|
||||
*/
|
||||
public static <T> T getRemoteService(Class<T> clazz) {
|
||||
T remoteService;
|
||||
//单体服务通过name获取RPC的覆盖服务
|
||||
if (ServiceConstants.isBoot(Utils.getServiceType())) {
|
||||
remoteService = SpringBeanFactory.getBean(StringUtils.firstLowerCase(clazz.getSimpleName()));
|
||||
} else {
|
||||
remoteService = SpringBeanFactory.getBean(clazz);
|
||||
}
|
||||
return remoteService;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
package cn.com.mfish.common.ds.common;
|
||||
|
||||
import cn.com.mfish.common.ds.scope.DataScopeHandle;
|
||||
import cn.com.mfish.common.ds.scope.RoleDataScopeHandle;
|
||||
import cn.com.mfish.common.ds.scope.TenantDataScopeHandle;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @description: 数据范围
|
||||
* @author: mfish
|
||||
* @date: 2024/4/26
|
||||
*/
|
||||
@Getter
|
||||
public enum DataScopeType {
|
||||
Tenant(0, new TenantDataScopeHandle()),
|
||||
Role(1, new RoleDataScopeHandle());
|
||||
private final int value;
|
||||
private final DataScopeHandle handle;
|
||||
|
||||
DataScopeType(int value, DataScopeHandle handle) {
|
||||
this.value = value;
|
||||
this.handle = handle;
|
||||
}
|
||||
|
||||
}
|
||||
+3
-2
@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.injector.AbstractMethod;
|
||||
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfo;
|
||||
import com.baomidou.mybatisplus.extension.injector.methods.InsertBatchSomeColumn;
|
||||
import org.apache.ibatis.session.Configuration;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
@@ -16,8 +17,8 @@ import java.util.List;
|
||||
@Component
|
||||
public class BatchSqlInjector extends DefaultSqlInjector {
|
||||
@Override
|
||||
public List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo) {
|
||||
List<AbstractMethod> methodList = super.getMethodList(mapperClass, tableInfo);
|
||||
public List<AbstractMethod> getMethodList(Configuration configuration, Class<?> mapperClass, TableInfo tableInfo) {
|
||||
List<AbstractMethod> methodList = super.getMethodList(configuration, mapperClass, tableInfo);
|
||||
// 注入InsertBatchSomeColumn
|
||||
// 在!t.isLogicDelete()表示不要逻辑删除字段
|
||||
methodList.add(new InsertBatchSomeColumn(t -> !t.isLogicDelete()));
|
||||
|
||||
-15
@@ -1,15 +0,0 @@
|
||||
package cn.com.mfish.common.ds.scope;
|
||||
|
||||
/**
|
||||
* @description: 租户数据处理
|
||||
* @author: mfish
|
||||
* @date: 2024/4/26
|
||||
*/
|
||||
public class RoleDataScopeHandle implements DataScopeHandle {
|
||||
|
||||
@Override
|
||||
public String sqlChange(String sql, String table, String fieldName,String value) {
|
||||
//todo 补充逻辑
|
||||
return sql;
|
||||
}
|
||||
}
|
||||
-33
@@ -1,33 +0,0 @@
|
||||
package cn.com.mfish.common.ds.scope;
|
||||
|
||||
import cn.com.mfish.common.core.utils.AuthInfoUtils;
|
||||
import cn.com.mfish.common.core.utils.StringUtils;
|
||||
import cn.com.mfish.common.ds.common.DataScopeUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @description: 租户数据处理
|
||||
* @author: mfish
|
||||
* @date: 2024/4/26
|
||||
*/
|
||||
public class TenantDataScopeHandle implements DataScopeHandle {
|
||||
@Override
|
||||
public String sqlChange(String sql, String table, String fieldName,String value) {
|
||||
fieldName = StringUtils.isEmpty(fieldName) ? "tenant_id" : fieldName;
|
||||
value = StringUtils.isEmpty(value) ? AuthInfoUtils.getCurrentTenantId() : value;
|
||||
List<DataScopeUtils.SqlSplit> list = DataScopeUtils.splitSql(sql, table);
|
||||
for (DataScopeUtils.SqlSplit split : list) {
|
||||
if (split.isHaveTable()) {
|
||||
split.setStatement(split.getStatement().replaceAll(table
|
||||
, "(select * from " + table + " where " + fieldName + "='" + value + "')"));
|
||||
if (split.isHaveAlias()) {
|
||||
continue;
|
||||
}
|
||||
split.setStatement(split.getStatement() + " " + table);
|
||||
}
|
||||
}
|
||||
return list.stream().map(DataScopeUtils.SqlSplit::getStatement).collect(Collectors.joining());
|
||||
}
|
||||
}
|
||||
-2
@@ -1,5 +1,3 @@
|
||||
cn.com.mfish.common.ds.config.MybatisInterceptor
|
||||
cn.com.mfish.common.ds.config.SelectInterceptor
|
||||
cn.com.mfish.common.ds.aspect.DataScopeAspect
|
||||
cn.com.mfish.common.ds.config.BatchSqlInjector
|
||||
com.alibaba.druid.spring.boot3.autoconfigure.DruidDataSourceAutoConfigure
|
||||
+12
-8
@@ -1,6 +1,6 @@
|
||||
package cn.com.mfish.common.ds.annotation;
|
||||
package cn.com.mfish.common.oauth.annotation;
|
||||
|
||||
import cn.com.mfish.common.ds.common.DataScopeType;
|
||||
import cn.com.mfish.common.oauth.common.DataScopeType;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
@@ -18,24 +18,28 @@ public @interface DataScope {
|
||||
/**
|
||||
* 需要进行权限控制的表
|
||||
*
|
||||
* @return
|
||||
* @return 表名
|
||||
*/
|
||||
String table() default "";
|
||||
|
||||
/**
|
||||
* 进行权限控制的类型
|
||||
*
|
||||
* @return
|
||||
* @return 权限控制类型
|
||||
*/
|
||||
DataScopeType type() default DataScopeType.Tenant;
|
||||
|
||||
/**
|
||||
* 表进行过滤的字段名称
|
||||
* 注意:fieldNames与tables数组值一一对应
|
||||
* 表进行过滤的字段名称(不填 采用默认值。例如:租户使用tenant_id)
|
||||
*
|
||||
* @return
|
||||
* @return 字段名
|
||||
*/
|
||||
String fieldName() default "";
|
||||
|
||||
String value() default "";
|
||||
/**
|
||||
* 字段值(不填各权限控制使用默认值,传入优先使用传入值。例如:租户使用当前租户)
|
||||
*
|
||||
* @return 字段值
|
||||
*/
|
||||
String[] values() default {};
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package cn.com.mfish.common.ds.annotation;
|
||||
package cn.com.mfish.common.oauth.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
+9
-9
@@ -1,9 +1,9 @@
|
||||
package cn.com.mfish.common.ds.aspect;
|
||||
package cn.com.mfish.common.oauth.aspect;
|
||||
|
||||
import cn.com.mfish.common.core.annotation.GlobalException;
|
||||
import cn.com.mfish.common.ds.annotation.DataScope;
|
||||
import cn.com.mfish.common.ds.annotation.DataScopes;
|
||||
import cn.com.mfish.common.ds.common.DataScopeUtils;
|
||||
import cn.com.mfish.common.oauth.annotation.DataScope;
|
||||
import cn.com.mfish.common.oauth.annotation.DataScopes;
|
||||
import cn.com.mfish.common.oauth.common.DataScopeUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.aspectj.lang.annotation.AfterReturning;
|
||||
@@ -29,7 +29,7 @@ import java.util.List;
|
||||
@Slf4j
|
||||
public class DataScopeAspect {
|
||||
|
||||
@Before("@annotation(cn.com.mfish.common.ds.annotation.DataScopes)||@annotation(cn.com.mfish.common.ds.annotation.DataScope)")
|
||||
@Before("@annotation(cn.com.mfish.common.oauth.annotation.DataScopes)||@annotation(cn.com.mfish.common.oauth.annotation.DataScope)")
|
||||
public void doBefore(JoinPoint joinPoint) {
|
||||
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
|
||||
Method method = methodSignature.getMethod();
|
||||
@@ -43,14 +43,14 @@ public class DataScopeAspect {
|
||||
DataScopeUtils.context.set(list);
|
||||
}
|
||||
|
||||
@AfterReturning("@annotation(cn.com.mfish.common.ds.annotation.DataScopes)||@annotation(cn.com.mfish.common.ds.annotation.DataScope)")
|
||||
@AfterReturning("@annotation(cn.com.mfish.common.oauth.annotation.DataScopes)||@annotation(cn.com.mfish.common.oauth.annotation.DataScope)")
|
||||
public void doAfterReturning() {
|
||||
DataScopeUtils.context.remove();
|
||||
|
||||
}
|
||||
|
||||
@AfterThrowing("@annotation(cn.com.mfish.common.ds.annotation.DataScopes)||@annotation(cn.com.mfish.common.ds.annotation.DataScope)")
|
||||
public void doAfterThrowing() {
|
||||
@AfterThrowing(value = "@annotation(cn.com.mfish.common.oauth.annotation.DataScopes)||@annotation(cn.com.mfish.common.oauth.annotation.DataScope)", throwing = "e")
|
||||
public void doAfterThrowing(Throwable e) {
|
||||
log.error("doAfterThrowing", e);
|
||||
DataScopeUtils.context.remove();
|
||||
}
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
package cn.com.mfish.common.oauth.common;
|
||||
|
||||
import cn.com.mfish.common.core.scope.DataScopeHandle;
|
||||
import cn.com.mfish.common.oauth.scope.OrgDataScopeHandle;
|
||||
import cn.com.mfish.common.oauth.scope.RoleDataScopeHandle;
|
||||
import cn.com.mfish.common.oauth.scope.TenantDataScopeHandle;
|
||||
import cn.com.mfish.common.oauth.scope.UserDataScopeHandle;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @description: 数据范围
|
||||
* @author: mfish
|
||||
* @date: 2024/4/26
|
||||
*/
|
||||
@Getter
|
||||
public enum DataScopeType {
|
||||
//租户
|
||||
Tenant(0, new TenantDataScopeHandle()),
|
||||
//用户
|
||||
User(1, new UserDataScopeHandle()),
|
||||
//角色
|
||||
Role(2, new RoleDataScopeHandle()),
|
||||
//组织
|
||||
Org(3, new OrgDataScopeHandle());
|
||||
|
||||
private final int value;
|
||||
private final DataScopeHandle handle;
|
||||
|
||||
DataScopeType(int value, DataScopeHandle handle) {
|
||||
this.value = value;
|
||||
this.handle = handle;
|
||||
}
|
||||
|
||||
}
|
||||
+41
-11
@@ -1,6 +1,8 @@
|
||||
package cn.com.mfish.common.ds.common;
|
||||
package cn.com.mfish.common.oauth.common;
|
||||
|
||||
import cn.com.mfish.common.ds.annotation.DataScope;
|
||||
import cn.com.mfish.common.core.exception.MyRuntimeException;
|
||||
import cn.com.mfish.common.core.utils.StringUtils;
|
||||
import cn.com.mfish.common.oauth.annotation.DataScope;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
@@ -22,6 +24,17 @@ public class DataScopeUtils {
|
||||
public static Set<Character> START_KEYWORD = new HashSet<>();
|
||||
public static Set<Character> END_KEYWORD = new HashSet<>();
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public static class SqlSplit {
|
||||
@Schema(name = "语句类型")
|
||||
private boolean haveTable = false;
|
||||
@Schema(name = "语句")
|
||||
private String statement;
|
||||
@Schema(name = "是否存在别名")
|
||||
private boolean haveAlias = false;
|
||||
}
|
||||
|
||||
static {
|
||||
START_KEYWORD.add('.');
|
||||
START_KEYWORD.add('(');
|
||||
@@ -135,14 +148,31 @@ public class DataScopeUtils {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public static class SqlSplit {
|
||||
@Schema(name = "语句类型")
|
||||
private boolean haveTable = false;
|
||||
@Schema(name = "语句")
|
||||
private String statement;
|
||||
@Schema(name = "是否存在别名")
|
||||
private boolean haveAlias = false;
|
||||
/**
|
||||
* 构建查询条件
|
||||
*
|
||||
* @param fieldName
|
||||
* @param values
|
||||
* @return
|
||||
*/
|
||||
public static String buildCondition(String fieldName, String[] values) {
|
||||
if (StringUtils.isEmpty(fieldName)) {
|
||||
throw new MyRuntimeException("错误:未传入条件字段名称");
|
||||
}
|
||||
if (values == null || values.length == 0) {
|
||||
throw new MyRuntimeException("错误:未传入条件值");
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(fieldName);
|
||||
if (values.length > 1) {
|
||||
sb.append(" in ('");
|
||||
sb.append(String.join("','", values));
|
||||
sb.append("')");
|
||||
} else {
|
||||
sb.append(" = '");
|
||||
sb.append(values[0]);
|
||||
sb.append("'");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package cn.com.mfish.common.oauth.common;
|
||||
|
||||
import cn.com.mfish.common.core.scope.DataScopeHandle;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* @description: 数据范围值
|
||||
* @author: mfish
|
||||
* @date: 2024/4/29
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class DataScopeValue {
|
||||
@Schema(name = "数据处理方式")
|
||||
private DataScopeHandle dataScopeHandle;
|
||||
@Schema(name = "字段名称")
|
||||
private String fieldName;
|
||||
@Schema(name = "字段值")
|
||||
private String[] values;
|
||||
}
|
||||
+6
-11
@@ -1,12 +1,10 @@
|
||||
package cn.com.mfish.common.oauth.common;
|
||||
|
||||
import cn.com.mfish.common.core.constants.RPCConstants;
|
||||
import cn.com.mfish.common.core.constants.ServiceConstants;
|
||||
import cn.com.mfish.common.core.enums.DeviceType;
|
||||
import cn.com.mfish.common.core.utils.AuthInfoUtils;
|
||||
import cn.com.mfish.common.core.utils.SpringBeanFactory;
|
||||
import cn.com.mfish.common.core.utils.StringUtils;
|
||||
import cn.com.mfish.common.core.utils.Utils;
|
||||
import cn.com.mfish.common.core.web.Result;
|
||||
import cn.com.mfish.common.oauth.annotation.RequiresPermissions;
|
||||
import cn.com.mfish.common.oauth.annotation.RequiresRoles;
|
||||
@@ -35,18 +33,15 @@ import java.util.stream.Collectors;
|
||||
public class OauthUtils {
|
||||
|
||||
private OauthUtils() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取远程用户接口服务
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private static RemoteUserService getRemoteUserService() {
|
||||
RemoteUserService remoteUserService;
|
||||
//单体服务通过name获取RPC的覆盖服务
|
||||
if (ServiceConstants.isBoot(Utils.getServiceType())) {
|
||||
remoteUserService = SpringBeanFactory.getBean(StringUtils.firstLowerCase(RemoteUserService.class.getSimpleName()));
|
||||
} else {
|
||||
remoteUserService = SpringBeanFactory.getBean(RemoteUserService.class);
|
||||
}
|
||||
return remoteUserService;
|
||||
return SpringBeanFactory.getRemoteService(RemoteUserService.class);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package cn.com.mfish.oauth.entity;
|
||||
package cn.com.mfish.common.oauth.entity;
|
||||
|
||||
import cn.com.mfish.common.core.entity.BaseEntity;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
package cn.com.mfish.common.oauth.scope;
|
||||
|
||||
|
||||
import cn.com.mfish.common.oauth.common.DataScopeUtils;
|
||||
import cn.com.mfish.common.oauth.common.DataScopeValue;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @description: 混合数据范围控制
|
||||
* @author: mfish
|
||||
* @date: 2024/4/29
|
||||
*/
|
||||
public class MixDataScopeHandle {
|
||||
|
||||
/**
|
||||
* 转换为数据权限SQL
|
||||
*
|
||||
* @param oriSql
|
||||
* @param map
|
||||
* @return
|
||||
*/
|
||||
public static String sqlChange(String oriSql, Map<String, List<DataScopeValue>> map) {
|
||||
for (Map.Entry<String, List<DataScopeValue>> entry : map.entrySet()) {
|
||||
if (!oriSql.toLowerCase().contains(entry.getKey())) {
|
||||
continue;
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (DataScopeValue value : entry.getValue()) {
|
||||
sb.append(value.getDataScopeHandle().buildCondition(value.getFieldName(), value.getValues()));
|
||||
sb.append(" and ");
|
||||
}
|
||||
if (!sb.isEmpty()) {
|
||||
sb.delete(sb.length() - 5, sb.length());
|
||||
}
|
||||
oriSql = sqlChange(oriSql, entry.getKey(), sb.toString());
|
||||
}
|
||||
return oriSql;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为数据权限SQL
|
||||
*
|
||||
* @param sql
|
||||
* @param table
|
||||
* @param condition
|
||||
* @return
|
||||
*/
|
||||
private static String sqlChange(String sql, String table, String condition) {
|
||||
List<DataScopeUtils.SqlSplit> list = DataScopeUtils.splitSql(sql, table);
|
||||
for (DataScopeUtils.SqlSplit split : list) {
|
||||
if (split.isHaveTable()) {
|
||||
split.setStatement(split.getStatement().replaceAll(table, buildReplaceSql(table, condition)));
|
||||
if (split.isHaveAlias()) {
|
||||
continue;
|
||||
}
|
||||
split.setStatement(split.getStatement() + " " + table);
|
||||
}
|
||||
}
|
||||
return list.stream().map(DataScopeUtils.SqlSplit::getStatement).collect(Collectors.joining());
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建替换SQL
|
||||
*
|
||||
* @param table
|
||||
* @param condition
|
||||
* @return
|
||||
*/
|
||||
private static String buildReplaceSql(String table, String condition) {
|
||||
return "(select * from " + table +
|
||||
" where " +
|
||||
condition +
|
||||
")";
|
||||
}
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
package cn.com.mfish.common.oauth.scope;
|
||||
|
||||
import cn.com.mfish.common.core.constants.RPCConstants;
|
||||
import cn.com.mfish.common.core.enums.TreeDirection;
|
||||
import cn.com.mfish.common.core.exception.MyRuntimeException;
|
||||
import cn.com.mfish.common.core.scope.DataScopeHandle;
|
||||
import cn.com.mfish.common.core.utils.AuthInfoUtils;
|
||||
import cn.com.mfish.common.core.utils.SpringBeanFactory;
|
||||
import cn.com.mfish.common.core.utils.StringUtils;
|
||||
import cn.com.mfish.common.core.web.Result;
|
||||
import cn.com.mfish.common.oauth.api.remote.RemoteOrgService;
|
||||
import cn.com.mfish.common.oauth.api.remote.RemoteUserService;
|
||||
import cn.com.mfish.common.oauth.common.DataScopeUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
/**
|
||||
* @description: 组织数据权限控制
|
||||
* @author: mfish
|
||||
* @date: 2024/4/29
|
||||
*/
|
||||
public class OrgDataScopeHandle implements DataScopeHandle {
|
||||
private static final String DEFAULT_FIELD = "org_id";
|
||||
|
||||
@Override
|
||||
public String buildCondition(String fieldName, String[] values) {
|
||||
fieldName = StringUtils.isEmpty(fieldName) ? DEFAULT_FIELD : fieldName;
|
||||
if (values == null || values.length == 0) {
|
||||
//未传值时使用当前用户的所有角色id
|
||||
values = getCurOrgs();
|
||||
} else {
|
||||
values = getOrgIdsByCode(values);
|
||||
}
|
||||
return DataScopeUtils.buildCondition(fieldName, values);
|
||||
}
|
||||
|
||||
private String[] getCurOrgs() {
|
||||
final String userId = AuthInfoUtils.getCurrentUserId();
|
||||
final String tenantId = AuthInfoUtils.getCurrentTenantId();
|
||||
RemoteUserService remoteUserService = SpringBeanFactory.getRemoteService(RemoteUserService.class);
|
||||
//异步调用防止切面主线程使用了PageHelper分页交叉
|
||||
CompletableFuture<Result<List<String>>> future = CompletableFuture.supplyAsync(() -> remoteUserService.getOrgIds(RPCConstants.INNER, userId, tenantId, TreeDirection.向下.toString()));
|
||||
try {
|
||||
Result<List<String>> result = future.get();
|
||||
if (!result.isSuccess()) {
|
||||
throw new MyRuntimeException(result.getMsg());
|
||||
}
|
||||
return result.getData().toArray(new String[0]);
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
throw new MyRuntimeException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private String[] getOrgIdsByCode(final String[] values) {
|
||||
final String tenantId = AuthInfoUtils.getCurrentTenantId();
|
||||
RemoteOrgService remoteOrgService = SpringBeanFactory.getRemoteService(RemoteOrgService.class);
|
||||
//异步调用防止切面主线程使用了PageHelper分页交叉
|
||||
CompletableFuture<Result<List<String>>> future = CompletableFuture.supplyAsync(() -> remoteOrgService.getOrgIdsByFixCode(RPCConstants.INNER, tenantId, String.join(",", values), TreeDirection.向下.toString()));
|
||||
try {
|
||||
Result<List<String>> result = future.get();
|
||||
if (!result.isSuccess()) {
|
||||
throw new MyRuntimeException(result.getMsg());
|
||||
}
|
||||
return result.getData().toArray(new String[0]);
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
throw new MyRuntimeException(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
package cn.com.mfish.common.oauth.scope;
|
||||
|
||||
import cn.com.mfish.common.core.constants.RPCConstants;
|
||||
import cn.com.mfish.common.core.exception.MyRuntimeException;
|
||||
import cn.com.mfish.common.core.scope.DataScopeHandle;
|
||||
import cn.com.mfish.common.core.utils.AuthInfoUtils;
|
||||
import cn.com.mfish.common.core.utils.SpringBeanFactory;
|
||||
import cn.com.mfish.common.core.utils.StringUtils;
|
||||
import cn.com.mfish.common.core.web.Result;
|
||||
import cn.com.mfish.common.oauth.api.entity.UserRole;
|
||||
import cn.com.mfish.common.oauth.api.remote.RemoteRoleService;
|
||||
import cn.com.mfish.common.oauth.api.remote.RemoteUserService;
|
||||
import cn.com.mfish.common.oauth.common.DataScopeUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
/**
|
||||
* @description: 租户数据处理
|
||||
* @author: mfish
|
||||
* @date: 2024/4/26
|
||||
*/
|
||||
public class RoleDataScopeHandle implements DataScopeHandle {
|
||||
private static final String DEFAULT_FIELD = "role_id";
|
||||
|
||||
@Override
|
||||
public String buildCondition(String fieldName, String[] values) {
|
||||
fieldName = StringUtils.isEmpty(fieldName) ? DEFAULT_FIELD : fieldName;
|
||||
if (values == null || values.length == 0) {
|
||||
//未传值时使用当前用户的所有角色id
|
||||
values = getCurRoles();
|
||||
} else {
|
||||
values = getRoleIdsByCode(values);
|
||||
}
|
||||
return DataScopeUtils.buildCondition(fieldName, values);
|
||||
}
|
||||
|
||||
private String[] getCurRoles() {
|
||||
final String userId = AuthInfoUtils.getCurrentUserId();
|
||||
final String tenantId = AuthInfoUtils.getCurrentTenantId();
|
||||
RemoteUserService remoteUserService = SpringBeanFactory.getRemoteService(RemoteUserService.class);
|
||||
//异步调用防止切面主线程使用了PageHelper分页交叉
|
||||
CompletableFuture<Result<List<UserRole>>> future = CompletableFuture.supplyAsync(() -> remoteUserService.getRoles(RPCConstants.INNER, userId, tenantId));
|
||||
try {
|
||||
Result<List<UserRole>> result = future.get();
|
||||
if (!result.isSuccess()) {
|
||||
throw new MyRuntimeException(result.getMsg());
|
||||
}
|
||||
return result.getData().stream().map(UserRole::getId).toList().toArray(String[]::new);
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
throw new MyRuntimeException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private String[] getRoleIdsByCode(final String[] values) {
|
||||
final String tenantId = AuthInfoUtils.getCurrentTenantId();
|
||||
RemoteRoleService remoteRoleService = SpringBeanFactory.getRemoteService(RemoteRoleService.class);
|
||||
//异步调用防止切面主线程使用了PageHelper分页交叉
|
||||
CompletableFuture<Result<List<String>>> future = CompletableFuture.supplyAsync(() -> remoteRoleService.getRoleIdsByCode(RPCConstants.INNER, tenantId, String.join(",", values)));
|
||||
try {
|
||||
Result<List<String>> result = future.get();
|
||||
if (!result.isSuccess()) {
|
||||
throw new MyRuntimeException(result.getMsg());
|
||||
}
|
||||
return result.getData().toArray(new String[0]);
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
throw new MyRuntimeException(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
+25
-10
@@ -1,8 +1,9 @@
|
||||
package cn.com.mfish.common.ds.config;
|
||||
package cn.com.mfish.common.oauth.scope;
|
||||
|
||||
import cn.com.mfish.common.core.exception.MyRuntimeException;
|
||||
import cn.com.mfish.common.ds.annotation.DataScope;
|
||||
import cn.com.mfish.common.ds.common.DataScopeUtils;
|
||||
import cn.com.mfish.common.oauth.annotation.DataScope;
|
||||
import cn.com.mfish.common.oauth.common.DataScopeUtils;
|
||||
import cn.com.mfish.common.oauth.common.DataScopeValue;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.ibatis.executor.statement.StatementHandler;
|
||||
import org.apache.ibatis.mapping.BoundSql;
|
||||
@@ -19,7 +20,10 @@ import org.springframework.stereotype.Component;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.sql.Connection;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @description: 查询拦截器
|
||||
@@ -51,13 +55,8 @@ public class SelectInterceptor implements Interceptor {
|
||||
BoundSql boundSql = statementHandler.getBoundSql();
|
||||
String oriSql = boundSql.getSql();
|
||||
try {
|
||||
for (DataScope scope : scopes) {
|
||||
String tableName = scope.table();
|
||||
if (!oriSql.toLowerCase().contains(tableName.toLowerCase())) {
|
||||
continue;
|
||||
}
|
||||
oriSql = scope.type().getHandle().sqlChange(oriSql, tableName, scope.fieldName(), scope.value());
|
||||
}
|
||||
Map<String, List<DataScopeValue>> map = buildParamsMap(scopes);
|
||||
oriSql = MixDataScopeHandle.sqlChange(oriSql, map);
|
||||
Field field = boundSql.getClass().getDeclaredField("sql");
|
||||
field.setAccessible(true);
|
||||
field.set(boundSql, oriSql);
|
||||
@@ -67,4 +66,20 @@ public class SelectInterceptor implements Interceptor {
|
||||
}
|
||||
return invocation.proceed();
|
||||
}
|
||||
|
||||
private Map<String, List<DataScopeValue>> buildParamsMap(List<DataScope> scopes) {
|
||||
Map<String, List<DataScopeValue>> map = new HashMap<>();
|
||||
for (DataScope scope : scopes) {
|
||||
String tableName = scope.table();
|
||||
List<DataScopeValue> list;
|
||||
if (map.containsKey(tableName)) {
|
||||
list = map.get(tableName);
|
||||
} else {
|
||||
list = new ArrayList<>();
|
||||
}
|
||||
list.add(new DataScopeValue().setDataScopeHandle(scope.type().getHandle()).setFieldName(scope.fieldName()).setValues(scope.values()));
|
||||
map.put(tableName, list);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package cn.com.mfish.common.oauth.scope;
|
||||
|
||||
import cn.com.mfish.common.core.scope.DataScopeHandle;
|
||||
import cn.com.mfish.common.core.utils.AuthInfoUtils;
|
||||
import cn.com.mfish.common.oauth.common.DataScopeUtils;
|
||||
import cn.com.mfish.common.core.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* @description: 租户数据处理
|
||||
* @author: mfish
|
||||
* @date: 2024/4/26
|
||||
*/
|
||||
public class TenantDataScopeHandle implements DataScopeHandle {
|
||||
private static final String DEFAULT_FIELD = "tenant_id";
|
||||
|
||||
@Override
|
||||
public String buildCondition(String fieldName, String[] values) {
|
||||
fieldName = StringUtils.isEmpty(fieldName) ? DEFAULT_FIELD : fieldName;
|
||||
if (values == null || values.length == 0) {
|
||||
//未传值时使用当前租户id
|
||||
values = new String[]{AuthInfoUtils.getCurrentTenantId()};
|
||||
}
|
||||
return DataScopeUtils.buildCondition(fieldName, values);
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package cn.com.mfish.common.oauth.scope;
|
||||
|
||||
import cn.com.mfish.common.core.scope.DataScopeHandle;
|
||||
import cn.com.mfish.common.core.utils.AuthInfoUtils;
|
||||
import cn.com.mfish.common.core.utils.StringUtils;
|
||||
import cn.com.mfish.common.oauth.common.DataScopeUtils;
|
||||
|
||||
/**
|
||||
* @description: 用户数据权限限制
|
||||
* @author: mfish
|
||||
* @date: 2024/4/29
|
||||
*/
|
||||
public class UserDataScopeHandle implements DataScopeHandle {
|
||||
private static final String DEFAULT_FIELD = "user_id";
|
||||
|
||||
@Override
|
||||
public String buildCondition(String fieldName, String[] values) {
|
||||
fieldName = StringUtils.isEmpty(fieldName) ? DEFAULT_FIELD : fieldName;
|
||||
if (values == null || values.length == 0) {
|
||||
//未传值时使用当前用户id
|
||||
values = new String[]{AuthInfoUtils.getCurrentUserId()};
|
||||
}
|
||||
return DataScopeUtils.buildCondition(fieldName, values);
|
||||
}
|
||||
}
|
||||
+4
@@ -36,6 +36,8 @@ public interface SsoOrgService extends IService<SsoOrg> {
|
||||
|
||||
List<SsoOrg> queryOrgById(String id, TreeDirection direction);
|
||||
|
||||
Result<List<String>> queryOrgIdsById(String tenantId, List<String> ids, TreeDirection direction);
|
||||
|
||||
List<UserRole> getOrgRoles(String... orgIds);
|
||||
|
||||
Result<List<SsoOrg>> queryByIds(String ids);
|
||||
@@ -43,4 +45,6 @@ public interface SsoOrgService extends IService<SsoOrg> {
|
||||
boolean isTenantOrg(String orgId, String tenantId);
|
||||
|
||||
PageResult<UserInfo> queryUserByCode(String code, ReqOrgUser reqOrgUser, ReqPage reqPage);
|
||||
|
||||
Result<List<String>> getOrgIdsByFixCode(String tenantId, List<String> orgCodes, TreeDirection direction);
|
||||
}
|
||||
|
||||
+4
-2
@@ -1,7 +1,7 @@
|
||||
package cn.com.mfish.oauth.service;
|
||||
package cn.com.mfish.common.oauth.service;
|
||||
|
||||
import cn.com.mfish.common.core.web.Result;
|
||||
import cn.com.mfish.oauth.entity.SsoRole;
|
||||
import cn.com.mfish.common.oauth.entity.SsoRole;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
import java.util.List;
|
||||
@@ -24,4 +24,6 @@ public interface SsoRoleService extends IService<SsoRole> {
|
||||
List<String> getRoleMenus(String roleId);
|
||||
|
||||
boolean isTenantRole(String roleId, String tenantId);
|
||||
|
||||
Result<List<String>> getRoleIdsByCode(String tenantId, List<String> roleCodes);
|
||||
}
|
||||
+3
-1
@@ -53,6 +53,8 @@ public interface SsoUserService extends IService<SsoUser> {
|
||||
|
||||
Result<List<SsoOrg>> getOrgs(String userId, String direction);
|
||||
|
||||
Result<List<String>> getOrgIds(String tenantId, String userId, String direction);
|
||||
|
||||
/**
|
||||
* 判断帐号是否存在
|
||||
*
|
||||
@@ -84,7 +86,7 @@ public interface SsoUserService extends IService<SsoUser> {
|
||||
|
||||
boolean isExistUserOrg(String userId, String orgId);
|
||||
|
||||
List<SimpleUserInfo> searchUserList(String condition);
|
||||
List<SimpleUserInfo> searchUserList(String condition);
|
||||
|
||||
UserInfo getUserInfo(String userId);
|
||||
|
||||
|
||||
+3
-1
@@ -3,4 +3,6 @@ cn.com.mfish.common.oauth.service.impl.WeChatTokenServiceImpl
|
||||
cn.com.mfish.common.oauth.aspect.AuthorizationAspect
|
||||
cn.com.mfish.common.oauth.validator.WebTokenValidator
|
||||
cn.com.mfish.common.oauth.validator.WeChatTokenValidator
|
||||
cn.com.mfish.common.oauth.validator.TokenValidator
|
||||
cn.com.mfish.common.oauth.validator.TokenValidator
|
||||
cn.com.mfish.common.oauth.scope.SelectInterceptor
|
||||
cn.com.mfish.common.oauth.aspect.DataScopeAspect
|
||||
@@ -49,7 +49,7 @@ public class SsoOrgController {
|
||||
* @param reqPage
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "组织结构表-分页列表查询", description = "组织结构表-分页列表查询")
|
||||
@Operation(summary = "组织结构表-分页列表查询", description = "组织结构表-分页列表查询")
|
||||
@GetMapping
|
||||
@RequiresPermissions("sys:org:query")
|
||||
public Result<PageResult<SsoOrg>> queryPageList(ReqSsoOrg reqSsoOrg, ReqPage reqPage) {
|
||||
@@ -90,7 +90,7 @@ public class SsoOrgController {
|
||||
* @return
|
||||
*/
|
||||
@Log(title = "组织结构表-添加", operateType = OperateType.INSERT)
|
||||
@Operation(summary = "组织结构表-添加", description = "组织结构表-添加")
|
||||
@Operation(summary = "组织结构表-添加", description = "组织结构表-添加")
|
||||
@PostMapping
|
||||
@RequiresPermissions("sys:org:insert")
|
||||
public Result<SsoOrg> add(@RequestBody SsoOrg ssoOrg) {
|
||||
@@ -104,7 +104,7 @@ public class SsoOrgController {
|
||||
* @return
|
||||
*/
|
||||
@Log(title = "组织结构表-编辑", operateType = OperateType.UPDATE)
|
||||
@Operation(summary = "组织结构表-编辑", description = "组织结构表-编辑")
|
||||
@Operation(summary = "组织结构表-编辑", description = "组织结构表-编辑")
|
||||
@PutMapping
|
||||
@RequiresPermissions("sys:org:update")
|
||||
public Result<SsoOrg> edit(@RequestBody SsoOrg ssoOrg) {
|
||||
@@ -118,7 +118,7 @@ public class SsoOrgController {
|
||||
* @return
|
||||
*/
|
||||
@Log(title = "组织结构表-通过id删除", operateType = OperateType.DELETE)
|
||||
@Operation(summary = "组织结构表-通过id删除", description = "组织结构表-通过id删除")
|
||||
@Operation(summary = "组织结构表-通过id删除", description = "组织结构表-通过id删除")
|
||||
@DeleteMapping("/{id}")
|
||||
@RequiresPermissions("sys:org:delete")
|
||||
public Result<Boolean> delete(@Parameter(name = "id", description = "唯一性ID") @PathVariable String id) {
|
||||
@@ -131,14 +131,14 @@ public class SsoOrgController {
|
||||
* @param ids 多个ID逗号分隔
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "组织结构表-通过id查询", description = "组织结构表-通过id查询")
|
||||
@Operation(summary = "组织结构表-通过id查询", description = "组织结构表-通过id查询")
|
||||
@GetMapping("/{ids}")
|
||||
@RequiresPermissions("sys:org:query")
|
||||
public Result<List<SsoOrg>> queryByIds(@Parameter(name = "ids", description = "唯一性ID") @PathVariable("ids") String ids) {
|
||||
return ssoOrgService.queryByIds(ids);
|
||||
}
|
||||
|
||||
@Operation(summary = "组织树-通过固定编码查询", description = "组织树-通过固定编码查询")
|
||||
@Operation(summary = "组织树-通过固定编码查询", description = "组织树-通过固定编码查询")
|
||||
@GetMapping("/code/{code}")
|
||||
@Parameters({
|
||||
@Parameter(name = "direction", description = "方向 all 返回所有父子节点 up返回父节点 down返回子节点", required = true),
|
||||
@@ -148,9 +148,26 @@ public class SsoOrgController {
|
||||
return Result.ok(list, "组织结构表-查询成功!");
|
||||
}
|
||||
|
||||
@Operation(summary = "获取组织及子组织下的所有用户-通过固定编码查询", description = "获取组织及子组织下的所有用户-通过固定编码查询")
|
||||
@Operation(summary = "获取组织及子组织下的所有用户-通过固定编码查询", description = "获取组织及子组织下的所有用户-通过固定编码查询")
|
||||
@GetMapping("/user/{code}")
|
||||
public Result<PageResult<UserInfo>> queryUserByCode(@Parameter(name = "code", description = "固定编码") @PathVariable("code") String code, ReqOrgUser reqOrgUser, ReqPage reqPage) {
|
||||
return Result.ok(ssoOrgService.queryUserByCode(code, reqOrgUser, reqPage), "组织下用户查询成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取组织id-通过组织编码查询
|
||||
*
|
||||
* @param codes 组织编码,多个逗号分隔
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "获取组织id", description = "获取组织id-通过组织编码查询")
|
||||
@GetMapping("/ids")
|
||||
@Parameters({
|
||||
@Parameter(name = "tenantId", description = "租户ID"),
|
||||
@Parameter(name = "codes", description = "组织固定编码", required = true),
|
||||
@Parameter(name = "direction", description = "方向 all 返回所有父子节点 up返回父节点 down返回子节点", required = true)
|
||||
})
|
||||
public Result<List<String>> getOrgIdsByFixCode(String tenantId, String codes, String direction) {
|
||||
return ssoOrgService.getOrgIdsByFixCode(tenantId, List.of(codes.split(",")), TreeDirection.getDirection(direction));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package cn.com.mfish.oauth.controller;
|
||||
|
||||
import cn.com.mfish.common.core.annotation.InnerUser;
|
||||
import cn.com.mfish.common.core.enums.OperateType;
|
||||
import cn.com.mfish.common.core.utils.AuthInfoUtils;
|
||||
import cn.com.mfish.common.core.utils.StringUtils;
|
||||
@@ -9,14 +10,15 @@ import cn.com.mfish.common.core.web.Result;
|
||||
import cn.com.mfish.common.log.annotation.Log;
|
||||
import cn.com.mfish.common.oauth.annotation.RequiresPermissions;
|
||||
import cn.com.mfish.common.oauth.api.entity.SsoTenant;
|
||||
import cn.com.mfish.oauth.entity.SsoRole;
|
||||
import cn.com.mfish.common.oauth.entity.SsoRole;
|
||||
import cn.com.mfish.oauth.mapper.SsoTenantMapper;
|
||||
import cn.com.mfish.oauth.req.ReqSsoRole;
|
||||
import cn.com.mfish.oauth.service.SsoRoleService;
|
||||
import cn.com.mfish.common.oauth.service.SsoRoleService;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Parameters;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -49,7 +51,7 @@ public class SsoRoleController {
|
||||
* @param reqPage
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "角色信息表-分页列表查询", description = "角色信息表-分页列表查询")
|
||||
@Operation(summary = "角色信息表-分页列表查询", description = "角色信息表-分页列表查询")
|
||||
@GetMapping
|
||||
@RequiresPermissions("sys:role:query")
|
||||
public Result<PageResult<SsoRole>> queryPageList(ReqSsoRole reqSsoRole, ReqPage reqPage) {
|
||||
@@ -65,7 +67,7 @@ public class SsoRoleController {
|
||||
return Result.ok(ssoRoleService.getRoleMenus(roleId), "查询角色下菜单成功");
|
||||
}
|
||||
|
||||
@Operation(summary = "角色信息表-列表查询", description = "角色信息表-列表查询")
|
||||
@Operation(summary = "角色信息表-列表查询", description = "角色信息表-列表查询")
|
||||
@GetMapping("/all")
|
||||
public Result<List<SsoRole>> queryList(ReqSsoRole reqSsoRole) {
|
||||
//组织参数不为空,获取组织所属租户的角色
|
||||
@@ -86,11 +88,11 @@ public class SsoRoleController {
|
||||
.like(reqSsoRole.getRoleCode() != null, SsoRole::getRoleCode, reqSsoRole.getRoleCode())
|
||||
.like(reqSsoRole.getRoleName() != null, SsoRole::getRoleName, reqSsoRole.getRoleName())
|
||||
.orderByAsc(SsoRole::getRoleSort);
|
||||
if(!StringUtils.isEmpty(reqSsoRole.getTenantId())){
|
||||
if (!StringUtils.isEmpty(reqSsoRole.getTenantId())) {
|
||||
String[] ids = reqSsoRole.getTenantId().split(",");
|
||||
wrapper.and(ssoRoleLambdaQueryWrapper -> {
|
||||
for(String id : ids){
|
||||
ssoRoleLambdaQueryWrapper.or().eq(!StringUtils.isEmpty(id),SsoRole::getTenantId,id);
|
||||
for (String id : ids) {
|
||||
ssoRoleLambdaQueryWrapper.or().eq(!StringUtils.isEmpty(id), SsoRole::getTenantId, id);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -104,7 +106,7 @@ public class SsoRoleController {
|
||||
* @return
|
||||
*/
|
||||
@Log(title = "角色信息表-添加", operateType = OperateType.INSERT)
|
||||
@Operation(summary = "角色信息表-添加", description = "角色信息表-添加")
|
||||
@Operation(summary = "角色信息表-添加", description = "角色信息表-添加")
|
||||
@PostMapping
|
||||
@RequiresPermissions("sys:role:insert")
|
||||
public Result<SsoRole> add(@RequestBody SsoRole ssoRole) {
|
||||
@@ -119,7 +121,7 @@ public class SsoRoleController {
|
||||
* @return
|
||||
*/
|
||||
@Log(title = "角色信息表-编辑", operateType = OperateType.UPDATE)
|
||||
@Operation(summary = "角色信息表-编辑", description = "角色信息表-编辑")
|
||||
@Operation(summary = "角色信息表-编辑", description = "角色信息表-编辑")
|
||||
@PutMapping
|
||||
@RequiresPermissions("sys:role:update")
|
||||
public Result<SsoRole> edit(@RequestBody SsoRole ssoRole) {
|
||||
@@ -128,7 +130,7 @@ public class SsoRoleController {
|
||||
}
|
||||
|
||||
@Log(title = "角色信息表-设置状态", operateType = OperateType.UPDATE)
|
||||
@Operation(summary = "角色信息表-设置状态", description = "角色信息表-设置状态")
|
||||
@Operation(summary = "角色信息表-设置状态", description = "角色信息表-设置状态")
|
||||
@PutMapping("/status")
|
||||
public Result<Boolean> setStatus(@RequestBody SsoRole ssoRole) {
|
||||
if (ssoRoleService.updateById(new SsoRole().setId(ssoRole.getId()).setStatus(ssoRole.getStatus()))) {
|
||||
@@ -144,7 +146,7 @@ public class SsoRoleController {
|
||||
* @return
|
||||
*/
|
||||
@Log(title = "角色信息表-通过id删除", operateType = OperateType.DELETE)
|
||||
@Operation(summary = "角色信息表-通过id删除", description = "角色信息表-通过id删除")
|
||||
@Operation(summary = "角色信息表-通过id删除", description = "角色信息表-通过id删除")
|
||||
@DeleteMapping("/{id}")
|
||||
@RequiresPermissions("sys:role:delete")
|
||||
public Result<Boolean> delete(@Parameter(name = "id", description = "唯一性ID") @PathVariable String id) {
|
||||
@@ -160,11 +162,28 @@ public class SsoRoleController {
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "角色信息表-通过id查询", description = "角色信息表-通过id查询")
|
||||
@Operation(summary = "角色信息表-通过id查询", description = "角色信息表-通过id查询")
|
||||
@GetMapping("/{id}")
|
||||
@RequiresPermissions("sys:role:query")
|
||||
public Result<SsoRole> queryById(@Parameter(name = "id", description = "唯一性ID") @PathVariable String id) {
|
||||
SsoRole ssoRole = ssoRoleService.getById(id);
|
||||
return Result.ok(ssoRole, "角色信息表-查询成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取角色id-通过角色编码查询
|
||||
*
|
||||
* @param codes 角色编码,多个逗号分隔
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "获取角色id", description = "获取角色id-通过角色编码查询")
|
||||
@GetMapping("/ids/{codes}")
|
||||
@InnerUser
|
||||
@Parameters({
|
||||
@Parameter(name = "tenantId", description = "租户ID", required = true),
|
||||
@Parameter(name = "codes", description = "角色编码", required = true)
|
||||
})
|
||||
public Result<List<String>> getRoleIdsByCode(String tenantId, String codes) {
|
||||
return ssoRoleService.getRoleIdsByCode(tenantId, List.of(codes.split(",")));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,8 +9,8 @@ import cn.com.mfish.common.core.utils.excel.ExcelUtils;
|
||||
import cn.com.mfish.common.core.web.PageResult;
|
||||
import cn.com.mfish.common.core.web.ReqPage;
|
||||
import cn.com.mfish.common.core.web.Result;
|
||||
import cn.com.mfish.common.ds.annotation.DataScope;
|
||||
import cn.com.mfish.common.ds.common.DataScopeType;
|
||||
import cn.com.mfish.common.oauth.annotation.DataScope;
|
||||
import cn.com.mfish.common.oauth.common.DataScopeType;
|
||||
import cn.com.mfish.common.log.annotation.Log;
|
||||
import cn.com.mfish.common.oauth.annotation.RequiresPermissions;
|
||||
import cn.com.mfish.common.oauth.api.entity.SsoMenu;
|
||||
@@ -28,11 +28,11 @@ import cn.com.mfish.common.oauth.service.SsoMenuService;
|
||||
import cn.com.mfish.common.oauth.service.SsoOrgService;
|
||||
import cn.com.mfish.common.oauth.service.SsoUserService;
|
||||
import cn.com.mfish.oauth.cache.common.ClearCache;
|
||||
import cn.com.mfish.oauth.entity.SsoRole;
|
||||
import cn.com.mfish.common.oauth.entity.SsoRole;
|
||||
import cn.com.mfish.oauth.entity.UserOrg;
|
||||
import cn.com.mfish.oauth.req.ReqSsoRole;
|
||||
import cn.com.mfish.oauth.req.ReqSsoTenant;
|
||||
import cn.com.mfish.oauth.service.SsoRoleService;
|
||||
import cn.com.mfish.common.oauth.service.SsoRoleService;
|
||||
import cn.com.mfish.oauth.service.SsoTenantService;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
|
||||
@@ -92,7 +92,7 @@ public class SsoUserController {
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "获取当前用户租户列表", description = "获取当前用户租户列表")
|
||||
@Operation(summary = "获取当前用户租户列表", description = "获取当前用户租户列表")
|
||||
@GetMapping("/tenants")
|
||||
public Result<List<TenantVo>> getUserTenants(String userId) {
|
||||
if (StringUtils.isEmpty(userId)) {
|
||||
@@ -101,9 +101,8 @@ public class SsoUserController {
|
||||
return Result.ok(ssoUserService.getUserTenants(userId), "获取当前租户列表成功!");
|
||||
}
|
||||
|
||||
@Operation(summary = "获取用户组织")
|
||||
@Operation(summary = "获取用户组织树")
|
||||
@GetMapping("/orgs/{userId}")
|
||||
@Log(title = "获取用户组织", operateType = OperateType.QUERY)
|
||||
@Parameters({
|
||||
@Parameter(name = "direction", description = "方向 all 返回所有父子节点 up返回父节点 down返回子节点", required = true)
|
||||
})
|
||||
@@ -111,6 +110,16 @@ public class SsoUserController {
|
||||
return ssoUserService.getOrgs(userId, direction);
|
||||
}
|
||||
|
||||
@Operation(summary = "获取用户组织ID列表")
|
||||
@GetMapping("/orgIds/{userId}")
|
||||
@Parameters({
|
||||
@Parameter(name = "tenantId", description = "租户id"),
|
||||
@Parameter(name = "direction", description = "方向 all 返回所有父子节点 up返回父节点 down返回子节点", required = true)
|
||||
})
|
||||
public Result<List<String>> getOrgIds(@PathVariable("userId") String userId, @RequestParam String tenantId, @RequestParam String direction) {
|
||||
return ssoUserService.getOrgIds(tenantId, userId, direction);
|
||||
}
|
||||
|
||||
@Operation(summary = "通过用户ID获取用户")
|
||||
@GetMapping("/{id}")
|
||||
public Result<UserInfo> getUserById(@Parameter(name = "id", description = "用户ID") @PathVariable String id) {
|
||||
@@ -133,7 +142,7 @@ public class SsoUserController {
|
||||
}
|
||||
|
||||
@Log(title = "用户-设置状态", operateType = OperateType.UPDATE)
|
||||
@Operation(summary = "用户-设置状态", description = "用户-设置状态")
|
||||
@Operation(summary = "用户-设置状态", description = "用户-设置状态")
|
||||
@PutMapping("/status")
|
||||
@RequiresPermissions("sys:account:update")
|
||||
public Result<Boolean> setStatus(@RequestBody SsoUser ssoUser) {
|
||||
@@ -146,7 +155,7 @@ public class SsoUserController {
|
||||
return Result.fail(false, "错误:用户-设置状态失败!");
|
||||
}
|
||||
|
||||
@Operation(summary = "用户登出", description = "用户登出--该方法只适用于web前端登录的用户登出")
|
||||
@Operation(summary = "用户登出", description = "用户登出--该方法只适用于web前端登录的用户登出")
|
||||
@GetMapping("/revoke")
|
||||
@Log(title = "用户登出", operateType = OperateType.LOGOUT)
|
||||
public Result<Boolean> revoke() {
|
||||
@@ -195,7 +204,7 @@ public class SsoUserController {
|
||||
* @param reqPage
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "用户信息-分页列表查询", description = "用户信息-分页列表查询")
|
||||
@Operation(summary = "用户信息-分页列表查询", description = "用户信息-分页列表查询")
|
||||
@GetMapping
|
||||
@RequiresPermissions("sys:account:query")
|
||||
public Result<PageResult<UserInfo>> queryPageList(ReqSsoUser reqSsoUser, ReqPage reqPage) {
|
||||
@@ -204,7 +213,7 @@ public class SsoUserController {
|
||||
return Result.ok(new PageResult<>(pageList), "用户信息-查询成功!");
|
||||
}
|
||||
|
||||
@Operation(summary = "检索用户列表-限制最多查询50人(有新增租户用户权限人允许检索)", description = "检索用户列表")
|
||||
@Operation(summary = "检索用户列表-限制最多查询50人(有新增租户用户权限人允许检索)", description = "检索用户列表")
|
||||
@GetMapping("/search")
|
||||
@Parameters({
|
||||
@Parameter(name = "condition", description = "检索条件,可输入用户名、昵称、手机号")
|
||||
@@ -215,7 +224,7 @@ public class SsoUserController {
|
||||
}
|
||||
|
||||
@Log(title = "用户信息-添加", operateType = OperateType.INSERT)
|
||||
@Operation(summary = "用户信息-添加", description = "用户信息-添加")
|
||||
@Operation(summary = "用户信息-添加", description = "用户信息-添加")
|
||||
@PostMapping
|
||||
@RequiresPermissions(value = {"sys:account:insert", "sys:tenantUser:insert"})
|
||||
public Result<SsoUser> add(@RequestBody SsoUser ssoUser) {
|
||||
@@ -229,7 +238,7 @@ public class SsoUserController {
|
||||
* @return
|
||||
*/
|
||||
@Log(title = "用户信息-编辑", operateType = OperateType.UPDATE)
|
||||
@Operation(summary = "用户信息-编辑", description = "用户信息-编辑")
|
||||
@Operation(summary = "用户信息-编辑", description = "用户信息-编辑")
|
||||
@PutMapping
|
||||
@RequiresPermissions("sys:account:update")
|
||||
public Result<SsoUser> edit(@RequestBody SsoUser ssoUser) {
|
||||
@@ -237,7 +246,7 @@ public class SsoUserController {
|
||||
}
|
||||
|
||||
@Log(title = "用户信息-编辑", operateType = OperateType.UPDATE)
|
||||
@Operation(summary = "用户信息-编辑", description = "用户信息-编辑")
|
||||
@Operation(summary = "用户信息-编辑", description = "用户信息-编辑")
|
||||
@PutMapping("/me")
|
||||
public Result<SsoUser> editMe(@RequestBody SsoUser ssoUser) {
|
||||
if (!ssoUser.getId().equals(AuthInfoUtils.getCurrentUserId())) {
|
||||
@@ -253,7 +262,7 @@ public class SsoUserController {
|
||||
* @return
|
||||
*/
|
||||
@Log(title = "用户信息-通过id删除", operateType = OperateType.DELETE)
|
||||
@Operation(summary = "用户信息-通过id删除", description = "用户信息-通过id删除")
|
||||
@Operation(summary = "用户信息-通过id删除", description = "用户信息-通过id删除")
|
||||
@DeleteMapping("/{id}")
|
||||
@RequiresPermissions("sys:account:delete")
|
||||
public Result<Boolean> delete(@Parameter(name = "id", description = "唯一性ID") @PathVariable String id) {
|
||||
|
||||
@@ -46,4 +46,6 @@ public interface SsoOrgMapper extends BaseMapper<SsoOrg> {
|
||||
int isTenantOrg(@Param("orgId") String orgId, @Param("tenantId") String tenantId);
|
||||
|
||||
List<UserInfo> queryUserByCode(@Param("code") String code, @Param("reqOrgUser") ReqOrgUser reqOrgUser);
|
||||
|
||||
List<String> getOrgDownIdsByCode(@Param("orgCodes") List<String> orgCodes);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package cn.com.mfish.oauth.mapper;
|
||||
|
||||
import cn.com.mfish.oauth.entity.SsoRole;
|
||||
import cn.com.mfish.common.oauth.entity.SsoRole;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Delete;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
@@ -34,4 +34,6 @@ public interface SsoRoleMapper extends BaseMapper<SsoRole> {
|
||||
List<String> getRoleMenus(String roleId);
|
||||
|
||||
int isTenantRole(@Param("roleId") String roleId, @Param("tenantId") String tenantId);
|
||||
|
||||
List<String> getRoleIdsByCode(@Param("tenantId") String tenantId, @Param("roleCodes") List<String> roleCodes);
|
||||
}
|
||||
|
||||
@@ -142,4 +142,11 @@
|
||||
and su.phone like CONCAT('%',#{reqOrgUser.phone},'%')
|
||||
</if>
|
||||
</select>
|
||||
<select id="getOrgDownIdsByCode" resultType="java.lang.String">
|
||||
select id from sso_org where 1!=1
|
||||
<foreach collection="orgCodes" item="code">
|
||||
or org_code like CONCAT(#{code},'%')
|
||||
</foreach>
|
||||
order by org_sort
|
||||
</select>
|
||||
</mapper>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
<resultMap id="roleMap" type="cn.com.mfish.oauth.entity.SsoRole">
|
||||
<resultMap id="roleMap" type="cn.com.mfish.common.oauth.entity.SsoRole">
|
||||
<result property="menus" column="menus" typeHandler="cn.com.mfish.oauth.handler.StrToListTypeHandler"/>
|
||||
</resultMap>
|
||||
<select id="getRoleUser" resultType="string">
|
||||
@@ -31,4 +31,10 @@
|
||||
<select id="isTenantRole" resultType="java.lang.Integer">
|
||||
select count(0) from sso_role where tenant_id = #{tenantId} and id = #{roleId}
|
||||
</select>
|
||||
<select id="getRoleIdsByCode" resultType="java.lang.String">
|
||||
select id from sso_role where tenant_id=#{tenantId} and role_code in
|
||||
<foreach collection="roleCodes" item="code" separator="," open="(" close=")">
|
||||
#{code}
|
||||
</foreach>
|
||||
</select>
|
||||
</mapper>
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -190,6 +191,15 @@ public class SsoOrgServiceImpl extends ServiceImpl<SsoOrgMapper, SsoOrg> impleme
|
||||
return queryOrg(org, direction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<List<String>> queryOrgIdsById(String tenantId, List<String> ids, TreeDirection direction) {
|
||||
if (ids == null || ids.isEmpty()) {
|
||||
throw new MyRuntimeException("错误:组织id不允许为空");
|
||||
}
|
||||
List<SsoOrg> list = baseMapper.selectList(new LambdaQueryWrapper<SsoOrg>().in(SsoOrg::getId, ids));
|
||||
return getOrgIdsByOrg(tenantId, list, direction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UserRole> getOrgRoles(String... orgIds) {
|
||||
return baseMapper.getOrgRoles(orgIds);
|
||||
@@ -218,6 +228,36 @@ public class SsoOrgServiceImpl extends ServiceImpl<SsoOrgMapper, SsoOrg> impleme
|
||||
return new PageResult<>(baseMapper.queryUserByCode(code, reqOrgUser));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<List<String>> getOrgIdsByFixCode(String tenantId, List<String> orgCodes, TreeDirection direction) {
|
||||
List<SsoOrg> list = baseMapper.selectList(new LambdaQueryWrapper<SsoOrg>().in(SsoOrg::getOrgFixCode, orgCodes));
|
||||
return getOrgIdsByOrg(tenantId, list, direction);
|
||||
}
|
||||
|
||||
private Result<List<String>> getOrgIdsByOrg(String tenantId, List<SsoOrg> list, TreeDirection direction) {
|
||||
//todo tenantId暂时未用到,后续完善
|
||||
switch (direction) {
|
||||
case 向下:
|
||||
return Result.ok(baseMapper.getOrgDownIdsByCode(list.stream().map(SsoOrg::getOrgCode).toList()), "查询下级组织ID成功");
|
||||
case 向上:
|
||||
List<String> listCode = new ArrayList<>();
|
||||
for (SsoOrg org : list) {
|
||||
listCode.addAll(getUpOrgCodes(org.getOrgCode(), org.getOrgLevel()));
|
||||
}
|
||||
return Result.ok(baseMapper.selectList(new LambdaQueryWrapper<SsoOrg>().in(SsoOrg::getOrgCode, listCode)).stream().map(SsoOrg::getId).toList(), "查询上级组织ID成功");
|
||||
default:
|
||||
List<String> ids = baseMapper.getOrgDownIdsByCode(list.stream().map(SsoOrg::getOrgCode).toList());
|
||||
List<String> codes = new ArrayList<>();
|
||||
for (SsoOrg org : list) {
|
||||
codes.addAll(getUpOrgCodes(org.getOrgCode(), org.getOrgLevel() - 1));
|
||||
}
|
||||
if (!codes.isEmpty()) {
|
||||
ids.addAll(baseMapper.selectList(new LambdaQueryWrapper<SsoOrg>().in(SsoOrg::getOrgCode, codes)).stream().map(SsoOrg::getId).toList());
|
||||
}
|
||||
return Result.ok(ids, "查询所有组织ID成功");
|
||||
}
|
||||
}
|
||||
|
||||
List<SsoOrg> queryOrg(SsoOrg org, TreeDirection direction) {
|
||||
if (org == null) {
|
||||
return new ArrayList<>();
|
||||
@@ -262,6 +302,21 @@ public class SsoOrgServiceImpl extends ServiceImpl<SsoOrgMapper, SsoOrg> impleme
|
||||
* @return
|
||||
*/
|
||||
private List<SsoOrg> upOrg(String code, int level) {
|
||||
List<String> orgList = getUpOrgCodes(code, level);
|
||||
if (orgList.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return baseMapper.selectList(new LambdaQueryWrapper<SsoOrg>().in(SsoOrg::getOrgCode, orgList));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有上级编码
|
||||
*
|
||||
* @param code
|
||||
* @param level
|
||||
* @return
|
||||
*/
|
||||
private List<String> getUpOrgCodes(String code, int level) {
|
||||
List<String> orgList = new ArrayList<>();
|
||||
if (level < 1) {
|
||||
return new ArrayList<>();
|
||||
@@ -269,6 +324,7 @@ public class SsoOrgServiceImpl extends ServiceImpl<SsoOrgMapper, SsoOrg> impleme
|
||||
for (int i = 1; i <= level; i++) {
|
||||
orgList.add(code.substring(0, i * 5));
|
||||
}
|
||||
return baseMapper.selectList(new LambdaQueryWrapper<SsoOrg>().in(SsoOrg::getOrgCode, orgList));
|
||||
return orgList;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,16 +3,16 @@ package cn.com.mfish.oauth.service.impl;
|
||||
import cn.com.mfish.common.core.exception.MyRuntimeException;
|
||||
import cn.com.mfish.common.core.utils.StringUtils;
|
||||
import cn.com.mfish.common.core.web.Result;
|
||||
import cn.com.mfish.common.oauth.entity.SsoRole;
|
||||
import cn.com.mfish.common.oauth.service.SsoRoleService;
|
||||
import cn.com.mfish.oauth.cache.common.ClearCache;
|
||||
import cn.com.mfish.oauth.entity.SsoRole;
|
||||
import cn.com.mfish.oauth.mapper.SsoRoleMapper;
|
||||
import cn.com.mfish.oauth.service.SsoRoleService;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
@@ -123,4 +123,9 @@ public class SsoRoleServiceImpl extends ServiceImpl<SsoRoleMapper, SsoRole> impl
|
||||
}
|
||||
return baseMapper.isTenantRole(roleId, tenantId) > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<List<String>> getRoleIdsByCode(String tenantId, List<String> roleCodes) {
|
||||
return Result.ok(baseMapper.getRoleIdsByCode(tenantId, roleCodes), "通过角色编码获取角色ID成功");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -327,6 +327,18 @@ public class SsoUserServiceImpl extends ServiceImpl<SsoUserMapper, SsoUser> impl
|
||||
return Result.ok(list, "组织结构-查询成功!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<List<String>> getOrgIds(String tenantId, String userId, String direction) {
|
||||
if (StringUtils.isEmpty(tenantId)) {
|
||||
userId = AuthInfoUtils.getCurrentTenantId();
|
||||
}
|
||||
if (StringUtils.isEmpty(userId)) {
|
||||
userId = AuthInfoUtils.getCurrentUserId();
|
||||
}
|
||||
SsoUser user = getUserById(userId);
|
||||
return ssoOrgService.queryOrgIdsById(tenantId, user.getOrgIds(), TreeDirection.getDirection(direction));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAccountExist(String account, String userId) {
|
||||
return baseMapper.isAccountExist(account, userId) > 0;
|
||||
@@ -334,7 +346,7 @@ public class SsoUserServiceImpl extends ServiceImpl<SsoUserMapper, SsoUser> impl
|
||||
|
||||
@Override
|
||||
public int insertUserRole(String userId, List<String> roles) {
|
||||
if (roles == null || roles.size() == 0) {
|
||||
if (roles == null || roles.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
int count = baseMapper.insertUserRole(userId, roles);
|
||||
|
||||
@@ -149,7 +149,7 @@ org:
|
||||
instanceId: AUTO
|
||||
threadPool:
|
||||
poolClass: org.quartz.simpl.SimpleThreadPool
|
||||
threadCount: 50
|
||||
threadCount: 10
|
||||
threadPriority: 5
|
||||
jobStore:
|
||||
jdbcClass: org.quartz.impl.jdbcjobstore.JobStoreTX
|
||||
|
||||
Reference in New Issue
Block a user