diff --git a/pom.xml b/pom.xml index 903180b4..502b2904 100644 --- a/pom.xml +++ b/pom.xml @@ -23,16 +23,16 @@ 3.0.0 2.3.3 1.4.6 - 2.0.34 - 6.4.3 - 2.11.0 + 2.0.39 + 6.4.4 + 2.13.0 3.2.2 4.1.2 2.3 0.9.1 6.7.2 - + diff --git a/ruoyi-admin/pom.xml b/ruoyi-admin/pom.xml index e1c5684b..9d68faa5 100644 --- a/ruoyi-admin/pom.xml +++ b/ruoyi-admin/pom.xml @@ -73,7 +73,7 @@ org.springframework.boot spring-boot-maven-plugin - 2.1.1.RELEASE + 2.5.15 true diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java index 0ffb7e8f..94c471e7 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java @@ -60,27 +60,22 @@ public class SysProfileController extends BaseController public AjaxResult updateProfile(@RequestBody SysUser user) { LoginUser loginUser = getLoginUser(); - SysUser sysUser = loginUser.getUser(); - user.setUserName(sysUser.getUserName()); - if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) + SysUser currentUser = loginUser.getUser(); + currentUser.setNickName(user.getNickName()); + currentUser.setEmail(user.getEmail()); + currentUser.setPhonenumber(user.getPhonenumber()); + currentUser.setSex(user.getSex()); + if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(currentUser)) { return error("修改用户'" + user.getUserName() + "'失败,手机号码已存在"); } - if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) + if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(currentUser)) { return error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在"); } - user.setUserId(sysUser.getUserId()); - user.setPassword(null); - user.setAvatar(null); - user.setDeptId(null); - if (userService.updateUserProfile(user) > 0) + if (userService.updateUserProfile(currentUser) > 0) { // 更新缓存用户信息 - sysUser.setNickName(user.getNickName()); - sysUser.setPhonenumber(user.getPhonenumber()); - sysUser.setEmail(user.getEmail()); - sysUser.setSex(user.getSex()); tokenService.setLoginUser(loginUser); return success(); } diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java index f4ba2934..cc9418e5 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java @@ -129,6 +129,11 @@ public class Constants */ public static final String LOOKUP_LDAPS = "ldaps:"; + /** + * 自动识别json对象白名单配置(仅允许解析的包名,范围越小越安全) + */ + public static final String[] JSON_WHITELIST_STR = { "org.springframework", "com.ruoyi" }; + /** * 定时任务白名单配置(仅允许访问的包名,如其他需要可以自行添加) */ diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelHandlerAdapter.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelHandlerAdapter.java index c9ca2d5e..c36c9f1f 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelHandlerAdapter.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelHandlerAdapter.java @@ -1,5 +1,8 @@ package com.ruoyi.common.utils.poi; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.Workbook; + /** * Excel数据格式处理适配器 * @@ -12,8 +15,10 @@ public interface ExcelHandlerAdapter * * @param value 单元格数据值 * @param args excel注解args参数组 + * @param cell 单元格对象 + * @param wb 工作簿对象 * * @return 处理后的值 */ - Object format(Object value, String[] args); + Object format(Object value, String[] args, Cell cell, Workbook wb); } diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java index cbe47b6c..68ccbf11 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java @@ -288,9 +288,23 @@ public class ExcelUtil * @param is 输入流 * @return 转换后集合 */ - public List importExcel(InputStream is) throws Exception + public List importExcel(InputStream is) { - return importExcel(is, 0); + List list = null; + try + { + list = importExcel(is, 0); + } + catch (Exception e) + { + log.error("导入Excel异常{}", e.getMessage()); + throw new UtilException(e.getMessage()); + } + finally + { + IOUtils.closeQuietly(is); + } + return list; } /** @@ -336,7 +350,6 @@ public class ExcelUtil } // 获取最后一个非空行的行下标,比如总行数为n,则返回的为n-1 int rows = sheet.getLastRowNum(); - if (rows > 0) { // 定义一个map用于存放excel列的序号和field. @@ -451,7 +464,7 @@ public class ExcelUtil { propertyName = field.getName() + "." + attr.targetAttr(); } - else if (StringUtils.isNotEmpty(attr.readConverterExp())) + if (StringUtils.isNotEmpty(attr.readConverterExp())) { val = reverseByExp(Convert.toStr(val), attr.readConverterExp(), attr.separator()); } @@ -461,7 +474,7 @@ public class ExcelUtil } else if (!attr.handler().equals(ExcelHandlerAdapter.class)) { - val = dataFormatHandlerAdapter(val, attr); + val = dataFormatHandlerAdapter(val, attr, null); } else if (ColumnType.IMAGE == attr.cellType() && StringUtils.isNotEmpty(pictures)) { @@ -1052,7 +1065,7 @@ public class ExcelUtil } else if (!attr.handler().equals(ExcelHandlerAdapter.class)) { - cell.setCellValue(dataFormatHandlerAdapter(value, attr)); + cell.setCellValue(dataFormatHandlerAdapter(value, attr, cell)); } else { @@ -1265,13 +1278,13 @@ public class ExcelUtil * @param excel 数据注解 * @return */ - public String dataFormatHandlerAdapter(Object value, Excel excel) + public String dataFormatHandlerAdapter(Object value, Excel excel, Cell cell) { try { Object instance = excel.handler().newInstance(); - Method formatMethod = excel.handler().getMethod("format", new Class[] { Object.class, String[].class }); - value = formatMethod.invoke(instance, value, excel.args()); + Method formatMethod = excel.handler().getMethod("format", new Class[] { Object.class, String[].class, Cell.class, Workbook.class }); + value = formatMethod.invoke(instance, value, excel.args(), cell, this.wb); } catch (Exception e) { diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FastJson2JsonRedisSerializer.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FastJson2JsonRedisSerializer.java index 9503f258..bd369b4c 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FastJson2JsonRedisSerializer.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FastJson2JsonRedisSerializer.java @@ -6,6 +6,8 @@ import org.springframework.data.redis.serializer.SerializationException; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONReader; import com.alibaba.fastjson2.JSONWriter; +import com.alibaba.fastjson2.filter.Filter; +import com.ruoyi.common.constant.Constants; /** * Redis使用FastJson序列化 @@ -16,6 +18,8 @@ public class FastJson2JsonRedisSerializer implements RedisSerializer { public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); + static final Filter AUTO_TYPE_FILTER = JSONReader.autoTypeFilter(Constants.JSON_WHITELIST_STR); + private Class clazz; public FastJson2JsonRedisSerializer(Class clazz) @@ -43,6 +47,6 @@ public class FastJson2JsonRedisSerializer implements RedisSerializer } String str = new String(bytes, DEFAULT_CHARSET); - return JSON.parseObject(str, clazz, JSONReader.Feature.SupportAutoType); + return JSON.parseObject(str, clazz, AUTO_TYPE_FILTER); } } diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/RepeatSubmitInterceptor.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/RepeatSubmitInterceptor.java index 05fff7bd..e41968a5 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/RepeatSubmitInterceptor.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/RepeatSubmitInterceptor.java @@ -47,8 +47,9 @@ public abstract class RepeatSubmitInterceptor implements HandlerInterceptor /** * 验证是否重复提交由子类实现具体的防重复提交的规则 * - * @param request - * @return + * @param request 请求信息 + * @param annotation 防重复注解参数 + * @return 结果 * @throws Exception */ public abstract boolean isRepeatSubmit(HttpServletRequest request, RepeatSubmit annotation); diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java index 4b190d02..e062fafb 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java @@ -4,6 +4,8 @@ import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; import javax.servlet.http.HttpServletRequest; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @@ -29,6 +31,8 @@ import io.jsonwebtoken.SignatureAlgorithm; @Component public class TokenService { + private static final Logger log = LoggerFactory.getLogger(TokenService.class); + // 令牌自定义标识 @Value("${token.header}") private String header; @@ -72,6 +76,7 @@ public class TokenService } catch (Exception e) { + log.error("获取用户信息异常'{}'", e.getMessage()); } } return null; diff --git a/ruoyi-generator/src/main/resources/vm/vue/index-tree.vue.vm b/ruoyi-generator/src/main/resources/vm/vue/index-tree.vue.vm index b7fdb62d..cbfb7cd7 100644 --- a/ruoyi-generator/src/main/resources/vm/vue/index-tree.vue.vm +++ b/ruoyi-generator/src/main/resources/vm/vue/index-tree.vue.vm @@ -453,7 +453,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.form = response.data; diff --git a/ruoyi-generator/src/main/resources/vm/vue/v3/index-tree.vue.vm b/ruoyi-generator/src/main/resources/vm/vue/v3/index-tree.vue.vm index 7bbd2fc5..c54d62bf 100644 --- a/ruoyi-generator/src/main/resources/vm/vue/v3/index-tree.vue.vm +++ b/ruoyi-generator/src/main/resources/vm/vue/v3/index-tree.vue.vm @@ -420,7 +420,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 => { form.value = response.data; diff --git a/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml index 3c1c6c54..eda0be22 100644 --- a/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml @@ -23,8 +23,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - - + + @@ -42,7 +42,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - + diff --git a/ruoyi-ui/src/components/TopNav/index.vue b/ruoyi-ui/src/components/TopNav/index.vue index 9fb8dd81..daee1b87 100644 --- a/ruoyi-ui/src/components/TopNav/index.vue +++ b/ruoyi-ui/src/components/TopNav/index.vue @@ -6,7 +6,10 @@ > diff --git a/ruoyi-ui/src/permission.js b/ruoyi-ui/src/permission.js index 609d2159..e1a14da7 100644 --- a/ruoyi-ui/src/permission.js +++ b/ruoyi-ui/src/permission.js @@ -45,7 +45,7 @@ router.beforeEach((to, from, next) => { // 在免登录白名单,直接进入 next() } else { - next(`/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页 + next(`/login?redirect=${encodeURIComponent(to.fullPath)}`) // 否则全部重定向到登录页 NProgress.done() } } diff --git a/ruoyi-ui/src/store/modules/dict.js b/ruoyi-ui/src/store/modules/dict.js index f48df422..8b044b60 100644 --- a/ruoyi-ui/src/store/modules/dict.js +++ b/ruoyi-ui/src/store/modules/dict.js @@ -14,7 +14,7 @@ const mutations = { try { for (let i = 0; i < state.dict.length; i++) { if (state.dict[i].key == key) { - state.dict.splice(i, i) + state.dict.splice(i, 1) return true } } diff --git a/ruoyi-ui/src/utils/request.js b/ruoyi-ui/src/utils/request.js index 8797e3f7..ffb0d219 100644 --- a/ruoyi-ui/src/utils/request.js +++ b/ruoyi-ui/src/utils/request.js @@ -42,6 +42,12 @@ service.interceptors.request.use(config => { data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data, time: new Date().getTime() } + const requestSize = Object.keys(JSON.stringify(requestObj)).length; // 请求数据大小 + const limitSize = 5 * 1024 * 1024; // 限制存放数据5M + if (requestSize >= limitSize) { + console.warn(`[${config.url}]: ` + '请求数据大小超出允许的5M限制,无法进行防重复提交验证。') + return config; + } const sessionObj = cache.session.getJSON('sessionObj') if (sessionObj === undefined || sessionObj === null || sessionObj === '') { cache.session.setJSON('sessionObj', requestObj) diff --git a/ruoyi-ui/src/views/monitor/job/index.vue b/ruoyi-ui/src/views/monitor/job/index.vue index 37c8fc11..892c7275 100644 --- a/ruoyi-ui/src/views/monitor/job/index.vue +++ b/ruoyi-ui/src/views/monitor/job/index.vue @@ -200,7 +200,18 @@ - + + + + {{dict.label}} + + + + 立即执行 @@ -217,17 +228,6 @@ - - - - {{dict.label}} - - -
- +
  • diff --git a/ruoyi-ui/src/views/system/user/profile/userAvatar.vue b/ruoyi-ui/src/views/system/user/profile/userAvatar.vue index 70d8487f..96aa01f4 100644 --- a/ruoyi-ui/src/views/system/user/profile/userAvatar.vue +++ b/ruoyi-ui/src/views/system/user/profile/userAvatar.vue @@ -61,11 +61,6 @@ import { debounce } from '@/utils' export default { components: { VueCropper }, - props: { - user: { - type: Object - } - }, data() { return { // 是否显示弹出层