旧的 {@link MultiDataPermissionHandler#getSqlSegment(Expression, String)} 方法第一个参数包含所有的 where 条件信息,如果 return 了 null 会覆盖原有的 where 数据,
+ *新版的 {@link MultiDataPermissionHandler#getSqlSegment(Table, Expression, String)} 方法不能覆盖原有的 where 数据,如果 return 了 null 则表示不追加任何 where 条件
+ * + * @param table 所执行的数据库表信息,可以通过此参数获取表名和表别名 + * @param where 原有的 where 条件信息 + * @param mappedStatementId Mybatis MappedStatement Id 根据该参数可以判断具体执行方法 + * @return JSqlParser 条件表达式,返回的条件表达式会拼接在原有的表达式后面(不会覆盖原有的表达式) + */ + + @Override + public Expression getSqlSegment(Table table, Expression where, String mappedStatementId) { + try { + if(table != null && CollectionUtils.isNotEmpty(table.getNameParts()) && !"1".equals(RedisResourceUtils.getRoleType())){ + String roleCode = RedisResourceUtils.getRoleCode(); + Class> mapperClazz = Class.forName(mappedStatementId.substring(0, mappedStatementId.lastIndexOf("."))); + //优先检查是不是单角色权限 + DataScope dataScope = mapperClazz.getAnnotation(DataScope.class); + if (ObjectUtils.isNotEmpty(dataScope) && dataScope.enabled()) { + if(dataScope.permissionObject().equals(roleCode)){ + return buildDataScopeByAnnotation(dataScope); + } + } + //如果不是, 检查多角色权限 + DataScopes dataScopesList = mapperClazz.getAnnotation(DataScopes.class); + if (ObjectUtils.isNotEmpty(dataScopesList)) { + for (DataScope dataScopes :dataScopesList.value()){ + if(dataScopes.enabled()){ + if(dataScopes.permissionObject().equals(roleCode)){ + return buildDataScopeByAnnotation(dataScopes); + } + } + } + } + } + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + return null; + } + + + + /** + * DataScope注解方式,拼装数据权限 + * + * @param dataScope + * @return + */ + private Expression buildDataScopeByAnnotation(DataScope dataScope) { + Expression expression = buildDataScopeExpression(dataScope, RedisResourceUtils.getPermissionValue(dataScope.permissionScopeRedisKey())); + return expression == null ? null : new Parenthesis(expression); + } + + + private Expression buildDataScopeExpression(DataScope dataScope, String value) { + if(!"null".equals(value)){ + ExpressionList expressionList = new ExpressionList(Arrays.asList(value.split(",")).stream().map(StringValue::new).collect(Collectors.toList())); + // 设置左边的字段表达式,右边设置值。 + InExpression operatorInExpression = new InExpression(); + operatorInExpression.setLeftExpression(buildColumn(dataScope.tableAlias(), dataScope.permissionScopeName())); + operatorInExpression.setRightExpression(new Parenthesis(expressionList)); + return operatorInExpression; + + } + return null; + } + + /** + * 构建Column + * + * @param tableAlias 表别名 + * @param columnName 字段名称 + * @return 带表别名字段 + */ + private static Column buildColumn(String tableAlias, String columnName) { + if (StringUtils.isNotEmpty(tableAlias)) { + columnName = tableAlias + "." + columnName; + } + return new Column(columnName); + } + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/utils/RedisResourceUtils.java b/resource-server/src/main/java/com/evotech/hd/resource/utils/RedisResourceUtils.java new file mode 100644 index 0000000..7960a80 --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/utils/RedisResourceUtils.java @@ -0,0 +1,179 @@ +package com.evotech.hd.resource.utils; + +import com.evotech.hd.common.core.constant.HDConstant; +import com.evotech.hd.common.core.entity.resource.auth.AuthUser; +import com.evotech.hd.common.redis.utils.RedisUtil; +import com.evotech.hd.common.web.util.RequestContextUtil; +import com.evotech.hd.common.web.util.SpringUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.util.ObjectUtils; +import org.springframework.util.StringUtils; + +/** + * @desc: + * @ClassName:RedisCloudUtils + * @date: 2025年04月14日 15:24 + * @author: andy.shi + * @contact: 17330188597 + * @remark: 开发人员联系方式 1042025947@qq.com/微信同步 + */ + +@Slf4j +public class RedisResourceUtils { + + public static AuthUser getUser(){ + AuthUser user = (AuthUser)getRedisObjectValue("user"); + return (ObjectUtils.isEmpty(user) ? null : user); + } + + public static String getRoleCode(){ + String roles = getRedisStringValue("rcodes"); + return StringUtils.isEmpty(roles) ? "" : roles; + } + + public static String getPermissionValue(String key){ + return getStringValue(HDConstant.LOGIN_CACHE_KEY_PREFIX + key+":"+getUserPkId()); + } + + public static String getStationCode(){ + return getStringValue(HDConstant.LOGIN_CACHE_KEY_PREFIX + HDConstant.PermissionConstant.PERMISSION_STATION_CODE+":"+getUserPkId()); + } + public static String getStationId(){ + return getStringValue(HDConstant.LOGIN_CACHE_KEY_PREFIX + HDConstant.PermissionConstant.PERMISSION_STATION_ID+":"+getUserPkId()); + } + + public static String getCompanyCode(){ + return getStringValue(HDConstant.LOGIN_CACHE_KEY_PREFIX + HDConstant.PermissionConstant.PERMISSION_COMPANY_CODE+":"+getUserPkId()); + } + public static String getCompanyId(){ + return getStringValue(HDConstant.LOGIN_CACHE_KEY_PREFIX + HDConstant.PermissionConstant.PERMISSION_COMPANY_ID+":"+getUserPkId()); + } + + public static String getCarCode(){ + return getStringValue(HDConstant.LOGIN_CACHE_KEY_PREFIX + HDConstant.PermissionConstant.PERMISSION_CAR_CODE+":"+getUserPkId()); + } + public static String getCarId(){ + return getStringValue(HDConstant.LOGIN_CACHE_KEY_PREFIX + HDConstant.PermissionConstant.PERMISSION_CAR_ID+":"+getUserPkId()); + } + + private static Integer getUserPkId(){ + AuthUser user = getUser(); + if(org.apache.commons.lang3.ObjectUtils.isEmpty(user) || user.getPkId() == null){ + return null; + } + return user.getPkId(); + } + + +// public static Integer getCompanyScopeId(){ +// return getUser().getPkId(); +// } + + + /** + * 获取当前登录的角色信息, 0 站端, 1 管理员, 2 运营商, 3 公司, + * @author: andy.shi + * @contact: 17330188597 + * @date: 2025/4/14/周一 14:21 + * @return: * @return: java.lang.String + */ + public static String getRoleType(){ + String roles = getRoleCode(); + if(isAdmin(roles)){ + return "1"; + } + if(isOperator(roles)){ + return "2"; + } + if(isCompany(roles)){ + return "3"; + } + return "0"; + } + + //如果不等于-1 则证明为管理员 + public static Boolean isAdmin(String roles){ + return isAuthority(roles, HDConstant.SYSTEM_MANAGER_ROLE_CODE); + } + + public static Boolean isOperator(String roles){ + return isAuthority(roles,HDConstant.OPERATOR_ROLE_CODE); + } + + public static Boolean isCompany(String roles){ + return isAuthority(roles,HDConstant.COMPANY_ROLE_CODE); + } + + private static Boolean isAuthority(String checkParamRoles, String paramRoleCode){ + if(org.apache.commons.lang3.StringUtils.isNotEmpty(checkParamRoles)){ + return checkParamRoles.lastIndexOf(paramRoleCode) != -1; + } + return getRoleCode().lastIndexOf(paramRoleCode) != -1; + } + + + /*** + * 根据token拼接key, 获取String结果 + * @param key + * @return + */ + private static String getRedisStringValue(String key) { + return String.valueOf(getRedisObjectValue(key)); + } + + /*** + * 根据token拼接key, 获取Object结果 + * @param key + * @return + */ + private static Object getRedisObjectValue(String key) { + String token = RequestContextUtil.getToken(); + if(StringUtils.isEmpty(token)){ + log.error("SpringUtil.getRedisValue========== token is null"); + return null; + } + String jti = null; + try { + jti = TokenUtil.getJti(token); + if(StringUtils.isEmpty(jti)){ + log.error("SpringUtil.getRedisValue========== jtj is null"); + return null; + } + } catch (Exception e) { + log.error("SpringUtil.gegetRedisValuetUser========== jtj is null"); + return null; + } + return getValue(HDConstant.LOGIN_CACHE_KEY_PREFIX + jti + ":"+key); + } + + + /*** + * 根据key获取redis缓存 + * @param key + * @return + */ + private static String getStringValue(String key){ + Object obj = getValue(key); + return ObjectUtils.isEmpty(obj) ? null : String.valueOf(obj); + } + + /*** + * 根据key获取redis缓存 + * @param key + * @return + */ + private static Object getValue(String key){ + RedisUtil redisUtil = SpringUtil.getBean(RedisUtil.class); + if(ObjectUtils.isEmpty(redisUtil)){ + log.error("SpringUtil.getRedisValue========== redisUtil is null"); + } + Object obj = redisUtil.get(key); + if(ObjectUtils.isEmpty(obj)){ + log.error("SpringUtil.getRedisValue=={}========== obj is null",key); + return null; + } + log.info("SpringUtil.getRedisValue=={}===={}",key,String.valueOf(obj)); + return obj; + } + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/utils/TokenUtil.java b/resource-server/src/main/java/com/evotech/hd/resource/utils/TokenUtil.java new file mode 100644 index 0000000..5f1e8a9 --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/utils/TokenUtil.java @@ -0,0 +1,56 @@ +package com.evotech.hd.resource.utils; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.jwt.JWT; +import cn.hutool.jwt.JWTUtil; +import org.springframework.security.oauth2.jwt.JwtClaimNames; + +import java.util.Date; + +/** + * token解析工具类 + */ +public class TokenUtil { + + + public static JWT parseToJwt(String token) { + JWT parseToken = JWTUtil.parseToken(token); + return parseToken; + } + + + /** + * 从token中获取userId + */ + public static String getUserId(String token) { + String uid = parseToJwt(token).getPayloads().getStr("uid"); + return uid; + } + + /** + * 从token中获取rcodes + */ + public static String getRcodes(String token) { + String uid = parseToJwt(token).getPayloads().getStr("rcodes"); + return uid; + } + + + /** + * 从token中获取jti + */ + public static String getJti(String token) { + String jti = parseToJwt(token).getPayloads().getStr(JwtClaimNames.JTI).replaceAll("-", ""); + return jti; + } + + + /** + * 从token中获取过期时间 + */ + public static Date getExp(String token) { + String exp = parseToJwt(token).getPayloads().getStr(JwtClaimNames.EXP).toString(); + return DateUtil.date(Long.valueOf(exp) * 1000); + } + +} diff --git a/wechat-server/pom.xml b/wechat-server/pom.xml index ef476e8..2f72c85 100644 --- a/wechat-server/pom.xml +++ b/wechat-server/pom.xml @@ -80,8 +80,16 @@旧的 {@link MultiDataPermissionHandler#getSqlSegment(Expression, String)} 方法第一个参数包含所有的 where 条件信息,如果 return 了 null 会覆盖原有的 where 数据,
+ *新版的 {@link MultiDataPermissionHandler#getSqlSegment(Table, Expression, String)} 方法不能覆盖原有的 where 数据,如果 return 了 null 则表示不追加任何 where 条件
+ * + * @param table 所执行的数据库表信息,可以通过此参数获取表名和表别名 + * @param where 原有的 where 条件信息 + * @param mappedStatementId Mybatis MappedStatement Id 根据该参数可以判断具体执行方法 + * @return JSqlParser 条件表达式,返回的条件表达式会拼接在原有的表达式后面(不会覆盖原有的表达式) + */ + + @Override + public Expression getSqlSegment(Table table, Expression where, String mappedStatementId) { + try { + if(table != null && CollectionUtils.isNotEmpty(table.getNameParts()) && !"1".equals(RedisWechatUtils.getRoleType())){ + String roleCode = RedisWechatUtils.getRoleCode(); + Class> mapperClazz = Class.forName(mappedStatementId.substring(0, mappedStatementId.lastIndexOf("."))); + //优先检查是不是单角色权限 + DataScope dataScope = mapperClazz.getAnnotation(DataScope.class); + if (ObjectUtils.isNotEmpty(dataScope) && dataScope.enabled()) { + if(dataScope.permissionObject().equals(roleCode)){ + return buildDataScopeByAnnotation(dataScope); + } + } + //如果不是, 检查多角色权限 + DataScopes dataScopesList = mapperClazz.getAnnotation(DataScopes.class); + if (ObjectUtils.isNotEmpty(dataScopesList)) { + for (DataScope dataScopes :dataScopesList.value()){ + if(dataScopes.enabled()){ + if(dataScopes.permissionObject().equals(roleCode)){ + return buildDataScopeByAnnotation(dataScopes); + } + } + } + } + } + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + return null; + } + + + + /** + * DataScope注解方式,拼装数据权限 + * + * @param dataScope + * @return + */ + private Expression buildDataScopeByAnnotation(DataScope dataScope) { + Expression expression = buildDataScopeExpression(dataScope, RedisWechatUtils.getPermissionValue(dataScope.permissionScopeRedisKey())); + return expression == null ? null : new Parenthesis(expression); + } + + + private Expression buildDataScopeExpression(DataScope dataScope, String value) { + if(!"null".equals(value)){ + ExpressionList expressionList = new ExpressionList(Arrays.asList(value.split(",")).stream().map(StringValue::new).collect(Collectors.toList())); + // 设置左边的字段表达式,右边设置值。 + InExpression operatorInExpression = new InExpression(); + operatorInExpression.setLeftExpression(buildColumn(dataScope.tableAlias(), dataScope.permissionScopeName())); + operatorInExpression.setRightExpression(new Parenthesis(expressionList)); + return operatorInExpression; + + } + return null; + } + + /** + * 构建Column + * + * @param tableAlias 表别名 + * @param columnName 字段名称 + * @return 带表别名字段 + */ + private static Column buildColumn(String tableAlias, String columnName) { + if (StringUtils.isNotEmpty(tableAlias)) { + columnName = tableAlias + "." + columnName; + } + return new Column(columnName); + } + +} diff --git a/wechat-server/src/main/java/com/evotech/hd/wechat/utils/permission/RedisWechatUtils.java b/wechat-server/src/main/java/com/evotech/hd/wechat/utils/permission/RedisWechatUtils.java new file mode 100644 index 0000000..2b477f0 --- /dev/null +++ b/wechat-server/src/main/java/com/evotech/hd/wechat/utils/permission/RedisWechatUtils.java @@ -0,0 +1,179 @@ +package com.evotech.hd.wechat.utils.permission; + +import com.evotech.hd.common.core.constant.HDConstant; +import com.evotech.hd.common.core.entity.resource.auth.AuthUser; +import com.evotech.hd.common.redis.utils.RedisUtil; +import com.evotech.hd.common.web.util.RequestContextUtil; +import com.evotech.hd.common.web.util.SpringUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.util.ObjectUtils; +import org.springframework.util.StringUtils; + +/** + * @desc: + * @ClassName:RedisCloudUtils + * @date: 2025年04月14日 15:24 + * @author: andy.shi + * @contact: 17330188597 + * @remark: 开发人员联系方式 1042025947@qq.com/微信同步 + */ + +@Slf4j +public class RedisWechatUtils { + + public static AuthUser getUser(){ + AuthUser user = (AuthUser)getRedisObjectValue("user"); + return (ObjectUtils.isEmpty(user) ? null : user); + } + + public static String getRoleCode(){ + String roles = getRedisStringValue("rcodes"); + return StringUtils.isEmpty(roles) ? "" : roles; + } + + public static String getPermissionValue(String key){ + return getStringValue(HDConstant.LOGIN_CACHE_KEY_PREFIX + key+":"+getUserPkId()); + } + + public static String getStationCode(){ + return getStringValue(HDConstant.LOGIN_CACHE_KEY_PREFIX + HDConstant.PermissionConstant.PERMISSION_STATION_CODE+":"+getUserPkId()); + } + public static String getStationId(){ + return getStringValue(HDConstant.LOGIN_CACHE_KEY_PREFIX + HDConstant.PermissionConstant.PERMISSION_STATION_ID+":"+getUserPkId()); + } + + public static String getCompanyCode(){ + return getStringValue(HDConstant.LOGIN_CACHE_KEY_PREFIX + HDConstant.PermissionConstant.PERMISSION_COMPANY_CODE+":"+getUserPkId()); + } + public static String getCompanyId(){ + return getStringValue(HDConstant.LOGIN_CACHE_KEY_PREFIX + HDConstant.PermissionConstant.PERMISSION_COMPANY_ID+":"+getUserPkId()); + } + + public static String getCarCode(){ + return getStringValue(HDConstant.LOGIN_CACHE_KEY_PREFIX + HDConstant.PermissionConstant.PERMISSION_CAR_CODE+":"+getUserPkId()); + } + public static String getCarId(){ + return getStringValue(HDConstant.LOGIN_CACHE_KEY_PREFIX + HDConstant.PermissionConstant.PERMISSION_CAR_ID+":"+getUserPkId()); + } + + private static Integer getUserPkId(){ + AuthUser user = getUser(); + if(org.apache.commons.lang3.ObjectUtils.isEmpty(user) || user.getPkId() == null){ + return null; + } + return user.getPkId(); + } + + +// public static Integer getCompanyScopeId(){ +// return getUser().getPkId(); +// } + + + /** + * 获取当前登录的角色信息, 0 站端, 1 管理员, 2 运营商, 3 公司, + * @author: andy.shi + * @contact: 17330188597 + * @date: 2025/4/14/周一 14:21 + * @return: * @return: java.lang.String + */ + public static String getRoleType(){ + String roles = getRoleCode(); + if(isAdmin(roles)){ + return "1"; + } + if(isOperator(roles)){ + return "2"; + } + if(isCompany(roles)){ + return "3"; + } + return "0"; + } + + //如果不等于-1 则证明为管理员 + public static Boolean isAdmin(String roles){ + return isAuthority(roles, HDConstant.SYSTEM_MANAGER_ROLE_CODE); + } + + public static Boolean isOperator(String roles){ + return isAuthority(roles,HDConstant.OPERATOR_ROLE_CODE); + } + + public static Boolean isCompany(String roles){ + return isAuthority(roles,HDConstant.COMPANY_ROLE_CODE); + } + + private static Boolean isAuthority(String checkParamRoles, String paramRoleCode){ + if(org.apache.commons.lang3.StringUtils.isNotEmpty(checkParamRoles)){ + return checkParamRoles.lastIndexOf(paramRoleCode) != -1; + } + return getRoleCode().lastIndexOf(paramRoleCode) != -1; + } + + + /*** + * 根据token拼接key, 获取String结果 + * @param key + * @return + */ + private static String getRedisStringValue(String key) { + return String.valueOf(getRedisObjectValue(key)); + } + + /*** + * 根据token拼接key, 获取Object结果 + * @param key + * @return + */ + private static Object getRedisObjectValue(String key) { + String token = RequestContextUtil.getToken(); + if(StringUtils.isEmpty(token)){ + log.error("SpringUtil.getRedisValue========== token is null"); + return null; + } + String jti = null; + try { + jti = TokenUtil.getJti(token); + if(StringUtils.isEmpty(jti)){ + log.error("SpringUtil.getRedisValue========== jtj is null"); + return null; + } + } catch (Exception e) { + log.error("SpringUtil.gegetRedisValuetUser========== jtj is null"); + return null; + } + return getValue(HDConstant.LOGIN_CACHE_KEY_PREFIX + jti + ":"+key); + } + + + /*** + * 根据key获取redis缓存 + * @param key + * @return + */ + private static String getStringValue(String key){ + Object obj = getValue(key); + return ObjectUtils.isEmpty(obj) ? null : String.valueOf(obj); + } + + /*** + * 根据key获取redis缓存 + * @param key + * @return + */ + private static Object getValue(String key){ + RedisUtil redisUtil = SpringUtil.getBean(RedisUtil.class); + if(ObjectUtils.isEmpty(redisUtil)){ + log.error("SpringUtil.getRedisValue========== redisUtil is null"); + } + Object obj = redisUtil.get(key); + if(ObjectUtils.isEmpty(obj)){ + log.error("SpringUtil.getRedisValue=={}========== obj is null",key); + return null; + } + log.info("SpringUtil.getRedisValue=={}===={}",key,String.valueOf(obj)); + return obj; + } + +} diff --git a/wechat-server/src/main/java/com/evotech/hd/wechat/utils/permission/TokenUtil.java b/wechat-server/src/main/java/com/evotech/hd/wechat/utils/permission/TokenUtil.java new file mode 100644 index 0000000..f85fa52 --- /dev/null +++ b/wechat-server/src/main/java/com/evotech/hd/wechat/utils/permission/TokenUtil.java @@ -0,0 +1,56 @@ +package com.evotech.hd.wechat.utils.permission; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.jwt.JWT; +import cn.hutool.jwt.JWTUtil; +import org.springframework.security.oauth2.jwt.JwtClaimNames; + +import java.util.Date; + +/** + * token解析工具类 + */ +public class TokenUtil { + + + public static JWT parseToJwt(String token) { + JWT parseToken = JWTUtil.parseToken(token); + return parseToken; + } + + + /** + * 从token中获取userId + */ + public static String getUserId(String token) { + String uid = parseToJwt(token).getPayloads().getStr("uid"); + return uid; + } + + /** + * 从token中获取rcodes + */ + public static String getRcodes(String token) { + String uid = parseToJwt(token).getPayloads().getStr("rcodes"); + return uid; + } + + + /** + * 从token中获取jti + */ + public static String getJti(String token) { + String jti = parseToJwt(token).getPayloads().getStr(JwtClaimNames.JTI).replaceAll("-", ""); + return jti; + } + + + /** + * 从token中获取过期时间 + */ + public static Date getExp(String token) { + String exp = parseToJwt(token).getPayloads().getStr(JwtClaimNames.EXP).toString(); + return DateUtil.date(Long.valueOf(exp) * 1000); + } + +}