😴发布 4.8.2 正式进入维护状态

This commit is contained in:
疯狂的狮子Li
2023-11-27 13:23:41 +08:00
parent a6f62ca86f
commit 267ff79b0c
53 changed files with 398 additions and 288 deletions

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>ruoyi-vue-plus</artifactId>
<groupId>com.ruoyi</groupId>
<version>4.8.1</version>
<version>4.8.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
@@ -110,12 +110,6 @@
<artifactId>easyexcel</artifactId>
</dependency>
<!-- yml解析器 -->
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
</dependency>
<!-- servlet包 -->
<dependency>
<groupId>javax.servlet</groupId>

View File

@@ -29,17 +29,17 @@ public enum DataScopeType {
/**
* 自定数据权限
*/
CUSTOM("2", " #{#deptName} IN ( #{@sdss.getRoleCustom( #user.roleId )} ) ", ""),
CUSTOM("2", " #{#deptName} IN ( #{@sdss.getRoleCustom( #user.roleId )} ) ", " 1 = 0 "),
/**
* 部门数据权限
*/
DEPT("3", " #{#deptName} = #{#user.deptId} ", ""),
DEPT("3", " #{#deptName} = #{#user.deptId} ", " 1 = 0 "),
/**
* 部门及以下数据权限
*/
DEPT_AND_CHILD("4", " #{#deptName} IN ( #{@sdss.getDeptAndChild( #user.deptId )} )", ""),
DEPT_AND_CHILD("4", " #{#deptName} IN ( #{@sdss.getDeptAndChild( #user.deptId )} )", " 1 = 0 "),
/**
* 仅本人数据权限

View File

@@ -24,7 +24,7 @@ public class AddressUtils {
return UNKNOWN;
}
// 内网不查询
ip = "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : HtmlUtil.cleanHtmlTag(ip);
ip = StringUtils.contains(ip, "0:0:0:0:0:0:0:1") ? "127.0.0.1" : HtmlUtil.cleanHtmlTag(ip);
if (NetUtil.isInnerIP(ip)) {
return "内网IP";
}

View File

@@ -224,8 +224,12 @@ public class QueueUtils {
/**
* 订阅阻塞队列(可订阅所有实现类 例如: 延迟 优先 有界 等)
*/
public static <T> void subscribeBlockingQueue(String queueName, Consumer<T> consumer) {
public static <T> void subscribeBlockingQueue(String queueName, Consumer<T> consumer, boolean isDelayed) {
RBlockingQueue<T> queue = CLIENT.getBlockingQueue(queueName);
if (isDelayed) {
// 订阅延迟队列
CLIENT.getDelayedQueue(queue);
}
queue.subscribeOnElements(consumer);
}

View File

@@ -40,7 +40,7 @@ public class DelayedQueueController {
QueueUtils.subscribeBlockingQueue(queueName, (String orderNum) -> {
// 观察接收时间
log.info("通道: {}, 收到数据: {}", queueName, orderNum);
});
}, true);
return R.ok("操作成功");
}

View File

@@ -1,9 +1,12 @@
package com.ruoyi.framework.interceptor;
import cn.hutool.core.collection.ConcurrentHashSet;
import cn.hutool.core.util.ArrayUtil;
import com.baomidou.mybatisplus.core.plugins.InterceptorIgnoreHelper;
import com.baomidou.mybatisplus.core.toolkit.PluginUtils;
import com.baomidou.mybatisplus.extension.parser.JsqlParserSupport;
import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
import com.ruoyi.common.annotation.DataColumn;
import com.ruoyi.framework.handler.PlusDataPermissionHandler;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.statement.delete.Delete;
@@ -23,6 +26,7 @@ import org.apache.ibatis.session.RowBounds;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import java.util.Set;
/**
* 数据权限拦截器
@@ -33,6 +37,11 @@ import java.util.List;
public class PlusDataPermissionInterceptor extends JsqlParserSupport implements InnerInterceptor {
private final PlusDataPermissionHandler dataPermissionHandler = new PlusDataPermissionHandler();
/**
* 无效注解方法缓存用于快速返回
*/
private final Set<String> invalidCacheSet = new ConcurrentHashSet<>();
@Override
public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
@@ -41,7 +50,12 @@ public class PlusDataPermissionInterceptor extends JsqlParserSupport implements
return;
}
// 检查是否无效 无数据权限注解
if (dataPermissionHandler.isInvalid(ms.getId())) {
if (invalidCacheSet.contains(ms.getId())) {
return;
}
DataColumn[] dataColumns = dataPermissionHandler.findAnnotation(ms.getId());
if (ArrayUtil.isEmpty(dataColumns)) {
invalidCacheSet.add(ms.getId());
return;
}
// 解析 sql 分配对应方法
@@ -58,6 +72,15 @@ public class PlusDataPermissionInterceptor extends JsqlParserSupport implements
if (InterceptorIgnoreHelper.willIgnoreDataPermission(ms.getId())) {
return;
}
// 检查是否无效 无数据权限注解
if (invalidCacheSet.contains(ms.getId())) {
return;
}
DataColumn[] dataColumns = dataPermissionHandler.findAnnotation(ms.getId());
if (ArrayUtil.isEmpty(dataColumns)) {
invalidCacheSet.add(ms.getId());
return;
}
PluginUtils.MPBoundSql mpBs = mpSh.mPBoundSql();
mpBs.sql(parserMulti(mpBs.sql(), ms.getId()));
}

View File

@@ -44,14 +44,14 @@ public class PlusWebInvokeTimeInterceptor implements HandlerInterceptor {
BufferedReader reader = request.getReader();
jsonParam = IoUtil.read(reader);
}
log.debug("[PLUS]开始请求 => URL[{}],参数类型[json],参数:[{}]", url, jsonParam);
log.info("[PLUS]开始请求 => URL[{}],参数类型[json],参数:[{}]", url, jsonParam);
} else {
Map<String, String[]> parameterMap = request.getParameterMap();
if (MapUtil.isNotEmpty(parameterMap)) {
String parameters = JsonUtils.toJsonString(parameterMap);
log.debug("[PLUS]开始请求 => URL[{}],参数类型[param],参数:[{}]", url, parameters);
log.info("[PLUS]开始请求 => URL[{}],参数类型[param],参数:[{}]", url, parameters);
} else {
log.debug("[PLUS]开始请求 => URL[{}],无参数", url);
log.info("[PLUS]开始请求 => URL[{}],无参数", url);
}
}
@@ -72,7 +72,7 @@ public class PlusWebInvokeTimeInterceptor implements HandlerInterceptor {
if (!prodProfile.equals(SpringUtils.getActiveProfile())) {
StopWatch stopWatch = invokeTimeTL.get();
stopWatch.stop();
log.debug("[PLUS]结束请求 => URL[{}],耗时:[{}]毫秒", request.getMethod() + " " + request.getRequestURI(), stopWatch.getTime());
log.info("[PLUS]结束请求 => URL[{}],耗时:[{}]毫秒", request.getMethod() + " " + request.getRequestURI(), stopWatch.getTime());
invokeTimeTL.remove();
}
}

View File

@@ -6,6 +6,7 @@ import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.domain.event.OperLogEvent;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.enums.BusinessStatus;
import com.ruoyi.common.enums.HttpMethod;
import com.ruoyi.common.helper.LoginHelper;
@@ -74,7 +75,9 @@ public class LogAspect {
String ip = ServletUtils.getClientIP();
operLog.setOperIp(ip);
operLog.setOperUrl(StringUtils.substring(ServletUtils.getRequest().getRequestURI(), 0, 255));
operLog.setOperName(LoginHelper.getUsername());
LoginUser loginUser = LoginHelper.getLoginUser();
operLog.setOperName(loginUser.getUsername());
operLog.setDeptName(loginUser.getDeptName());
if (e != null) {
operLog.setStatus(BusinessStatus.FAIL.ordinal());

View File

@@ -50,8 +50,8 @@ public class SaTokenConfig implements WebMvcConfigurer {
// 有效率影响 用于临时测试
// if (log.isDebugEnabled()) {
// log.debug("剩余有效时间: {}", StpUtil.getTokenTimeout());
// log.debug("临时有效时间: {}", StpUtil.getTokenActiveTimeout());
// log.info("剩余有效时间: {}", StpUtil.getTokenTimeout());
// log.info("临时有效时间: {}", StpUtil.getTokenActiveTimeout());
// }
});

View File

@@ -2,8 +2,6 @@ package com.ruoyi.framework.handler;
import cn.hutool.core.annotation.AnnotationUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ConcurrentHashSet;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.ObjectUtil;
import com.ruoyi.common.annotation.DataColumn;
@@ -51,11 +49,6 @@ public class PlusDataPermissionHandler {
*/
private final Map<String, DataPermission> dataPermissionCacheMap = new ConcurrentHashMap<>();
/**
* 无效注解方法缓存用于快速返回
*/
private final Set<String> invalidCacheSet = new ConcurrentHashSet<>();
/**
* spel 解析器
*/
@@ -69,10 +62,6 @@ public class PlusDataPermissionHandler {
public Expression getSqlSegment(Expression where, String mappedStatementId, boolean isSelect) {
DataColumn[] dataColumns = findAnnotation(mappedStatementId);
if (ArrayUtil.isEmpty(dataColumns)) {
invalidCacheSet.add(mappedStatementId);
return where;
}
LoginUser currentUser = DataPermissionHelper.getVariable("user");
if (ObjectUtil.isNull(currentUser)) {
currentUser = LoginHelper.getLoginUser();
@@ -156,7 +145,7 @@ public class PlusDataPermissionHandler {
return "";
}
private DataColumn[] findAnnotation(String mappedStatementId) {
public DataColumn[] findAnnotation(String mappedStatementId) {
StringBuilder sb = new StringBuilder(mappedStatementId);
int index = sb.lastIndexOf(".");
String clazzName = sb.substring(0, index);
@@ -190,10 +179,4 @@ public class PlusDataPermissionHandler {
return null;
}
/**
* 是否为无效方法 无数据权限
*/
public boolean isInvalid(String mappedStatementId) {
return invalidCacheSet.contains(mappedStatementId);
}
}

View File

@@ -78,7 +78,7 @@ public class GenController extends BaseController {
*/
@SaCheckPermission("tool:gen:list")
@GetMapping(value = "/column/{tableId}")
public TableDataInfo<GenTableColumn> columnList(Long tableId) {
public TableDataInfo<GenTableColumn> columnList(@PathVariable("tableId") Long tableId) {
TableDataInfo<GenTableColumn> dataInfo = new TableDataInfo<>();
List<GenTableColumn> list = genTableService.selectGenTableColumnListByTableId(tableId);
dataInfo.setRows(list);

View File

@@ -39,7 +39,7 @@ public class OssFactory {
/**
* 根据类型获取实例
*/
public static OssClient instance(String configKey) {
public static synchronized OssClient instance(String configKey) {
String json = CacheUtils.get(CacheNames.SYS_OSS_CONFIG, configKey);
if (json == null) {
throw new OssException("系统异常, '" + configKey + "'配置信息不存在!");

View File

@@ -49,11 +49,8 @@ public class SysDataScopeServiceImpl implements ISysDataScopeService {
.apply(DataBaseHelper.findInSet(deptId, "ancestors")));
List<Long> ids = StreamUtils.toList(deptList, SysDept::getDeptId);
ids.add(deptId);
List<SysDept> list = deptMapper.selectList(new LambdaQueryWrapper<SysDept>()
.select(SysDept::getDeptId)
.in(SysDept::getDeptId, ids));
if (CollUtil.isNotEmpty(list)) {
return StreamUtils.join(list, d -> Convert.toStr(d.getDeptId()));
if (CollUtil.isNotEmpty(ids)) {
return StreamUtils.join(ids, Convert::toStr);
}
return null;
}

View File

@@ -437,7 +437,7 @@ public class SysMenuServiceImpl implements ISysMenuService {
* 内链域名特殊字符替换
*/
public String innerLinkReplaceEach(String path) {
return StringUtils.replaceEach(path, new String[]{Constants.HTTP, Constants.HTTPS, Constants.WWW, "."},
new String[]{"", "", "", "/"});
return StringUtils.replaceEach(path, new String[]{Constants.HTTP, Constants.HTTPS, Constants.WWW, ".", ":"},
new String[]{"", "", "", "/", "/"});
}
}

View File

@@ -51,6 +51,7 @@ public class SysOperLogServiceImpl implements ISysOperLogService {
public TableDataInfo<SysOperLog> selectPageOperLogList(SysOperLog operLog, PageQuery pageQuery) {
Map<String, Object> params = operLog.getParams();
LambdaQueryWrapper<SysOperLog> lqw = new LambdaQueryWrapper<SysOperLog>()
.like(StringUtils.isNotBlank(operLog.getOperIp()), SysOperLog::getOperIp, operLog.getOperIp())
.like(StringUtils.isNotBlank(operLog.getTitle()), SysOperLog::getTitle, operLog.getTitle())
.eq(operLog.getBusinessType() != null && operLog.getBusinessType() > 0,
SysOperLog::getBusinessType, operLog.getBusinessType())
@@ -93,6 +94,7 @@ public class SysOperLogServiceImpl implements ISysOperLogService {
public List<SysOperLog> selectOperLogList(SysOperLog operLog) {
Map<String, Object> params = operLog.getParams();
return baseMapper.selectList(new LambdaQueryWrapper<SysOperLog>()
.like(StringUtils.isNotBlank(operLog.getOperIp()), SysOperLog::getOperIp, operLog.getOperIp())
.like(StringUtils.isNotBlank(operLog.getTitle()), SysOperLog::getTitle, operLog.getTitle())
.eq(operLog.getBusinessType() != null && operLog.getBusinessType() > 0,
SysOperLog::getBusinessType, operLog.getBusinessType())

View File

@@ -66,8 +66,12 @@ public class SysOssServiceImpl implements ISysOssService, OssService {
for (Long id : ossIds) {
SysOssVo vo = SpringUtils.getAopProxy(this).getById(id);
if (ObjectUtil.isNotNull(vo)) {
list.add(this.matchingUrl(vo));
}
try {
list.add(this.matchingUrl(vo));
} catch (Exception ignored) {
// 如果oss异常无法连接则将数据直接返回
list.add(vo);
} }
}
return list;
}
@@ -78,7 +82,12 @@ public class SysOssServiceImpl implements ISysOssService, OssService {
for (Long id : StringUtils.splitTo(ossIds, Convert::toLong)) {
SysOssVo vo = SpringUtils.getAopProxy(this).getById(id);
if (ObjectUtil.isNotNull(vo)) {
list.add(this.matchingUrl(vo).getUrl());
try {
list.add(this.matchingUrl(vo).getUrl());
} catch (Exception ignored) {
// 如果oss异常无法连接则将数据直接返回
list.add(vo.getUrl());
}
}
}
return String.join(StringUtils.SEPARATOR, list);

View File

@@ -195,9 +195,12 @@ public class SysRoleServiceImpl implements ISysRoleService {
if (ObjectUtil.isNotNull(role.getRoleId())) {
SysRole sysRole = baseMapper.selectById(role.getRoleId());
// 如果标识符不相等 判断为修改了管理员标识符
if (!StringUtils.equals(sysRole.getRoleKey(), role.getRoleKey())
&& StringUtils.equals(sysRole.getRoleKey(), UserConstants.ADMIN_ROLE_KEY)) {
throw new ServiceException("不允许修改系统内置管理员角色标识符!");
if (!StringUtils.equals(sysRole.getRoleKey(), role.getRoleKey())) {
if (StringUtils.equals(sysRole.getRoleKey(), UserConstants.ADMIN_ROLE_KEY)) {
throw new ServiceException("不允许修改系统内置管理员角色标识符!");
} else if (StringUtils.equals(role.getRoleKey(), UserConstants.ADMIN_ROLE_KEY)) {
throw new ServiceException("不允许使用系统内置管理员角色标识符!");
}
}
}
}

View File

@@ -32,7 +32,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<select id="selectDbTableColumnsByName" parameterType="String" resultMap="GenTableColumnResult">
<if test="@com.ruoyi.common.helper.DataBaseHelper@isMySql()">
select column_name,
(case when (is_nullable = 'no' <![CDATA[ && ]]> column_key != 'PRI') then '1' else null end) as is_required,
(case when (is_nullable = 'no' <![CDATA[ && ]]> column_key != 'PRI') then '1' else '0' end) as is_required,
(case when column_key = 'PRI' then '1' else '0' end) as is_pk,
ordinal_position as sort,
column_comment,
@@ -43,7 +43,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</if>
<if test="@com.ruoyi.common.helper.DataBaseHelper@isOracle()">
select lower(temp.column_name) as column_name,
(case when (temp.nullable = 'N' and temp.constraint_type != 'P') then '1' else null end) as is_required,
(case when (temp.nullable = 'N' and temp.constraint_type != 'P') then '1' else '0' end) as is_required,
(case when temp.constraint_type = 'P' then '1' else '0' end) as is_pk,
temp.column_id as sort,
temp.comments as column_comment,

View File

@@ -434,7 +434,7 @@ export default {
this.reset();
this.getTreeselect();
if (row != null && row.${treeCode}) {
this.form.${treeParentCode} = row.${treeParentCode};
this.form.${treeParentCode} = row.${treeCode};
} else {
this.form.${treeParentCode} = 0;
}
@@ -455,7 +455,7 @@ export default {
this.reset();
this.getTreeselect();
if (row != null) {
this.form.${treeParentCode} = row.${treeCode};
this.form.${treeParentCode} = row.${treeParentCode};
}
get${BusinessName}(row.${pkColumn.javaField}).then(response => {
this.loading = false;

View File

@@ -398,7 +398,7 @@ function handleAdd(row) {
reset();
getTreeselect();
if (row != null && row.${treeCode}) {
form.value.${treeParentCode} = row.${treeParentCode};
form.value.${treeParentCode} = row.${treeCode};
} else {
form.value.${treeParentCode} = 0;
}
@@ -421,7 +421,7 @@ async function handleUpdate(row) {
reset();
await getTreeselect();
if (row != null) {
form.value.${treeParentCode} = row.${treeCode};
form.value.${treeParentCode} = row.${treeParentCode};
}
get${BusinessName}(row.${pkColumn.javaField}).then(response => {
loading.value = false;