diff --git a/pom.xml b/pom.xml index eb11dd3d..4b39a3d6 100644 --- a/pom.xml +++ b/pom.xml @@ -14,27 +14,26 @@ 0.7.2 - 2.7.5 + 2.7.6 UTF-8 UTF-8 1.8 3.2.2 2.2.2 - 1.2.12 - 1.6.12 + 1.6.13 5.2.3 - 3.1.1 + 3.1.3 2.3 - 1.31.0 + 1.33.0 3.5.2 3.9.1 - 5.8.8 + 5.8.10 4.10.0 - 2.7.6 - 3.17.7 - 2.2.2 + 2.7.7 + 3.18.0 + 2.2.3 3.5.2 - 1.5.0 + 2.14.2 2.3.1 1.18.24 6.7.2 @@ -45,10 +44,10 @@ 1.32 - 1.12.324 + 1.12.349 2.0.22 - 3.1.611 + 3.1.635 @@ -73,13 +72,6 @@ import - - - com.alibaba - druid-spring-boot-starter - ${druid.version} - - org.springdoc springdoc-openapi-webmvc-core @@ -190,7 +182,7 @@ com.tencentcloudapi - tencentcloud-sdk-java + tencentcloud-sdk-java-sms ${tencent.sms.version} @@ -225,29 +217,9 @@ - com.yomahub - tlog-web-spring-boot-starter - ${tlog.version} - - - log4j - log4j - - - dom4j - dom4j - - - commons-beanutils - commons-beanutils - - - - - - com.yomahub - tlog-xxljob-spring-boot-starter - ${tlog.version} + com.alibaba + transmittable-thread-local + ${alibaba-ttl.version} @@ -381,6 +353,19 @@ + + + org.apache.maven.plugins + maven-surefire-plugin + 2.22.2 + + -Dfile.encoding=UTF-8 + + ${profiles.active} + + exclude + + @@ -405,8 +390,8 @@ public - aliyun nexus - https://maven.aliyun.com/repository/public/ + huawei nexus + https://mirrors.huaweicloud.com/repository/maven/ true @@ -416,8 +401,8 @@ public - aliyun nexus - https://maven.aliyun.com/repository/public/ + huawei nexus + https://mirrors.huaweicloud.com/repository/maven/ true diff --git a/ruoyi-admin/Dockerfile b/ruoyi-admin/Dockerfile index 7bb2b0d0..6033f7e8 100644 --- a/ruoyi-admin/Dockerfile +++ b/ruoyi-admin/Dockerfile @@ -2,9 +2,9 @@ FROM anapsix/alpine-java:8_server-jre_unlimited MAINTAINER Lion Li -RUN mkdir -p /ruoyi/server -RUN mkdir -p /ruoyi/server/logs -RUN mkdir -p /ruoyi/server/temp +RUN mkdir -p /ruoyi/server/logs \ + /ruoyi/server/temp \ + /ruoyi/skywalking/agent WORKDIR /ruoyi/server @@ -14,4 +14,10 @@ EXPOSE ${SERVER_PORT} ADD ./target/ruoyi-admin.jar ./app.jar -ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-Dserver.port=${SERVER_PORT}","-jar", "app.jar"] +ENTRYPOINT ["java", \ + "-Djava.security.egd=file:/dev/./urandom", \ + "-Dserver.port=${SERVER_PORT}", \ + # 应用名称 如果想区分集群节点监控 改成不同的名称即可 +# "-Dskywalking.agent.service_name=ruoyi-server", \ +# "-javaagent:/ruoyi/skywalking/agent/skywalking-agent.jar", \ + "-jar", "app.jar"] diff --git a/ruoyi-admin/pom.xml b/ruoyi-admin/pom.xml index ec98c454..77447e20 100644 --- a/ruoyi-admin/pom.xml +++ b/ruoyi-admin/pom.xml @@ -26,8 +26,8 @@ - mysql - mysql-connector-java + com.mysql + mysql-connector-j @@ -84,6 +84,24 @@ ruoyi-flowable + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + + + + + + + + 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 01a4a82c..b0b574c3 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 @@ -42,7 +42,7 @@ public class SysUserOnlineController extends BaseController { @GetMapping("/list") public TableDataInfo list(String ipaddr, String userName) { // 获取所有未过期的 token - List keys = StpUtil.searchTokenValue("", -1, 0, false); + List keys = StpUtil.searchTokenValue("", 0, -1, false); List userOnlineDTOList = new ArrayList<>(); for (String key : keys) { String token = key.replace(CacheConstants.LOGIN_TOKEN_KEY, ""); @@ -83,7 +83,7 @@ public class SysUserOnlineController extends BaseController { public R forceLogout(@PathVariable String tokenId) { try { StpUtil.kickoutByTokenValue(tokenId); - } catch (NotLoginException e) { + } catch (NotLoginException ignored) { } return R.ok(); } 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 411eee9e..fa763df3 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 @@ -108,10 +108,10 @@ public class SysDeptController extends BaseController { @DeleteMapping("/{deptId}") public R remove(@PathVariable Long deptId) { if (deptService.hasChildByDeptId(deptId)) { - return R.fail("存在下级部门,不允许删除"); + return R.warn("存在下级部门,不允许删除"); } if (deptService.checkDeptExistUser(deptId)) { - return R.fail("部门存在用户,不允许删除"); + return R.warn("部门存在用户,不允许删除"); } deptService.checkDeptDataScope(deptId); return toAjax(deptService.deleteDeptById(deptId)); diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysMenuController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysMenuController.java index 2000fd03..e80f0ee7 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysMenuController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysMenuController.java @@ -117,10 +117,10 @@ public class SysMenuController extends BaseController { @DeleteMapping("/{menuId}") public R remove(@PathVariable("menuId") Long menuId) { if (menuService.hasChildByMenuId(menuId)) { - return R.fail("存在子菜单,不允许删除"); + return R.warn("存在子菜单,不允许删除"); } if (menuService.checkMenuExistRole(menuId)) { - return R.fail("菜单已分配,不允许删除"); + return R.warn("菜单已分配,不允许删除"); } return toAjax(menuService.deleteMenuById(menuId)); } 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 cdba39cc..8dc4876e 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 @@ -66,7 +66,7 @@ public class SysOssConfigController extends BaseController { @RepeatSubmit() @PostMapping() public R add(@Validated(AddGroup.class) @RequestBody SysOssConfigBo bo) { - return toAjax(iSysOssConfigService.insertByBo(bo) ? 1 : 0); + return toAjax(iSysOssConfigService.insertByBo(bo)); } /** @@ -77,7 +77,7 @@ public class SysOssConfigController extends BaseController { @RepeatSubmit() @PutMapping() public R edit(@Validated(EditGroup.class) @RequestBody SysOssConfigBo bo) { - return toAjax(iSysOssConfigService.updateByBo(bo) ? 1 : 0); + return toAjax(iSysOssConfigService.updateByBo(bo)); } /** @@ -90,7 +90,7 @@ public class SysOssConfigController extends BaseController { @DeleteMapping("/{ossConfigIds}") public R remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] ossConfigIds) { - return toAjax(iSysOssConfigService.deleteWithValidByIds(Arrays.asList(ossConfigIds), true) ? 1 : 0); + return toAjax(iSysOssConfigService.deleteWithValidByIds(Arrays.asList(ossConfigIds), true)); } /** 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 fac5ddef..606895a7 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 @@ -15,6 +15,8 @@ import com.ruoyi.common.core.validate.QueryGroup; import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.file.FileUtils; +import com.ruoyi.oss.core.OssClient; +import com.ruoyi.oss.factory.OssFactory; import com.ruoyi.system.domain.SysOss; import com.ruoyi.system.domain.bo.SysOssBo; import com.ruoyi.system.domain.vo.SysOssVo; @@ -80,7 +82,7 @@ public class SysOssController extends BaseController { if (ObjectUtil.isNull(file)) { throw new ServiceException("上传文件不能为空"); } - SysOss oss = iSysOssService.upload(file); + SysOssVo oss = iSysOssService.upload(file); Map map = new HashMap<>(2); map.put("url", oss.getUrl()); map.put("fileName", oss.getOriginalName()); @@ -96,23 +98,7 @@ public class SysOssController extends BaseController { @SaCheckPermission("system:oss:download") @GetMapping("/download/{ossId}") public void download(@PathVariable Long ossId, HttpServletResponse response) throws IOException { - SysOssVo sysOss = iSysOssService.getById(ossId); - if (ObjectUtil.isNull(sysOss)) { - throw new ServiceException("文件数据不存在!"); - } - FileUtils.setAttachmentResponseHeader(response, sysOss.getOriginalName()); - response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE + "; charset=UTF-8"); - long data; - try { - data = HttpUtil.download(sysOss.getUrl(), response.getOutputStream(), false); - } catch (HttpException e) { - if (e.getMessage().contains("403")) { - throw new ServiceException("无读取权限, 请在对应的OSS开启'公有读'权限!"); - } else { - throw new ServiceException(e.getMessage()); - } - } - response.setContentLength(Convert.toInt(data)); + iSysOssService.download(ossId,response); } /** @@ -125,7 +111,7 @@ public class SysOssController extends BaseController { @DeleteMapping("/{ossIds}") public R remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] ossIds) { - return toAjax(iSysOssService.deleteWithValidByIds(Arrays.asList(ossIds), true) ? 1 : 0); + return toAjax(iSysOssService.deleteWithValidByIds(Arrays.asList(ossIds), true)); } } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java index 5c331681..77a8767d 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 @@ -12,6 +12,7 @@ import com.ruoyi.common.helper.LoginHelper; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.file.MimeTypeUtils; import com.ruoyi.system.domain.SysOss; +import com.ruoyi.system.domain.vo.SysOssVo; import com.ruoyi.system.service.ISysOssService; import com.ruoyi.system.service.ISysUserService; import lombok.RequiredArgsConstructor; @@ -115,7 +116,7 @@ public class SysProfileController extends BaseController { if (!StringUtils.equalsAnyIgnoreCase(extension, MimeTypeUtils.IMAGE_EXTENSION)) { return R.fail("文件格式不正确,请上传" + Arrays.toString(MimeTypeUtils.IMAGE_EXTENSION) + "格式"); } - SysOss oss = iSysOssService.upload(avatarfile); + SysOssVo oss = iSysOssService.upload(avatarfile); String avatar = oss.getUrl(); if (userService.updateUserAvatar(getUsername(), avatar)) { ajax.put("imgUrl", avatar); 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 215b53c9..7e358d51 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 @@ -1,6 +1,5 @@ package com.ruoyi.web.controller.system; -import cn.dev33.satoken.annotation.SaCheckLogin; import cn.dev33.satoken.annotation.SaCheckPermission; import cn.dev33.satoken.secure.BCrypt; import cn.hutool.core.bean.BeanUtil; @@ -66,15 +65,6 @@ public class SysUserController extends BaseController { return userService.selectPageUserList(user, pageQuery); } - /** - * 查询用户列表,用于用户选择场景 - */ - @SaCheckLogin - @GetMapping("/selectUser") - public TableDataInfo selectUser(SysUser user, PageQuery pageQuery) { - return userService.selectPageUserList(user, pageQuery); - } - /** * 导出用户列表 */ diff --git a/ruoyi-admin/src/main/resources/application-dev.yml b/ruoyi-admin/src/main/resources/application-dev.yml index 5844a242..98041c09 100644 --- a/ruoyi-admin/src/main/resources/application-dev.yml +++ b/ruoyi-admin/src/main/resources/application-dev.yml @@ -33,7 +33,7 @@ xxl.job: --- # 数据源配置 spring: datasource: - type: com.alibaba.druid.pool.DruidDataSource + type: com.zaxxer.hikari.HikariDataSource # 动态数据源文档 https://www.kancloud.cn/tracy5546/dynamic-datasource/content dynamic: # 性能分析插件(有性能损耗 不建议生产环境使用) @@ -45,6 +45,7 @@ spring: datasource: # 主库数据源 master: + type: ${spring.datasource.type} driverClassName: com.mysql.cj.jdbc.Driver # jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562 # rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应考虑性能问题) @@ -54,72 +55,46 @@ spring: # 从库数据源 slave: lazy: true + type: ${spring.datasource.type} driverClassName: com.mysql.cj.jdbc.Driver - url: + url: jdbc:mysql://localhost:3306/ry-flowable-plus?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&nullCatalogMeansCurrent=true username: password: # oracle: +# type: ${spring.datasource.type} # driverClassName: oracle.jdbc.OracleDriver # url: jdbc:oracle:thin:@//localhost:1521/XE # username: ROOT # password: root -# druid: -# validationQuery: SELECT 1 FROM DUAL +# hikari: +# connectionTestQuery: SELECT 1 FROM DUAL # postgres: +# type: ${spring.datasource.type} # driverClassName: org.postgresql.Driver # url: jdbc:postgresql://localhost:5432/postgres?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true # username: root # password: root # sqlserver: +# type: ${spring.datasource.type} # driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver -# url: jdbc:sqlserver://localhost:1433;DatabaseName=tempdb;SelectMethod=cursor;rewriteBatchedStatements=true +# url: jdbc:sqlserver://localhost:1433;DatabaseName=tempdb;SelectMethod=cursor;encrypt=false;rewriteBatchedStatements=true # username: SA # password: root - druid: - # 初始连接数 - initialSize: 5 - # 最小连接池数量 - minIdle: 10 + hikari: # 最大连接池数量 - maxActive: 20 + maxPoolSize: 20 + # 最小空闲线程数量 + minIdle: 10 # 配置获取连接等待超时的时间 - maxWait: 60000 - # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 - timeBetweenEvictionRunsMillis: 60000 - # 配置一个连接在池中最小生存的时间,单位是毫秒 - minEvictableIdleTimeMillis: 300000 - # 配置一个连接在池中最大生存的时间,单位是毫秒 - maxEvictableIdleTimeMillis: 900000 - # 配置检测连接是否有效 - validationQuery: SELECT 1 - testWhileIdle: true - testOnBorrow: false - testOnReturn: false - # 注意这个值和druid原生不一致,默认启动了stat - filters: stat - ---- # druid 配置 -spring.datasource.druid: - webStatFilter: - enabled: true - statViewServlet: - enabled: true - # 设置白名单,不填则允许所有访问 - allow: - url-pattern: /druid/* - # 控制台管理用户名和密码 - login-username: ruoyi - login-password: 123456 - filter: - stat: - enabled: true - # 慢SQL记录 - log-slow-sql: true - slow-sql-millis: 1000 - merge-sql: true - wall: - config: - multi-statement-allow: true + connectionTimeout: 10000 + # 校验超时时间 + validationTimeout: 5000 + # 空闲连接存活最大时间,默认10分钟 + idleTimeout: 60000 + # 此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认30分钟 + maxLifetime: 900000 + # 连接测试query(配置检测连接是否有效) + connectionTestQuery: SELECT 1 --- # redis 单机配置(单机与集群只能开启一个另一个需要注释掉) spring: diff --git a/ruoyi-admin/src/main/resources/application-prod.yml b/ruoyi-admin/src/main/resources/application-prod.yml index 0987874f..970fe4c5 100644 --- a/ruoyi-admin/src/main/resources/application-prod.yml +++ b/ruoyi-admin/src/main/resources/application-prod.yml @@ -36,7 +36,7 @@ xxl.job: --- # 数据源配置 spring: datasource: - type: com.alibaba.druid.pool.DruidDataSource + type: com.zaxxer.hikari.HikariDataSource # 动态数据源文档 https://www.kancloud.cn/tracy5546/dynamic-datasource/content dynamic: # 性能分析插件(有性能损耗 不建议生产环境使用) @@ -48,6 +48,7 @@ spring: datasource: # 主库数据源 master: + type: ${spring.datasource.type} driverClassName: com.mysql.cj.jdbc.Driver # jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562 # rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应考虑性能问题) @@ -57,72 +58,46 @@ spring: # 从库数据源 slave: lazy: true + type: ${spring.datasource.type} driverClassName: com.mysql.cj.jdbc.Driver - url: + url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true username: password: # oracle: +# type: ${spring.datasource.type} # driverClassName: oracle.jdbc.OracleDriver # url: jdbc:oracle:thin:@//localhost:1521/XE # username: ROOT # password: root -# druid: -# validationQuery: SELECT 1 FROM DUAL +# hikari: +# connectionTestQuery: SELECT 1 FROM DUAL # postgres: +# type: ${spring.datasource.type} # driverClassName: org.postgresql.Driver # url: jdbc:postgresql://localhost:5432/postgres?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true # username: root # password: root # sqlserver: +# type: ${spring.datasource.type} # driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver -# url: jdbc:sqlserver://localhost:1433;DatabaseName=tempdb;SelectMethod=cursor;rewriteBatchedStatements=true +# url: jdbc:sqlserver://localhost:1433;DatabaseName=tempdb;SelectMethod=cursor;encrypt=false;rewriteBatchedStatements=true # username: SA # password: root - druid: - # 初始连接数 - initialSize: 5 - # 最小连接池数量 - minIdle: 10 + hikari: # 最大连接池数量 - maxActive: 20 + maxPoolSize: 20 + # 最小空闲线程数量 + minIdle: 10 # 配置获取连接等待超时的时间 - maxWait: 60000 - # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 - timeBetweenEvictionRunsMillis: 60000 - # 配置一个连接在池中最小生存的时间,单位是毫秒 - minEvictableIdleTimeMillis: 300000 - # 配置一个连接在池中最大生存的时间,单位是毫秒 - maxEvictableIdleTimeMillis: 900000 - # 配置检测连接是否有效 - validationQuery: SELECT 1 - testWhileIdle: true - testOnBorrow: false - testOnReturn: false - # 注意这个值和druid原生不一致,默认启动了stat - filters: stat - ---- # druid 配置 -spring.datasource.druid: - webStatFilter: - enabled: true - statViewServlet: - enabled: true - # 设置白名单,不填则允许所有访问 - allow: - url-pattern: /druid/* - # 控制台管理用户名和密码 - login-username: ruoyi - login-password: 123456 - filter: - stat: - enabled: true - # 慢SQL记录 - log-slow-sql: true - slow-sql-millis: 1000 - merge-sql: true - wall: - config: - multi-statement-allow: true + connectionTimeout: 10000 + # 校验超时时间 + validationTimeout: 5000 + # 空闲连接存活最大时间,默认10分钟 + idleTimeout: 60000 + # 此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认30分钟 + maxLifetime: 900000 + # 连接测试query(配置检测连接是否有效) + connectionTestQuery: SELECT 1 --- # redis 单机配置(单机与集群只能开启一个另一个需要注释掉) spring: diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml index ab78e332..176cb938 100644 --- a/ruoyi-admin/src/main/resources/application.yml +++ b/ruoyi-admin/src/main/resources/application.yml @@ -115,8 +115,6 @@ sa-token: token-prefix: "Bearer" # jwt秘钥 jwt-secret-key: abcdefghijklmnopqrstuvwxyz - # 是否输出操作日志 - is-log: true # security配置 security: @@ -131,8 +129,6 @@ security: - /favicon.ico - /*/api-docs - /*/api-docs/** - # druid 监控配置 - - /druid/** # actuator 监控配置 - /actuator - /actuator/** diff --git a/ruoyi-admin/src/main/resources/logback.xml b/ruoyi-admin/src/main/resources/logback.xml index b78044b3..40fa33b7 100644 --- a/ruoyi-admin/src/main/resources/logback.xml +++ b/ruoyi-admin/src/main/resources/logback.xml @@ -7,7 +7,7 @@ - + ${console.log.pattern} utf-8 @@ -22,7 +22,7 @@ 1 - + ${log.pattern} utf-8 @@ -42,7 +42,7 @@ 60 - + ${log.pattern} @@ -64,7 +64,7 @@ 60 - + ${log.pattern} @@ -78,7 +78,7 @@ - + 0 @@ -88,7 +88,7 @@ - + 0 @@ -97,12 +97,33 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/ruoyi-admin/src/main/resources/spy.properties b/ruoyi-admin/src/main/resources/spy.properties index bee2392d..abbd8931 100644 --- a/ruoyi-admin/src/main/resources/spy.properties +++ b/ruoyi-admin/src/main/resources/spy.properties @@ -24,3 +24,5 @@ outagedetection=true outagedetectioninterval=2 # 是否过滤 Log filter=true +# 过滤 Log 时所排除的 sql 关键字,以逗号分隔 +exclude=SELECT 1 diff --git a/ruoyi-admin/src/test/java/com/ruoyi/test/AssertUnitTest.java b/ruoyi-admin/src/test/java/com/ruoyi/test/AssertUnitTest.java new file mode 100644 index 00000000..5b9c9f84 --- /dev/null +++ b/ruoyi-admin/src/test/java/com/ruoyi/test/AssertUnitTest.java @@ -0,0 +1,45 @@ +package com.ruoyi.test; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +/** + * 断言单元测试案例 + * + * @author Lion Li + */ +@DisplayName("断言单元测试案例") +public class AssertUnitTest { + + @DisplayName("测试 assertEquals 方法") + @Test + public void testAssertEquals() { + Assertions.assertEquals("666", new String("666")); + Assertions.assertNotEquals("666", new String("666")); + } + + @DisplayName("测试 assertSame 方法") + @Test + public void testAssertSame() { + Object obj = new Object(); + Object obj1 = obj; + Assertions.assertSame(obj, obj1); + Assertions.assertNotSame(obj, obj1); + } + + @DisplayName("测试 assertTrue 方法") + @Test + public void testAssertTrue() { + Assertions.assertTrue(true); + Assertions.assertFalse(true); + } + + @DisplayName("测试 assertNull 方法") + @Test + public void testAssertNull() { + Assertions.assertNull(null); + Assertions.assertNotNull(null); + } + +} diff --git a/ruoyi-admin/src/test/java/com/ruoyi/test/DemoUnitTest.java b/ruoyi-admin/src/test/java/com/ruoyi/test/DemoUnitTest.java new file mode 100644 index 00000000..a40fd827 --- /dev/null +++ b/ruoyi-admin/src/test/java/com/ruoyi/test/DemoUnitTest.java @@ -0,0 +1,70 @@ +package com.ruoyi.test; + +import com.ruoyi.common.config.RuoYiConfig; +import org.junit.jupiter.api.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import java.util.concurrent.TimeUnit; + +/** + * 单元测试案例 + * + * @author Lion Li + */ +@SpringBootTest // 此注解只能在 springboot 主包下使用 需包含 main 方法与 yml 配置文件 +@DisplayName("单元测试案例") +public class DemoUnitTest { + + @Autowired + private RuoYiConfig ruoYiConfig; + + @DisplayName("测试 @SpringBootTest @Test @DisplayName 注解") + @Test + public void testTest() { + System.out.println(ruoYiConfig); + } + + @Disabled + @DisplayName("测试 @Disabled 注解") + @Test + public void testDisabled() { + System.out.println(ruoYiConfig); + } + + @Timeout(value = 2L, unit = TimeUnit.SECONDS) + @DisplayName("测试 @Timeout 注解") + @Test + public void testTimeout() throws InterruptedException { + Thread.sleep(3000); + System.out.println(ruoYiConfig); + } + + + @DisplayName("测试 @RepeatedTest 注解") + @RepeatedTest(3) + public void testRepeatedTest() { + System.out.println(666); + } + + @BeforeAll + public static void testBeforeAll() { + System.out.println("@BeforeAll =================="); + } + + @BeforeEach + public void testBeforeEach() { + System.out.println("@BeforeEach =================="); + } + + @AfterEach + public void testAfterEach() { + System.out.println("@AfterEach =================="); + } + + @AfterAll + public static void testAfterAll() { + System.out.println("@AfterAll =================="); + } + +} diff --git a/ruoyi-admin/src/test/java/com/ruoyi/test/ParamUnitTest.java b/ruoyi-admin/src/test/java/com/ruoyi/test/ParamUnitTest.java new file mode 100644 index 00000000..04bf1b5c --- /dev/null +++ b/ruoyi-admin/src/test/java/com/ruoyi/test/ParamUnitTest.java @@ -0,0 +1,72 @@ +package com.ruoyi.test; + +import com.ruoyi.common.enums.UserType; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; +import org.junit.jupiter.params.provider.MethodSource; +import org.junit.jupiter.params.provider.NullSource; +import org.junit.jupiter.params.provider.ValueSource; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Stream; + +/** + * 带参数单元测试案例 + * + * @author Lion Li + */ +@DisplayName("带参数单元测试案例") +public class ParamUnitTest { + + @DisplayName("测试 @ValueSource 注解") + @ParameterizedTest + @ValueSource(strings = {"t1", "t2", "t3"}) + public void testValueSource(String str) { + System.out.println(str); + } + + @DisplayName("测试 @NullSource 注解") + @ParameterizedTest + @NullSource + public void testNullSource(String str) { + System.out.println(str); + } + + @DisplayName("测试 @EnumSource 注解") + @ParameterizedTest + @EnumSource(UserType.class) + public void testEnumSource(UserType type) { + System.out.println(type.getUserType()); + } + + @DisplayName("测试 @MethodSource 注解") + @ParameterizedTest + @MethodSource("getParam") + public void testMethodSource(String str) { + System.out.println(str); + } + + public static Stream getParam() { + List list = new ArrayList<>(); + list.add("t1"); + list.add("t2"); + list.add("t3"); + return list.stream(); + } + + @BeforeEach + public void testBeforeEach() { + System.out.println("@BeforeEach =================="); + } + + @AfterEach + public void testAfterEach() { + System.out.println("@AfterEach =================="); + } + + +} diff --git a/ruoyi-admin/src/test/java/com/ruoyi/test/TagUnitTest.java b/ruoyi-admin/src/test/java/com/ruoyi/test/TagUnitTest.java new file mode 100644 index 00000000..04240a07 --- /dev/null +++ b/ruoyi-admin/src/test/java/com/ruoyi/test/TagUnitTest.java @@ -0,0 +1,54 @@ +package com.ruoyi.test; + +import org.junit.jupiter.api.*; +import org.springframework.boot.test.context.SpringBootTest; + +/** + * 标签单元测试案例 + * + * @author Lion Li + */ +@SpringBootTest +@DisplayName("标签单元测试案例") +public class TagUnitTest { + + @Tag("dev") + @DisplayName("测试 @Tag dev") + @Test + public void testTagDev() { + System.out.println("dev"); + } + + @Tag("prod") + @DisplayName("测试 @Tag prod") + @Test + public void testTagProd() { + System.out.println("prod"); + } + + @Tag("local") + @DisplayName("测试 @Tag local") + @Test + public void testTagLocal() { + System.out.println("local"); + } + + @Tag("exclude") + @DisplayName("测试 @Tag exclude") + @Test + public void testTagExclude() { + System.out.println("exclude"); + } + + @BeforeEach + public void testBeforeEach() { + System.out.println("@BeforeEach =================="); + } + + @AfterEach + public void testAfterEach() { + System.out.println("@AfterEach =================="); + } + + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/annotation/Anonymous.java b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/Anonymous.java deleted file mode 100644 index 51eaf082..00000000 --- a/ruoyi-common/src/main/java/com/ruoyi/common/annotation/Anonymous.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.ruoyi.common.annotation; - -import cn.dev33.satoken.annotation.SaIgnore; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * 匿名访问不鉴权注解 - * - * @author ruoyi - * @deprecated 将在后续版本使用Sa-Token注解 {@link SaIgnore} 代替 - */ -@Deprecated -@Target({ElementType.METHOD, ElementType.TYPE}) -@Retention(RetentionPolicy.RUNTIME) -@Documented -public @interface Anonymous { -} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/annotation/DictDataMapper.java b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/DictDataMapper.java new file mode 100644 index 00000000..5c14a552 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/DictDataMapper.java @@ -0,0 +1,27 @@ +package com.ruoyi.common.annotation; + +import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.ruoyi.common.jackson.DictDataJsonSerializer; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 字典数据映射注解 + * + * @author itino + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.FIELD, ElementType.METHOD}) +@JacksonAnnotationsInside +@JsonSerialize(using = DictDataJsonSerializer.class) +public @interface DictDataMapper { + + /** + * 设置字典的type值 (如: sys_user_sex) + */ + String dictType() default ""; +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/HttpStatus.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/HttpStatus.java new file mode 100644 index 00000000..f007b8c8 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/HttpStatus.java @@ -0,0 +1,93 @@ +package com.ruoyi.common.constant; + +/** + * 返回状态码 + * + * @author Lion Li + */ +public interface HttpStatus { + /** + * 操作成功 + */ + int SUCCESS = 200; + + /** + * 对象创建成功 + */ + int CREATED = 201; + + /** + * 请求已经被接受 + */ + int ACCEPTED = 202; + + /** + * 操作已经执行成功,但是没有返回数据 + */ + int NO_CONTENT = 204; + + /** + * 资源已被移除 + */ + int MOVED_PERM = 301; + + /** + * 重定向 + */ + int SEE_OTHER = 303; + + /** + * 资源没有被修改 + */ + int NOT_MODIFIED = 304; + + /** + * 参数列表错误(缺少,格式不匹配) + */ + int BAD_REQUEST = 400; + + /** + * 未授权 + */ + int UNAUTHORIZED = 401; + + /** + * 访问受限,授权过期 + */ + int FORBIDDEN = 403; + + /** + * 资源,服务未找到 + */ + int NOT_FOUND = 404; + + /** + * 不允许的http方法 + */ + int BAD_METHOD = 405; + + /** + * 资源冲突,或者资源被锁 + */ + int CONFLICT = 409; + + /** + * 不支持的数据,媒体类型 + */ + int UNSUPPORTED_TYPE = 415; + + /** + * 系统内部错误 + */ + int ERROR = 500; + + /** + * 接口未实现 + */ + int NOT_IMPLEMENTED = 501; + + /** + * 系统警告消息 + */ + int WARN = 601; +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/BaseEntity.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/BaseEntity.java index 5a20f9d0..bd316079 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/BaseEntity.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/BaseEntity.java @@ -2,6 +2,8 @@ package com.ruoyi.common.core.domain; import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.TableField; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; import lombok.Data; import java.io.Serializable; @@ -23,6 +25,7 @@ public class BaseEntity implements Serializable { /** * 搜索值 */ + @JsonIgnore @TableField(exist = false) private String searchValue; @@ -53,6 +56,7 @@ public class BaseEntity implements Serializable { /** * 请求参数 */ + @JsonInclude(JsonInclude.Include.NON_EMPTY) @TableField(exist = false) private Map params = new HashMap<>(); diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/R.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/R.java index 1c7b1d86..381a6f60 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/R.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/R.java @@ -1,5 +1,6 @@ package com.ruoyi.common.core.domain; +import com.ruoyi.common.constant.HttpStatus; import lombok.Data; import lombok.NoArgsConstructor; @@ -67,6 +68,27 @@ public class R implements Serializable { return restResult(null, code, msg); } + /** + * 返回警告消息 + * + * @param msg 返回内容 + * @return 警告消息 + */ + public static R warn(String msg) { + return restResult(null, HttpStatus.WARN, msg); + } + + /** + * 返回警告消息 + * + * @param msg 返回内容 + * @param data 数据对象 + * @return 警告消息 + */ + public static R warn(String msg, T data) { + return restResult(data, HttpStatus.WARN, msg); + } + private static R restResult(T data, int code, String msg) { R r = new R<>(); r.setCode(code); diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/filter/RepeatedlyRequestWrapper.java b/ruoyi-common/src/main/java/com/ruoyi/common/filter/RepeatedlyRequestWrapper.java index ca76e76c..c1cbe3f2 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/filter/RepeatedlyRequestWrapper.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/filter/RepeatedlyRequestWrapper.java @@ -12,7 +12,6 @@ import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStreamReader; -import java.nio.charset.StandardCharsets; /** * 构建可重复读取inputStream的request @@ -27,7 +26,7 @@ public class RepeatedlyRequestWrapper extends HttpServletRequestWrapper { request.setCharacterEncoding(Constants.UTF8); response.setCharacterEncoding(Constants.UTF8); - body = IoUtil.readUtf8(request.getInputStream()).getBytes(StandardCharsets.UTF_8); + body = IoUtil.readBytes(request.getInputStream(), false); } @Override 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 f1b51315..3646f1fe 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 @@ -1,6 +1,7 @@ package com.ruoyi.common.filter; import cn.hutool.core.io.IoUtil; +import cn.hutool.core.util.StrUtil; import cn.hutool.http.HtmlUtil; import com.ruoyi.common.utils.StringUtils; import org.springframework.http.HttpHeaders; @@ -50,7 +51,7 @@ public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper { } // 为空,直接返回 - String json = IoUtil.read(super.getInputStream(), StandardCharsets.UTF_8); + String json = StrUtil.str(IoUtil.readBytes(super.getInputStream(), false), StandardCharsets.UTF_8); if (StringUtils.isEmpty(json)) { return super.getInputStream(); } @@ -88,7 +89,6 @@ public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper { /** * 是否是Json请求 - * */ public boolean isJsonRequest() { String header = super.getHeader(HttpHeaders.CONTENT_TYPE); diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/helper/LoginHelper.java b/ruoyi-common/src/main/java/com/ruoyi/common/helper/LoginHelper.java index f1216662..a82f4195 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/helper/LoginHelper.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/helper/LoginHelper.java @@ -2,6 +2,7 @@ package com.ruoyi.common.helper; import cn.dev33.satoken.context.SaHolder; import cn.dev33.satoken.stp.StpUtil; +import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ObjectUtil; import com.ruoyi.common.constant.UserConstants; import com.ruoyi.common.core.domain.model.LoginUser; @@ -80,18 +81,12 @@ public class LoginHelper { LoginUser loginUser = getLoginUser(); if (ObjectUtil.isNull(loginUser)) { String loginId = StpUtil.getLoginIdAsString(); - String userId = null; - for (UserType value : UserType.values()) { - if (StringUtils.contains(loginId, value.getUserType())) { - String[] strs = StringUtils.split(loginId, JOIN_CODE); - // 用户id在总是在最后 - userId = strs[strs.length - 1]; - } - } - if (StringUtils.isBlank(userId)) { + String[] strs = StringUtils.split(loginId, JOIN_CODE); + if (!ArrayUtil.containsAny(strs, UserType.values())) { throw new UtilException("登录用户: LoginId异常 => " + loginId); } - return Long.parseLong(userId); + // 用户id在总是在最后 + return Long.parseLong(strs[strs.length - 1]); } return loginUser.getUserId(); } diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/jackson/DictDataJsonSerializer.java b/ruoyi-common/src/main/java/com/ruoyi/common/jackson/DictDataJsonSerializer.java new file mode 100644 index 00000000..caa059b9 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/jackson/DictDataJsonSerializer.java @@ -0,0 +1,56 @@ +package com.ruoyi.common.jackson; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.BeanProperty; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.ContextualSerializer; +import com.ruoyi.common.annotation.DictDataMapper; +import com.ruoyi.common.core.service.DictService; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.spring.SpringUtils; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.BeansException; + +import java.io.IOException; +import java.util.Objects; + +/** + * 字典数据json序列化工具 + * + * @author itino + */ +@Slf4j +public class DictDataJsonSerializer extends JsonSerializer implements ContextualSerializer { + + private String dictType; + + @Override + public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + try { + DictService dictService = SpringUtils.getBean(DictService.class); + if (ObjectUtil.isNotNull(dictService)) { + String label = dictService.getDictLabel(dictType, value); + gen.writeString(StringUtils.isNotBlank(label) ? label : value); + } else { + gen.writeString(value); + } + } catch (BeansException e) { + log.error("字典数据未查到, 采用默认处理 => {}", e.getMessage()); + gen.writeString(value); + } + } + + @Override + public JsonSerializer createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException { + DictDataMapper anno = property.getAnnotation(DictDataMapper.class); + if (Objects.nonNull(anno) && StrUtil.isNotBlank(anno.dictType())) { + this.dictType = anno.dictType(); + return this; + } + return prov.findValueSerializer(property.getType(), property); + } +} 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 7012a01f..91ddd3f6 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 @@ -11,6 +11,7 @@ import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; +import javax.servlet.ServletRequest; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; @@ -19,6 +20,9 @@ import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; /** * 客户端工具类 @@ -70,6 +74,31 @@ public class ServletUtils extends ServletUtil { return Convert.toBool(getRequest().getParameter(name), defaultValue); } + /** + * 获得所有请求参数 + * + * @param request 请求对象{@link ServletRequest} + * @return Map + */ + public static Map getParams(ServletRequest request) { + final Map map = request.getParameterMap(); + return Collections.unmodifiableMap(map); + } + + /** + * 获得所有请求参数 + * + * @param request 请求对象{@link ServletRequest} + * @return Map + */ + public static Map getParamMap(ServletRequest request) { + Map params = new HashMap<>(); + for (Map.Entry entry : getParams(request).entrySet()) { + params.put(entry.getKey(), StringUtils.join(entry.getValue(), ",")); + } + return params; + } + /** * 获取request */ diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/redis/RedisUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/redis/RedisUtils.java index c14b3938..80f5f528 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/redis/RedisUtils.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/redis/RedisUtils.java @@ -327,6 +327,17 @@ public class RedisUtils { return rMap.getAll(rMap.keySet()); } + /** + * 获得缓存Map的key列表 + * + * @param key 缓存的键值 + * @return key列表 + */ + public static Set getCacheMapKeySet(final String key) { + RMap rMap = CLIENT.getMap(key); + return rMap.keySet(); + } + /** * 往Hash中存入数据 * diff --git a/ruoyi-demo/pom.xml b/ruoyi-demo/pom.xml index 2a0335cd..1331fc62 100644 --- a/ruoyi-demo/pom.xml +++ b/ruoyi-demo/pom.xml @@ -36,7 +36,7 @@ - + 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 caed9756..3bd2867e 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 @@ -46,7 +46,7 @@ public class TestBatchController extends BaseController { testDemo.setValue("测试新增"); list.add(testDemo); } - return toAjax(testDemoMapper.insertBatch(list) ? 1 : 0); + return toAjax(testDemoMapper.insertBatch(list)); } /** @@ -74,7 +74,7 @@ public class TestBatchController extends BaseController { testDemo.setId(null); } } - return toAjax(testDemoMapper.insertOrUpdateBatch(list) ? 1 : 0); + return toAjax(testDemoMapper.insertOrUpdateBatch(list)); } /** 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 33b34128..873facc3 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 @@ -119,7 +119,7 @@ public class TestDemoController extends BaseController { // 使用校验工具对标 @Validated(AddGroup.class) 注解 // 用于在非 Controller 的地方校验对象 ValidatorUtils.validate(bo, AddGroup.class); - return toAjax(iTestDemoService.insertByBo(bo) ? 1 : 0); + return toAjax(iTestDemoService.insertByBo(bo)); } /** @@ -130,7 +130,7 @@ public class TestDemoController extends BaseController { @RepeatSubmit @PutMapping() public R edit(@Validated(EditGroup.class) @RequestBody TestDemoBo bo) { - return toAjax(iTestDemoService.updateByBo(bo) ? 1 : 0); + return toAjax(iTestDemoService.updateByBo(bo)); } /** @@ -143,6 +143,6 @@ public class TestDemoController extends BaseController { @DeleteMapping("/{ids}") public R remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] ids) { - return toAjax(iTestDemoService.deleteWithValidByIds(Arrays.asList(ids), true) ? 1 : 0); + return toAjax(iTestDemoService.deleteWithValidByIds(Arrays.asList(ids), true)); } } 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 52d881ed..db54230c 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 @@ -78,7 +78,7 @@ public class TestTreeController extends BaseController { @RepeatSubmit @PostMapping() public R add(@Validated(AddGroup.class) @RequestBody TestTreeBo bo) { - return toAjax(iTestTreeService.insertByBo(bo) ? 1 : 0); + return toAjax(iTestTreeService.insertByBo(bo)); } /** @@ -89,7 +89,7 @@ public class TestTreeController extends BaseController { @RepeatSubmit @PutMapping() public R edit(@Validated(EditGroup.class) @RequestBody TestTreeBo bo) { - return toAjax(iTestTreeService.updateByBo(bo) ? 1 : 0); + return toAjax(iTestTreeService.updateByBo(bo)); } /** @@ -102,6 +102,6 @@ public class TestTreeController extends BaseController { @DeleteMapping("/{ids}") public R remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] ids) { - return toAjax(iTestTreeService.deleteWithValidByIds(Arrays.asList(ids), true) ? 1 : 0); + return toAjax(iTestTreeService.deleteWithValidByIds(Arrays.asList(ids), true)); } } diff --git a/ruoyi-extend/ruoyi-monitor-admin/Dockerfile b/ruoyi-extend/ruoyi-monitor-admin/Dockerfile index b506a2dd..02b741f4 100644 --- a/ruoyi-extend/ruoyi-monitor-admin/Dockerfile +++ b/ruoyi-extend/ruoyi-monitor-admin/Dockerfile @@ -2,7 +2,6 @@ FROM anapsix/alpine-java:8_server-jre_unlimited MAINTAINER Lion Li -RUN mkdir -p /ruoyi/monitor RUN mkdir -p /ruoyi/monitor/logs WORKDIR /ruoyi/monitor diff --git a/ruoyi-extend/ruoyi-xxl-job-admin/Dockerfile b/ruoyi-extend/ruoyi-xxl-job-admin/Dockerfile index f7221bdf..bd61580a 100644 --- a/ruoyi-extend/ruoyi-xxl-job-admin/Dockerfile +++ b/ruoyi-extend/ruoyi-xxl-job-admin/Dockerfile @@ -2,7 +2,6 @@ FROM anapsix/alpine-java:8_server-jre_unlimited MAINTAINER Lion Li -RUN mkdir -p /ruoyi/xxljob RUN mkdir -p /ruoyi/xxljob/logs WORKDIR /ruoyi/xxljob @@ -14,4 +13,4 @@ EXPOSE 9100 ADD ./target/ruoyi-xxl-job-admin.jar ./app.jar -ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "app.jar"] \ No newline at end of file +ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "app.jar"] diff --git a/ruoyi-extend/ruoyi-xxl-job-admin/pom.xml b/ruoyi-extend/ruoyi-xxl-job-admin/pom.xml index d68066da..936a1ab0 100644 --- a/ruoyi-extend/ruoyi-xxl-job-admin/pom.xml +++ b/ruoyi-extend/ruoyi-xxl-job-admin/pom.xml @@ -64,8 +64,8 @@ - mysql - mysql-connector-java + com.mysql + mysql-connector-j diff --git a/ruoyi-framework/pom.xml b/ruoyi-framework/pom.xml index f139717e..274fa0c4 100644 --- a/ruoyi-framework/pom.xml +++ b/ruoyi-framework/pom.xml @@ -40,12 +40,6 @@ spring-boot-starter-aop - - - com.alibaba - druid-spring-boot-starter - - p6spy @@ -62,17 +56,17 @@ spring-boot-admin-starter-client + + com.alibaba + transmittable-thread-local + + com.ruoyi ruoyi-common - - com.yomahub - tlog-web-spring-boot-starter - - 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 0159bc3c..3b6a858a 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 @@ -21,7 +21,6 @@ import org.aspectj.lang.annotation.Aspect; import org.springframework.stereotype.Component; import org.springframework.validation.BindingResult; import org.springframework.web.multipart.MultipartFile; -import org.springframework.web.servlet.HandlerMapping; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -92,7 +91,6 @@ public class LogAspect { SpringUtils.getBean(OperLogService.class).recordOper(operLog); } catch (Exception exp) { // 记录本地异常日志 - log.error("==前置通知异常=="); log.error("异常信息:{}", exp.getMessage()); exp.printStackTrace(); } @@ -135,8 +133,9 @@ public class LogAspect { String params = argsArrayToString(joinPoint.getArgs()); operLog.setOperParam(StringUtils.substring(params, 0, 2000)); } else { - Map paramsMap = (Map) ServletUtils.getRequest().getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE); - operLog.setOperParam(StringUtils.substring(paramsMap.toString(), 0, 2000)); + Map paramsMap = ServletUtils.getParamMap(ServletUtils.getRequest()); + MapUtil.removeAny(paramsMap, EXCLUDE_PROPERTIES); + operLog.setOperParam(StringUtils.substring(JsonUtils.toJsonString(paramsMap), 0, 2000)); } } diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/DruidConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/DruidConfig.java deleted file mode 100644 index 6f7a82ec..00000000 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/DruidConfig.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.ruoyi.framework.config; - -import com.alibaba.druid.spring.boot.autoconfigure.properties.DruidStatProperties; -import com.alibaba.druid.util.Utils; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.web.servlet.FilterRegistrationBean; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import javax.servlet.*; -import java.io.IOException; - -/** - * druid 配置多数据源 - * - * @author ruoyi - */ -@Configuration -public class DruidConfig { - - /** - * 去除监控页面底部的广告 - */ - @SuppressWarnings({"rawtypes", "unchecked"}) - @Bean - @ConditionalOnProperty(name = "spring.datasource.druid.statViewServlet.enabled", havingValue = "true") - public FilterRegistrationBean removeDruidFilterRegistrationBean(DruidStatProperties properties) { - // 获取web监控页面的参数 - DruidStatProperties.StatViewServlet config = properties.getStatViewServlet(); - // 提取common.js的配置路径 - String pattern = config.getUrlPattern() != null ? config.getUrlPattern() : "/druid/*"; - String commonJsPattern = pattern.replaceAll("\\*", "js/common.js"); - final String filePath = "support/http/resources/js/common.js"; - // 创建filter进行过滤 - Filter filter = new Filter() { - @Override - public void init(javax.servlet.FilterConfig filterConfig) throws ServletException { - } - - @Override - public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) - throws IOException, ServletException { - chain.doFilter(request, response); - // 重置缓冲区,响应头不会被重置 -// response.resetBuffer(); - // 获取common.js - String text = Utils.readFromResource(filePath); - // 正则替换banner, 除去底部的广告信息 - text = text.replaceAll("
", ""); - text = text.replaceAll("powered.*?shrek.wang", ""); - response.getWriter().write(text); - } - - @Override - public void destroy() { - } - }; - FilterRegistrationBean registrationBean = new FilterRegistrationBean(); - registrationBean.setFilter(filter); - registrationBean.addUrlPatterns(commonJsPattern); - return registrationBean; - } -} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java index f43ecab7..ea83338b 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java @@ -1,7 +1,6 @@ package com.ruoyi.framework.config; import com.ruoyi.framework.interceptor.PlusWebInvokeTimeInterceptor; -import com.yomahub.tlog.web.interceptor.TLogWebInterceptor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.cors.CorsConfiguration; @@ -21,8 +20,6 @@ public class ResourcesConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { - // 全局链路跟踪拦截器 - registry.addInterceptor(new TLogWebInterceptor()); // 全局访问性能拦截 registry.addInterceptor(new PlusWebInvokeTimeInterceptor()); } diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SaTokenConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SaTokenConfig.java index a7c51fa6..29122866 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SaTokenConfig.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SaTokenConfig.java @@ -5,8 +5,6 @@ import cn.dev33.satoken.jwt.StpLogicJwtForSimple; import cn.dev33.satoken.router.SaRouter; import cn.dev33.satoken.stp.StpLogic; import cn.dev33.satoken.stp.StpUtil; -import com.ruoyi.common.utils.spring.SpringUtils; -import com.ruoyi.framework.config.properties.ExcludeUrlProperties; import com.ruoyi.framework.config.properties.SecurityProperties; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -34,14 +32,10 @@ public class SaTokenConfig implements WebMvcConfigurer { public void addInterceptors(InterceptorRegistry registry) { // 注册路由拦截器,自定义验证规则 registry.addInterceptor(new SaInterceptor(handler -> { - // 自定义注解 @Anonymous 匿名访问配置,后续版本将删除 - ExcludeUrlProperties excludeUrlProperties = SpringUtils.getBean(ExcludeUrlProperties.class); // 登录验证 -- 排除多个路径 SaRouter // 获取所有的 .match("/**") - // 排除下不需要拦截的(每次匹配) - .notMatch(excludeUrlProperties.getExcludes()) // 对未排除的路径进行检查 .check(() -> { // 检查是否登录 是否有token diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/TLogConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/TLogConfig.java deleted file mode 100644 index 5ae55add..00000000 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/TLogConfig.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.ruoyi.framework.config; - -import com.yomahub.tlog.springboot.TLogWebAutoConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.context.annotation.Configuration; - -/** - * 整合 TLog 框架配置 - * - * @author Lion Li - * @since 3.3.0 - */ -@Configuration -// 排除 web 自动配置 自定义实现 -@EnableAutoConfiguration(exclude = TLogWebAutoConfiguration.class) -public class TLogConfig { - -} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/ExcludeUrlProperties.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/ExcludeUrlProperties.java deleted file mode 100644 index 99d2eae8..00000000 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/ExcludeUrlProperties.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.ruoyi.framework.config.properties; - -import cn.dev33.satoken.annotation.SaIgnore; -import cn.dev33.satoken.interceptor.SaInterceptor; -import cn.hutool.core.util.ReUtil; -import com.ruoyi.common.annotation.Anonymous; -import com.ruoyi.common.utils.spring.SpringUtils; -import lombok.Getter; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.context.annotation.Lazy; -import org.springframework.core.annotation.AnnotationUtils; -import org.springframework.stereotype.Component; -import org.springframework.web.method.HandlerMethod; -import org.springframework.web.servlet.mvc.method.RequestMappingInfo; -import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; -import org.springframework.web.util.pattern.PathPattern; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.util.*; -import java.util.regex.Pattern; - -/** - * 设置注解允许匿名访问的url - * - * @author Lion Li - * @deprecated 将在后续版本使用Sa-Token注解 {@link SaIgnore} 代替, - * 底层过滤方法详见 {@link SaInterceptor#preHandle(HttpServletRequest, HttpServletResponse, Object)} - */ -@Deprecated -@Lazy -@Component -public class ExcludeUrlProperties implements InitializingBean { - - private static final Pattern PATTERN = Pattern.compile("\\{(.*?)\\}"); - - @Getter - private final List excludes = new ArrayList<>(); - - @Override - public void afterPropertiesSet() { - String asterisk = "*"; - RequestMappingHandlerMapping mapping = SpringUtils.getBean("requestMappingHandlerMapping", RequestMappingHandlerMapping.class); - Map map = mapping.getHandlerMethods(); - - map.keySet().forEach(info -> { - HandlerMethod handlerMethod = map.get(info); - - // 获取方法上边的注解 替代path variable 为 * - Anonymous method = AnnotationUtils.findAnnotation(handlerMethod.getMethod(), Anonymous.class); - Optional.ofNullable(method).ifPresent(anonymous -> { - Set patterns = info.getPathPatternsCondition().getPatterns(); - patterns.forEach(url -> { - excludes.add(ReUtil.replaceAll(url.getPatternString(), PATTERN, asterisk)); - }); - }); - - // 获取类上边的注解, 替代path variable 为 * - Anonymous controller = AnnotationUtils.findAnnotation(handlerMethod.getBeanType(), Anonymous.class); - Optional.ofNullable(controller).ifPresent(anonymous -> { - Set patterns = info.getPathPatternsCondition().getPatterns(); - patterns.forEach(url -> { - excludes.add(ReUtil.replaceAll(url.getPatternString(), PATTERN, asterisk)); - }); - }); - }); - } - -} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/listener/UserActionListener.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/listener/UserActionListener.java index 9c48c135..a9de17e6 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/listener/UserActionListener.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/listener/UserActionListener.java @@ -102,6 +102,20 @@ public class UserActionListener implements SaTokenListener { public void doUntieDisable(String loginType, Object loginId, String service) { } + /** + * 每次打开二级认证时触发 + */ + @Override + public void doOpenSafe(String loginType, String tokenValue, String service, long safeTime) { + } + + /** + * 每次创建Session时触发 + */ + @Override + public void doCloseSafe(String loginType, String tokenValue, String service) { + } + /** * 每次创建Session时触发 */ diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java index e04d528a..40f2d27c 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java @@ -105,7 +105,7 @@ public class GlobalExceptionHandler { public R handleServiceException(ServiceException e, HttpServletRequest request) { log.error(e.getMessage(), e); Integer code = e.getCode(); - return ObjectUtil.isNotNull(code) ? R.fail(code.intValue(), e.getMessage()) : R.fail(e.getMessage()); + return ObjectUtil.isNotNull(code) ? R.fail(code, e.getMessage()) : R.fail(e.getMessage()); } /** diff --git a/ruoyi-generator/src/main/resources/vm/java/controller.java.vm b/ruoyi-generator/src/main/resources/vm/java/controller.java.vm index 1b2bc136..3edbc338 100644 --- a/ruoyi-generator/src/main/resources/vm/java/controller.java.vm +++ b/ruoyi-generator/src/main/resources/vm/java/controller.java.vm @@ -89,7 +89,7 @@ public class ${ClassName}Controller extends BaseController { @RepeatSubmit() @PostMapping() public R add(@Validated(AddGroup.class) @RequestBody ${ClassName}Bo bo) { - return toAjax(i${ClassName}Service.insertByBo(bo) ? 1 : 0); + return toAjax(i${ClassName}Service.insertByBo(bo)); } /** @@ -100,7 +100,7 @@ public class ${ClassName}Controller extends BaseController { @RepeatSubmit() @PutMapping() public R edit(@Validated(EditGroup.class) @RequestBody ${ClassName}Bo bo) { - return toAjax(i${ClassName}Service.updateByBo(bo) ? 1 : 0); + return toAjax(i${ClassName}Service.updateByBo(bo)); } /** @@ -113,6 +113,6 @@ public class ${ClassName}Controller extends BaseController { @DeleteMapping("/{${pkColumn.javaField}s}") public R remove(@NotEmpty(message = "主键不能为空") @PathVariable ${pkColumn.javaType}[] ${pkColumn.javaField}s) { - return toAjax(i${ClassName}Service.deleteWithValidByIds(Arrays.asList(${pkColumn.javaField}s), true) ? 1 : 0); + return toAjax(i${ClassName}Service.deleteWithValidByIds(Arrays.asList(${pkColumn.javaField}s), true)); } } diff --git a/ruoyi-generator/src/main/resources/vm/vue/v3/index-tree.vue.vm b/ruoyi-generator/src/main/resources/vm/vue/v3/index-tree.vue.vm index d44e082f..01a7367f 100644 --- a/ruoyi-generator/src/main/resources/vm/vue/v3/index-tree.vue.vm +++ b/ruoyi-generator/src/main/resources/vm/vue/v3/index-tree.vue.vm @@ -136,24 +136,9 @@ #end diff --git a/ruoyi-generator/src/main/resources/vm/vue/v3/index.vue.vm b/ruoyi-generator/src/main/resources/vm/vue/v3/index.vue.vm index f7c1bd02..d0f4f8bc 100644 --- a/ruoyi-generator/src/main/resources/vm/vue/v3/index.vue.vm +++ b/ruoyi-generator/src/main/resources/vm/vue/v3/index.vue.vm @@ -148,18 +148,8 @@ #end diff --git a/ruoyi-job/pom.xml b/ruoyi-job/pom.xml index 632faf96..a53b53bb 100644 --- a/ruoyi-job/pom.xml +++ b/ruoyi-job/pom.xml @@ -29,11 +29,6 @@ xxl-job-core - - com.yomahub - tlog-xxljob-spring-boot-starter - - diff --git a/ruoyi-job/src/main/java/com/ruoyi/job/service/SampleService.java b/ruoyi-job/src/main/java/com/ruoyi/job/service/SampleService.java index 20afa2e6..4ca170be 100644 --- a/ruoyi-job/src/main/java/com/ruoyi/job/service/SampleService.java +++ b/ruoyi-job/src/main/java/com/ruoyi/job/service/SampleService.java @@ -12,7 +12,6 @@ import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.util.Arrays; -import java.util.concurrent.TimeUnit; /** * XxlJob开发示例(Bean模式) @@ -39,7 +38,6 @@ public class SampleService { for (int i = 0; i < 5; i++) { XxlJobHelper.log("beat at:" + i); - TimeUnit.SECONDS.sleep(2); } // default success } diff --git a/ruoyi-oss/src/main/java/com/ruoyi/oss/constant/OssConstant.java b/ruoyi-oss/src/main/java/com/ruoyi/oss/constant/OssConstant.java index ff88c117..06202d0f 100644 --- a/ruoyi-oss/src/main/java/com/ruoyi/oss/constant/OssConstant.java +++ b/ruoyi-oss/src/main/java/com/ruoyi/oss/constant/OssConstant.java @@ -28,7 +28,7 @@ public interface OssConstant { /** * 云服务商 */ - String[] CLOUD_SERVICE = new String[] {"aliyun", "qcloud", "qiniu"}; + String[] CLOUD_SERVICE = new String[] {"aliyun", "qcloud", "qiniu", "obs"}; /** * https 状态 diff --git a/ruoyi-oss/src/main/java/com/ruoyi/oss/core/OssClient.java b/ruoyi-oss/src/main/java/com/ruoyi/oss/core/OssClient.java index 15833d3c..fe409ce7 100644 --- a/ruoyi-oss/src/main/java/com/ruoyi/oss/core/OssClient.java +++ b/ruoyi-oss/src/main/java/com/ruoyi/oss/core/OssClient.java @@ -1,7 +1,9 @@ package com.ruoyi.oss.core; +import cn.hutool.core.io.IoUtil; import cn.hutool.core.util.IdUtil; import com.amazonaws.ClientConfiguration; +import com.amazonaws.HttpMethod; import com.amazonaws.Protocol; import com.amazonaws.auth.AWSCredentials; import com.amazonaws.auth.AWSCredentialsProvider; @@ -16,12 +18,15 @@ import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.oss.constant.OssConstant; import com.ruoyi.oss.entity.UploadResult; +import com.ruoyi.oss.enumd.AccessPolicyType; import com.ruoyi.oss.enumd.PolicyType; import com.ruoyi.oss.exception.OssException; import com.ruoyi.oss.properties.OssProperties; import java.io.ByteArrayInputStream; import java.io.InputStream; +import java.net.URL; +import java.util.Date; /** * S3 存储协议 所有兼容S3协议的云厂商均支持 @@ -57,7 +62,7 @@ public class OssClient { .withClientConfiguration(clientConfig) .withCredentials(credentialsProvider) .disableChunkedEncoding(); - if (!StringUtils.containsAny(properties.getEndpoint(), OssConstant.CLOUD_SERVICE)){ + if (!StringUtils.containsAny(properties.getEndpoint(), OssConstant.CLOUD_SERVICE)) { // minio 使用https限制使用域名访问 需要此配置 站点填域名 build.enablePathStyleAccess(); } @@ -79,9 +84,10 @@ public class OssClient { return; } CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName); - createBucketRequest.setCannedAcl(CannedAccessControlList.PublicRead); + AccessPolicyType accessPolicy = getAccessPolicy(); + createBucketRequest.setCannedAcl(accessPolicy.getAcl()); client.createBucket(createBucketRequest); - client.setBucketPolicy(bucketName, getPolicy(bucketName, PolicyType.READ)); + client.setBucketPolicy(bucketName, getPolicy(bucketName, accessPolicy.getPolicyType())); } catch (Exception e) { throw new OssException("创建Bucket失败, 请核对配置信息:[" + e.getMessage() + "]"); } @@ -92,13 +98,16 @@ public class OssClient { } public UploadResult upload(InputStream inputStream, String path, String contentType) { + if (!(inputStream instanceof ByteArrayInputStream)) { + inputStream = new ByteArrayInputStream(IoUtil.readBytes(inputStream)); + } try { ObjectMetadata metadata = new ObjectMetadata(); metadata.setContentType(contentType); metadata.setContentLength(inputStream.available()); PutObjectRequest putObjectRequest = new PutObjectRequest(properties.getBucketName(), path, inputStream, metadata); // 设置上传对象的 Acl 为公共读 - putObjectRequest.setCannedAcl(CannedAccessControlList.PublicRead); + putObjectRequest.setCannedAcl(getAccessPolicy().getAcl()); client.putObject(putObjectRequest); } catch (Exception e) { throw new OssException("上传文件失败,请检查配置信息:[" + e.getMessage() + "]"); @@ -111,7 +120,7 @@ public class OssClient { try { client.deleteObject(properties.getBucketName(), path); } catch (Exception e) { - throw new OssException("上传文件失败,请检查配置信息:[" + e.getMessage() + "]"); + throw new OssException("删除文件失败,请检查配置信息:[" + e.getMessage() + "]"); } } @@ -129,16 +138,23 @@ public class OssClient { * @param path 完整文件路径 */ public ObjectMetadata getObjectMetadata(String path) { + path = path.replace(getUrl() + "/", ""); S3Object object = client.getObject(properties.getBucketName(), path); return object.getObjectMetadata(); } + public InputStream getObjectContent(String path) { + path = path.replace(getUrl() + "/", ""); + S3Object object = client.getObject(properties.getBucketName(), path); + return object.getObjectContent(); + } + public String getUrl() { String domain = properties.getDomain(); String endpoint = properties.getEndpoint(); String header = OssConstant.IS_HTTPS.equals(properties.getIsHttps()) ? "https://" : "http://"; // 云服务商直接返回 - if (StringUtils.containsAny(endpoint, OssConstant.CLOUD_SERVICE)){ + if (StringUtils.containsAny(endpoint, OssConstant.CLOUD_SERVICE)) { if (StringUtils.isNotBlank(domain)) { return header + domain; } @@ -167,6 +183,24 @@ public class OssClient { return configKey; } + public String getPrivateUrl(String objectKey, Integer second) { + GeneratePresignedUrlRequest generatePresignedUrlRequest = + new GeneratePresignedUrlRequest(properties.getBucketName(), objectKey) + .withMethod(HttpMethod.GET) + .withExpiration(new Date(System.currentTimeMillis() + 1000L * second)); + URL url = client.generatePresignedUrl(generatePresignedUrlRequest); + return url.toString(); + } + + /** + * 获取当前桶权限类型 + * + * @return 当前桶权限类型code + */ + public AccessPolicyType getAccessPolicy() { + return AccessPolicyType.getByType(properties.getAccessPolicy()); + } + private static String getPolicy(String bucketName, PolicyType policyType) { StringBuilder builder = new StringBuilder(); builder.append("{\n\"Statement\": [\n{\n\"Action\": [\n"); diff --git a/ruoyi-oss/src/main/java/com/ruoyi/oss/enumd/AccessPolicyType.java b/ruoyi-oss/src/main/java/com/ruoyi/oss/enumd/AccessPolicyType.java new file mode 100644 index 00000000..1cae6709 --- /dev/null +++ b/ruoyi-oss/src/main/java/com/ruoyi/oss/enumd/AccessPolicyType.java @@ -0,0 +1,55 @@ +package com.ruoyi.oss.enumd; + +import com.amazonaws.services.s3.model.CannedAccessControlList; +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 桶访问策略配置 + * + * @author 陈賝 + */ +@Getter +@AllArgsConstructor +public enum AccessPolicyType { + + /** + * private + */ + PRIVATE("0", CannedAccessControlList.Private, PolicyType.WRITE), + + /** + * public + */ + PUBLIC("1", CannedAccessControlList.PublicRead, PolicyType.READ), + + /** + * custom + */ + CUSTOM("2",CannedAccessControlList.PublicRead, PolicyType.READ); + + /** + * 桶 权限类型 + */ + private final String type; + + /** + * 文件对象 权限类型 + */ + private final CannedAccessControlList acl; + + /** + * 桶策略类型 + */ + private final PolicyType policyType; + + public static AccessPolicyType getByType(String type) { + for (AccessPolicyType value : values()) { + if (value.getType().equals(type)) { + return value; + } + } + throw new RuntimeException("'type' not found By " + type); + } + +} diff --git a/ruoyi-oss/src/main/java/com/ruoyi/oss/properties/OssProperties.java b/ruoyi-oss/src/main/java/com/ruoyi/oss/properties/OssProperties.java index a0177790..781a1700 100644 --- a/ruoyi-oss/src/main/java/com/ruoyi/oss/properties/OssProperties.java +++ b/ruoyi-oss/src/main/java/com/ruoyi/oss/properties/OssProperties.java @@ -50,4 +50,9 @@ public class OssProperties { */ private String isHttps; + /** + * 桶权限类型(0private 1public 2custom) + */ + private String accessPolicy; + } diff --git a/ruoyi-sms/pom.xml b/ruoyi-sms/pom.xml index 342a8c5f..ba7703e9 100644 --- a/ruoyi-sms/pom.xml +++ b/ruoyi-sms/pom.xml @@ -31,7 +31,7 @@ com.tencentcloudapi - tencentcloud-sdk-java + tencentcloud-sdk-java-sms true diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysOssConfig.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysOssConfig.java index 577f17fb..7f2b05f6 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysOssConfig.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysOssConfig.java @@ -82,4 +82,8 @@ public class SysOssConfig extends BaseEntity { */ private String remark; + /** + * 桶权限类型(0private 1public 2custom) + */ + private String accessPolicy; } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysOssConfigBo.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysOssConfigBo.java index e9f481d5..af289376 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysOssConfigBo.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysOssConfigBo.java @@ -98,4 +98,10 @@ public class SysOssConfigBo extends BaseEntity { */ private String remark; + /** + * 桶权限类型(0private 1public 2custom) + */ + @NotBlank(message = "桶权限类型不能为空", groups = {AddGroup.class, EditGroup.class}) + private String accessPolicy; + } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysOssConfigVo.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysOssConfigVo.java index f8b31d6b..616e4e82 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysOssConfigVo.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysOssConfigVo.java @@ -82,4 +82,9 @@ public class SysOssConfigVo { */ private String remark; + /** + * 桶权限类型(0private 1public 2custom) + */ + private String accessPolicy; + } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysOssService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysOssService.java index f02ea3d9..7f5c090e 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysOssService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysOssService.java @@ -2,11 +2,12 @@ package com.ruoyi.system.service; import com.ruoyi.common.core.domain.PageQuery; import com.ruoyi.common.core.page.TableDataInfo; -import com.ruoyi.system.domain.SysOss; import com.ruoyi.system.domain.bo.SysOssBo; import com.ruoyi.system.domain.vo.SysOssVo; import org.springframework.web.multipart.MultipartFile; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; import java.util.Collection; import java.util.List; @@ -23,7 +24,9 @@ public interface ISysOssService { SysOssVo getById(Long ossId); - SysOss upload(MultipartFile file); + SysOssVo upload(MultipartFile file); + + void download(Long ossId, HttpServletResponse response) throws IOException; Boolean deleteWithValidByIds(Collection ids, Boolean isValid); diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/SysLoginService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/SysLoginService.java index d18ceac5..6ea4a883 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/SysLoginService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/SysLoginService.java @@ -128,7 +128,7 @@ public class SysLoginService { LoginUser loginUser = LoginHelper.getLoginUser(); StpUtil.logout(); asyncService.recordLogininfor(loginUser.getUsername(), Constants.LOGOUT, MessageUtils.message("user.logout.success"), ServletUtils.getRequest()); - } catch (NotLoginException e) { + } catch (NotLoginException ignored) { } } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictTypeServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictTypeServiceImpl.java index c7dc8d62..d7244116 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictTypeServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictTypeServiceImpl.java @@ -1,10 +1,12 @@ package com.ruoyi.system.service.impl; +import cn.dev33.satoken.context.SaHolder; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.ruoyi.common.constant.CacheConstants; import com.ruoyi.common.constant.CacheNames; import com.ruoyi.common.constant.UserConstants; import com.ruoyi.common.core.domain.PageQuery; @@ -27,6 +29,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.*; +import java.util.stream.Collectors; /** * 字典 业务层处理 @@ -231,28 +234,24 @@ public class SysDictTypeServiceImpl implements ISysDictTypeService, DictService * @param separator 分隔符 * @return 字典标签 */ + @SuppressWarnings("unchecked cast") @Override public String getDictLabel(String dictType, String dictValue, String separator) { - StringBuilder propertyString = new StringBuilder(); - List datas = SpringUtils.getAopProxy(this).selectDictDataByType(dictType); - - if (StringUtils.containsAny(dictValue, separator) && CollUtil.isNotEmpty(datas)) { - for (SysDictData dict : datas) { - for (String value : dictValue.split(separator)) { - if (value.equals(dict.getDictValue())) { - propertyString.append(dict.getDictLabel() + separator); - break; - } - } - } - } else { - for (SysDictData dict : datas) { - if (dictValue.equals(dict.getDictValue())) { - return dict.getDictLabel(); - } - } + // 优先从本地缓存获取 + List datas = (List) SaHolder.getStorage().get(CacheConstants.SYS_DICT_KEY + dictType); + if (ObjectUtil.isNull(datas)) { + datas = SpringUtils.getAopProxy(this).selectDictDataByType(dictType); + SaHolder.getStorage().set(CacheConstants.SYS_DICT_KEY + dictType, datas); + } + + Map map = StreamUtils.toMap(datas, SysDictData::getDictValue, SysDictData::getDictLabel); + if (StringUtils.containsAny(dictValue, separator)) { + return Arrays.stream(dictValue.split(separator)) + .map(v -> map.getOrDefault(v, StringUtils.EMPTY)) + .collect(Collectors.joining(separator)); + } else { + return map.getOrDefault(dictValue, StringUtils.EMPTY); } - return StringUtils.stripEnd(propertyString.toString(), separator); } /** @@ -263,28 +262,24 @@ public class SysDictTypeServiceImpl implements ISysDictTypeService, DictService * @param separator 分隔符 * @return 字典值 */ + @SuppressWarnings("unchecked cast") @Override public String getDictValue(String dictType, String dictLabel, String separator) { - StringBuilder propertyString = new StringBuilder(); - List datas = SpringUtils.getAopProxy(this).selectDictDataByType(dictType); - - if (StringUtils.containsAny(dictLabel, separator) && CollUtil.isNotEmpty(datas)) { - for (SysDictData dict : datas) { - for (String label : dictLabel.split(separator)) { - if (label.equals(dict.getDictLabel())) { - propertyString.append(dict.getDictValue() + separator); - break; - } - } - } - } else { - for (SysDictData dict : datas) { - if (dictLabel.equals(dict.getDictLabel())) { - return dict.getDictValue(); - } - } + // 优先从本地缓存获取 + List datas = (List) SaHolder.getStorage().get(CacheConstants.SYS_DICT_KEY + dictType); + if (ObjectUtil.isNull(datas)) { + datas = SpringUtils.getAopProxy(this).selectDictDataByType(dictType); + SaHolder.getStorage().set(CacheConstants.SYS_DICT_KEY + dictType, datas); + } + + Map map = StreamUtils.toMap(datas, SysDictData::getDictLabel, SysDictData::getDictValue); + if (StringUtils.containsAny(dictLabel, separator)) { + return Arrays.stream(dictLabel.split(separator)) + .map(l -> map.getOrDefault(l, StringUtils.EMPTY)) + .collect(Collectors.joining(separator)); + } else { + return map.getOrDefault(dictLabel, StringUtils.EMPTY); } - return StringUtils.stripEnd(propertyString.toString(), separator); } } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java index ea6c604a..4d340675 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java @@ -11,6 +11,7 @@ import com.ruoyi.common.constant.UserConstants; import com.ruoyi.common.core.domain.entity.SysMenu; import com.ruoyi.common.core.domain.entity.SysRole; import com.ruoyi.common.helper.LoginHelper; +import com.ruoyi.common.utils.StreamUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.TreeBuildUtils; import com.ruoyi.system.domain.SysRoleMenu; @@ -425,13 +426,7 @@ public class SysMenuServiceImpl implements ISysMenuService { * 得到子节点列表 */ private List getChildList(List list, SysMenu t) { - List tlist = new ArrayList(); - for (SysMenu n : list) { - if (n.getParentId().longValue() == t.getMenuId().longValue()) { - tlist.add(n); - } - } - return tlist; + return StreamUtils.filter(list, n -> n.getParentId().equals(t.getMenuId())); } /** diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOssServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOssServiceImpl.java index 6c63821f..cd9bffb1 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOssServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOssServiceImpl.java @@ -1,5 +1,6 @@ package com.ruoyi.system.service.impl; +import cn.hutool.core.io.IoUtil; import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; @@ -8,10 +9,13 @@ import com.ruoyi.common.constant.CacheNames; import com.ruoyi.common.core.domain.PageQuery; import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.BeanCopyUtils; import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.file.FileUtils; import com.ruoyi.common.utils.spring.SpringUtils; import com.ruoyi.oss.core.OssClient; import com.ruoyi.oss.entity.UploadResult; +import com.ruoyi.oss.enumd.AccessPolicyType; import com.ruoyi.oss.factory.OssFactory; import com.ruoyi.system.domain.SysOss; import com.ruoyi.system.domain.bo.SysOssBo; @@ -20,14 +24,18 @@ import com.ruoyi.system.mapper.SysOssMapper; import com.ruoyi.system.service.ISysOssService; import lombok.RequiredArgsConstructor; import org.springframework.cache.annotation.Cacheable; +import org.springframework.http.MediaType; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; +import javax.servlet.http.HttpServletResponse; import java.io.IOException; +import java.io.InputStream; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; /** * 文件上传 服务层实现 @@ -44,6 +52,8 @@ public class SysOssServiceImpl implements ISysOssService { public TableDataInfo queryPageList(SysOssBo bo, PageQuery pageQuery) { LambdaQueryWrapper lqw = buildQueryWrapper(bo); Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + List filterResult = result.getRecords().stream().map(this::matchingUrl).collect(Collectors.toList()); + result.setRecords(filterResult); return TableDataInfo.build(result); } @@ -53,7 +63,7 @@ public class SysOssServiceImpl implements ISysOssService { for (Long id : ossIds) { SysOssVo vo = SpringUtils.getAopProxy(this).getById(id); if (ObjectUtil.isNotNull(vo)) { - list.add(vo); + list.add(this.matchingUrl(vo)); } } return list; @@ -80,7 +90,25 @@ public class SysOssServiceImpl implements ISysOssService { } @Override - public SysOss upload(MultipartFile file) { + public void download(Long ossId, HttpServletResponse response) throws IOException { + SysOssVo sysOss = SpringUtils.getAopProxy(this).getById(ossId); + if (ObjectUtil.isNull(sysOss)) { + throw new ServiceException("文件数据不存在!"); + } + FileUtils.setAttachmentResponseHeader(response, sysOss.getOriginalName()); + response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE + "; charset=UTF-8"); + OssClient storage = OssFactory.instance(); + try(InputStream inputStream = storage.getObjectContent(sysOss.getUrl())) { + int available = inputStream.available(); + IoUtil.copy(inputStream, response.getOutputStream(), available); + response.setContentLength(available); + } catch (Exception e) { + throw new ServiceException(e.getMessage()); + } + } + + @Override + public SysOssVo upload(MultipartFile file) { String originalfileName = file.getOriginalFilename(); String suffix = StringUtils.substring(originalfileName, originalfileName.lastIndexOf("."), originalfileName.length()); OssClient storage = OssFactory.instance(); @@ -98,7 +126,9 @@ public class SysOssServiceImpl implements ISysOssService { oss.setOriginalName(originalfileName); oss.setService(storage.getConfigKey()); baseMapper.insert(oss); - return oss; + SysOssVo sysOssVo = new SysOssVo(); + BeanCopyUtils.copy(oss, sysOssVo); + return this.matchingUrl(sysOssVo); } @Override @@ -114,4 +144,18 @@ public class SysOssServiceImpl implements ISysOssService { return baseMapper.deleteBatchIds(ids) > 0; } + /** + * 匹配Url + * + * @param oss OSS对象 + * @return oss 匹配Url的OSS对象 + */ + private SysOssVo matchingUrl(SysOssVo oss) { + OssClient storage = OssFactory.instance(oss.getService()); + // 仅修改桶类型为 private 的URL,临时URL时长为120s + if (AccessPolicyType.PRIVATE == storage.getAccessPolicy()) { + oss.setUrl(storage.getPrivateUrl(oss.getFileName(), 120)); + } + return oss; + } } diff --git a/ruoyi-ui/bin/package.bat b/ruoyi-ui/bin/package.bat index 9f6e5f4d..2f22a4ad 100644 --- a/ruoyi-ui/bin/package.bat +++ b/ruoyi-ui/bin/package.bat @@ -1,6 +1,6 @@ @echo off echo. -echo [��Ϣ] ��װWeb���̣�����node_modules�ļ��� +echo [信息] 安装Web工程,生成node_modules文件。 echo. %~d0 diff --git a/ruoyi-ui/bin/run-web.bat b/ruoyi-ui/bin/run-web.bat index 3e209d77..0318c525 100644 --- a/ruoyi-ui/bin/run-web.bat +++ b/ruoyi-ui/bin/run-web.bat @@ -1,6 +1,6 @@ @echo off echo. -echo [��Ϣ] ʹ�� Vue CLI �������� Web ���̡� +echo [信息] 使用 Vue CLI 命令运行 Web 工程。 echo. %~d0 @@ -9,4 +9,4 @@ cd %~dp0 cd .. npm run dev -pause +pause \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/code.svg b/ruoyi-ui/src/assets/icons/svg/code.svg index ed4d23cf..5f9c5abd 100644 --- a/ruoyi-ui/src/assets/icons/svg/code.svg +++ b/ruoyi-ui/src/assets/icons/svg/code.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/server.svg b/ruoyi-ui/src/assets/icons/svg/server.svg index ca37b001..eb287e36 100644 --- a/ruoyi-ui/src/assets/icons/svg/server.svg +++ b/ruoyi-ui/src/assets/icons/svg/server.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/system.svg b/ruoyi-ui/src/assets/icons/svg/system.svg index dba28cf6..5992593e 100644 --- a/ruoyi-ui/src/assets/icons/svg/system.svg +++ b/ruoyi-ui/src/assets/icons/svg/system.svg @@ -1,2 +1,2 @@ \ No newline at end of file + \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/tool.svg b/ruoyi-ui/src/assets/icons/svg/tool.svg index c813067e..48e0e357 100644 --- a/ruoyi-ui/src/assets/icons/svg/tool.svg +++ b/ruoyi-ui/src/assets/icons/svg/tool.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/ruoyi-ui/src/assets/styles/ruoyi.scss b/ruoyi-ui/src/assets/styles/ruoyi.scss index ca7c6f96..16a4740f 100644 --- a/ruoyi-ui/src/assets/styles/ruoyi.scss +++ b/ruoyi-ui/src/assets/styles/ruoyi.scss @@ -149,10 +149,9 @@ } /** 表格更多操作下拉样式 */ -.el-table .el-dropdown-link { - cursor: pointer; - color: #409EFF; - margin-left: 5px; +.el-table .el-dropdown-link,.el-table .el-dropdown-selfdefine { + cursor: pointer; + margin-left: 5px; } .el-table .el-dropdown, .el-icon-arrow-down { diff --git a/ruoyi-ui/src/components/Crontab/hour.vue b/ruoyi-ui/src/components/Crontab/hour.vue index abee0bfe..4b1f1fcd 100644 --- a/ruoyi-ui/src/components/Crontab/hour.vue +++ b/ruoyi-ui/src/components/Crontab/hour.vue @@ -1,114 +1,114 @@ diff --git a/ruoyi-ui/src/components/TopNav/index.vue b/ruoyi-ui/src/components/TopNav/index.vue index 0cc24dba..5f0edbef 100644 --- a/ruoyi-ui/src/components/TopNav/index.vue +++ b/ruoyi-ui/src/components/TopNav/index.vue @@ -92,7 +92,9 @@ export default { if (path !== undefined && path.lastIndexOf("/") > 0 && hideList.indexOf(path) === -1) { const tmpPath = path.substring(1, path.length); activePath = "/" + tmpPath.substring(0, tmpPath.indexOf("/")); - this.$store.dispatch('app/toggleSideBarHide', false); + if (!this.$route.meta.link) { + this.$store.dispatch('app/toggleSideBarHide', false); + } } else if(!this.$route.children) { activePath = path; this.$store.dispatch('app/toggleSideBarHide', true); @@ -145,6 +147,8 @@ export default { } if(routes.length > 0) { this.$store.commit("SET_SIDEBAR_ROUTERS", routes); + } else { + this.$store.dispatch('app/toggleSideBarHide', true); } }, ishttp(url) { diff --git a/ruoyi-ui/src/utils/request.js b/ruoyi-ui/src/utils/request.js index 2473bc13..f94fa0e5 100644 --- a/ruoyi-ui/src/utils/request.js +++ b/ruoyi-ui/src/utils/request.js @@ -80,31 +80,24 @@ service.interceptors.response.use(res => { if (code === 401) { if (!isRelogin.show) { isRelogin.show = true; - MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - isRelogin.show = false; - store.dispatch('LogOut').then(() => { - location.href = process.env.VUE_APP_CONTEXT_PATH + "index"; - }) + MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' }).then(() => { + isRelogin.show = false; + store.dispatch('LogOut').then(() => { + location.href = process.env.VUE_APP_CONTEXT_PATH + "index"; + }) }).catch(() => { isRelogin.show = false; }); } return Promise.reject('无效的会话,或者会话已过期,请重新登录。') } else if (code === 500) { - Message({ - message: msg, - type: 'error' - }) + Message({ message: msg, type: 'error' }) return Promise.reject(new Error(msg)) + } else if (code === 601) { + Message({ message: msg, type: 'warning' }) + return Promise.reject('error') } else if (code !== 200) { - Notification.error({ - title: msg - }) + Notification.error({ title: msg }) return Promise.reject('error') } else { return res.data @@ -115,18 +108,12 @@ service.interceptors.response.use(res => { let { message } = error; if (message == "Network Error") { message = "后端接口连接异常"; - } - else if (message.includes("timeout")) { + } else if (message.includes("timeout")) { message = "系统接口请求超时"; - } - else if (message.includes("Request failed with status code")) { + } else if (message.includes("Request failed with status code")) { message = "系统接口" + message.substr(message.length - 3) + "异常"; } - Message({ - message: message, - type: 'error', - duration: 5 * 1000 - }) + Message({ message: message, type: 'error', duration: 5 * 1000 }) return Promise.reject(error) } ) diff --git a/ruoyi-ui/src/utils/ruoyi.js b/ruoyi-ui/src/utils/ruoyi.js index d2cd2a06..243c4c7b 100644 --- a/ruoyi-ui/src/utils/ruoyi.js +++ b/ruoyi-ui/src/utils/ruoyi.js @@ -86,11 +86,14 @@ export function selectDictLabel(datas, value) { return actions.join(''); } -// 回显数据字典(字符串数组) +// 回显数据字典(字符串、数组) export function selectDictLabels(datas, value, separator) { - if (value === undefined) { + if (value === undefined || value.length ===0) { return ""; } + if (Array.isArray(value)) { + value = value.join(","); + } var actions = []; var currentSeparator = undefined === separator ? "," : separator; var temp = value.split(currentSeparator); diff --git a/ruoyi-ui/src/views/index.vue b/ruoyi-ui/src/views/index.vue index d59814cc..6207f3bf 100644 --- a/ruoyi-ui/src/views/index.vue +++ b/ruoyi-ui/src/views/index.vue @@ -23,7 +23,7 @@ * 分布式限流 Redisson 全局、请求IP、集群ID 多种限流
* 分布式锁 Lock4j 注解锁、工具锁 多种多样
* 分布式幂等 Redisson 拦截重复提交
- * 分布式日志 TLog 支持跟踪链路日志记录、性能分析、链路排查
+ * 分布式链路追踪 SkyWalking 支持链路追踪、网格分析、度量聚合、可视化
* 分布式任务调度 Xxl-Job 高性能 高可靠 易扩展
* 分布式文件存储 Minio 本地存储
* 分布式云存储 七牛、阿里、腾讯 云存储
@@ -32,7 +32,7 @@ * Excel框架 Alibaba EasyExcel 性能优异 扩展性强
* 文档框架 SpringDoc、javadoc 无注解零入侵基于java注释
* 工具类框架 Hutool、Lombok 减少代码冗余 增加安全性
- * 代码生成器 适配MP、Knife4j规范化代码 一键生成前后端代码
+ * 代码生成器 适配MP、SpringDoc规范化代码 一键生成前后端代码
* 部署方式 Docker 容器编排 一键部署业务集群
* 国际化 SpringMessage Spring标准国际化方案

diff --git a/ruoyi-ui/src/views/monitor/druid/index.vue b/ruoyi-ui/src/views/monitor/druid/index.vue deleted file mode 100644 index c6ad585c..00000000 --- a/ruoyi-ui/src/views/monitor/druid/index.vue +++ /dev/null @@ -1,15 +0,0 @@ - - diff --git a/ruoyi-ui/src/views/system/oss/config.vue b/ruoyi-ui/src/views/system/oss/config.vue index 54ad98cb..0120641d 100644 --- a/ruoyi-ui/src/views/system/oss/config.vue +++ b/ruoyi-ui/src/views/system/oss/config.vue @@ -80,6 +80,13 @@ + + +