diff --git a/.editorconfig b/.editorconfig index 8cfd37094..672defc11 100644 --- a/.editorconfig +++ b/.editorconfig @@ -10,9 +10,6 @@ end_of_line = lf trim_trailing_whitespace = true insert_final_newline = true -[*.java] -indent_style = tab - [*.{json,yml}] indent_size = 2 diff --git a/README.md b/README.md index 778b901f4..a46023682 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [![License](https://img.shields.io/badge/License-MIT-blue.svg)](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/blob/master/LICENSE) [![使用IntelliJ IDEA开发维护](https://img.shields.io/badge/IntelliJ%20IDEA-提供支持-blue.svg)](https://www.jetbrains.com/?from=RuoYi-Vue-Plus)
-[![RuoYi-Vue-Plus](https://img.shields.io/badge/RuoYi_Vue_Plus-3.0.0-success.svg)](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus) +[![RuoYi-Vue-Plus](https://img.shields.io/badge/RuoYi_Vue_Plus-3.1.0-success.svg)](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus) [![Spring Boot](https://img.shields.io/badge/Spring%20Boot-2.5-blue.svg)]() [![JDK-8+](https://img.shields.io/badge/JDK-8+-green.svg)]() [![JDK-11](https://img.shields.io/badge/JDK-11-green.svg)]() diff --git a/docker/deploy.sh b/docker/deploy.sh index 79fb9ae5b..28822ecfd 100644 --- a/docker/deploy.sh +++ b/docker/deploy.sh @@ -22,11 +22,16 @@ port(){ ##放置挂载文件 mount(){ - #挂载配置文件 + #挂载 nginx 配置文件 if test ! -f "/docker/nginx/conf/nginx.conf" ;then mkdir -p /docker/nginx/conf cp nginx/nginx.conf /docker/nginx/conf/nginx.conf fi + #挂载 redis 配置文件 + if test ! -f "/docker/redis/conf/redis.conf" ;then + mkdir -p /docker/redis/conf + cp redis/redis.conf /docker/redis/conf/redis.conf + fi } #启动基础模块 diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 228ddbf29..1535f3d6f 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -65,10 +65,10 @@ services: TZ: Asia/Shanghai volumes: # 配置文件 - - /docker/redis/conf/redis.conf:/redis.conf:rw + - /docker/redis/conf:/redis/config:rw # 数据文件 - - /docker/redis/data:/data:rw - command: "redis-server --appendonly yes" + - /docker/redis/data:/redis/data:rw + command: "redis-server /redis/config/redis.conf --appendonly yes" privileged: true restart: always networks: @@ -77,7 +77,7 @@ services: minio: image: minio/minio:RELEASE.2021-07-08T01-15-01Z - hostname: "minio" + container_name: minio ports: # api 端口 - 9000:9000 @@ -103,14 +103,14 @@ services: ipv4_address: 172.30.0.54 ruoyi-server1: - image: "ruoyi/ruoyi-server:3.0.0" + image: "ruoyi/ruoyi-server:3.1.0" + container_name: ruoyi-server1 environment: # 时区上海 TZ: Asia/Shanghai volumes: # 配置文件 - /docker/server1/logs/:/ruoyi/server/logs/ - - /docker/ruoyi/uploadPath/:/ruoyi/server/ruoyi/uploadPath/ privileged: true restart: always networks: @@ -118,14 +118,14 @@ services: ipv4_address: 172.30.0.60 ruoyi-server2: - image: "ruoyi/ruoyi-server:3.0.0" + image: "ruoyi/ruoyi-server:3.1.0" + container_name: ruoyi-server2 environment: # 时区上海 TZ: Asia/Shanghai volumes: # 配置文件 - /docker/server2/logs/:/ruoyi/server/logs/ - - /docker/ruoyi/uploadPath/:/ruoyi/server/ruoyi/uploadPath/ privileged: true restart: always networks: @@ -133,7 +133,8 @@ services: ipv4_address: 172.30.0.61 ruoyi-monitor-admin: - image: "ruoyi/ruoyi-monitor-admin:3.0.0" + image: "ruoyi/ruoyi-monitor-admin:3.1.0" + container_name: ruoyi-monitor-admin environment: # 时区上海 TZ: Asia/Shanghai diff --git a/docker/nginx/nginx.conf b/docker/nginx/nginx.conf index 66ac29e3e..a511f351b 100644 --- a/docker/nginx/nginx.conf +++ b/docker/nginx/nginx.conf @@ -22,6 +22,7 @@ http { access_log /var/log/nginx/access.log main; upstream server { + ip_hash; server 172.30.0.60:8080; server 172.30.0.61:8080; } diff --git a/docker/redis/redis.conf b/docker/redis/redis.conf new file mode 100644 index 000000000..213e9ba9e --- /dev/null +++ b/docker/redis/redis.conf @@ -0,0 +1,2 @@ +# redis 密码 +# requirepass 123456 \ No newline at end of file diff --git a/pom.xml b/pom.xml index cdd1f9e4d..eba5a164c 100644 --- a/pom.xml +++ b/pom.xml @@ -6,41 +6,41 @@ com.ruoyi ruoyi-vue-plus - 3.0.0 + 3.1.0 RuoYi-Vue-Plus https://gitee.com/JavaLionLi/RuoYi-Vue-Plus RuoYi-Vue-Plus后台管理系统 - 3.0.0 - 2.5.3 + 3.1.0 + 2.5.4 UTF-8 UTF-8 1.8 - 3.1.1 + 3.2.0 1.2.6 3.0.3 4.1.2 2.2.10 1.7 0.9.1 - 3.4.3 + 3.4.3.3 3.9.1 - 5.7.7 + 5.7.11 3.0.3 - 11.2 + 11.6 4.9.1 - 2.5.0 - 3.16.1 + 2.5.1 + 3.16.2 2.2.1 3.4.1 7.8.0 - 3.13.0 - 5.6.47 - 8.2.0 + 3.13.1 + 5.6.51 + 8.3.0 localhost diff --git a/ruoyi-admin/Dockerfile b/ruoyi-admin/Dockerfile index dc484c5b4..88f4932b6 100644 --- a/ruoyi-admin/Dockerfile +++ b/ruoyi-admin/Dockerfile @@ -4,7 +4,6 @@ MAINTAINER Lion Li RUN mkdir -p /ruoyi/server RUN mkdir -p /ruoyi/server/logs -RUN mkdir -p /ruoyi/server/ruoyi/uploadPath WORKDIR /ruoyi/server diff --git a/ruoyi-admin/pom.xml b/ruoyi-admin/pom.xml index b46acd50a..b455a5e47 100644 --- a/ruoyi-admin/pom.xml +++ b/ruoyi-admin/pom.xml @@ -5,7 +5,7 @@ ruoyi-vue-plus com.ruoyi - 3.0.0 + 3.1.0 4.0.0 jar diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java index 210cceecc..b6f8a5087 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java @@ -1,25 +1,22 @@ package com.ruoyi.web.controller.common; import cn.hutool.captcha.AbstractCaptcha; -import cn.hutool.captcha.CircleCaptcha; -import cn.hutool.captcha.LineCaptcha; -import cn.hutool.captcha.ShearCaptcha; import cn.hutool.captcha.generator.CodeGenerator; -import cn.hutool.captcha.generator.RandomGenerator; import cn.hutool.core.convert.Convert; import cn.hutool.core.util.IdUtil; -import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.core.redis.RedisCache; -import com.ruoyi.framework.captcha.UnsignedMathGenerator; +import com.ruoyi.common.enums.CaptchaType; +import com.ruoyi.common.utils.RedisUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.reflect.ReflectUtils; +import com.ruoyi.common.utils.spring.SpringUtils; import com.ruoyi.framework.config.properties.CaptchaProperties; import com.ruoyi.system.service.ISysConfigService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; -import javax.annotation.Resource; import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; @@ -32,19 +29,6 @@ import java.util.concurrent.TimeUnit; @RestController public class CaptchaController { - // 圆圈干扰验证码 - @Resource(name = "CircleCaptcha") - private CircleCaptcha circleCaptcha; - // 线段干扰的验证码 - @Resource(name = "LineCaptcha") - private LineCaptcha lineCaptcha; - // 扭曲干扰验证码 - @Resource(name = "ShearCaptcha") - private ShearCaptcha shearCaptcha; - - @Autowired - private RedisCache redisCache; - @Autowired private CaptchaProperties captchaProperties; @@ -65,41 +49,16 @@ public class CaptchaController { // 保存验证码信息 String uuid = IdUtil.simpleUUID(); String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid; - String code = null; // 生成验证码 - CodeGenerator codeGenerator; - AbstractCaptcha captcha; - switch (captchaProperties.getType()) { - case "math": - codeGenerator = new UnsignedMathGenerator(captchaProperties.getNumberLength()); - break; - case "char": - codeGenerator = new RandomGenerator(captchaProperties.getCharLength()); - break; - default: - throw new IllegalArgumentException("验证码类型异常"); - } - switch (captchaProperties.getCategory()) { - case "line": - captcha = lineCaptcha; - break; - case "circle": - captcha = circleCaptcha; - break; - case "shear": - captcha = shearCaptcha; - break; - default: - throw new IllegalArgumentException("验证码类别异常"); - } + CaptchaType captchaType = captchaProperties.getType(); + boolean isMath = CaptchaType.MATH == captchaType; + Integer length = isMath ? captchaProperties.getNumberLength() : captchaProperties.getCharLength(); + CodeGenerator codeGenerator = ReflectUtils.newInstance(captchaType.getClazz(), length); + AbstractCaptcha captcha = SpringUtils.getBean(captchaProperties.getCategory().getClazz()); captcha.setGenerator(codeGenerator); captcha.createCode(); - if ("math".equals(captchaProperties.getType())) { - code = getCodeResult(captcha.getCode()); - } else if ("char".equals(captchaProperties.getType())) { - code = captcha.getCode(); - } - redisCache.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES); + String code = isMath ? getCodeResult(captcha.getCode()) : captcha.getCode(); + RedisUtils.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES); ajax.put("uuid", uuid); ajax.put("img", captcha.getImageBase64()); return AjaxResult.success(ajax); @@ -112,13 +71,13 @@ public class CaptchaController { int b = Convert.toInt(StringUtils.substring(capStr, numberLength + 1, numberLength + 1 + numberLength).trim()); switch (operator) { case '*': - return a * b + ""; + return Convert.toStr(a * b); case '+': - return a + b + ""; + return Convert.toStr(a + b); case '-': - return a - b + ""; + return Convert.toStr(a - b); default: - return ""; + return StringUtils.EMPTY; } } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysUserOnlineController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysUserOnlineController.java index f1442cc71..9c836093f 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysUserOnlineController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysUserOnlineController.java @@ -6,9 +6,9 @@ import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.model.LoginUser; import com.ruoyi.common.core.page.TableDataInfo; -import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.utils.PageUtils; +import com.ruoyi.common.utils.RedisUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.system.domain.SysUserOnline; import com.ruoyi.system.service.ISysUserOnlineService; @@ -33,18 +33,15 @@ public class SysUserOnlineController extends BaseController @Autowired private ISysUserOnlineService userOnlineService; - @Autowired - private RedisCache redisCache; - @PreAuthorize("@ss.hasPermi('monitor:online:list')") @GetMapping("/list") public TableDataInfo list(String ipaddr, String userName) { - Collection keys = redisCache.keys(Constants.LOGIN_TOKEN_KEY + "*"); + Collection keys = RedisUtils.keys(Constants.LOGIN_TOKEN_KEY + "*"); List userOnlineList = new ArrayList(); for (String key : keys) { - LoginUser user = redisCache.getCacheObject(key); + LoginUser user = RedisUtils.getCacheObject(key); if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName)) { if (StringUtils.equals(ipaddr, user.getIpaddr()) && StringUtils.equals(userName, user.getUsername())) @@ -84,7 +81,7 @@ public class SysUserOnlineController extends BaseController @DeleteMapping("/{tokenId}") public AjaxResult forceLogout(@PathVariable String tokenId) { - redisCache.deleteObject(Constants.LOGIN_TOKEN_KEY + tokenId); + RedisUtils.deleteObject(Constants.LOGIN_TOKEN_KEY + tokenId); return AjaxResult.success(); } } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDeptController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDeptController.java index edf0b2287..fc26e9773 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDeptController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDeptController.java @@ -70,6 +70,7 @@ public class SysDeptController extends BaseController @GetMapping(value = "/{deptId}") public AjaxResult getInfo(@PathVariable Long deptId) { + deptService.checkDeptDataScope(deptId); return AjaxResult.success(deptService.selectDeptById(deptId)); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java index 9971ac464..76141b9b7 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java @@ -5,12 +5,9 @@ import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.entity.SysMenu; import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.domain.model.LoginBody; -import com.ruoyi.common.core.domain.model.LoginUser; import com.ruoyi.common.utils.SecurityUtils; -import com.ruoyi.common.utils.ServletUtils; import com.ruoyi.framework.web.service.SysLoginService; import com.ruoyi.framework.web.service.SysPermissionService; -import com.ruoyi.framework.web.service.TokenService; import com.ruoyi.system.service.ISysMenuService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; @@ -40,9 +37,6 @@ public class SysLoginController @Autowired private SysPermissionService permissionService; - @Autowired - private TokenService tokenService; - /** * 登录方法 * @@ -68,8 +62,7 @@ public class SysLoginController @GetMapping("getInfo") public AjaxResult getInfo() { - LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); - SysUser user = loginUser.getUser(); + SysUser user = SecurityUtils.getLoginUser().getUser(); // 角色集合 Set roles = permissionService.getRolePermission(user); // 权限集合 diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysOssConfigController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysOssConfigController.java index 60fed2a41..55f25dfa7 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysOssConfigController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysOssConfigController.java @@ -7,6 +7,7 @@ import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.core.validate.AddGroup; import com.ruoyi.common.core.validate.EditGroup; +import com.ruoyi.common.core.validate.QueryGroup; import com.ruoyi.common.enums.BusinessType; import com.ruoyi.system.domain.bo.SysOssConfigBo; import com.ruoyi.system.domain.vo.SysOssConfigVo; @@ -45,7 +46,7 @@ public class SysOssConfigController extends BaseController { @ApiOperation("查询云存储配置列表") @PreAuthorize("@ss.hasPermi('system:oss:list')") @GetMapping("/list") - public TableDataInfo list(@Validated SysOssConfigBo bo) { + public TableDataInfo list(@Validated(QueryGroup.class) SysOssConfigBo bo) { return iSysOssConfigService.queryPageList(bo); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysOssController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysOssController.java index c7772ab9c..ff379910a 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysOssController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysOssController.java @@ -10,6 +10,7 @@ import com.ruoyi.common.annotation.RepeatSubmit; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.core.validate.QueryGroup; import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.JsonUtils; @@ -63,7 +64,7 @@ public class SysOssController extends BaseController { @ApiOperation("查询OSS云存储列表") @PreAuthorize("@ss.hasPermi('system:oss:list')") @GetMapping("/list") - public TableDataInfo list(@Validated SysOssBo bo) { + public TableDataInfo list(@Validated(QueryGroup.class) SysOssBo bo) { return iSysOssService.queryPageList(bo); } 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 e106fa127..422355da0 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 @@ -8,7 +8,6 @@ import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.domain.model.LoginUser; import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.utils.SecurityUtils; -import com.ruoyi.common.utils.ServletUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.framework.web.service.TokenService; import com.ruoyi.system.domain.SysOss; @@ -46,7 +45,7 @@ public class SysProfileController extends BaseController @GetMapping public AjaxResult profile() { - LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); + LoginUser loginUser = getLoginUser(); SysUser user = loginUser.getUser(); Map ajax = new HashMap<>(); ajax.put("user", user); @@ -72,17 +71,17 @@ public class SysProfileController extends BaseController { return AjaxResult.error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在"); } - LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); + LoginUser loginUser = getLoginUser(); SysUser sysUser = loginUser.getUser(); user.setUserId(sysUser.getUserId()); user.setPassword(null); if (userService.updateUserProfile(user) > 0) { // 更新缓存用户信息 - loginUser.getUser().setNickName(user.getNickName()); - loginUser.getUser().setPhonenumber(user.getPhonenumber()); - loginUser.getUser().setEmail(user.getEmail()); - loginUser.getUser().setSex(user.getSex()); + sysUser.setNickName(user.getNickName()); + sysUser.setPhonenumber(user.getPhonenumber()); + sysUser.setEmail(user.getEmail()); + sysUser.setSex(user.getSex()); tokenService.setLoginUser(loginUser); return AjaxResult.success(); } @@ -96,7 +95,7 @@ public class SysProfileController extends BaseController @PutMapping("/updatePwd") public AjaxResult updatePwd(String oldPassword, String newPassword) { - LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); + LoginUser loginUser = getLoginUser(); String userName = loginUser.getUsername(); String password = loginUser.getPassword(); if (!SecurityUtils.matchesPassword(oldPassword, password)) @@ -126,7 +125,7 @@ public class SysProfileController extends BaseController { if (!file.isEmpty()) { - LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); + LoginUser loginUser = getLoginUser(); SysOss oss = iSysOssService.upload(file); String avatar = oss.getUrl(); if (userService.updateUserAvatar(loginUser.getUsername(), avatar)) diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java index c8344b86b..b1cd26380 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java @@ -9,7 +9,6 @@ import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.domain.model.LoginUser; import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.enums.BusinessType; -import com.ruoyi.common.utils.ServletUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.framework.web.service.SysPermissionService; @@ -69,6 +68,7 @@ public class SysRoleController extends BaseController @GetMapping(value = "/{roleId}") public AjaxResult getInfo(@PathVariable Long roleId) { + roleService.checkRoleDataScope(roleId); return AjaxResult.success(roleService.selectRoleById(roleId)); } @@ -115,7 +115,7 @@ public class SysRoleController extends BaseController if (roleService.updateRole(role) > 0) { // 更新缓存用户权限 - LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); + LoginUser loginUser = getLoginUser(); if (StringUtils.isNotNull(loginUser.getUser()) && !loginUser.getUser().isAdmin()) { loginUser.setPermissions(permissionService.getMenuPermission(loginUser.getUser())); diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java index 9e0633c85..28c9f15ef 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java @@ -10,14 +10,11 @@ import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.entity.SysDept; import com.ruoyi.common.core.domain.entity.SysRole; import com.ruoyi.common.core.domain.entity.SysUser; -import com.ruoyi.common.core.domain.model.LoginUser; import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.utils.SecurityUtils; -import com.ruoyi.common.utils.ServletUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.poi.ExcelUtil; -import com.ruoyi.framework.web.service.TokenService; import com.ruoyi.system.domain.vo.SysUserExportVo; import com.ruoyi.system.domain.vo.SysUserImportVo; import com.ruoyi.system.service.ISysPostService; @@ -54,9 +51,6 @@ public class SysUserController extends BaseController @Autowired private ISysPostService postService; - @Autowired - private TokenService tokenService; - /** * 获取用户列表 */ @@ -92,8 +86,7 @@ public class SysUserController extends BaseController { List userListVo = ExcelUtil.importExcel(file.getInputStream(), SysUserImportVo.class); List userList = BeanUtil.copyToList(userListVo, SysUser.class); - LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); - String operName = loginUser.getUsername(); + String operName = getUsername(); String message = userService.importUser(userList, updateSupport, operName); return AjaxResult.success(message); } @@ -111,6 +104,7 @@ public class SysUserController extends BaseController @GetMapping(value = { "/", "/{userId}" }) public AjaxResult getInfo(@PathVariable(value = "userId", required = false) Long userId) { + userService.checkUserDataScope(userId); Map ajax = new HashMap<>(); List roles = roleService.selectRoleAll(); ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList())); diff --git a/ruoyi-admin/src/main/resources/application-dev.yml b/ruoyi-admin/src/main/resources/application-dev.yml index 780499400..6db813cf2 100644 --- a/ruoyi-admin/src/main/resources/application-dev.yml +++ b/ruoyi-admin/src/main/resources/application-dev.yml @@ -38,7 +38,7 @@ spring: # 配置一个连接在池中最大生存的时间,单位是毫秒 maxEvictableIdleTimeMillis: 900000 # 配置检测连接是否有效 - validationQuery: SELECT 1 FROM DUAL + validationQuery: SELECT 1 testWhileIdle: true testOnBorrow: false testOnReturn: false diff --git a/ruoyi-admin/src/main/resources/application-prod.yml b/ruoyi-admin/src/main/resources/application-prod.yml index 446d54d45..ea16c20a1 100644 --- a/ruoyi-admin/src/main/resources/application-prod.yml +++ b/ruoyi-admin/src/main/resources/application-prod.yml @@ -38,7 +38,7 @@ spring: # 配置一个连接在池中最大生存的时间,单位是毫秒 maxEvictableIdleTimeMillis: 900000 # 配置检测连接是否有效 - validationQuery: SELECT 1 FROM DUAL + validationQuery: SELECT 1 testWhileIdle: true testOnBorrow: false testOnReturn: false diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml index 8b633f852..deffa273b 100644 --- a/ruoyi-admin/src/main/resources/application.yml +++ b/ruoyi-admin/src/main/resources/application.yml @@ -12,10 +12,11 @@ ruoyi: addressEnabled: true captcha: + # 页面 <参数设置> 可开启关闭 验证码校验 # 验证码类型 math 数组计算 char 字符验证 - type: math + type: MATH # line 线段干扰 circle 圆圈干扰 shear 扭曲干扰 - category: circle + category: CIRCLE # 数字验证码位数 numberLength: 1 # 字符验证码长度 @@ -133,8 +134,6 @@ mybatis-plus: # REUSE:该执行器类型会复用预处理语句(PreparedStatement) # BATCH:该执行器类型会批量执行所有的更新语句 executorType: SIMPLE - # 指定外部化 MyBatis Properties 配置,通过该配置可以抽离配置,实现不同环境的配置部署 - configurationProperties: null configuration: # 自动驼峰命名规则(camel case)映射 # 如果您的数据库命名符合规则无需使用 @TableField 注解指定数据库字段名 @@ -199,11 +198,11 @@ mybatis-plus: # NOT_EMPTY 非空判断(只对字符串类型字段,其他类型字段依然为非NULL判断) # DEFAULT 默认的,一般只用于注解里 # NEVER 不加入 SQL - insertStrategy: NOT_EMPTY + insertStrategy: NOT_NULL # 字段验证策略之 update,在 update 的时候的字段验证策略 - updateStrategy: NOT_EMPTY + updateStrategy: NOT_NULL # 字段验证策略之 select,在 select 的时候的字段验证策略既 wrapper 根据内部 entity 生成的 where 条件 - selectStrategy: NOT_EMPTY + where-strategy: NOT_NULL # Swagger配置 swagger: @@ -245,11 +244,11 @@ thread-pool: # 线程池维护线程所允许的空闲时间 keepAliveSeconds: 300 # 线程池对拒绝任务(无线程可用)的处理策略 - # CallerRunsPolicy 等待 - # DiscardOldestPolicy 放弃最旧的 - # DiscardPolicy 丢弃 - # AbortPolicy 中止 - rejectedExecutionHandler: CallerRunsPolicy + # CALLER_RUNS_POLICY 等待 + # DISCARD_OLDEST_POLICY 放弃最旧的 + # DISCARD_POLICY 丢弃 + # ABORT_POLICY 中止 + rejectedExecutionHandler: CALLER_RUNS_POLICY # feign 相关配置 feign: diff --git a/ruoyi-admin/src/main/resources/spy.properties b/ruoyi-admin/src/main/resources/spy.properties index b361dbbef..0ed983b3b 100644 --- a/ruoyi-admin/src/main/resources/spy.properties +++ b/ruoyi-admin/src/main/resources/spy.properties @@ -1,26 +1,26 @@ -# p6spy ܷļ +# p6spy 性能分析插件配置文件 modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory -# Զ־ӡ +# 自定义日志打印 logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger -#־̨ +#日志输出到控制台 appender=com.baomidou.mybatisplus.extension.p6spy.StdoutLogger -# ʹ־ϵͳ¼ sql +# 使用日志系统记录 sql #appender=com.p6spy.engine.spy.appender.Slf4JLogger -# p6spy driver +# 设置 p6spy driver 代理 #deregisterdrivers=true -# ȡJDBC URLǰ׺ +# 取消JDBC URL前缀 useprefix=true -# ü¼ Log ,ȥĽerror,info,batch,debug,statement,commit,rollback,result,resultset. +# 配置记录 Log 例外,可去掉的结果集有error,info,batch,debug,statement,commit,rollback,result,resultset. excludecategories=info,debug,result,commit,resultset -# ڸʽ +# 日期格式 dateformat=yyyy-MM-dd HH:mm:ss -# ʵɶ +# 实际驱动可多个 #driverlist=org.h2.Driver -# ǷSQL¼ +# 是否开启慢SQL记录 outagedetection=true -# SQL¼׼ 2 +# 慢SQL记录标准 2 秒 outagedetectioninterval=2 -# Ƿ Log +# 是否过滤 Log filter=true -# Log ʱųıбԶŷָ +# 过滤 Log 时所排除的表名列表,以逗号分隔 exclude=QRTZ_ diff --git a/ruoyi-common/pom.xml b/ruoyi-common/pom.xml index c242a0823..89f56b169 100644 --- a/ruoyi-common/pom.xml +++ b/ruoyi-common/pom.xml @@ -5,7 +5,7 @@ ruoyi-vue-plus com.ruoyi - 3.0.0 + 3.1.0 4.0.0 diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/captcha/UnsignedMathGenerator.java b/ruoyi-common/src/main/java/com/ruoyi/common/captcha/UnsignedMathGenerator.java similarity index 98% rename from ruoyi-framework/src/main/java/com/ruoyi/framework/captcha/UnsignedMathGenerator.java rename to ruoyi-common/src/main/java/com/ruoyi/common/captcha/UnsignedMathGenerator.java index f35afdf68..9c0f26f5b 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/captcha/UnsignedMathGenerator.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/captcha/UnsignedMathGenerator.java @@ -1,4 +1,4 @@ -package com.ruoyi.framework.captcha; +package com.ruoyi.common.captcha; import cn.hutool.captcha.generator.CodeGenerator; import cn.hutool.core.math.Calculator; 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 c1a6469d7..c2cb29dcb 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 @@ -139,4 +139,8 @@ public class Constants */ public static final String LOOKUP_RMI = "rmi://"; + /** + * LDAP 远程方法调用 + */ + public static final String LOOKUP_LDAP = "ldap://"; } diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/convert/ExcelBigNumberConvert.java b/ruoyi-common/src/main/java/com/ruoyi/common/convert/ExcelBigNumberConvert.java new file mode 100644 index 000000000..df1f95a0f --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/convert/ExcelBigNumberConvert.java @@ -0,0 +1,51 @@ +package com.ruoyi.common.convert; + +import cn.hutool.core.convert.Convert; +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.excel.converters.Converter; +import com.alibaba.excel.enums.CellDataTypeEnum; +import com.alibaba.excel.metadata.CellData; +import com.alibaba.excel.metadata.GlobalConfiguration; +import com.alibaba.excel.metadata.property.ExcelContentProperty; +import lombok.extern.slf4j.Slf4j; + +import java.math.BigDecimal; + +/** + * 大数值转换 + * Excel 数值长度位15位 大于15位的数值转换位字符串 + * + * @author Lion Li + */ +@Slf4j +public class ExcelBigNumberConvert implements Converter { + + @Override + public Class supportJavaTypeKey() { + return Long.class; + } + + @Override + public CellDataTypeEnum supportExcelTypeKey() { + return CellDataTypeEnum.STRING; + } + + @Override + public Long convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { + return Convert.toLong(cellData.getData()); + } + + @Override + public CellData convertToExcelData(Long object, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { + if (ObjectUtil.isNotNull(object)) { + String str = Convert.toStr(object); + if (str.length() > 15) { + return new CellData<>(str); + } + } + CellData cellData = new CellData<>(new BigDecimal(object)); + cellData.setType(CellDataTypeEnum.NUMBER); + return cellData; + } + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/controller/BaseController.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/controller/BaseController.java index 39158678f..04a21a7b4 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/core/controller/BaseController.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/controller/BaseController.java @@ -16,28 +16,6 @@ public class BaseController { protected final Logger logger = LoggerFactory.getLogger(this.getClass()); - /** - * 响应返回结果 - * - * @param rows 影响行数 - * @return 操作结果 - */ - protected AjaxResult toAjax(int rows) - { - return rows > 0 ? AjaxResult.success() : AjaxResult.error(); - } - - /** - * 响应返回结果 - * - * @param result 结果 - * @return 操作结果 - */ - protected AjaxResult toAjax(boolean result) - { - return result ? success() : error(); - } - /** * 返回成功 */ @@ -70,6 +48,28 @@ public class BaseController return AjaxResult.error(message); } + /** + * 响应返回结果 + * + * @param rows 影响行数 + * @return 操作结果 + */ + protected AjaxResult toAjax(int rows) + { + return rows > 0 ? AjaxResult.success() : AjaxResult.error(); + } + + /** + * 响应返回结果 + * + * @param result 结果 + * @return 操作结果 + */ + protected AjaxResult toAjax(boolean result) + { + return result ? success() : error(); + } + /** * 页面跳转 */ diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java index c5c82fd6c..6e44a3b95 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java @@ -78,6 +78,11 @@ public class SysUser implements Serializable { /** * 密码 */ + @TableField( + insertStrategy = FieldStrategy.NOT_EMPTY, + updateStrategy = FieldStrategy.NOT_EMPTY, + whereStrategy = FieldStrategy.NOT_EMPTY + ) private String password; @JsonIgnore diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/cache/MybatisPlusRedisCache.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/cache/MybatisPlusRedisCache.java index 633a0b5ab..51b9ec38e 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/cache/MybatisPlusRedisCache.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/cache/MybatisPlusRedisCache.java @@ -1,7 +1,7 @@ package com.ruoyi.common.core.mybatisplus.cache; import cn.hutool.extra.spring.SpringUtil; -import com.ruoyi.common.core.redis.RedisCache; +import com.ruoyi.common.utils.RedisUtils; import lombok.extern.slf4j.Slf4j; import org.apache.ibatis.cache.Cache; import org.springframework.data.redis.connection.RedisServerCommands; @@ -25,8 +25,6 @@ public class MybatisPlusRedisCache implements Cache { private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(true); - private RedisCache redisCache; - private String id; public MybatisPlusRedisCache(final String id) { @@ -43,23 +41,16 @@ public class MybatisPlusRedisCache implements Cache { @Override public void putObject(Object key, Object value) { - if (redisCache == null) { - redisCache = SpringUtil.getBean(RedisCache.class); - } if (value != null) { - redisCache.setCacheObject(key.toString(), value); + RedisUtils.setCacheObject(key.toString(), value); } } @Override public Object getObject(Object key) { - if (redisCache == null) { - //由于启动期间注入失败,只能运行期间注入,这段代码可以删除 - redisCache = SpringUtil.getBean(RedisCache.class); - } try { if (key != null) { - return redisCache.getCacheObject(key.toString()); + return RedisUtils.getCacheObject(key.toString()); } } catch (Exception e) { e.printStackTrace(); @@ -70,11 +61,8 @@ public class MybatisPlusRedisCache implements Cache { @Override public Object removeObject(Object key) { - if (redisCache == null) { - redisCache = SpringUtil.getBean(RedisCache.class); - } if (key != null) { - redisCache.deleteObject(key.toString()); + RedisUtils.deleteObject(key.toString()); } return null; } @@ -82,12 +70,9 @@ public class MybatisPlusRedisCache implements Cache { @Override public void clear() { log.debug("清空缓存"); - if (redisCache == null) { - redisCache = SpringUtil.getBean(RedisCache.class); - } - Collection keys = redisCache.keys("*:" + this.id + "*"); + Collection keys = RedisUtils.keys("*:" + this.id + "*"); if (!CollectionUtils.isEmpty(keys)) { - redisCache.deleteObject(keys); + RedisUtils.deleteObject(keys); } } diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/core/BaseMapperPlus.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/core/BaseMapperPlus.java index ee779a5b8..ee20abd81 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/core/BaseMapperPlus.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/core/BaseMapperPlus.java @@ -14,8 +14,7 @@ import java.util.Collection; public interface BaseMapperPlus extends BaseMapper { /** - * 单sql批量插入( 全量填充 无视数据库默认值 ) - * 适用于无脑插入 + * 单sql批量插入( 全量填充 ) */ int insertAll(@Param("list") Collection batchList); diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/core/IServicePlus.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/core/IServicePlus.java index 710f11afb..815791bf0 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/core/IServicePlus.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/core/IServicePlus.java @@ -15,45 +15,46 @@ import java.util.function.Function; /** * 自定义 Service 接口, 实现 数据库实体与 vo 对象转换返回 * + * @param 数据实体类 + * @param vo类 * @author Lion Li - * @since 2021-05-13 */ -public interface IServicePlus extends IService { +public interface IServicePlus extends IService { /** * @param id 主键id * @param copyOptions copy条件 - * @return K对象 + * @return V对象 */ - K getVoById(Serializable id, CopyOptions copyOptions); + V getVoById(Serializable id, CopyOptions copyOptions); - default K getVoById(Serializable id) { + default V getVoById(Serializable id) { return getVoById(id, new CopyOptions()); } /** * @param convertor 自定义转换器 */ - default K getVoById(Serializable id, Function convertor) { + default V getVoById(Serializable id, Function convertor) { return convertor.apply(getById(id)); } /** * @param idList id列表 * @param copyOptions copy条件 - * @return K对象 + * @return V对象 */ - List listVoByIds(Collection idList, CopyOptions copyOptions); + List listVoByIds(Collection idList, CopyOptions copyOptions); - default List listVoByIds(Collection idList) { + default List listVoByIds(Collection idList) { return listVoByIds(idList, new CopyOptions()); } /** * @param convertor 自定义转换器 */ - default List listVoByIds(Collection idList, - Function, List> convertor) { + default List listVoByIds(Collection idList, + Function, List> convertor) { List list = getBaseMapper().selectBatchIds(idList); if (list == null) { return null; @@ -64,19 +65,19 @@ public interface IServicePlus extends IService { /** * @param columnMap 表字段 map 对象 * @param copyOptions copy条件 - * @return K对象 + * @return V对象 */ - List listVoByMap(Map columnMap, CopyOptions copyOptions); + List listVoByMap(Map columnMap, CopyOptions copyOptions); - default List listVoByMap(Map columnMap) { + default List listVoByMap(Map columnMap) { return listVoByMap(columnMap, new CopyOptions()); } /** * @param convertor 自定义转换器 */ - default List listVoByMap(Map columnMap, - Function, List> convertor) { + default List listVoByMap(Map columnMap, + Function, List> convertor) { List list = getBaseMapper().selectByMap(columnMap); if (list == null) { return null; @@ -87,36 +88,36 @@ public interface IServicePlus extends IService { /** * @param queryWrapper 查询条件 * @param copyOptions copy条件 - * @return K对象 + * @return V对象 */ - K getVoOne(Wrapper queryWrapper, CopyOptions copyOptions); + V getVoOne(Wrapper queryWrapper, CopyOptions copyOptions); - default K getVoOne(Wrapper queryWrapper) { + default V getVoOne(Wrapper queryWrapper) { return getVoOne(queryWrapper, new CopyOptions()); } /** * @param convertor 自定义转换器 */ - default K getVoOne(Wrapper queryWrapper, Function convertor) { + default V getVoOne(Wrapper queryWrapper, Function convertor) { return convertor.apply(getOne(queryWrapper, true)); } /** * @param queryWrapper 查询条件 * @param copyOptions copy条件 - * @return K对象 + * @return V对象 */ - List listVo(Wrapper queryWrapper, CopyOptions copyOptions); + List listVo(Wrapper queryWrapper, CopyOptions copyOptions); - default List listVo(Wrapper queryWrapper) { + default List listVo(Wrapper queryWrapper) { return listVo(queryWrapper, new CopyOptions()); } /** * @param convertor 自定义转换器 */ - default List listVo(Wrapper queryWrapper, Function, List> convertor) { + default List listVo(Wrapper queryWrapper, Function, List> convertor) { List list = getBaseMapper().selectList(queryWrapper); if (list == null) { return null; @@ -124,14 +125,14 @@ public interface IServicePlus extends IService { return convertor.apply(list); } - default List listVo() { + default List listVo() { return listVo(Wrappers.emptyWrapper()); } /** * @param convertor 自定义转换器 */ - default List listVo(Function, List> convertor) { + default List listVo(Function, List> convertor) { return listVo(Wrappers.emptyWrapper(), convertor); } @@ -139,34 +140,36 @@ public interface IServicePlus extends IService { * @param page 分页对象 * @param queryWrapper 查询条件 * @param copyOptions copy条件 - * @return K对象 + * @return V对象 */ - PagePlus pageVo(PagePlus page, Wrapper queryWrapper, CopyOptions copyOptions); + PagePlus pageVo(PagePlus page, Wrapper queryWrapper, CopyOptions copyOptions); - default PagePlus pageVo(PagePlus page, Wrapper queryWrapper) { + default PagePlus pageVo(PagePlus page, Wrapper queryWrapper) { return pageVo(page, queryWrapper, new CopyOptions()); } /** * @param convertor 自定义转换器 */ - default PagePlus pageVo(PagePlus page, Wrapper queryWrapper, - Function, List> convertor) { - PagePlus result = getBaseMapper().selectPage(page, queryWrapper); + default PagePlus pageVo(PagePlus page, Wrapper queryWrapper, + Function, List> convertor) { + PagePlus result = getBaseMapper().selectPage(page, queryWrapper); return result.setRecordsVo(convertor.apply(result.getRecords())); } - default PagePlus pageVo(PagePlus page) { + default PagePlus pageVo(PagePlus page) { return pageVo(page, Wrappers.emptyWrapper()); } /** * @param convertor 自定义转换器 */ - default PagePlus pageVo(PagePlus page, Function, List> convertor) { + default PagePlus pageVo(PagePlus page, Function, List> convertor) { return pageVo(page, Wrappers.emptyWrapper(), convertor); } boolean saveAll(Collection entityList); + + boolean saveOrUpdateAll(Collection entityList); } diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/core/ServicePlusImpl.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/core/ServicePlusImpl.java index e00076e0e..e9c1f191e 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/core/ServicePlusImpl.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/core/ServicePlusImpl.java @@ -1,16 +1,22 @@ package com.ruoyi.common.core.mybatisplus.core; import cn.hutool.core.bean.copier.CopyOptions; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.core.conditions.Wrapper; -import com.baomidou.mybatisplus.core.toolkit.ClassUtils; +import com.baomidou.mybatisplus.core.metadata.TableInfo; +import com.baomidou.mybatisplus.core.metadata.TableInfoHelper; +import com.baomidou.mybatisplus.core.toolkit.Assert; +import com.baomidou.mybatisplus.core.toolkit.ReflectionKit; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.common.core.page.PagePlus; import com.ruoyi.common.utils.BeanCopyUtils; +import com.ruoyi.common.utils.reflect.ReflectUtils; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.ResolvableType; import java.io.Serializable; +import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; @@ -18,11 +24,14 @@ import java.util.Map; /** * IServicePlus 实现类 * + * @param Mapper类 + * @param 数据实体类 + * @param vo类 * @author Lion Li */ @Slf4j @SuppressWarnings("unchecked") -public class ServicePlusImpl, T, K> extends ServiceImpl implements IServicePlus { +public class ServicePlusImpl, T, V> extends ServiceImpl implements IServicePlus { @Autowired protected M baseMapper; @@ -40,31 +49,26 @@ public class ServicePlusImpl, T, K> extends ServiceI return entityClass; } - protected Class mapperClass = currentMapperClass(); + protected Class mapperClass = currentMapperClass(); - protected Class voClass = currentVoClass(); + protected Class voClass = currentVoClass(); - public Class getVoClass() { + public Class getVoClass() { return voClass; } @Override - protected Class currentMapperClass() { - return (Class) this.getResolvableType().as(ServicePlusImpl.class).getGeneric(0).getType(); + protected Class currentMapperClass() { + return (Class) ReflectionKit.getSuperClassGenericType(this.getClass(), ServicePlusImpl.class, 0); } @Override protected Class currentModelClass() { - return (Class) this.getResolvableType().as(ServicePlusImpl.class).getGeneric(1).getType(); + return (Class) ReflectionKit.getSuperClassGenericType(this.getClass(), ServicePlusImpl.class, 1); } - protected Class currentVoClass() { - return (Class) this.getResolvableType().as(ServicePlusImpl.class).getGeneric(2).getType(); - } - - @Override - protected ResolvableType getResolvableType() { - return ResolvableType.forClass(ClassUtils.getUserClass(getClass())); + protected Class currentVoClass() { + return (Class) ReflectionKit.getSuperClassGenericType(this.getClass(), ServicePlusImpl.class, 2); } /** @@ -113,21 +117,55 @@ public class ServicePlusImpl, T, K> extends ServiceI } /** - * 单sql批量插入( 全量填充 无视数据库默认值 ) - * 适用于无脑插入 + * 单sql批量插入( 全量填充 ) */ @Override public boolean saveAll(Collection entityList) { + if (CollUtil.isEmpty(entityList)) { + return false; + } return baseMapper.insertAll(entityList) == entityList.size(); } + /** + * 全量保存或更新 ( 按主键区分 ) + */ + @Override + public boolean saveOrUpdateAll(Collection entityList) { + if (CollUtil.isEmpty(entityList)) { + return false; + } + TableInfo tableInfo = TableInfoHelper.getTableInfo(entityClass); + Assert.notNull(tableInfo, "error: can not execute. because can not find cache of TableInfo for entity!"); + String keyProperty = tableInfo.getKeyProperty(); + Assert.notEmpty(keyProperty, "error: can not execute. because can not find column for id from entity!"); + List addList = new ArrayList<>(); + List updateList = new ArrayList<>(); + int row = 0; + for (T entity : entityList) { + Object id = ReflectUtils.invokeGetter(entity, keyProperty); + if (ObjectUtil.isNull(id)) { + addList.add(entity); + } else { + updateList.add(entity); + } + } + if (CollUtil.isNotEmpty(updateList) && updateBatchById(updateList)) { + row += updateList.size(); + } + if (CollUtil.isNotEmpty(addList)) { + row += baseMapper.insertAll(addList); + } + return row == entityList.size(); + } + /** * 根据 ID 查询 * * @param id 主键ID */ @Override - public K getVoById(Serializable id, CopyOptions copyOptions) { + public V getVoById(Serializable id, CopyOptions copyOptions) { T t = getBaseMapper().selectById(id); return BeanCopyUtils.oneCopy(t, copyOptions, voClass); } @@ -138,7 +176,7 @@ public class ServicePlusImpl, T, K> extends ServiceI * @param idList 主键ID列表 */ @Override - public List listVoByIds(Collection idList, CopyOptions copyOptions) { + public List listVoByIds(Collection idList, CopyOptions copyOptions) { List list = getBaseMapper().selectBatchIds(idList); if (list == null) { return null; @@ -152,7 +190,7 @@ public class ServicePlusImpl, T, K> extends ServiceI * @param columnMap 表字段 map 对象 */ @Override - public List listVoByMap(Map columnMap, CopyOptions copyOptions) { + public List listVoByMap(Map columnMap, CopyOptions copyOptions) { List list = getBaseMapper().selectByMap(columnMap); if (list == null) { return null; @@ -167,7 +205,7 @@ public class ServicePlusImpl, T, K> extends ServiceI * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} */ @Override - public K getVoOne(Wrapper queryWrapper, CopyOptions copyOptions) { + public V getVoOne(Wrapper queryWrapper, CopyOptions copyOptions) { T t = getOne(queryWrapper, true); return BeanCopyUtils.oneCopy(t, copyOptions, voClass); } @@ -178,7 +216,7 @@ public class ServicePlusImpl, T, K> extends ServiceI * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} */ @Override - public List listVo(Wrapper queryWrapper, CopyOptions copyOptions) { + public List listVo(Wrapper queryWrapper, CopyOptions copyOptions) { List list = getBaseMapper().selectList(queryWrapper); if (list == null) { return null; @@ -193,9 +231,9 @@ public class ServicePlusImpl, T, K> extends ServiceI * @param queryWrapper 实体对象封装操作类 */ @Override - public PagePlus pageVo(PagePlus page, Wrapper queryWrapper, CopyOptions copyOptions) { - PagePlus result = getBaseMapper().selectPage(page, queryWrapper); - List volist = BeanCopyUtils.listCopy(result.getRecords(), copyOptions, voClass); + public PagePlus pageVo(PagePlus page, Wrapper queryWrapper, CopyOptions copyOptions) { + PagePlus result = getBaseMapper().selectPage(page, queryWrapper); + List volist = BeanCopyUtils.listCopy(result.getRecords(), copyOptions, voClass); result.setRecordsVo(volist); return result; } diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/methods/InsertAll.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/methods/InsertAll.java index 2aba06e0e..403ea539b 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/methods/InsertAll.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/methods/InsertAll.java @@ -2,6 +2,7 @@ package com.ruoyi.common.core.mybatisplus.methods; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.core.injector.AbstractMethod; +import com.baomidou.mybatisplus.core.metadata.TableFieldInfo; import com.baomidou.mybatisplus.core.metadata.TableInfo; import com.baomidou.mybatisplus.core.metadata.TableInfoHelper; import com.ruoyi.common.utils.StringUtils; @@ -11,13 +12,17 @@ import org.apache.ibatis.executor.keygen.NoKeyGenerator; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.mapping.SqlSource; +import java.util.List; + /** - * 单sql批量插入( 全量填充 无视数据库默认值 ) + * 单sql批量插入( 全量填充 ) * * @author Lion Li */ public class InsertAll extends AbstractMethod { + private final static String[] FILL_PROPERTY = {"createTime", "createBy", "updateTime", "updateBy"}; + @Override public MappedStatement injectMappedStatement(Class mapperClass, Class modelClass, TableInfo tableInfo) { final String sql = ""; @@ -63,10 +68,32 @@ public class InsertAll extends AbstractMethod { final StringBuilder valueSql = new StringBuilder(); valueSql.append(""); if (StringUtils.isNotBlank(tableInfo.getKeyColumn())) { - valueSql.append("#{item.").append(tableInfo.getKeyProperty()).append("},"); + valueSql.append("\n#{item.").append(tableInfo.getKeyProperty()).append("},\n"); + } + List fieldList = tableInfo.getFieldList(); + int last = fieldList.size() - 1; + for (int i = 0; i < fieldList.size(); i++) { + String property = fieldList.get(i).getProperty(); + if (!StringUtils.equalsAny(property, FILL_PROPERTY)) { + valueSql.append(""); + valueSql.append("#{item.").append(property).append("}"); + if (i != last) { + valueSql.append(","); + } + valueSql.append(""); + valueSql.append(""); + valueSql.append("DEFAULT"); + if (i != last) { + valueSql.append(","); + } + valueSql.append(""); + } else { + valueSql.append("#{item.").append(property).append("}"); + if (i != last) { + valueSql.append(","); + } + } } - tableInfo.getFieldList().forEach(x -> valueSql.append("#{item.").append(x.getProperty()).append("},")); - valueSql.delete(valueSql.length() - 1, valueSql.length()); valueSql.append(""); return valueSql.toString(); } diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisCache.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisCache.java index f46a21576..23a25e045 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisCache.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisCache.java @@ -5,21 +5,58 @@ import org.redisson.api.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import java.util.*; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; /** * spring redis 工具类 * * @author shenxinquan + * @see com.ruoyi.common.utils.RedisUtils + * @deprecated 3.2.0 删除此类 **/ @SuppressWarnings(value = {"unchecked", "rawtypes"}) @Component +@Deprecated public class RedisCache { @Autowired private RedissonClient redissonClient; + /** + * 发布通道消息 + * + * @param channelKey 通道key + * @param msg 发送数据 + * @param consumer 自定义处理 + */ + public void publish(String channelKey, T msg, Consumer consumer) { + RTopic topic = redissonClient.getTopic(channelKey); + topic.publish(msg); + consumer.accept(msg); + } + + public void publish(String channelKey, T msg) { + RTopic topic = redissonClient.getTopic(channelKey); + topic.publish(msg); + } + + /** + * 订阅通道接收消息 + * + * @param channelKey 通道key + * @param clazz 消息类型 + * @param consumer 自定义处理 + */ + public void subscribe(String channelKey, Class clazz, Consumer consumer) { + RTopic topic = redissonClient.getTopic(channelKey); + topic.addListener(clazz, (channel, msg) -> consumer.accept(msg)); + } + /** * 缓存基本的对象,Integer、String、实体类等 * diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/validate/QueryGroup.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/validate/QueryGroup.java new file mode 100644 index 000000000..bbbfe0388 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/validate/QueryGroup.java @@ -0,0 +1,9 @@ +package com.ruoyi.common.core.validate; + +/** + * 校验分组 query + * + * @author Lion Li + */ +public interface QueryGroup { +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/enums/CaptchaCategory.java b/ruoyi-common/src/main/java/com/ruoyi/common/enums/CaptchaCategory.java new file mode 100644 index 000000000..35d3ea3cf --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/enums/CaptchaCategory.java @@ -0,0 +1,35 @@ +package com.ruoyi.common.enums; + +import cn.hutool.captcha.AbstractCaptcha; +import cn.hutool.captcha.CircleCaptcha; +import cn.hutool.captcha.LineCaptcha; +import cn.hutool.captcha.ShearCaptcha; +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 验证码类别 + * + * @author Lion Li + */ +@Getter +@AllArgsConstructor +public enum CaptchaCategory { + + /** + * 线段干扰 + */ + LINE(LineCaptcha.class), + + /** + * 圆圈干扰 + */ + CIRCLE(CircleCaptcha.class), + + /** + * 扭曲干扰 + */ + SHEAR(ShearCaptcha.class); + + private final Class clazz; +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/enums/CaptchaType.java b/ruoyi-common/src/main/java/com/ruoyi/common/enums/CaptchaType.java new file mode 100644 index 000000000..b1c50ca75 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/enums/CaptchaType.java @@ -0,0 +1,29 @@ +package com.ruoyi.common.enums; + +import cn.hutool.captcha.generator.CodeGenerator; +import cn.hutool.captcha.generator.RandomGenerator; +import com.ruoyi.common.captcha.UnsignedMathGenerator; +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 验证码类型 + * + * @author Lion Li + */ +@Getter +@AllArgsConstructor +public enum CaptchaType { + + /** + * 数字 + */ + MATH(UnsignedMathGenerator.class), + + /** + * 字符 + */ + CHAR(RandomGenerator.class); + + private final Class clazz; +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/enums/ThreadPoolRejectedPolicy.java b/ruoyi-common/src/main/java/com/ruoyi/common/enums/ThreadPoolRejectedPolicy.java new file mode 100644 index 000000000..0c40f341c --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/enums/ThreadPoolRejectedPolicy.java @@ -0,0 +1,26 @@ +package com.ruoyi.common.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.concurrent.RejectedExecutionHandler; +import java.util.concurrent.ThreadPoolExecutor; + +/** + * 线程池 拒绝策略 泛型 + * + * @author Lion Li + */ +@Getter +@AllArgsConstructor +public enum ThreadPoolRejectedPolicy { + + CALLER_RUNS_POLICY("等待", ThreadPoolExecutor.CallerRunsPolicy.class), + DISCARD_OLDEST_POLICY("放弃最旧的", ThreadPoolExecutor.DiscardOldestPolicy.class), + DISCARD_POLICY("丢弃", ThreadPoolExecutor.DiscardPolicy.class), + ABORT_POLICY("中止", ThreadPoolExecutor.AbortPolicy.class); + + private final String name; + private final Class clazz; + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/filter/XssHttpServletRequestWrapper.java b/ruoyi-common/src/main/java/com/ruoyi/common/filter/XssHttpServletRequestWrapper.java index 700a88dcc..8af1257df 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/filter/XssHttpServletRequestWrapper.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/filter/XssHttpServletRequestWrapper.java @@ -65,8 +65,8 @@ public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper // xss过滤 json = HtmlUtil.cleanHtmlTag(json).trim(); - - final ByteArrayInputStream bis = IoUtil.toStream(json, StandardCharsets.UTF_8); + byte[] jsonBytes = json.getBytes(StandardCharsets.UTF_8); + final ByteArrayInputStream bis = IoUtil.toStream(jsonBytes); return new ServletInputStream() { @Override @@ -81,6 +81,12 @@ public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper return true; } + @Override + public int available() throws IOException + { + return jsonBytes.length; + } + @Override public void setReadListener(ReadListener readListener) { @@ -104,4 +110,4 @@ public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper String header = super.getHeader(HttpHeaders.CONTENT_TYPE); return StringUtils.startsWithIgnoreCase(header, MediaType.APPLICATION_JSON_VALUE); } -} +} \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/BeanCopyUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/BeanCopyUtils.java index bea09f8ba..16a252d0f 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/BeanCopyUtils.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/BeanCopyUtils.java @@ -2,6 +2,8 @@ package com.ruoyi.common.utils; import cn.hutool.core.bean.copier.BeanCopier; import cn.hutool.core.bean.copier.CopyOptions; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ReflectUtil; import java.util.List; @@ -36,6 +38,9 @@ public class BeanCopyUtils { * @return desc */ public static V oneCopy(T source, CopyOptions copyOptions, V desc) { + if (ObjectUtil.isNull(source)) { + return null; + } return BeanCopier.create(source, desc, copyOptions).copy(); } @@ -48,6 +53,12 @@ public class BeanCopyUtils { * @return desc */ public static List listCopy(List sourceList, CopyOptions copyOptions, Class desc) { + if (ObjectUtil.isNull(sourceList)) { + return null; + } + if (CollUtil.isEmpty(sourceList)) { + return CollUtil.newArrayList(); + } return sourceList.stream() .map(source -> oneCopy(source, copyOptions, desc)) .collect(Collectors.toList()); diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/DictUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/DictUtils.java index 64ac8efdc..39e71a66a 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/DictUtils.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/DictUtils.java @@ -3,8 +3,6 @@ package com.ruoyi.common.utils; import cn.hutool.core.collection.CollUtil; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.core.domain.entity.SysDictData; -import com.ruoyi.common.core.redis.RedisCache; -import com.ruoyi.common.utils.spring.SpringUtils; import java.util.Collection; import java.util.List; @@ -29,7 +27,7 @@ public class DictUtils */ public static void setDictCache(String key, List dictDatas) { - SpringUtils.getBean(RedisCache.class).setCacheObject(getCacheKey(key), dictDatas); + RedisUtils.setCacheObject(getCacheKey(key), dictDatas); } /** @@ -40,7 +38,7 @@ public class DictUtils */ public static List getDictCache(String key) { - Object cacheObj = SpringUtils.getBean(RedisCache.class).getCacheObject(getCacheKey(key)); + Object cacheObj = RedisUtils.getCacheObject(getCacheKey(key)); if (StringUtils.isNotNull(cacheObj)) { List dictDatas = (List)cacheObj; @@ -160,7 +158,7 @@ public class DictUtils */ public static void removeDictCache(String key) { - SpringUtils.getBean(RedisCache.class).deleteObject(getCacheKey(key)); + RedisUtils.deleteObject(getCacheKey(key)); } /** @@ -168,8 +166,8 @@ public class DictUtils */ public static void clearDictCache() { - Collection keys = SpringUtils.getBean(RedisCache.class).keys(Constants.SYS_DICT_KEY + "*"); - SpringUtils.getBean(RedisCache.class).deleteObject(keys); + Collection keys = RedisUtils.keys(Constants.SYS_DICT_KEY + "*"); + RedisUtils.deleteObject(keys); } /** diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/JsonUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/JsonUtils.java index 676de013a..7246b0af6 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/JsonUtils.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/JsonUtils.java @@ -4,6 +4,9 @@ import cn.hutool.core.util.ArrayUtil; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; +import com.ruoyi.common.utils.spring.SpringUtils; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; import java.io.IOException; import java.util.ArrayList; @@ -15,20 +18,10 @@ import java.util.Map; * * @author 芋道源码 */ +@NoArgsConstructor(access = AccessLevel.PRIVATE) public class JsonUtils { - private static ObjectMapper objectMapper = new ObjectMapper(); - - /** - * 初始化 objectMapper 属性 - *

- * 通过这样的方式,使用 Spring 创建的 ObjectMapper Bean - * - * @param objectMapper ObjectMapper 对象 - */ - public static void init(ObjectMapper objectMapper) { - JsonUtils.objectMapper = objectMapper; - } + private static ObjectMapper objectMapper = SpringUtils.getBean(ObjectMapper.class); public static String toJsonString(Object object) { if (StringUtils.isNull(object)) { diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/PageUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/PageUtils.java index 27125ab8f..a0b4d3c65 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/PageUtils.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/PageUtils.java @@ -57,15 +57,12 @@ public class PageUtils { Integer pageSize = ServletUtils.getParameterToInt(PAGE_SIZE, DEFAULT_PAGE_SIZE); String orderByColumn = ServletUtils.getParameter(ORDER_BY_COLUMN); String isAsc = ServletUtils.getParameter(IS_ASC); - PagePlus page = new PagePlus<>(pageNum, pageSize); - if (StringUtils.isNotBlank(orderByColumn)) { - String orderBy = SqlUtil.escapeOrderBySql(orderByColumn); - if ("asc".equals(isAsc)) { - page.addOrder(OrderItem.asc(orderBy)); - } else if ("desc".equals(isAsc)) { - page.addOrder(OrderItem.desc(orderBy)); - } + if (pageNum <= 0) { + pageNum = DEFAULT_PAGE_NUM; } + PagePlus page = new PagePlus<>(pageNum, pageSize); + OrderItem orderItem = buildOrderItem(orderByColumn, isAsc); + page.addOrder(orderItem); return page; } @@ -83,23 +80,32 @@ public class PageUtils { Integer pageSize = ServletUtils.getParameterToInt(PAGE_SIZE, DEFAULT_PAGE_SIZE); String orderByColumn = ServletUtils.getParameter(ORDER_BY_COLUMN, defaultOrderByColumn); String isAsc = ServletUtils.getParameter(IS_ASC, defaultIsAsc); - // 兼容前端排序类型 - if ("ascending".equals(isAsc)) { - isAsc = "asc"; - } else if ("descending".equals(isAsc)) { - isAsc = "desc"; - } + if (pageNum <= 0) { + pageNum = DEFAULT_PAGE_NUM; + } Page page = new Page<>(pageNum, pageSize); + OrderItem orderItem = buildOrderItem(orderByColumn, isAsc); + page.addOrder(orderItem); + return page; + } + + private static OrderItem buildOrderItem(String orderByColumn, String isAsc) { + // 兼容前端排序类型 + if ("ascending".equals(isAsc)) { + isAsc = "asc"; + } else if ("descending".equals(isAsc)) { + isAsc = "desc"; + } if (StringUtils.isNotBlank(orderByColumn)) { String orderBy = SqlUtil.escapeOrderBySql(orderByColumn); orderBy = StringUtils.toUnderScoreCase(orderBy); if ("asc".equals(isAsc)) { - page.addOrder(OrderItem.asc(orderBy)); + return OrderItem.asc(orderBy); } else if ("desc".equals(isAsc)) { - page.addOrder(OrderItem.desc(orderBy)); + return OrderItem.desc(orderBy); } } - return page; + return null; } public static TableDataInfo buildDataInfo(PagePlus page) { @@ -129,4 +135,11 @@ public class PageUtils { return rspData; } + public static TableDataInfo buildDataInfo() { + TableDataInfo rspData = new TableDataInfo<>(); + rspData.setCode(HttpStatus.HTTP_OK); + rspData.setMsg("查询成功"); + return rspData; + } + } diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/RedisUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/RedisUtils.java new file mode 100644 index 000000000..5fcfb9dee --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/RedisUtils.java @@ -0,0 +1,258 @@ +package com.ruoyi.common.utils; + +import com.google.common.collect.Lists; +import com.ruoyi.common.utils.spring.SpringUtils; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import org.redisson.api.*; + +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; + +/** + * redis 工具类 + * + * @author Lion Li + * @version 3.1.0 新增 + */ +@NoArgsConstructor(access = AccessLevel.PRIVATE) +@SuppressWarnings(value = {"unchecked", "rawtypes"}) +public class RedisUtils { + + private static RedissonClient client = SpringUtils.getBean(RedissonClient.class); + + /** + * 发布通道消息 + * + * @param channelKey 通道key + * @param msg 发送数据 + * @param consumer 自定义处理 + */ + public static void publish(String channelKey, T msg, Consumer consumer) { + RTopic topic = client.getTopic(channelKey); + topic.publish(msg); + consumer.accept(msg); + } + + public static void publish(String channelKey, T msg) { + RTopic topic = client.getTopic(channelKey); + topic.publish(msg); + } + + /** + * 订阅通道接收消息 + * + * @param channelKey 通道key + * @param clazz 消息类型 + * @param consumer 自定义处理 + */ + public static void subscribe(String channelKey, Class clazz, Consumer consumer) { + RTopic topic = client.getTopic(channelKey); + topic.addListener(clazz, (channel, msg) -> consumer.accept(msg)); + } + + /** + * 缓存基本的对象,Integer、String、实体类等 + * + * @param key 缓存的键值 + * @param value 缓存的值 + */ + public static void setCacheObject(final String key, final T value) { + client.getBucket(key).set(value); + } + + /** + * 缓存基本的对象,Integer、String、实体类等 + * + * @param key 缓存的键值 + * @param value 缓存的值 + * @param timeout 时间 + * @param timeUnit 时间颗粒度 + */ + public static void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit) { + RBucket result = client.getBucket(key); + result.set(value); + result.expire(timeout, timeUnit); + } + + /** + * 设置有效时间 + * + * @param key Redis键 + * @param timeout 超时时间 + * @return true=设置成功;false=设置失败 + */ + public static boolean expire(final String key, final long timeout) { + return expire(key, timeout, TimeUnit.SECONDS); + } + + /** + * 设置有效时间 + * + * @param key Redis键 + * @param timeout 超时时间 + * @param unit 时间单位 + * @return true=设置成功;false=设置失败 + */ + public static boolean expire(final String key, final long timeout, final TimeUnit unit) { + RBucket rBucket = client.getBucket(key); + return rBucket.expire(timeout, unit); + } + + /** + * 获得缓存的基本对象。 + * + * @param key 缓存键值 + * @return 缓存键值对应的数据 + */ + public static T getCacheObject(final String key) { + RBucket rBucket = client.getBucket(key); + return rBucket.get(); + } + + /** + * 删除单个对象 + * + * @param key + */ + public static boolean deleteObject(final String key) { + return client.getBucket(key).delete(); + } + + /* */ + + /** + * 删除集合对象 + * + * @param collection 多个对象 + * @return + */ + public static void deleteObject(final Collection collection) { + RBatch batch = client.createBatch(); + collection.forEach(t -> { + batch.getBucket(t.toString()).deleteAsync(); + }); + batch.execute(); + } + + /** + * 缓存List数据 + * + * @param key 缓存的键值 + * @param dataList 待缓存的List数据 + * @return 缓存的对象 + */ + public static boolean setCacheList(final String key, final List dataList) { + RList rList = client.getList(key); + return rList.addAll(dataList); + } + + /** + * 获得缓存的list对象 + * + * @param key 缓存的键值 + * @return 缓存键值对应的数据 + */ + public static List getCacheList(final String key) { + RList rList = client.getList(key); + return rList.readAll(); + } + + /** + * 缓存Set + * + * @param key 缓存键值 + * @param dataSet 缓存的数据 + * @return 缓存数据的对象 + */ + public static boolean setCacheSet(final String key, final Set dataSet) { + RSet rSet = client.getSet(key); + return rSet.addAll(dataSet); + } + + /** + * 获得缓存的set + * + * @param key + * @return + */ + public static Set getCacheSet(final String key) { + RSet rSet = client.getSet(key); + return rSet.readAll(); + } + + /** + * 缓存Map + * + * @param key + * @param dataMap + */ + public static void setCacheMap(final String key, final Map dataMap) { + if (dataMap != null) { + RMap rMap = client.getMap(key); + rMap.putAll(dataMap); + } + } + + /** + * 获得缓存的Map + * + * @param key + * @return + */ + public static Map getCacheMap(final String key) { + RMap rMap = client.getMap(key); + return rMap.getAll(rMap.keySet()); + } + + /** + * 往Hash中存入数据 + * + * @param key Redis键 + * @param hKey Hash键 + * @param value 值 + */ + public static void setCacheMapValue(final String key, final String hKey, final T value) { + RMap rMap = client.getMap(key); + rMap.put(hKey, value); + } + + /** + * 获取Hash中的数据 + * + * @param key Redis键 + * @param hKey Hash键 + * @return Hash中的对象 + */ + public static T getCacheMapValue(final String key, final String hKey) { + RMap rMap = client.getMap(key); + return rMap.get(hKey); + } + + /** + * 获取多个Hash中的数据 + * + * @param key Redis键 + * @param hKeys Hash键集合 + * @return Hash对象集合 + */ + public static Map getMultiCacheMapValue(final String key, final Set hKeys) { + RMap rMap = client.getMap(key); + return rMap.getAll(hKeys); + } + + /** + * 获得缓存的基本对象列表 + * + * @param pattern 字符串前缀 + * @return 对象列表 + */ + public static Collection keys(final String pattern) { + Iterable iterable = client.getKeys().getKeysByPattern(pattern); + return Lists.newArrayList(iterable); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/ServletUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/ServletUtils.java index beaa26c6e..f611834d3 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/ServletUtils.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/ServletUtils.java @@ -48,12 +48,26 @@ public class ServletUtils extends ServletUtil { return Convert.toInt(getRequest().getParameter(name), defaultValue); } - /** - * 获取request - */ - public static HttpServletRequest getRequest() { - return getRequestAttributes().getRequest(); - } + /** + * 获取Boolean参数 + */ + public static Boolean getParameterToBool(String name) { + return Convert.toBool(getRequest().getParameter(name)); + } + + /** + * 获取Boolean参数 + */ + public static Boolean getParameterToBool(String name, Boolean defaultValue) { + return Convert.toBool(getRequest().getParameter(name), defaultValue); + } + + /** + * 获取request + */ + public static HttpServletRequest getRequest() { + return getRequestAttributes().getRequest(); + } /** * 获取response 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 e5d385f2d..4060b1794 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 @@ -3,6 +3,7 @@ package com.ruoyi.common.utils.poi; import cn.hutool.core.util.IdUtil; import com.alibaba.excel.EasyExcel; import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy; +import com.ruoyi.common.convert.ExcelBigNumberConvert; import com.ruoyi.common.utils.DictUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.file.FileUtils; @@ -52,6 +53,8 @@ public class ExcelUtil { .autoCloseStream(false) // 自动适配 .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) + // 大数值自动转换 防止失真 + .registerConverter(new ExcelBigNumberConvert()) .sheet(sheetName).doWrite(list); } catch (IOException e) { throw new RuntimeException("导出Excel异常"); diff --git a/ruoyi-demo/pom.xml b/ruoyi-demo/pom.xml index 1393d491e..2eff3c2db 100644 --- a/ruoyi-demo/pom.xml +++ b/ruoyi-demo/pom.xml @@ -5,7 +5,7 @@ ruoyi-vue-plus com.ruoyi - 3.0.0 + 3.1.0 4.0.0 diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/FeignTestController.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/FeignTestController.java index ec3e0d665..f8bec9f9c 100644 --- a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/FeignTestController.java +++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/FeignTestController.java @@ -2,6 +2,8 @@ package com.ruoyi.demo.controller; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.demo.feign.FeignTestService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; @@ -14,6 +16,7 @@ import org.springframework.web.bind.annotation.RestController; * * @author Lion Li */ +@Api(value = "feign测试", tags = {"feign测试"}) @RequiredArgsConstructor(onConstructor_ = @Autowired) @RestController @RequestMapping("/feign/test") @@ -21,6 +24,10 @@ public class FeignTestController { private final FeignTestService feignTestService; + /** + * 搜索数据 + */ + @ApiOperation("测试使用feign请求数据") @GetMapping("/search/{wd}") public AjaxResult search(@PathVariable String wd) { String search = feignTestService.search(wd); diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisCacheController.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisCacheController.java index 4588f1386..6877aed2d 100644 --- a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisCacheController.java +++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisCacheController.java @@ -1,6 +1,8 @@ package com.ruoyi.demo.controller; import com.ruoyi.common.core.domain.AjaxResult; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CacheEvict; @@ -17,6 +19,7 @@ import org.springframework.web.bind.annotation.RestController; */ // 类级别 缓存统一配置 //@CacheConfig(cacheNames = "redissonCacheMap") +@Api(value = "spring-cache 演示案例", tags = {"spring-cache 演示案例"}) @RequiredArgsConstructor(onConstructor_ = @Autowired) @RestController @RequestMapping("/demo/cache") @@ -33,6 +36,7 @@ public class RedisCacheController { * * cacheNames 为配置文件内 groupId */ + @ApiOperation("测试 @Cacheable") @Cacheable(cacheNames = "redissonCacheMap", key = "#key", condition = "#key != null") @GetMapping("/test1") public AjaxResult test1(String key, String value){ @@ -47,6 +51,7 @@ public class RedisCacheController { * * cacheNames 为 配置文件内 groupId */ + @ApiOperation("测试 @CachePut") @CachePut(cacheNames = "redissonCacheMap", key = "#key", condition = "#key != null") @GetMapping("/test2") public AjaxResult test2(String key, String value){ @@ -61,6 +66,7 @@ public class RedisCacheController { * * cacheNames 为 配置文件内 groupId */ + @ApiOperation("测试 @CacheEvict") @CacheEvict(cacheNames = "redissonCacheMap", key = "#key", condition = "#key != null") @GetMapping("/test3") public AjaxResult test3(String key, String value){ diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisLockController.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisLockController.java index f6649ed9c..a72024663 100644 --- a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisLockController.java +++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisLockController.java @@ -5,6 +5,8 @@ import com.baomidou.lock.LockTemplate; import com.baomidou.lock.annotation.Lock4j; import com.baomidou.lock.executor.RedissonLockExecutor; import com.ruoyi.common.core.domain.AjaxResult; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.Cacheable; @@ -20,6 +22,7 @@ import java.time.LocalTime; * * @author shenxinquan */ +@Api(value = "测试分布式锁的样例", tags = {"测试分布式锁的样例"}) @Slf4j @RestController @RequestMapping("/demo/redisLock") @@ -31,6 +34,7 @@ public class RedisLockController { /** * 测试lock4j 注解 */ + @ApiOperation("测试lock4j 注解") @Lock4j(keys = {"#key"}) @GetMapping("/testLock4j") public AjaxResult testLock4j(String key,String value){ @@ -47,6 +51,7 @@ public class RedisLockController { /** * 测试lock4j 工具 */ + @ApiOperation("测试lock4j 工具") @GetMapping("/testLock4jLockTemaplate") public AjaxResult testLock4jLockTemaplate(String key,String value){ final LockInfo lockInfo = lockTemplate.lock(key, 30000L, 5000L, RedissonLockExecutor.class); @@ -72,6 +77,7 @@ public class RedisLockController { /** * 测试spring-cache注解 */ + @ApiOperation("测试spring-cache注解") @Cacheable(value = "test", key = "#key") @GetMapping("/testCache") public AjaxResult testCache(String key) { diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisPubSubController.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisPubSubController.java new file mode 100644 index 000000000..810b307dc --- /dev/null +++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisPubSubController.java @@ -0,0 +1,42 @@ +package com.ruoyi.demo.controller; + +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.utils.RedisUtils; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * Redis 发布订阅 演示案例 + * + * @author Lion Li + */ +@Api(value = "Redis发布订阅 演示案例", tags = {"Redis发布订阅"}) +@RequiredArgsConstructor(onConstructor_ = @Autowired) +@RestController +@RequestMapping("/demo/redis/pubsub") +public class RedisPubSubController { + + @ApiOperation("发布消息") + @GetMapping("/pub") + public AjaxResult pub(String key, String value){ + RedisUtils.publish(key, value, consumer -> { + System.out.println("发布通道 => " + key + ", 发送值 => " + value); + }); + return AjaxResult.success("操作成功"); + } + + @ApiOperation("订阅消息") + @GetMapping("/sub") + public AjaxResult sub(String key){ + RedisUtils.subscribe(key, String.class, msg -> { + System.out.println("订阅通道 => " + key + ", 接收值 => " + msg); + }); + return AjaxResult.success("操作成功"); + } + +} diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestBatchController.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestBatchController.java index 9a66fddff..ef117a11c 100644 --- a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestBatchController.java +++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestBatchController.java @@ -32,10 +32,10 @@ public class TestBatchController extends BaseController { private final ITestDemoService iTestDemoService; /** - * 新增批量方法 ( 全量覆盖填充 ) + * 新增批量方法 可完美替代 saveBatch 秒级插入上万数据 (对mysql负荷较大) */ @ApiOperation(value = "新增批量方法") - @PostMapping() + @PostMapping("/add") // @DataSource(DataSourceType.SLAVE) public AjaxResult add() { List list = new ArrayList<>(); @@ -45,6 +45,28 @@ public class TestBatchController extends BaseController { return toAjax(iTestDemoService.saveAll(list) ? 1 : 0); } + /** + * 新增或更新 可完美替代 saveOrUpdateBatch 高性能 + */ + @ApiOperation(value = "新增或更新批量方法") + @PostMapping("/addOrUpdate") +// @DataSource(DataSourceType.SLAVE) + public AjaxResult addOrUpdate() { + List list = new ArrayList<>(); + for (int i = 0; i < 1000; i++) { + list.add(new TestDemo().setOrderNum(-1L).setTestKey("批量新增").setValue("测试新增")); + } + iTestDemoService.saveAll(list); + for (int i = 0; i < list.size(); i++) { + TestDemo testDemo = list.get(i); + testDemo.setTestKey("批量新增或修改").setValue("批量新增或修改"); + if (i % 2 == 0) { + testDemo.setId(null); + } + } + return toAjax(iTestDemoService.saveOrUpdateAll(list) ? 1 : 0); + } + /** * 删除批量方法 */ diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestDemoController.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestDemoController.java index a393c9199..563704e05 100644 --- a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestDemoController.java +++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestDemoController.java @@ -7,6 +7,7 @@ import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.core.validate.AddGroup; import com.ruoyi.common.core.validate.EditGroup; +import com.ruoyi.common.core.validate.QueryGroup; import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.demo.domain.bo.TestDemoBo; @@ -48,7 +49,7 @@ public class TestDemoController extends BaseController { @ApiOperation("查询测试单表列表") @PreAuthorize("@ss.hasPermi('demo:demo:list')") @GetMapping("/list") - public TableDataInfo list(@Validated TestDemoBo bo) { + public TableDataInfo list(@Validated(QueryGroup.class) TestDemoBo bo) { return iTestDemoService.queryPageList(bo); } @@ -71,6 +72,10 @@ public class TestDemoController extends BaseController { @GetMapping("/export") public void export(@Validated TestDemoBo bo, HttpServletResponse response) { List list = iTestDemoService.queryList(bo); + // 测试雪花id导出 +// for (TestDemoVo vo : list) { +// vo.setId(1234567891234567893L); +// } ExcelUtil.exportExcel(list, "测试单表", TestDemoVo.class, response); } diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestI18nController.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestI18nController.java index 8ccce2a58..bb0695f78 100644 --- a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestI18nController.java +++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestI18nController.java @@ -2,6 +2,8 @@ package com.ruoyi.demo.controller; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.utils.MessageUtils; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -12,6 +14,7 @@ import org.springframework.web.bind.annotation.RestController; * * @author Lion Li */ +@Api(value = "测试国际化控制器", tags = {"测试国际化管理"}) @RestController @RequestMapping("/demo/i18n") public class TestI18nController { @@ -22,6 +25,7 @@ public class TestI18nController { * * 测试使用 user.register.success */ + @ApiOperation("通过code获取国际化内容") @GetMapping() public AjaxResult get(String code) { return AjaxResult.success(MessageUtils.message(code)); diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestTreeController.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestTreeController.java index 63b1743ff..c34c77c4b 100644 --- a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestTreeController.java +++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestTreeController.java @@ -6,6 +6,7 @@ import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.validate.AddGroup; import com.ruoyi.common.core.validate.EditGroup; +import com.ruoyi.common.core.validate.QueryGroup; import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.demo.domain.bo.TestTreeBo; @@ -46,7 +47,7 @@ public class TestTreeController extends BaseController { @ApiOperation("查询测试树表列表") @PreAuthorize("@ss.hasPermi('demo:tree:list')") @GetMapping("/list") - public AjaxResult> list(@Validated TestTreeBo bo) { + public AjaxResult> list(@Validated(QueryGroup.class) TestTreeBo bo) { List list = iTestTreeService.queryList(bo); return AjaxResult.success(list); } diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/TestDemo.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/TestDemo.java index 13fdc2400..21149d80d 100644 --- a/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/TestDemo.java +++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/TestDemo.java @@ -1,8 +1,6 @@ package com.ruoyi.demo.domain; import com.baomidou.mybatisplus.annotation.*; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; @@ -29,7 +27,6 @@ public class TestDemo implements Serializable { * 主键 */ @TableId(value = "id") - @JsonSerialize(using = ToStringSerializer.class) private Long id; /** diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/vo/TestDemoVo.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/vo/TestDemoVo.java index 3c8e45234..4919bbde2 100644 --- a/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/vo/TestDemoVo.java +++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/vo/TestDemoVo.java @@ -26,6 +26,7 @@ public class TestDemoVo { /** * 主键 */ + @ExcelProperty(value = "主键") @ApiModelProperty("主键") private Long id; diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/feign/FeignTestService.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/feign/FeignTestService.java index 5273a69ae..afda66cfb 100644 --- a/ruoyi-demo/src/main/java/com/ruoyi/demo/feign/FeignTestService.java +++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/feign/FeignTestService.java @@ -10,7 +10,9 @@ import org.springframework.web.bind.annotation.RequestParam; * feign测试service * 规范接口 Service 无感调用 * 常量管理请求路径 更加规范 - * 自定义容错处理 安全可靠 + * 自定义容错处理 安全可靠 (需自行配置熔断器) + * 增加 feign 的目的为使 http 请求接口化 + * * @author Lion Li */ @FeignClient( diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/feign/fallback/FeignTestFallback.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/feign/fallback/FeignTestFallback.java index 0f9e40023..b7e4a1931 100644 --- a/ruoyi-demo/src/main/java/com/ruoyi/demo/feign/fallback/FeignTestFallback.java +++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/feign/fallback/FeignTestFallback.java @@ -10,6 +10,8 @@ import org.springframework.stereotype.Component; * 自定义封装结构体熔断 * 需重写解码器 根据自定义实体 自行解析熔断 * + * 熔断器需要自行添加配置 + * * @see {com.ruoyi.framework.config.FeignConfig#errorDecoder()} * @author Lion Li */ diff --git a/ruoyi-extend/pom.xml b/ruoyi-extend/pom.xml index 3bfe77021..2a348af4a 100644 --- a/ruoyi-extend/pom.xml +++ b/ruoyi-extend/pom.xml @@ -5,7 +5,7 @@ ruoyi-vue-plus com.ruoyi - 3.0.0 + 3.1.0 4.0.0 ruoyi-extend diff --git a/ruoyi-extend/ruoyi-monitor-admin/pom.xml b/ruoyi-extend/ruoyi-monitor-admin/pom.xml index bada747b4..dc0830373 100644 --- a/ruoyi-extend/ruoyi-monitor-admin/pom.xml +++ b/ruoyi-extend/ruoyi-monitor-admin/pom.xml @@ -5,7 +5,7 @@ ruoyi-extend com.ruoyi - 3.0.0 + 3.1.0 4.0.0 jar diff --git a/ruoyi-framework/pom.xml b/ruoyi-framework/pom.xml index 5fca8f94b..918a4cc58 100644 --- a/ruoyi-framework/pom.xml +++ b/ruoyi-framework/pom.xml @@ -5,7 +5,7 @@ ruoyi-vue-plus com.ruoyi - 3.0.0 + 3.1.0 4.0.0 diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/DataScopeAspect.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/DataScopeAspect.java index 773952a6e..a2c101e3d 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/DataScopeAspect.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/DataScopeAspect.java @@ -5,11 +5,9 @@ import com.ruoyi.common.core.domain.BaseEntity; import com.ruoyi.common.core.domain.entity.SysRole; import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.domain.model.LoginUser; -import com.ruoyi.common.utils.ServletUtils; +import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.reflect.ReflectUtils; -import com.ruoyi.common.utils.spring.SpringUtils; -import com.ruoyi.framework.web.service.TokenService; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.Signature; import org.aspectj.lang.annotation.Aspect; @@ -78,7 +76,7 @@ public class DataScopeAspect { return; } // 获取当前的用户 - LoginUser loginUser = SpringUtils.getBean(TokenService.class).getLoginUser(ServletUtils.getRequest()); + LoginUser loginUser = SecurityUtils.getLoginUser(); if (StringUtils.isNotNull(loginUser)) { SysUser currentUser = loginUser.getUser(); // 如果是超级管理员,则不过滤数据 diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java index c9025117a..e8c47a364 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java @@ -5,11 +5,11 @@ import com.ruoyi.common.core.domain.model.LoginUser; import com.ruoyi.common.enums.BusinessStatus; import com.ruoyi.common.enums.HttpMethod; import com.ruoyi.common.utils.JsonUtils; +import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.ServletUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.spring.SpringUtils; import com.ruoyi.framework.web.service.AsyncService; -import com.ruoyi.framework.web.service.TokenService; import com.ruoyi.system.domain.SysOperLog; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.Signature; @@ -83,7 +83,7 @@ public class LogAspect } // 获取当前的用户 - LoginUser loginUser = SpringUtils.getBean(TokenService.class).getLoginUser(ServletUtils.getRequest()); + LoginUser loginUser = SecurityUtils.getLoginUser(); // *========数据库日志=========*// SysOperLog operLog = new SysOperLog(); diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/CaptchaConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/CaptchaConfig.java index 4cd99970c..3d4bc9e8b 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/CaptchaConfig.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/CaptchaConfig.java @@ -1,10 +1,14 @@ package com.ruoyi.framework.config; -import java.awt.*; - -import cn.hutool.captcha.*; +import cn.hutool.captcha.CaptchaUtil; +import cn.hutool.captcha.CircleCaptcha; +import cn.hutool.captcha.LineCaptcha; +import cn.hutool.captcha.ShearCaptcha; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Lazy; + +import java.awt.*; /** * 验证码配置 @@ -22,8 +26,9 @@ public class CaptchaConfig { /** * 圆圈干扰验证码 */ - @Bean(name = "CircleCaptcha") - public CircleCaptcha getCircleCaptcha() { + @Lazy + @Bean + public CircleCaptcha circleCaptcha() { CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(width, height); captcha.setBackground(background); captcha.setFont(font); @@ -33,8 +38,9 @@ public class CaptchaConfig { /** * 线段干扰的验证码 */ - @Bean(name = "LineCaptcha") - public LineCaptcha getLineCaptcha() { + @Lazy + @Bean + public LineCaptcha lineCaptcha() { LineCaptcha captcha = CaptchaUtil.createLineCaptcha(width, height); captcha.setBackground(background); captcha.setFont(font); @@ -44,8 +50,9 @@ public class CaptchaConfig { /** * 扭曲干扰验证码 */ - @Bean(name = "ShearCaptcha") - public ShearCaptcha getShearCaptcha() { + @Lazy + @Bean + public ShearCaptcha shearCaptcha() { ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(width, height); captcha.setBackground(background); captcha.setFont(font); diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/JacksonConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/JacksonConfig.java index 4346610f8..55756d49b 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/JacksonConfig.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/JacksonConfig.java @@ -5,17 +5,18 @@ import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; -import com.ruoyi.common.utils.JsonUtils; import com.ruoyi.framework.jackson.BigNumberSerializer; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.boot.autoconfigure.jackson.JacksonProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; import java.math.BigDecimal; import java.math.BigInteger; import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; import java.util.TimeZone; /** @@ -27,30 +28,23 @@ import java.util.TimeZone; @Configuration public class JacksonConfig { + @Primary @Bean - public BeanPostProcessor objectMapperBeanPostProcessor() { - return new BeanPostProcessor() { - @Override - public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { - if (!(bean instanceof ObjectMapper)) { - return bean; - } - ObjectMapper objectMapper = (ObjectMapper) bean; - // 全局配置序列化返回 JSON 处理 - SimpleModule simpleModule = new SimpleModule(); - simpleModule.addSerializer(Long.class, BigNumberSerializer.INSTANCE); - simpleModule.addSerializer(Long.TYPE, BigNumberSerializer.INSTANCE); - simpleModule.addSerializer(BigInteger.class, BigNumberSerializer.INSTANCE); - simpleModule.addSerializer(BigDecimal.class, ToStringSerializer.instance); - simpleModule.addSerializer(LocalDateTime.class, LocalDateTimeSerializer.INSTANCE); - simpleModule.addDeserializer(LocalDateTime.class, LocalDateTimeDeserializer.INSTANCE); - objectMapper.registerModule(simpleModule); - objectMapper.setTimeZone(TimeZone.getDefault()); - JsonUtils.init(objectMapper); - log.info("初始化 jackson 配置"); - return bean; - } - }; + public ObjectMapper getObjectMapper(Jackson2ObjectMapperBuilder builder, JacksonProperties jacksonProperties) { + ObjectMapper objectMapper = builder.createXmlMapper(false).build(); + // 全局配置序列化返回 JSON 处理 + SimpleModule simpleModule = new SimpleModule(); + simpleModule.addSerializer(Long.class, BigNumberSerializer.INSTANCE); + simpleModule.addSerializer(Long.TYPE, BigNumberSerializer.INSTANCE); + simpleModule.addSerializer(BigInteger.class, BigNumberSerializer.INSTANCE); + simpleModule.addSerializer(BigDecimal.class, ToStringSerializer.instance); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern(jacksonProperties.getDateFormat()); + simpleModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(formatter)); + simpleModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(formatter)); + objectMapper.registerModule(simpleModule); + objectMapper.setTimeZone(TimeZone.getDefault()); + log.info("初始化 jackson 配置"); + return objectMapper; } } diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/MybatisPlusConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/MybatisPlusConfig.java index 1246a2954..2d3cdbf35 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/MybatisPlusConfig.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/MybatisPlusConfig.java @@ -1,10 +1,10 @@ package com.ruoyi.framework.config; -import com.baomidou.mybatisplus.annotation.DbType; import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; import com.baomidou.mybatisplus.core.injector.AbstractMethod; import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector; import com.baomidou.mybatisplus.core.injector.ISqlInjector; +import com.baomidou.mybatisplus.core.metadata.TableInfo; import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; @@ -46,10 +46,10 @@ public class MybatisPlusConfig { */ public PaginationInnerInterceptor paginationInnerInterceptor() { PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(); - // 设置数据库类型为mysql - paginationInnerInterceptor.setDbType(DbType.MYSQL); // 设置最大单页限制数量,默认 500 条,-1 不受限制 paginationInnerInterceptor.setMaxLimit(-1L); + // 分页合理化 + paginationInnerInterceptor.setOverflow(true); return paginationInnerInterceptor; } @@ -104,8 +104,8 @@ public class MybatisPlusConfig { public ISqlInjector sqlInjector() { return new DefaultSqlInjector() { @Override - public List getMethodList(Class mapperClass) { - List methodList = super.getMethodList(mapperClass); + public List getMethodList(Class mapperClass, TableInfo tableInfo) { + List methodList = super.getMethodList(mapperClass, tableInfo); methodList.add(new InsertAll()); return methodList; } diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/RedisConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/RedisConfig.java index d66d86bf6..867cd40b5 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/RedisConfig.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/RedisConfig.java @@ -3,6 +3,7 @@ package com.ruoyi.framework.config; import cn.hutool.core.util.StrUtil; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.framework.config.properties.RedissonProperties; +import lombok.extern.slf4j.Slf4j; import org.redisson.Redisson; import org.redisson.api.RedissonClient; import org.redisson.codec.JsonJacksonCodec; @@ -29,6 +30,7 @@ import java.util.Map; * * @author Lion Li */ +@Slf4j @Configuration @EnableCaching public class RedisConfig extends CachingConfigurerSupport { @@ -73,7 +75,9 @@ public class RedisConfig extends CachingConfigurerSupport { .setConnectionMinimumIdleSize(singleServerConfig.getConnectionMinimumIdleSize()) .setConnectionPoolSize(singleServerConfig.getConnectionPoolSize()) .setDnsMonitoringInterval(singleServerConfig.getDnsMonitoringInterval()); - return Redisson.create(config); + RedissonClient redissonClient = Redisson.create(config); + log.info("初始化 redis 配置"); + return redissonClient; } /** diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ThreadPoolConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ThreadPoolConfig.java index 7758e974a..5dd2b5f64 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ThreadPoolConfig.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ThreadPoolConfig.java @@ -1,6 +1,7 @@ package com.ruoyi.framework.config; import com.ruoyi.common.utils.Threads; +import com.ruoyi.common.utils.reflect.ReflectUtils; import com.ruoyi.framework.config.properties.ThreadPoolProperties; import org.apache.commons.lang3.concurrent.BasicThreadFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -12,7 +13,6 @@ import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import java.util.concurrent.RejectedExecutionHandler; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.util.concurrent.ThreadPoolExecutor; /** * 线程池配置 @@ -33,21 +33,7 @@ public class ThreadPoolConfig { executor.setCorePoolSize(threadPoolProperties.getCorePoolSize()); executor.setQueueCapacity(threadPoolProperties.getQueueCapacity()); executor.setKeepAliveSeconds(threadPoolProperties.getKeepAliveSeconds()); - RejectedExecutionHandler handler; - switch (threadPoolProperties.getRejectedExecutionHandler()) { - case "CallerRunsPolicy": - handler = new ThreadPoolExecutor.CallerRunsPolicy(); - break; - case "DiscardOldestPolicy": - handler = new ThreadPoolExecutor.DiscardOldestPolicy(); - break; - case "DiscardPolicy": - handler = new ThreadPoolExecutor.DiscardPolicy(); - break; - default: - handler = new ThreadPoolExecutor.AbortPolicy(); - break; - } + RejectedExecutionHandler handler = ReflectUtils.newInstance(threadPoolProperties.getRejectedExecutionHandler().getClazz()); executor.setRejectedExecutionHandler(handler); return executor; } diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/CaptchaProperties.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/CaptchaProperties.java index cf9ad8b07..354d8c304 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/CaptchaProperties.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/CaptchaProperties.java @@ -1,5 +1,7 @@ package com.ruoyi.framework.config.properties; +import com.ruoyi.common.enums.CaptchaCategory; +import com.ruoyi.common.enums.CaptchaType; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; @@ -17,12 +19,12 @@ public class CaptchaProperties { /** * 验证码类型 */ - private String type; + private CaptchaType type; /** * 验证码类别 */ - private String category; + private CaptchaCategory category; /** * 数字验证码位数 diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/ThreadPoolProperties.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/ThreadPoolProperties.java index 08b6842aa..fbffc0f45 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/ThreadPoolProperties.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/ThreadPoolProperties.java @@ -1,5 +1,6 @@ package com.ruoyi.framework.config.properties; +import com.ruoyi.common.enums.ThreadPoolRejectedPolicy; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; @@ -42,6 +43,6 @@ public class ThreadPoolProperties { /** * 线程池对拒绝任务(无线程可用)的处理策略 */ - private String rejectedExecutionHandler; + private ThreadPoolRejectedPolicy rejectedExecutionHandler; } diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/impl/SameUrlDataInterceptor.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/impl/SameUrlDataInterceptor.java index d9b3464e4..b2256c935 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/impl/SameUrlDataInterceptor.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/impl/SameUrlDataInterceptor.java @@ -4,9 +4,9 @@ import cn.hutool.core.convert.Convert; import cn.hutool.core.io.IoUtil; import com.ruoyi.common.annotation.RepeatSubmit; import com.ruoyi.common.constant.Constants; -import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.common.filter.RepeatedlyRequestWrapper; import com.ruoyi.common.utils.JsonUtils; +import com.ruoyi.common.utils.RedisUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.framework.config.properties.RepeatSubmitProperties; import com.ruoyi.framework.config.properties.TokenProperties; @@ -38,7 +38,6 @@ public class SameUrlDataInterceptor extends RepeatSubmitInterceptor { private final TokenProperties tokenProperties; private final RepeatSubmitProperties repeatSubmitProperties; - private final RedisCache redisCache; @SuppressWarnings("unchecked") @@ -79,7 +78,7 @@ public class SameUrlDataInterceptor extends RepeatSubmitInterceptor { // 唯一标识(指定key + 消息头) String cacheRepeatKey = Constants.REPEAT_SUBMIT_KEY + submitKey; - Object sessionObj = redisCache.getCacheObject(cacheRepeatKey); + Object sessionObj = RedisUtils.getCacheObject(cacheRepeatKey); if (sessionObj != null) { Map sessionMap = (Map) sessionObj; if (sessionMap.containsKey(url)) { @@ -91,7 +90,7 @@ public class SameUrlDataInterceptor extends RepeatSubmitInterceptor { } Map cacheMap = new HashMap(); cacheMap.put(url, nowDataMap); - redisCache.setCacheObject(cacheRepeatKey, cacheMap, Convert.toInt(intervalTime), TimeUnit.MILLISECONDS); + RedisUtils.setCacheObject(cacheRepeatKey, cacheMap, Convert.toInt(intervalTime), TimeUnit.MILLISECONDS); return false; } diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/PermissionService.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/PermissionService.java index af7fd5726..080177f80 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/PermissionService.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/PermissionService.java @@ -1,10 +1,9 @@ package com.ruoyi.framework.web.service; -import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.core.domain.entity.SysRole; import com.ruoyi.common.core.domain.model.LoginUser; -import com.ruoyi.common.utils.ServletUtils; -import org.springframework.beans.factory.annotation.Autowired; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; @@ -28,9 +27,6 @@ public class PermissionService private static final String PERMISSION_DELIMETER = ","; - @Autowired - private TokenService tokenService; - /** * 验证用户是否具备某权限 * @@ -43,7 +39,7 @@ public class PermissionService { return false; } - LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); + LoginUser loginUser = SecurityUtils.getLoginUser(); if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getPermissions())) { return false; @@ -74,7 +70,7 @@ public class PermissionService { return false; } - LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); + LoginUser loginUser = SecurityUtils.getLoginUser(); if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getPermissions())) { return false; @@ -102,7 +98,7 @@ public class PermissionService { return false; } - LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); + LoginUser loginUser = SecurityUtils.getLoginUser(); if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getUser().getRoles())) { return false; @@ -141,7 +137,7 @@ public class PermissionService { return false; } - LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); + LoginUser loginUser = SecurityUtils.getLoginUser(); if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getUser().getRoles())) { return false; diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java index e3e8e71f5..7df8c26d5 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java @@ -3,13 +3,13 @@ package com.ruoyi.framework.web.service; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.domain.model.LoginUser; -import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.exception.user.CaptchaException; import com.ruoyi.common.exception.user.CaptchaExpireException; import com.ruoyi.common.exception.user.UserPasswordNotMatchException; import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.MessageUtils; +import com.ruoyi.common.utils.RedisUtils; import com.ruoyi.common.utils.ServletUtils; import com.ruoyi.system.service.ISysConfigService; import com.ruoyi.system.service.ISysUserService; @@ -37,9 +37,6 @@ public class SysLoginService @Resource private AuthenticationManager authenticationManager; - @Autowired - private RedisCache redisCache; - @Autowired private ISysUserService userService; @@ -105,8 +102,8 @@ public class SysLoginService */ public void validateCaptcha(String username, String code, String uuid, HttpServletRequest request) { String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid; - String captcha = redisCache.getCacheObject(verifyKey); - redisCache.deleteObject(verifyKey); + String captcha = RedisUtils.getCacheObject(verifyKey); + RedisUtils.deleteObject(verifyKey); if (captcha == null) { asyncService.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"), request); throw new CaptchaExpireException(); diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysRegisterService.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysRegisterService.java index 48d40af8a..149392f21 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysRegisterService.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysRegisterService.java @@ -4,13 +4,9 @@ import com.ruoyi.common.constant.Constants; import com.ruoyi.common.constant.UserConstants; import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.domain.model.RegisterBody; -import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.common.exception.user.CaptchaException; import com.ruoyi.common.exception.user.CaptchaExpireException; -import com.ruoyi.common.utils.MessageUtils; -import com.ruoyi.common.utils.SecurityUtils; -import com.ruoyi.common.utils.ServletUtils; -import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.*; import com.ruoyi.system.service.ISysConfigService; import com.ruoyi.system.service.ISysUserService; import org.springframework.beans.factory.annotation.Autowired; @@ -30,9 +26,6 @@ public class SysRegisterService @Autowired private ISysConfigService configService; - @Autowired - private RedisCache redisCache; - @Autowired private AsyncService asyncService; @@ -103,8 +96,8 @@ public class SysRegisterService public void validateCaptcha(String username, String code, String uuid) { String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid; - String captcha = redisCache.getCacheObject(verifyKey); - redisCache.deleteObject(verifyKey); + String captcha = RedisUtils.getCacheObject(verifyKey); + RedisUtils.deleteObject(verifyKey); if (captcha == null) { throw new CaptchaExpireException(); 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 3414e372f..cb8878e86 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 @@ -5,7 +5,7 @@ import cn.hutool.http.useragent.UserAgent; import cn.hutool.http.useragent.UserAgentUtil; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.core.domain.model.LoginUser; -import com.ruoyi.common.core.redis.RedisCache; +import com.ruoyi.common.utils.RedisUtils; import com.ruoyi.common.utils.ServletUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.ip.AddressUtils; @@ -35,9 +35,6 @@ public class TokenService { private static final Long MILLIS_MINUTE_TEN = 20 * 60 * 1000L; - @Autowired - private RedisCache redisCache; - @Autowired private TokenProperties tokenProperties; @@ -55,7 +52,7 @@ public class TokenService { // 解析对应的权限以及用户信息 String uuid = (String) claims.get(Constants.LOGIN_USER_KEY); String userKey = getTokenKey(uuid); - LoginUser user = redisCache.getCacheObject(userKey); + LoginUser user = RedisUtils.getCacheObject(userKey); return user; } catch (Exception e) { @@ -79,7 +76,7 @@ public class TokenService { public void delLoginUser(String token) { if (StringUtils.isNotEmpty(token)) { String userKey = getTokenKey(token); - redisCache.deleteObject(userKey); + RedisUtils.deleteObject(userKey); } } @@ -124,7 +121,7 @@ public class TokenService { loginUser.setExpireTime(loginUser.getLoginTime() + tokenProperties.getExpireTime() * MILLIS_MINUTE); // 根据uuid将loginUser缓存 String userKey = getTokenKey(loginUser.getToken()); - redisCache.setCacheObject(userKey, loginUser, tokenProperties.getExpireTime(), TimeUnit.MINUTES); + RedisUtils.setCacheObject(userKey, loginUser, tokenProperties.getExpireTime(), TimeUnit.MINUTES); } /** diff --git a/ruoyi-generator/pom.xml b/ruoyi-generator/pom.xml index a712e1fc7..d5bdc7e53 100644 --- a/ruoyi-generator/pom.xml +++ b/ruoyi-generator/pom.xml @@ -5,7 +5,7 @@ ruoyi-vue-plus com.ruoyi - 3.0.0 + 3.1.0 4.0.0 diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/domain/GenTableColumn.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/domain/GenTableColumn.java index 92ba7a982..246036089 100644 --- a/ruoyi-generator/src/main/java/com/ruoyi/generator/domain/GenTableColumn.java +++ b/ruoyi-generator/src/main/java/com/ruoyi/generator/domain/GenTableColumn.java @@ -44,6 +44,7 @@ public class GenTableColumn implements Serializable { /** * 列描述 */ + @TableField(updateStrategy = FieldStrategy.IGNORED) private String columnComment; /** @@ -65,36 +66,43 @@ public class GenTableColumn implements Serializable { /** * 是否主键(1是) */ + @TableField(updateStrategy = FieldStrategy.IGNORED) private String isPk; /** * 是否自增(1是) */ + @TableField(updateStrategy = FieldStrategy.IGNORED) private String isIncrement; /** * 是否必填(1是) */ + @TableField(updateStrategy = FieldStrategy.IGNORED) private String isRequired; /** * 是否为插入字段(1是) */ + @TableField(updateStrategy = FieldStrategy.IGNORED) private String isInsert; /** * 是否编辑字段(1是) */ + @TableField(updateStrategy = FieldStrategy.IGNORED) private String isEdit; /** * 是否列表字段(1是) */ + @TableField(updateStrategy = FieldStrategy.IGNORED) private String isList; /** * 是否查询字段(1是) */ + @TableField(updateStrategy = FieldStrategy.IGNORED) private String isQuery; /** diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableServiceImpl.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableServiceImpl.java index 94a9975c6..9280abc73 100644 --- a/ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableServiceImpl.java +++ b/ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableServiceImpl.java @@ -2,9 +2,7 @@ package com.ruoyi.generator.service; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.convert.Convert; -import com.ruoyi.common.utils.StringUtils; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.constant.GenConstants; import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl; @@ -13,6 +11,7 @@ import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.JsonUtils; import com.ruoyi.common.utils.PageUtils; import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.file.FileUtils; import com.ruoyi.generator.domain.GenTable; import com.ruoyi.generator.domain.GenTableColumn; @@ -34,10 +33,7 @@ import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.StringWriter; -import java.util.Arrays; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; @@ -134,18 +130,7 @@ public class GenTableServiceImpl extends ServicePlusImpl 0) { for (GenTableColumn cenTableColumn : genTable.getColumns()) { - genTableColumnMapper.update(cenTableColumn, - new LambdaUpdateWrapper() - .set(StringUtils.isBlank(cenTableColumn.getColumnComment()), GenTableColumn::getColumnComment, null) - .set(StringUtils.isBlank(cenTableColumn.getIsPk()), GenTableColumn::getIsPk, null) - .set(StringUtils.isBlank(cenTableColumn.getIsIncrement()), GenTableColumn::getIsIncrement, null) - .set(StringUtils.isBlank(cenTableColumn.getIsInsert()), GenTableColumn::getIsInsert, null) - .set(StringUtils.isBlank(cenTableColumn.getIsEdit()), GenTableColumn::getIsEdit, null) - .set(StringUtils.isBlank(cenTableColumn.getIsList()), GenTableColumn::getIsList, null) - .set(StringUtils.isBlank(cenTableColumn.getIsQuery()), GenTableColumn::getIsQuery, null) - .set(StringUtils.isBlank(cenTableColumn.getIsRequired()), GenTableColumn::getIsRequired, null) - .set(StringUtils.isBlank(cenTableColumn.getDictType()), GenTableColumn::getDictType, "") - .eq(GenTableColumn::getColumnId,cenTableColumn.getColumnId())); + genTableColumnMapper.updateById(cenTableColumn); } } } @@ -178,13 +163,17 @@ public class GenTableServiceImpl extends ServicePlusImpl 0) { - // 保存列信息 - List genTableColumns = genTableColumnMapper.selectDbTableColumnsByName(tableName); - for (GenTableColumn column : genTableColumns) { - GenUtils.initColumnField(column, table); - genTableColumnMapper.insert(column); - } + if (row > 0) { + // 保存列信息 + List genTableColumns = genTableColumnMapper.selectDbTableColumnsByName(tableName); + List saveColumns = new ArrayList<>(); + for (GenTableColumn column : genTableColumns) { + GenUtils.initColumnField(column, table); + saveColumns.add(column); + } + if (CollUtil.isNotEmpty(saveColumns)) { + genTableColumnMapper.insertAll(saveColumns); + } } } } catch (Exception e) { @@ -292,12 +281,16 @@ public class GenTableServiceImpl extends ServicePlusImpl dbTableColumnNames = dbTableColumns.stream().map(GenTableColumn::getColumnName).collect(Collectors.toList()); - dbTableColumns.forEach(column -> { - if (!tableColumnNames.contains(column.getColumnName())) { - GenUtils.initColumnField(column, table); - genTableColumnMapper.insert(column); + List saveColumns = new ArrayList<>(); + dbTableColumns.forEach(column -> { + if (!tableColumnNames.contains(column.getColumnName())) { + GenUtils.initColumnField(column, table); + saveColumns.add(column); } }); + if (CollUtil.isNotEmpty(saveColumns)) { + genTableColumnMapper.insertAll(saveColumns); + } List delColumns = tableColumns.stream().filter(column -> !dbTableColumnNames.contains(column.getColumnName())).collect(Collectors.toList()); if (CollUtil.isNotEmpty(delColumns)) { diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/util/GenUtils.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/util/GenUtils.java index 01afce003..a64ac3e10 100644 --- a/ruoyi-generator/src/main/java/com/ruoyi/generator/util/GenUtils.java +++ b/ruoyi-generator/src/main/java/com/ruoyi/generator/util/GenUtils.java @@ -164,9 +164,10 @@ public class GenUtils */ public static String getBusinessName(String tableName) { - int lastIndex = tableName.lastIndexOf("_"); + int firstIndex = tableName.indexOf("_"); int nameLength = tableName.length(); - String businessName = StringUtils.substring(tableName, lastIndex + 1, nameLength); + String businessName = StringUtils.substring(tableName, firstIndex + 1, nameLength); + businessName = StringUtils.toCamelCase(businessName); return businessName; } diff --git a/ruoyi-generator/src/main/resources/mapper/generator/GenTableMapper.xml b/ruoyi-generator/src/main/resources/mapper/generator/GenTableMapper.xml index c752c5cfb..768b9fdb0 100644 --- a/ruoyi-generator/src/main/resources/mapper/generator/GenTableMapper.xml +++ b/ruoyi-generator/src/main/resources/mapper/generator/GenTableMapper.xml @@ -92,6 +92,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" AND date_format(create_time,'%y%m%d') <= date_format(#{genTable.params.endTime},'%y%m%d') + order by create_time desc @@ -130,6 +131,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" AND date_format(create_time,'%y%m%d') <= date_format(#{params.endTime},'%y%m%d') + order by create_time desc - +