diff --git a/README.md b/README.md index a5cae9332..1d0b3465a 100644 --- a/README.md +++ b/README.md @@ -10,12 +10,14 @@ [![JDK-11](https://img.shields.io/badge/JDK-11-green.svg)]() [![JDK-17](https://img.shields.io/badge/JDK-17-green.svg)]() -RuoYi-Vue-Plus 是基于 RuoYi-Vue 针对 `分布式集群` 场景升级(不兼容原框架) +> RuoYi-Vue-Plus 是基于 RuoYi-Vue 针对 `分布式集群` 场景升级(不兼容原框架) + +> 系统演示: [传送门](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/系统演示?sort_id=4836388) | 功能介绍 | 使用技术 | 文档地址 | 特性注意事项 | |---|---|---|---| | 当前框架 | RuoYi-Vue-Plus | [RuoYi-Vue-Plus文档](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/pages) | 重写RuoYi-Vue全方位升级(不兼容原框架) | -| satoken分支 | RuoYi-Vue-Plus-satoken | [satoken分支地址](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/tree/satoken/) | 使用satoken重构权限鉴权(仅供学习不推荐上生产) | +| satoken分支 | RuoYi-Vue-Plus-satoken | [satoken分支地址](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/tree/satoken/) | 使用satoken重构权限鉴权(公测 可尝试上生产) | | 单体分支 | RuoYi-Vue-Plus-fast | [fast分支地址](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/tree/fast/) | 单体应用结构 | | 原框架 | RuoYi-Vue | [RuoYi-Vue官网](http://ruoyi.vip/) | 定期同步需要的功能 | | 前端开发框架 | Vue、Element UI | [Element UI官网](https://element.eleme.cn/#/zh-CN) | | @@ -28,17 +30,16 @@ RuoYi-Vue-Plus 是基于 RuoYi-Vue 针对 `分布式集群` 场景升级(不兼 | 数据库框架 | p6spy | [p6spy官网](https://p6spy.readthedocs.io/) | 更强劲的 SQL 分析 | | 多数据源框架 | dynamic-datasource | [dynamic-ds文档](https://www.kancloud.cn/tracy5546/dynamic-datasource/content) | 支持主从与多种类数据库异构 | | 序列化框架 | Jackson | [Jackson官网](https://github.com/FasterXML/jackson) | 统一使用 jackson 高效可靠 | -| 网络框架 | Feign、OkHttp3 | [Feign官网](https://github.com/OpenFeign/feign) | 接口化管理 HTTP 请求 | | Redis客户端 | Redisson | [Redisson文档](https://github.com/redisson/redisson/wiki/%E7%9B%AE%E5%BD%95) | 支持单机、集群配置 | | 分布式限流 | Redisson | [Redisson文档](https://github.com/redisson/redisson/wiki/%E7%9B%AE%E5%BD%95) | 全局、请求IP、集群ID 多种限流 | | 分布式锁 | Lock4j | [Lock4j官网](https://gitee.com/baomidou/lock4j) | 注解锁、工具锁 多种多样 | -| 分布式幂等 | Lock4j | [Lock4j文档](https://gitee.com/baomidou/lock4j) | 基于分布式锁实现 | +| 分布式幂等 | Redisson | [Lock4j文档](https://gitee.com/baomidou/lock4j) | 拦截重复提交 | | 分布式日志 | TLog | [TLog文档](https://yomahub.com/tlog/docs) | 支持跟踪链路日志记录、性能分析、链路排查 | | 分布式任务调度 | Xxl-Job | [Xxl-Job官网](https://www.xuxueli.com/xxl-job/) | 高性能 高可靠 易扩展 | | 文件存储 | Minio | [Minio文档](https://docs.min.io/) | 本地存储 | | 文件存储 | 七牛、阿里、腾讯 | [OSS使用文档](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/pages?sort_id=4359146&doc_id=1469725) | 云存储 | | 监控框架 | SpringBoot-Admin | [SpringBoot-Admin文档](https://codecentric.github.io/spring-boot-admin/current/) | 全方位服务监控 | -| 校验框架 | Validation | [Validation文档](https://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/) | 增强接口安全性、严谨性 | +| 校验框架 | Validation | [Validation文档](https://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/) | 增强接口安全性、严谨性 支持国际化 | | Excel框架 | Alibaba EasyExcel | [EasyExcel文档](https://www.yuque.com/easyexcel/doc/easyexcel) | 性能优异 扩展性强 | | 文档框架 | Knife4j | [Knife4j文档](https://doc.xiaominfo.com/knife4j/documentation/) | 美化接口文档 | | 工具类框架 | Hutool、Lombok | [Hutool文档](https://www.hutool.cn/docs/) | 减少代码冗余 增加安全性 | @@ -61,8 +62,7 @@ RuoYi-Vue-Plus 是基于 RuoYi-Vue 针对 `分布式集群` 场景升级(不兼 ## 软件架构图 -![Plus部署架构图](https://images.gitee.com/uploads/images/2021/0729/112230_4295e5ce_1766278.png "Plus部署架构图.png") - +![Plus部署架构图](https://images.gitee.com/uploads/images/2021/1112/202137_673ac5d2_1766278.png "Plus部署架构图.png") ## 贡献代码 欢迎各路英雄豪杰 `PR` 代码 请提交到 `dev` 开发分支 统一测试发版 diff --git a/pom.xml b/pom.xml index 956d1675f..9274e6a74 100644 --- a/pom.xml +++ b/pom.xml @@ -14,7 +14,7 @@ 3.3.0 - 2.5.6 + 2.5.7 UTF-8 UTF-8 1.8 @@ -24,19 +24,17 @@ 1.5.22 4.1.2 2.2.11 - 1.7 + 2.3 1.28.0 3.4.3.4 3.9.1 - 5.7.15 - 3.0.3 - 11.6 - 4.9.1 - 2.5.2 - 3.16.3 + 5.7.16 + 4.9.2 + 2.5.4 + 3.16.4 2.2.1 3.4.1 - 1.3.3 + 1.3.4 2.3.0 @@ -120,7 +118,7 @@ org.apache.velocity - velocity + velocity-engine-core ${velocity.version} @@ -174,25 +172,6 @@ ${hutool.version} - - - org.springframework.cloud - spring-cloud-starter-openfeign - ${feign.version} - - - feign-core - io.github.openfeign - - - - - - io.github.openfeign - feign-okhttp - ${feign-okhttp.version} - - com.squareup.okhttp3 okhttp @@ -251,25 +230,12 @@ - - com.yomahub - tlog-feign - ${tlog.version} - - com.yomahub tlog-xxl-job ${tlog.version} - - - com.ruoyi - ruoyi-quartz - ${ruoyi-vue-plus.version} - - com.ruoyi @@ -326,7 +292,6 @@ ruoyi-admin ruoyi-framework ruoyi-system - ruoyi-quartz ruoyi-job ruoyi-generator ruoyi-common @@ -391,6 +356,7 @@ local debug + false '*' @@ -400,6 +366,7 @@ dev debug + false '*' @@ -412,6 +379,7 @@ prod warn + true health, info, logfile diff --git a/ruoyi-admin/Dockerfile b/ruoyi-admin/Dockerfile index 88f4932b6..1bbd2ccf6 100644 --- a/ruoyi-admin/Dockerfile +++ b/ruoyi-admin/Dockerfile @@ -4,6 +4,7 @@ MAINTAINER Lion Li RUN mkdir -p /ruoyi/server RUN mkdir -p /ruoyi/server/logs +RUN mkdir -p /ruoyi/server/temp WORKDIR /ruoyi/server diff --git a/ruoyi-admin/pom.xml b/ruoyi-admin/pom.xml index 9ec68cdd1..b736a4245 100644 --- a/ruoyi-admin/pom.xml +++ b/ruoyi-admin/pom.xml @@ -41,12 +41,6 @@ ruoyi-system - - - - - - com.ruoyi ruoyi-job diff --git a/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java b/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java index f389ff437..b52d32d6e 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java @@ -2,6 +2,7 @@ package com.ruoyi; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup; /** * 启动程序 @@ -14,7 +15,9 @@ public class RuoYiApplication { public static void main(String[] args) { System.setProperty("spring.devtools.restart.enabled", "false"); - SpringApplication.run(RuoYiApplication.class, args); + SpringApplication application = new SpringApplication(RuoYiApplication.class); + application.setApplicationStartup(new BufferingApplicationStartup(2048)); + application.run(args); System.out.println("(♥◠‿◠)ノ゙ RuoYi-Vue-Plus启动成功 ლ(´ڡ`ლ)゙"); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysLogininforController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysLogininforController.java index 9ecc5a760..cd02bba38 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysLogininforController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysLogininforController.java @@ -43,7 +43,7 @@ public class SysLogininforController extends BaseController { @ApiOperation("导出系统访问记录列表") @Log(title = "登录日志", businessType = BusinessType.EXPORT) @SaCheckPermission("monitor:logininfor:export") - @GetMapping("/export") + @PostMapping("/export") public void export(SysLogininfor logininfor, HttpServletResponse response) { List list = logininforService.selectLogininforList(logininfor); ExcelUtil.exportExcel(list, "登录日志", SysLogininfor.class, response); diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysOperlogController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysOperlogController.java index cec09ffa1..69781012b 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysOperlogController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysOperlogController.java @@ -43,7 +43,7 @@ public class SysOperlogController extends BaseController { @ApiOperation("导出操作日志记录列表") @Log(title = "操作日志", businessType = BusinessType.EXPORT) @SaCheckPermission("monitor:operlog:export") - @GetMapping("/export") + @PostMapping("/export") public void export(SysOperLog operLog, HttpServletResponse response) { List list = operLogService.selectOperLogList(operLog); ExcelUtil.exportExcel(list, "操作日志", SysOperLog.class, response); diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysConfigController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysConfigController.java index 3cb665546..f5dac6f78 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysConfigController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysConfigController.java @@ -2,7 +2,6 @@ package com.ruoyi.web.controller.system; import cn.dev33.satoken.annotation.SaCheckPermission; import com.ruoyi.common.annotation.Log; -import com.ruoyi.common.annotation.RepeatSubmit; import com.ruoyi.common.constant.UserConstants; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; @@ -13,6 +12,7 @@ import com.ruoyi.system.domain.SysConfig; import com.ruoyi.system.service.ISysConfigService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; @@ -48,7 +48,7 @@ public class SysConfigController extends BaseController { @ApiOperation("导出参数配置列表") @Log(title = "参数管理", businessType = BusinessType.EXPORT) @SaCheckPermission("system:config:export") - @GetMapping("/export") + @PostMapping("/export") public void export(SysConfig config, HttpServletResponse response) { List list = configService.selectConfigList(config); ExcelUtil.exportExcel(list, "参数数据", SysConfig.class, response); @@ -60,7 +60,7 @@ public class SysConfigController extends BaseController { @ApiOperation("根据参数编号获取详细信息") @SaCheckPermission("system:config:query") @GetMapping(value = "/{configId}") - public AjaxResult getInfo(@PathVariable Long configId) { + public AjaxResult getInfo(@ApiParam("参数ID") @PathVariable Long configId) { return AjaxResult.success(configService.selectConfigById(configId)); } @@ -69,7 +69,7 @@ public class SysConfigController extends BaseController { */ @ApiOperation("根据参数键名查询参数值") @GetMapping(value = "/configKey/{configKey}") - public AjaxResult getConfigKey(@PathVariable String configKey) { + public AjaxResult getConfigKey(@ApiParam("参数Key") @PathVariable String configKey) { return AjaxResult.success(configService.selectConfigByKey(configKey)); } @@ -80,7 +80,6 @@ public class SysConfigController extends BaseController { @SaCheckPermission("system:config:add") @Log(title = "参数管理", businessType = BusinessType.INSERT) @PostMapping - @RepeatSubmit public AjaxResult add(@Validated @RequestBody SysConfig config) { if (UserConstants.NOT_UNIQUE.equals(configService.checkConfigKeyUnique(config))) { return AjaxResult.error("新增参数'" + config.getConfigName() + "'失败,参数键名已存在"); @@ -109,7 +108,7 @@ public class SysConfigController extends BaseController { @SaCheckPermission("system:config:remove") @Log(title = "参数管理", businessType = BusinessType.DELETE) @DeleteMapping("/{configIds}") - public AjaxResult remove(@PathVariable Long[] configIds) { + public AjaxResult remove(@ApiParam("参数ID串") @PathVariable Long[] configIds) { configService.deleteConfigByIds(configIds); return 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 a8630b1df..08ebf9606 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 @@ -1,18 +1,19 @@ package com.ruoyi.web.controller.system; import cn.dev33.satoken.annotation.SaCheckPermission; +import cn.hutool.core.lang.tree.Tree; import cn.hutool.core.util.ArrayUtil; import com.ruoyi.common.annotation.Log; import com.ruoyi.common.constant.UserConstants; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.core.domain.TreeSelect; import com.ruoyi.common.core.domain.entity.SysDept; import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.system.service.ISysDeptService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; @@ -53,7 +54,7 @@ public class SysDeptController extends BaseController { @ApiOperation("查询部门列表(排除节点)") @SaCheckPermission("system:dept:list") @GetMapping("/list/exclude/{deptId}") - public AjaxResult> excludeChild(@PathVariable(value = "deptId", required = false) Long deptId) { + public AjaxResult> excludeChild(@ApiParam("部门ID") @PathVariable(value = "deptId", required = false) Long deptId) { List depts = deptService.selectDeptList(new SysDept()); depts.removeIf(d -> d.getDeptId().equals(deptId) || ArrayUtil.contains(StringUtils.split(d.getAncestors(), ","), deptId + "")); @@ -66,7 +67,7 @@ public class SysDeptController extends BaseController { @ApiOperation("根据部门编号获取详细信息") @SaCheckPermission("system:dept:query") @GetMapping(value = "/{deptId}") - public AjaxResult getInfo(@PathVariable Long deptId) { + public AjaxResult getInfo(@ApiParam("部门ID") @PathVariable Long deptId) { deptService.checkDeptDataScope(deptId); return AjaxResult.success(deptService.selectDeptById(deptId)); } @@ -76,7 +77,7 @@ public class SysDeptController extends BaseController { */ @ApiOperation("获取部门下拉树列表") @GetMapping("/treeselect") - public AjaxResult> treeselect(SysDept dept) { + public AjaxResult>> treeselect(SysDept dept) { List depts = deptService.selectDeptList(dept); return AjaxResult.success(deptService.buildDeptTreeSelect(depts)); } @@ -86,7 +87,7 @@ public class SysDeptController extends BaseController { */ @ApiOperation("加载对应角色部门列表树") @GetMapping(value = "/roleDeptTreeselect/{roleId}") - public AjaxResult> roleDeptTreeselect(@PathVariable("roleId") Long roleId) { + public AjaxResult> roleDeptTreeselect(@ApiParam("角色ID") @PathVariable("roleId") Long roleId) { List depts = deptService.selectDeptList(new SysDept()); Map ajax = new HashMap<>(); ajax.put("checkedKeys", deptService.selectDeptListByRoleId(roleId)); @@ -134,7 +135,7 @@ public class SysDeptController extends BaseController { @SaCheckPermission("system:dept:remove") @Log(title = "部门管理", businessType = BusinessType.DELETE) @DeleteMapping("/{deptId}") - public AjaxResult remove(@PathVariable Long deptId) { + public AjaxResult remove(@ApiParam("部门ID串") @PathVariable Long deptId) { if (deptService.hasChildByDeptId(deptId)) { return AjaxResult.error("存在下级部门,不允许删除"); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictDataController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictDataController.java index dafd6667a..6d472d7a9 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictDataController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictDataController.java @@ -13,6 +13,7 @@ import com.ruoyi.system.service.ISysDictDataService; import com.ruoyi.system.service.ISysDictTypeService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; @@ -47,7 +48,7 @@ public class SysDictDataController extends BaseController { @ApiOperation("导出字典数据列表") @Log(title = "字典数据", businessType = BusinessType.EXPORT) @SaCheckPermission("system:dict:export") - @GetMapping("/export") + @PostMapping("/export") public void export(SysDictData dictData, HttpServletResponse response) { List list = dictDataService.selectDictDataList(dictData); ExcelUtil.exportExcel(list, "字典数据", SysDictData.class, response); @@ -59,7 +60,7 @@ public class SysDictDataController extends BaseController { @ApiOperation("查询字典数据详细") @SaCheckPermission("system:dict:query") @GetMapping(value = "/{dictCode}") - public AjaxResult getInfo(@PathVariable Long dictCode) { + public AjaxResult getInfo(@ApiParam("字典code") @PathVariable Long dictCode) { return AjaxResult.success(dictDataService.selectDictDataById(dictCode)); } @@ -68,7 +69,7 @@ public class SysDictDataController extends BaseController { */ @ApiOperation("根据字典类型查询字典数据信息") @GetMapping(value = "/type/{dictType}") - public AjaxResult> dictType(@PathVariable String dictType) { + public AjaxResult> dictType(@ApiParam("字典类型") @PathVariable String dictType) { List data = dictTypeService.selectDictDataByType(dictType); if (StringUtils.isNull(data)) { data = new ArrayList<>(); @@ -105,7 +106,7 @@ public class SysDictDataController extends BaseController { @SaCheckPermission("system:dict:remove") @Log(title = "字典类型", businessType = BusinessType.DELETE) @DeleteMapping("/{dictCodes}") - public AjaxResult remove(@PathVariable Long[] dictCodes) { + public AjaxResult remove(@ApiParam("字典code串") @PathVariable Long[] dictCodes) { dictDataService.deleteDictDataByIds(dictCodes); return success(); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictTypeController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictTypeController.java index 1743fd020..1e544043b 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictTypeController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictTypeController.java @@ -12,6 +12,7 @@ import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.system.service.ISysDictTypeService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; @@ -44,7 +45,7 @@ public class SysDictTypeController extends BaseController { @ApiOperation("导出字典类型列表") @Log(title = "字典类型", businessType = BusinessType.EXPORT) @SaCheckPermission("system:dict:export") - @GetMapping("/export") + @PostMapping("/export") public void export(SysDictType dictType, HttpServletResponse response) { List list = dictTypeService.selectDictTypeList(dictType); ExcelUtil.exportExcel(list, "字典类型", SysDictType.class, response); @@ -56,7 +57,7 @@ public class SysDictTypeController extends BaseController { @ApiOperation("查询字典类型详细") @SaCheckPermission("system:dict:query") @GetMapping(value = "/{dictId}") - public AjaxResult getInfo(@PathVariable Long dictId) { + public AjaxResult getInfo(@ApiParam("字典ID") @PathVariable Long dictId) { return AjaxResult.success(dictTypeService.selectDictTypeById(dictId)); } @@ -95,7 +96,7 @@ public class SysDictTypeController extends BaseController { @SaCheckPermission("system:dict:remove") @Log(title = "字典类型", businessType = BusinessType.DELETE) @DeleteMapping("/{dictIds}") - public AjaxResult remove(@PathVariable Long[] dictIds) { + public AjaxResult remove(@ApiParam("字典ID串") @PathVariable Long[] dictIds) { dictTypeService.deleteDictTypeByIds(dictIds); return success(); } 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 d6ea043b8..5cf5170da 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 @@ -10,6 +10,7 @@ import com.ruoyi.common.core.domain.model.LoginBody; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.system.domain.vo.RouterVo; import com.ruoyi.system.service.ISysMenuService; +import com.ruoyi.system.service.ISysUserService; import com.ruoyi.system.service.SysLoginService; import com.ruoyi.system.service.SysPermissionService; import io.swagger.annotations.Api; @@ -33,13 +34,14 @@ import java.util.Set; * @author Lion Li */ @Validated -@Api(value = "数据字典信息控制器", tags = {"数据字典信息管理"}) +@Api(value = "登录验证控制器", tags = {"登录验证管理"}) @RequiredArgsConstructor(onConstructor_ = @Autowired) @RestController public class SysLoginController { private final SysLoginService loginService; private final ISysMenuService menuService; + private final ISysUserService userService; private final SysPermissionService permissionService; /** 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 0f496cc71..118f87b1b 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 @@ -1,17 +1,18 @@ package com.ruoyi.web.controller.system; import cn.dev33.satoken.annotation.SaCheckPermission; +import cn.hutool.core.lang.tree.Tree; import com.ruoyi.common.annotation.Log; import com.ruoyi.common.constant.UserConstants; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.core.domain.TreeSelect; import com.ruoyi.common.core.domain.entity.SysMenu; import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.system.service.ISysMenuService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; @@ -52,7 +53,7 @@ public class SysMenuController extends BaseController { @ApiOperation("根据菜单编号获取详细信息") @SaCheckPermission("system:menu:query") @GetMapping(value = "/{menuId}") - public AjaxResult getInfo(@PathVariable Long menuId) { + public AjaxResult getInfo(@ApiParam("菜单ID") @PathVariable Long menuId) { return AjaxResult.success(menuService.selectMenuById(menuId)); } @@ -61,7 +62,7 @@ public class SysMenuController extends BaseController { */ @ApiOperation("获取菜单下拉树列表") @GetMapping("/treeselect") - public AjaxResult> treeselect(SysMenu menu) { + public AjaxResult>> treeselect(SysMenu menu) { List menus = menuService.selectMenuList(menu, getUserId()); return AjaxResult.success(menuService.buildMenuTreeSelect(menus)); } @@ -71,7 +72,7 @@ public class SysMenuController extends BaseController { */ @ApiOperation("加载对应角色菜单列表树") @GetMapping(value = "/roleMenuTreeselect/{roleId}") - public AjaxResult> roleMenuTreeselect(@PathVariable("roleId") Long roleId) { + public AjaxResult> roleMenuTreeselect(@ApiParam("角色ID") @PathVariable("roleId") Long roleId) { List menus = menuService.selectMenuList(getUserId()); Map ajax = new HashMap<>(); ajax.put("checkedKeys", menuService.selectMenuListByRoleId(roleId)); @@ -120,7 +121,7 @@ public class SysMenuController extends BaseController { @SaCheckPermission("system:menu:remove") @Log(title = "菜单管理", businessType = BusinessType.DELETE) @DeleteMapping("/{menuId}") - public AjaxResult remove(@PathVariable("menuId") Long menuId) { + public AjaxResult remove(@ApiParam("菜单ID") @PathVariable("menuId") Long menuId) { if (menuService.hasChildByMenuId(menuId)) { return AjaxResult.error("存在子菜单,不允许删除"); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysNoticeController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysNoticeController.java index 9414e5df4..31ed43965 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysNoticeController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysNoticeController.java @@ -13,6 +13,7 @@ import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; import lombok.RequiredArgsConstructor; /** @@ -45,7 +46,7 @@ public class SysNoticeController extends BaseController { @ApiOperation("根据通知公告编号获取详细信息") @SaCheckPermission("system:notice:query") @GetMapping(value = "/{noticeId}") - public AjaxResult getInfo(@PathVariable Long noticeId) { + public AjaxResult getInfo(@ApiParam("公告ID") @PathVariable Long noticeId) { return AjaxResult.success(noticeService.selectNoticeById(noticeId)); } @@ -78,7 +79,7 @@ public class SysNoticeController extends BaseController { @SaCheckPermission("system:notice:remove") @Log(title = "通知公告", businessType = BusinessType.DELETE) @DeleteMapping("/{noticeIds}") - public AjaxResult remove(@PathVariable Long[] noticeIds) { + public AjaxResult remove(@ApiParam("公告ID串") @PathVariable Long[] noticeIds) { return toAjax(noticeService.deleteNoticeByIds(noticeIds)); } } 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 6fa75be15..18dfd51eb 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 @@ -15,6 +15,7 @@ import com.ruoyi.system.domain.vo.SysOssConfigVo; import com.ruoyi.system.service.ISysOssConfigService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; @@ -56,7 +57,8 @@ public class SysOssConfigController extends BaseController { @ApiOperation("获取对象存储配置详细信息") @SaCheckPermission("system:oss:query") @GetMapping("/{ossConfigId}") - public AjaxResult getInfo(@NotNull(message = "主键不能为空") + public AjaxResult getInfo(@ApiParam("OSS配置ID") + @NotNull(message = "主键不能为空") @PathVariable("ossConfigId") Integer ossConfigId) { return AjaxResult.success(iSysOssConfigService.queryById(ossConfigId)); } @@ -92,7 +94,8 @@ public class SysOssConfigController extends BaseController { @SaCheckPermission("system:oss:remove") @Log(title = "对象存储配置", businessType = BusinessType.DELETE) @DeleteMapping("/{ossConfigIds}") - public AjaxResult remove(@NotEmpty(message = "主键不能为空") + public AjaxResult remove(@ApiParam("OSS配置ID串") + @NotEmpty(message = "主键不能为空") @PathVariable Long[] ossConfigIds) { return toAjax(iSysOssConfigService.deleteWithValidByIds(Arrays.asList(ossConfigIds), true) ? 1 : 0); } 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 24c158823..5d229c88d 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 @@ -17,17 +17,14 @@ import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.JsonUtils; import com.ruoyi.common.utils.file.FileUtils; -import com.ruoyi.oss.constant.CloudConstant; +import com.ruoyi.oss.constant.OssConstant; import com.ruoyi.system.domain.SysConfig; import com.ruoyi.system.domain.SysOss; import com.ruoyi.system.domain.bo.SysOssBo; import com.ruoyi.system.domain.vo.SysOssVo; import com.ruoyi.system.service.ISysConfigService; import com.ruoyi.system.service.ISysOssService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiImplicitParams; -import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.*; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; @@ -37,6 +34,7 @@ import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletResponse; import javax.validation.constraints.NotEmpty; +import java.io.File; import java.io.IOException; import java.util.Arrays; import java.util.HashMap; @@ -72,7 +70,7 @@ public class SysOssController extends BaseController { */ @ApiOperation("上传OSS对象存储") @ApiImplicitParams({ - @ApiImplicitParam(name = "file", value = "文件", dataType = "java.io.File", required = true), + @ApiImplicitParam(name = "file", value = "文件", dataTypeClass = File.class, required = true), }) @SaCheckPermission("system:oss:upload") @Log(title = "OSS对象存储", businessType = BusinessType.INSERT) @@ -92,7 +90,7 @@ public class SysOssController extends BaseController { @ApiOperation("下载OSS对象存储") @SaCheckPermission("system:oss:download") @GetMapping("/download/{ossId}") - public void download(@PathVariable Long ossId, HttpServletResponse response) throws IOException { + public void download(@ApiParam("OSS对象ID") @PathVariable Long ossId, HttpServletResponse response) throws IOException { SysOss sysOss = iSysOssService.getById(ossId); if (ObjectUtil.isNull(sysOss)) { throw new ServiceException("文件数据不存在!"); @@ -120,7 +118,8 @@ public class SysOssController extends BaseController { @SaCheckPermission("system:oss:remove") @Log(title = "OSS对象存储", businessType = BusinessType.DELETE) @DeleteMapping("/{ossIds}") - public AjaxResult remove(@NotEmpty(message = "主键不能为空") + public AjaxResult remove(@ApiParam("OSS对象ID串") + @NotEmpty(message = "主键不能为空") @PathVariable Long[] ossIds) { return toAjax(iSysOssService.deleteWithValidByIds(Arrays.asList(ossIds), true) ? 1 : 0); } @@ -135,7 +134,7 @@ public class SysOssController extends BaseController { public AjaxResult changePreviewListResource(@RequestBody String body) { Map map = JsonUtils.parseMap(body); SysConfig config = iSysConfigService.getOne(new LambdaQueryWrapper() - .eq(SysConfig::getConfigKey, CloudConstant.PEREVIEW_LIST_RESOURCE_KEY)); + .eq(SysConfig::getConfigKey, OssConstant.PEREVIEW_LIST_RESOURCE_KEY)); config.setConfigValue(map.get("previewListResource").toString()); return toAjax(iSysConfigService.updateConfig(config)); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysPostController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysPostController.java index 3ca73fdf7..b41d75bd0 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysPostController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysPostController.java @@ -12,6 +12,7 @@ import com.ruoyi.system.domain.SysPost; import com.ruoyi.system.service.ISysPostService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; @@ -47,7 +48,7 @@ public class SysPostController extends BaseController { @ApiOperation("导出岗位列表") @Log(title = "岗位管理", businessType = BusinessType.EXPORT) @SaCheckPermission("system:post:export") - @GetMapping("/export") + @PostMapping("/export") public void export(SysPost post, HttpServletResponse response) { List list = postService.selectPostList(post); ExcelUtil.exportExcel(list, "岗位数据", SysPost.class, response); @@ -59,7 +60,7 @@ public class SysPostController extends BaseController { @ApiOperation("根据岗位编号获取详细信息") @SaCheckPermission("system:post:query") @GetMapping(value = "/{postId}") - public AjaxResult getInfo(@PathVariable Long postId) { + public AjaxResult getInfo(@ApiParam("岗位ID") @PathVariable Long postId) { return AjaxResult.success(postService.selectPostById(postId)); } @@ -102,7 +103,7 @@ public class SysPostController extends BaseController { @SaCheckPermission("system:post:remove") @Log(title = "岗位管理", businessType = BusinessType.DELETE) @DeleteMapping("/{postIds}") - public AjaxResult remove(@PathVariable Long[] postIds) { + public AjaxResult remove(@ApiParam("岗位ID串") @PathVariable Long[] postIds) { return toAjax(postService.deletePostByIds(postIds)); } 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 71d9de2d9..50ba930bd 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 @@ -18,6 +18,7 @@ import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; +import java.io.File; import java.util.HashMap; import java.util.Map; @@ -43,7 +44,7 @@ public class SysProfileController extends BaseController { @GetMapping public AjaxResult> profile() { SysUser user = userService.getById(getUserId()); - Map ajax = new HashMap<>(); + Map ajax = new HashMap<>(); ajax.put("user", user); ajax.put("roleGroup", userService.selectUserRoleGroup(user.getUserName())); ajax.put("postGroup", userService.selectUserPostGroup(user.getUserName())); @@ -66,6 +67,7 @@ public class SysProfileController extends BaseController { return AjaxResult.error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在"); } user.setUserId(getUserId()); + user.setUserName(null); user.setPassword(null); if (userService.updateUserProfile(user) > 0) { return AjaxResult.success(); @@ -77,6 +79,10 @@ public class SysProfileController extends BaseController { * 重置密码 */ @ApiOperation("重置密码") + @ApiImplicitParams({ + @ApiImplicitParam(name = "oldPassword", value = "旧密码", paramType = "query", dataTypeClass = String.class), + @ApiImplicitParam(name = "newPassword", value = "新密码", paramType = "query", dataTypeClass = String.class) + }) @Log(title = "个人信息", businessType = BusinessType.UPDATE) @PutMapping("/updatePwd") public AjaxResult updatePwd(String oldPassword, String newPassword) { @@ -100,7 +106,7 @@ public class SysProfileController extends BaseController { */ @ApiOperation("头像上传") @ApiImplicitParams({ - @ApiImplicitParam(name = "file", value = "用户头像", dataType = "java.io.File", required = true), + @ApiImplicitParam(name = "avatarfile", value = "用户头像", dataTypeClass = File.class, required = true), }) @Log(title = "用户头像", businessType = BusinessType.UPDATE) @PostMapping("/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 f1d7e779e..2a339181b 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 @@ -13,8 +13,7 @@ import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.system.domain.SysUserRole; import com.ruoyi.system.service.ISysRoleService; import com.ruoyi.system.service.ISysUserService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.*; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; @@ -48,7 +47,7 @@ public class SysRoleController extends BaseController { @ApiOperation("导出角色信息列表") @Log(title = "角色管理", businessType = BusinessType.EXPORT) @SaCheckPermission("system:role:export") - @GetMapping("/export") + @PostMapping("/export") public void export(SysRole role, HttpServletResponse response) { List list = roleService.selectRoleList(role); ExcelUtil.exportExcel(list, "角色数据", SysRole.class, response); @@ -60,7 +59,7 @@ public class SysRoleController extends BaseController { @ApiOperation("根据角色编号获取详细信息") @SaCheckPermission("system:role:query") @GetMapping(value = "/{roleId}") - public AjaxResult getInfo(@PathVariable Long roleId) { + public AjaxResult getInfo(@ApiParam("角色ID") @PathVariable Long roleId) { roleService.checkRoleDataScope(roleId); return AjaxResult.success(roleService.selectRoleById(roleId)); } @@ -134,7 +133,7 @@ public class SysRoleController extends BaseController { @SaCheckPermission("system:role:remove") @Log(title = "角色管理", businessType = BusinessType.DELETE) @DeleteMapping("/{roleIds}") - public AjaxResult remove(@PathVariable Long[] roleIds) { + public AjaxResult remove(@ApiParam("岗位ID串") @PathVariable Long[] roleIds) { return toAjax(roleService.deleteRoleByIds(roleIds)); } @@ -183,6 +182,10 @@ public class SysRoleController extends BaseController { * 批量取消授权用户 */ @ApiOperation("批量取消授权用户") + @ApiImplicitParams({ + @ApiImplicitParam(name = "roleId", value = "角色ID", paramType = "query", dataTypeClass = String.class), + @ApiImplicitParam(name = "userIds", value = "用户ID串", paramType = "query", dataTypeClass = String.class) + }) @SaCheckPermission("system:role:edit") @Log(title = "角色管理", businessType = BusinessType.GRANT) @PutMapping("/authUser/cancelAll") @@ -194,6 +197,10 @@ public class SysRoleController extends BaseController { * 批量选择用户授权 */ @ApiOperation("批量选择用户授权") + @ApiImplicitParams({ + @ApiImplicitParam(name = "roleId", value = "角色ID", paramType = "query", dataTypeClass = String.class), + @ApiImplicitParam(name = "userIds", value = "用户ID串", paramType = "query", dataTypeClass = String.class) + }) @SaCheckPermission("system:role:edit") @Log(title = "角色管理", businessType = BusinessType.GRANT) @PutMapping("/authUser/selectAll") 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 b7328d66d..bd77f611d 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 @@ -13,18 +13,17 @@ import com.ruoyi.common.core.domain.entity.SysRole; import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.excel.ExcelResult; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.system.domain.vo.SysUserExportVo; import com.ruoyi.system.domain.vo.SysUserImportVo; +import com.ruoyi.system.listener.SysUserImportListener; import com.ruoyi.system.service.ISysPostService; import com.ruoyi.system.service.ISysRoleService; import com.ruoyi.system.service.ISysUserService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiImplicitParams; -import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.*; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; @@ -67,7 +66,7 @@ public class SysUserController extends BaseController { @ApiOperation("导出用户列表") @Log(title = "用户管理", businessType = BusinessType.EXPORT) @SaCheckPermission("system:user:export") - @GetMapping("/export") + @PostMapping("/export") public void export(SysUser user, HttpServletResponse response) { List list = userService.selectUserList(user); List listVo = BeanUtil.copyToList(list, SysUserExportVo.class); @@ -90,15 +89,12 @@ public class SysUserController extends BaseController { @SaCheckPermission("system:user:import") @PostMapping("/importData") public AjaxResult importData(@RequestPart("file") MultipartFile file, boolean updateSupport) throws Exception { - List userListVo = ExcelUtil.importExcel(file.getInputStream(), SysUserImportVo.class); - List userList = BeanUtil.copyToList(userListVo, SysUser.class); - String operName = userService.getById(getUserId()).getUserName(); - String message = userService.importUser(userList, updateSupport, operName); - return AjaxResult.success(message); + ExcelResult result = ExcelUtil.importExcel(file.getInputStream(), SysUserImportVo.class, new SysUserImportListener(updateSupport)); + return AjaxResult.success(result.getAnalysis()); } @ApiOperation("下载导入模板") - @GetMapping("/importTemplate") + @PostMapping("/importTemplate") public void importTemplate(HttpServletResponse response) { ExcelUtil.exportExcel(new ArrayList<>(), "用户数据", SysUserImportVo.class, response); } @@ -109,7 +105,7 @@ public class SysUserController extends BaseController { @ApiOperation("根据用户编号获取详细信息") @SaCheckPermission("system:user:query") @GetMapping(value = {"/", "/{userId}" }) - public AjaxResult> getInfo(@PathVariable(value = "userId", required = false) Long userId) { + public AjaxResult> getInfo(@ApiParam("用户ID") @PathVariable(value = "userId", required = false) Long userId) { userService.checkUserDataScope(userId); Map ajax = new HashMap<>(); List roles = roleService.selectRoleAll(); @@ -170,7 +166,7 @@ public class SysUserController extends BaseController { @SaCheckPermission("system:user:remove") @Log(title = "用户管理", businessType = BusinessType.DELETE) @DeleteMapping("/{userIds}") - public AjaxResult remove(@PathVariable Long[] userIds) { + public AjaxResult remove(@ApiParam("角色ID串") @PathVariable Long[] userIds) { if (ArrayUtil.contains(userIds, getUserId())) { return error("当前用户不能删除"); } @@ -208,7 +204,7 @@ public class SysUserController extends BaseController { @ApiOperation("根据用户编号获取授权角色") @SaCheckPermission("system:user:query") @GetMapping("/authRole/{userId}") - public AjaxResult> authRole(@PathVariable("userId") Long userId) { + public AjaxResult> authRole(@ApiParam("用户ID") @PathVariable("userId") Long userId) { SysUser user = userService.selectUserById(userId); List roles = roleService.selectRolesByUserId(userId); Map ajax = new HashMap<>(); @@ -221,6 +217,10 @@ public class SysUserController extends BaseController { * 用户授权角色 */ @ApiOperation("用户授权角色") + @ApiImplicitParams({ + @ApiImplicitParam(name = "userId", value = "用户Id", paramType = "query", dataTypeClass = String.class), + @ApiImplicitParam(name = "roleIds", value = "角色ID串", paramType = "query", dataTypeClass = String.class) + }) @SaCheckPermission("system:user:edit") @Log(title = "用户管理", businessType = BusinessType.GRANT) @PutMapping("/authRole") diff --git a/ruoyi-admin/src/main/resources/application-prod.yml b/ruoyi-admin/src/main/resources/application-prod.yml index 9aac0e3b3..1d680d7de 100644 --- a/ruoyi-admin/src/main/resources/application-prod.yml +++ b/ruoyi-admin/src/main/resources/application-prod.yml @@ -1,3 +1,10 @@ +--- # 配置临时路径存储 +spring: + servlet: + multipart: + # 临时文件存储位置 避免临时文件被系统清理报错 + location: /ruoyi/server/temp + --- # 监控配置 spring: boot: diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml index 4a0aebc0d..dbd182f32 100644 --- a/ruoyi-admin/src/main/resources/application.yml +++ b/ruoyi-admin/src/main/resources/application.yml @@ -10,6 +10,8 @@ ruoyi: demoEnabled: true # 获取ip地址开关 addressEnabled: true + # 缓存懒加载 + cacheLazy: true captcha: # 页面 <参数设置> 可开启关闭 验证码校验 @@ -234,6 +236,22 @@ swagger: - name: 3.代码生成模块 basePackage: com.ruoyi.generator +knife4j: + # 是否开启Knife4j增强模式 + enable: true + # 是否开启生产环境保护策略 + production: @knife4j.production@ + # 前端Ui的个性化配置属性 + setting: + # 默认语言 + language: zh-CN + # 是否显示Footer + enableFooter: false + # 是否开启动态参数调试功能 + enableDynamicParameter: true + # 是否在每个Debug调试栏后显示刷新变量按钮 + enableReloadCacheParameter: true + # 防止XSS攻击 xss: # 过滤开关 @@ -262,22 +280,6 @@ thread-pool: # ABORT_POLICY 中止 rejectedExecutionHandler: CALLER_RUNS_POLICY -# feign 相关配置 -feign: - # 不支持多包, 如有需要可在注解配置 或 提升扫包等级 - # 例如 com.**.**.feign - package: com.ruoyi.**.feign - # 开启压缩 - compression: - request: - enabled: true - response: - enabled: true - okhttp: - enabled: true - circuitbreaker: - enabled: true - --- # redisson 缓存配置 redisson: cacheGroup: @@ -313,34 +315,3 @@ management: endpoint: logfile: external-file: ./logs/sys-console.log - ---- # 定时任务配置 -spring: - quartz: - scheduler-name: RuoyiScheduler - startup-delay: 1s - overwrite-existing-jobs: true - auto-startup: true - job-store-type: jdbc - properties: - org: - quartz: - # Scheduler 相关配置 - scheduler: - instanceName: RuoyiScheduler - instanceId: AUTO - # 线程池相关配置 - threadPool: - class: org.quartz.simpl.SimpleThreadPool - threadCount: 20 - threadPriority: 5 - # JobStore 集群配置 - jobStore: - class: org.quartz.impl.jdbcjobstore.JobStoreTX - isClustered: true - clusterCheckinInterval: 15000 - txIsolationLevelSerializable: true - misfireThreshold: 60000 - tablePrefix: QRTZ_ - # sqlserver 启用 - # selectWithLockSQL: SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ? diff --git a/ruoyi-admin/src/main/resources/logback.xml b/ruoyi-admin/src/main/resources/logback.xml index 33a169725..6e3280fb3 100644 --- a/ruoyi-admin/src/main/resources/logback.xml +++ b/ruoyi-admin/src/main/resources/logback.xml @@ -31,7 +31,7 @@ INFO - + ${log.path}/sys-info.log @@ -54,7 +54,7 @@ DENY - + ${log.path}/sys-error.log @@ -76,21 +76,7 @@ DENY - - - - ${log.path}/sys-user.log - - - ${log.path}/sys-user.%d{yyyy-MM-dd}.log - - 60 - - - ${log.pattern} - - - + @@ -99,16 +85,12 @@ - + - - - - - - \ No newline at end of file + + diff --git a/ruoyi-admin/src/main/resources/spy.properties b/ruoyi-admin/src/main/resources/spy.properties index 0ed983b3b..918f1cb5e 100644 --- a/ruoyi-admin/src/main/resources/spy.properties +++ b/ruoyi-admin/src/main/resources/spy.properties @@ -22,5 +22,3 @@ outagedetection=true outagedetectioninterval=2 # 是否过滤 Log filter=true -# 过滤 Log 时所排除的表名列表,以逗号分隔 -exclude=QRTZ_ diff --git a/ruoyi-common/pom.xml b/ruoyi-common/pom.xml index a033c7f4c..fa3bbc8b5 100644 --- a/ruoyi-common/pom.xml +++ b/ruoyi-common/pom.xml @@ -87,18 +87,6 @@ jaxb-impl - - - org.springframework.boot - spring-boot-starter-data-redis - - - - - org.apache.commons - commons-pool2 - - javax.servlet @@ -122,18 +110,6 @@ lombok - - - org.springframework.cloud - spring-cloud-starter-openfeign - - - - - io.github.openfeign - feign-okhttp - - de.codecentric spring-boot-admin-starter-client @@ -180,10 +156,6 @@ tlog-webroot - - com.yomahub - tlog-feign - diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/config/RuoYiConfig.java b/ruoyi-common/src/main/java/com/ruoyi/common/config/RuoYiConfig.java index 9343a4a08..bcfc677bd 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/config/RuoYiConfig.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/config/RuoYiConfig.java @@ -38,6 +38,11 @@ public class RuoYiConfig { */ private boolean demoEnabled; + /** + * 缓存懒加载 + */ + private boolean cacheLazy; + /** * 获取地址开关 */ 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 b41f5d737..fc1137b6d 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 @@ -106,13 +106,4 @@ public class Constants { */ public static final String SYS_DICT_KEY = "sys_dict:"; - /** - * RMI 远程方法调用 - */ - 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/constant/ScheduleConstants.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/ScheduleConstants.java deleted file mode 100644 index ec430c26a..000000000 --- a/ruoyi-common/src/main/java/com/ruoyi/common/constant/ScheduleConstants.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.ruoyi.common.constant; - -/** - * 任务调度通用常量 - * - * @deprecated 3.4.0删除 迁移至xxl-job - * @author ruoyi - */ -public class ScheduleConstants -{ - public static final String TASK_CLASS_NAME = "TASK_CLASS_NAME"; - - /** 执行目标key */ - public static final String TASK_PROPERTIES = "TASK_PROPERTIES"; - - /** 默认 */ - public static final String MISFIRE_DEFAULT = "0"; - - /** 立即触发执行 */ - public static final String MISFIRE_IGNORE_MISFIRES = "1"; - - /** 触发一次执行 */ - public static final String MISFIRE_FIRE_AND_PROCEED = "2"; - - /** 不触发立即执行 */ - public static final String MISFIRE_DO_NOTHING = "3"; - - public enum Status - { - /** - * 正常 - */ - NORMAL("0"), - /** - * 暂停 - */ - PAUSE("1"); - - private String value; - - private Status(String value) - { - this.value = value; - } - - public String getValue() - { - return value; - } - } -} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/convert/ExcelDictConvert.java b/ruoyi-common/src/main/java/com/ruoyi/common/convert/ExcelDictConvert.java index 58560d0b1..7c4d63124 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/convert/ExcelDictConvert.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/convert/ExcelDictConvert.java @@ -8,8 +8,10 @@ import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.GlobalConfiguration; import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.ruoyi.common.annotation.ExcelDictFormat; +import com.ruoyi.common.core.service.DictService; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.common.utils.spring.SpringUtils; import lombok.extern.slf4j.Slf4j; import java.lang.reflect.Field; @@ -41,7 +43,7 @@ public class ExcelDictConvert implements Converter { if (StringUtils.isBlank(type)) { value = ExcelUtil.reverseByExp(label, anno.readConverterExp(), anno.separator()); } else { - value = ExcelUtil.reverseDictByExp(label, type, anno.separator()); + value = SpringUtils.getBean(DictService.class).getDictValue(type, label, anno.separator()); } return Convert.convert(contentProperty.getField().getType(), value); } @@ -58,7 +60,7 @@ public class ExcelDictConvert implements Converter { if (StringUtils.isBlank(type)) { label = ExcelUtil.convertByExp(value, anno.readConverterExp(), anno.separator()); } else { - label = ExcelUtil.convertDictByExp(value, type, anno.separator()); + label = SpringUtils.getBean(DictService.class).getDictLabel(type, value, anno.separator()); } return new CellData<>(label); } diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/TreeSelect.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/TreeSelect.java deleted file mode 100644 index 963ac5c4d..000000000 --- a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/TreeSelect.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.ruoyi.common.core.domain; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.ruoyi.common.core.domain.entity.SysDept; -import com.ruoyi.common.core.domain.entity.SysMenu; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.experimental.Accessors; - -import java.io.Serializable; -import java.util.List; -import java.util.stream.Collectors; - -/** - * Treeselect树结构实体类 - * - * @author Lion Li - */ - -@Data -@NoArgsConstructor -@Accessors(chain = true) -@ApiModel("树结构实体类") -public class TreeSelect implements Serializable { - - private static final long serialVersionUID = 1L; - - /** - * 节点ID - */ - @ApiModelProperty(value = "节点ID") - private Long id; - - /** - * 节点名称 - */ - @ApiModelProperty(value = "节点名称") - private String label; - - /** - * 子节点 - */ - @ApiModelProperty(value = "子节点") - @JsonInclude(JsonInclude.Include.NON_EMPTY) - private List children; - - public TreeSelect(SysDept dept) { - this.id = dept.getDeptId(); - this.label = dept.getDeptName(); - this.children = dept.getChildren() - .stream() - .map(d -> new TreeSelect((SysDept) d)) - .collect(Collectors.toList()); - } - - public TreeSelect(SysMenu menu) { - this.id = menu.getMenuId(); - this.label = menu.getMenuName(); - this.children = menu.getChildren() - .stream() - .map(d -> new TreeSelect((SysMenu) d)) - .collect(Collectors.toList()); - } - -} 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 deleted file mode 100644 index c790c663b..000000000 --- a/ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/cache/MybatisPlusRedisCache.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.ruoyi.common.core.mybatisplus.cache; - -import cn.hutool.extra.spring.SpringUtil; -import com.ruoyi.common.utils.RedisUtils; -import lombok.extern.slf4j.Slf4j; -import org.apache.ibatis.cache.Cache; -import org.springframework.data.redis.connection.RedisServerCommands; -import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.util.CollectionUtils; - -import java.util.Collection; -import java.util.concurrent.locks.ReadWriteLock; -import java.util.concurrent.locks.ReentrantReadWriteLock; - -/** - * mybatis-redis 二级缓存 - * - * 使用方法 配置文件开启 mybatis-plus 二级缓存 - * 在 XxxMapper.java 类上添加注解 @CacheNamespace(implementation = MybatisPlusRedisCache.class, eviction = MybatisPlusRedisCache.class) - * - * @deprecated 3.4.0删除 推荐使用spirng-cache - * @author Lion Li - */ -@Slf4j -public class MybatisPlusRedisCache implements Cache { - - private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(true); - - private String id; - - public MybatisPlusRedisCache(final String id) { - if (id == null) { - throw new IllegalArgumentException("Cache instances require an ID"); - } - this.id = id; - } - - @Override - public String getId() { - return this.id; - } - - @Override - public void putObject(Object key, Object value) { - if (value != null) { - RedisUtils.setCacheObject(key.toString(), value); - } - } - - @Override - public Object getObject(Object key) { - try { - if (key != null) { - return RedisUtils.getCacheObject(key.toString()); - } - } catch (Exception e) { - e.printStackTrace(); - log.error("缓存出错"); - } - return null; - } - - @Override - public Object removeObject(Object key) { - if (key != null) { - RedisUtils.deleteObject(key.toString()); - } - return null; - } - - @Override - public void clear() { - log.debug("清空缓存"); - Collection keys = RedisUtils.keys("*:" + this.id + "*"); - if (!CollectionUtils.isEmpty(keys)) { - RedisUtils.deleteObject(keys); - } - } - - @Override - public int getSize() { - RedisTemplate redisTemplate = SpringUtil.getBean("redisTemplate"); - Long size = redisTemplate.execute(RedisServerCommands::dbSize); - return size.intValue(); - } - - @Override - public ReadWriteLock getReadWriteLock() { - return this.readWriteLock; - } -} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/service/ConfigService.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/service/ConfigService.java new file mode 100644 index 000000000..c6badf65c --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/service/ConfigService.java @@ -0,0 +1,18 @@ +package com.ruoyi.common.core.service; + +/** + * 通用 参数配置服务 + * + * @author Lion Li + */ +public interface ConfigService { + + /** + * 根据参数 key 获取参数值 + * + * @param configKey 参数 key + * @return 参数值 + */ + String getConfigValue(String configKey); + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/service/DictService.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/service/DictService.java new file mode 100644 index 000000000..b334c82af --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/service/DictService.java @@ -0,0 +1,57 @@ +package com.ruoyi.common.core.service; + +/** + * 通用 字典服务 + * + * @author Lion Li + */ +public interface DictService { + + /** + * 分隔符 + */ + String SEPARATOR = ","; + + /** + * 根据字典类型和字典值获取字典标签 + * + * @param dictType 字典类型 + * @param dictValue 字典值 + * @return 字典标签 + */ + default String getDictLabel(String dictType, String dictValue) { + return getDictLabel(dictType, dictValue, SEPARATOR); + } + + /** + * 根据字典类型和字典标签获取字典值 + * + * @param dictType 字典类型 + * @param dictLabel 字典标签 + * @return 字典值 + */ + default String getDictValue(String dictType, String dictLabel) { + return getDictValue(dictType, dictLabel, SEPARATOR); + } + + /** + * 根据字典类型和字典值获取字典标签 + * + * @param dictType 字典类型 + * @param dictValue 字典值 + * @param separator 分隔符 + * @return 字典标签 + */ + String getDictLabel(String dictType, String dictValue, String separator); + + /** + * 根据字典类型和字典标签获取字典值 + * + * @param dictType 字典类型 + * @param dictLabel 字典标签 + * @param separator 分隔符 + * @return 字典值 + */ + String getDictValue(String dictType, String dictLabel, String separator); + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/service/LogininforService.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/service/LogininforService.java index 1bf34d526..91aee4369 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/core/service/LogininforService.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/service/LogininforService.java @@ -2,6 +2,11 @@ package com.ruoyi.common.core.service; import javax.servlet.http.HttpServletRequest; +/** + * 通用 系统访问日志 + * + * @author Lion Li + */ public interface LogininforService { void recordLogininfor(String username, String status, String message, diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/service/OperLogService.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/service/OperLogService.java index 71e5647ee..a3b27e6a7 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/core/service/OperLogService.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/service/OperLogService.java @@ -3,7 +3,13 @@ package com.ruoyi.common.core.service; import com.ruoyi.common.core.domain.dto.OperLogDTO; import org.springframework.scheduling.annotation.Async; +/** + * 通用 操作日志 + * + * @author Lion Li + */ public interface OperLogService { + @Async void recordOper(OperLogDTO operLogDTO); } diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/excel/DefaultExcelListener.java b/ruoyi-common/src/main/java/com/ruoyi/common/excel/DefaultExcelListener.java new file mode 100644 index 000000000..f626a5e11 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/excel/DefaultExcelListener.java @@ -0,0 +1,108 @@ +package com.ruoyi.common.excel; + +import cn.hutool.core.util.StrUtil; +import com.alibaba.excel.context.AnalysisContext; +import com.alibaba.excel.event.AnalysisEventListener; +import com.alibaba.excel.exception.ExcelAnalysisException; +import com.alibaba.excel.exception.ExcelDataConvertException; +import com.alibaba.fastjson.JSON; +import com.ruoyi.common.utils.ValidatorUtils; +import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +import javax.validation.ConstraintViolation; +import javax.validation.ConstraintViolationException; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * Excel 导入监听 + * + * @author Yjoioooo + * @author Lion Li + */ +@Slf4j +@NoArgsConstructor +public class DefaultExcelListener extends AnalysisEventListener implements ExcelListener { + + /** + * 是否Validator检验,默认为是 + */ + private Boolean isValidate = Boolean.TRUE; + + /** + * excel 表头数据 + */ + private Map headMap; + + /** + * 导入回执 + */ + private ExcelResult excelResult; + + public DefaultExcelListener(boolean isValidate) { + this.excelResult = new DefautExcelResult<>(); + this.isValidate = isValidate; + } + + /** + * 处理异常 + * + * @param exception ExcelDataConvertException + * @param context Excel 上下文 + */ + @Override + public void onException(Exception exception, AnalysisContext context) throws Exception { + String errMsg = null; + if (exception instanceof ExcelDataConvertException) { + // 如果是某一个单元格的转换异常 能获取到具体行号 + ExcelDataConvertException excelDataConvertException = (ExcelDataConvertException) exception; + Integer rowIndex = excelDataConvertException.getRowIndex(); + Integer columnIndex = excelDataConvertException.getColumnIndex(); + errMsg = StrUtil.format("第{}行-第{}列-表头{}: 解析异常
", + rowIndex + 1, columnIndex + 1, headMap.get(columnIndex)); + if (log.isDebugEnabled()) { + log.error(errMsg); + } + } + if (exception instanceof ConstraintViolationException) { + ConstraintViolationException constraintViolationException = (ConstraintViolationException) exception; + Set> constraintViolations = constraintViolationException.getConstraintViolations(); + String constraintViolationsMsg = constraintViolations.stream() + .map(ConstraintViolation::getMessage) + .collect(Collectors.joining(", ")); + errMsg = StrUtil.format("第{}行数据校验异常: {}", context.readRowHolder().getRowIndex() + 1, constraintViolationsMsg); + if (log.isDebugEnabled()) { + log.error(errMsg); + } + } + excelResult.getErrorList().add(errMsg); + throw new ExcelAnalysisException(errMsg); + } + + @Override + public void invokeHeadMap(Map headMap, AnalysisContext context) { + this.headMap = headMap; + log.debug("解析到一条表头数据: {}", JSON.toJSONString(headMap)); + } + + @Override + public void invoke(T data, AnalysisContext context) { + if (isValidate) { + ValidatorUtils.validate(data); + } + excelResult.getList().add(data); + } + + @Override + public void doAfterAllAnalysed(AnalysisContext context) { + log.debug("所有数据解析完成!"); + } + + @Override + public ExcelResult getExcelResult() { + return excelResult; + } + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/excel/DefautExcelResult.java b/ruoyi-common/src/main/java/com/ruoyi/common/excel/DefautExcelResult.java new file mode 100644 index 000000000..c852ce65f --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/excel/DefautExcelResult.java @@ -0,0 +1,73 @@ +package com.ruoyi.common.excel; + +import cn.hutool.core.util.StrUtil; +import lombok.Setter; + +import java.util.ArrayList; +import java.util.List; + +/** + * 默认excel返回对象 + * + * @author Yjoioooo + * @author Lion Li + */ +public class DefautExcelResult implements ExcelResult { + + /** + * 数据对象list + */ + @Setter + private List list; + + /** + * 错误信息列表 + */ + @Setter + private List errorList; + + public DefautExcelResult() { + this.list = new ArrayList<>(); + this.errorList = new ArrayList<>(); + } + + public DefautExcelResult(List list, List errorList) { + this.list = list; + this.errorList = errorList; + } + + public DefautExcelResult(ExcelResult excelResult) { + this.list = excelResult.getList(); + this.errorList = excelResult.getErrorList(); + } + + @Override + public List getList() { + return list; + } + + @Override + public List getErrorList() { + return errorList; + } + + /** + * 获取导入回执 + * + * @return 导入回执 + */ + @Override + public String getAnalysis() { + int successCount = list.size(); + int errorCount = errorList.size(); + if (successCount == 0) { + return "读取失败,未解析到数据"; + } else { + if (errorCount == 0) { + return StrUtil.format("恭喜您,全部读取成功!共{}条", successCount); + } else { + return ""; + } + } + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/excel/ExcelListener.java b/ruoyi-common/src/main/java/com/ruoyi/common/excel/ExcelListener.java new file mode 100644 index 000000000..2064cad36 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/excel/ExcelListener.java @@ -0,0 +1,14 @@ +package com.ruoyi.common.excel; + +import com.alibaba.excel.read.listener.ReadListener; + +/** + * Excel 导入监听 + * + * @author Lion Li + */ +public interface ExcelListener extends ReadListener { + + ExcelResult getExcelResult(); + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/excel/ExcelResult.java b/ruoyi-common/src/main/java/com/ruoyi/common/excel/ExcelResult.java new file mode 100644 index 000000000..63f8b8ac6 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/excel/ExcelResult.java @@ -0,0 +1,26 @@ +package com.ruoyi.common.excel; + +import java.util.List; + +/** + * excel返回对象 + * + * @author Lion Li + */ +public interface ExcelResult { + + /** + * 对象列表 + */ + List getList(); + + /** + * 错误列表 + */ + List getErrorList(); + + /** + * 导入回执 + */ + String getAnalysis(); +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/exception/file/InvalidExtensionException.java b/ruoyi-common/src/main/java/com/ruoyi/common/exception/file/InvalidExtensionException.java deleted file mode 100644 index 7de92e24c..000000000 --- a/ruoyi-common/src/main/java/com/ruoyi/common/exception/file/InvalidExtensionException.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.ruoyi.common.exception.file; - -import lombok.*; -import org.apache.commons.fileupload.FileUploadException; - -import java.util.Arrays; - -/** - * 文件上传 误异常类 - * - * @author ruoyi - */ -@Data -@EqualsAndHashCode(callSuper = true) -@NoArgsConstructor -public class InvalidExtensionException extends FileUploadException { - private static final long serialVersionUID = 1L; - - private String[] allowedExtension; - private String extension; - private String filename; - - public InvalidExtensionException(String[] allowedExtension, String extension, String filename) { - super("filename : [" + filename + "], extension : [" + extension + "], allowed extension : [" + Arrays.toString(allowedExtension) + "]"); - this.allowedExtension = allowedExtension; - this.extension = extension; - this.filename = filename; - } - - public static class InvalidImageExtensionException extends InvalidExtensionException { - private static final long serialVersionUID = 1L; - - public InvalidImageExtensionException(String[] allowedExtension, String extension, String filename) { - super(allowedExtension, extension, filename); - } - } - - public static class InvalidFlashExtensionException extends InvalidExtensionException { - private static final long serialVersionUID = 1L; - - public InvalidFlashExtensionException(String[] allowedExtension, String extension, String filename) { - super(allowedExtension, extension, filename); - } - } - - public static class InvalidMediaExtensionException extends InvalidExtensionException { - private static final long serialVersionUID = 1L; - - public InvalidMediaExtensionException(String[] allowedExtension, String extension, String filename) { - super(allowedExtension, extension, filename); - } - } - - public static class InvalidVideoExtensionException extends InvalidExtensionException { - private static final long serialVersionUID = 1L; - - public InvalidVideoExtensionException(String[] allowedExtension, String extension, String filename) { - super(allowedExtension, extension, filename); - } - } -} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/exception/job/TaskException.java b/ruoyi-common/src/main/java/com/ruoyi/common/exception/job/TaskException.java deleted file mode 100644 index 59ea3a687..000000000 --- a/ruoyi-common/src/main/java/com/ruoyi/common/exception/job/TaskException.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.ruoyi.common.exception.job; - -/** - * 计划策略异常 - * - * @deprecated 3.4.0删除 迁移至xxl-job - * @author ruoyi - */ -public class TaskException extends Exception -{ - private static final long serialVersionUID = 1L; - - private Code code; - - public TaskException(String msg, Code code) - { - this(msg, code, null); - } - - public TaskException(String msg, Code code, Exception nestedEx) - { - super(msg, nestedEx); - this.code = code; - } - - public Code getCode() - { - return code; - } - - public enum Code - { - TASK_EXISTS, NO_TASK_EXISTS, TASK_ALREADY_STARTED, UNKNOWN, CONFIG_ERROR, TASK_NODE_NOT_AVAILABLE - } -} \ No newline at end of file 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 f24d0e8b4..3309da14e 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 @@ -11,7 +11,9 @@ import java.util.List; * 字典工具类 * * @author ruoyi + * @deprecated 3.5.0 版本删除 迁移至 {@link com.ruoyi.common.core.service.DictService} */ +@Deprecated public class DictUtils { /** @@ -36,9 +38,8 @@ public class DictUtils { * @return dictDatas 字典数据列表 */ public static List getDictCache(String key) { - Object cacheObj = RedisUtils.getCacheObject(getCacheKey(key)); - if (StringUtils.isNotNull(cacheObj)) { - List dictDatas = (List) cacheObj; + List dictDatas = RedisUtils.getCacheObject(getCacheKey(key)); + if (StringUtils.isNotNull(dictDatas)) { return dictDatas; } return null; 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 b358e3be7..abc42ddd2 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 @@ -1,5 +1,6 @@ package com.ruoyi.common.utils; +import cn.hutool.core.util.ObjectUtil; import cn.hutool.http.HttpStatus; import com.baomidou.mybatisplus.core.metadata.OrderItem; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -63,7 +64,9 @@ public class PageUtils { } PagePlus page = new PagePlus<>(pageNum, pageSize); OrderItem orderItem = buildOrderItem(orderByColumn, isAsc); - page.addOrder(orderItem); + if (ObjectUtil.isNotNull(orderItem)) { + page.addOrder(orderItem); + } return page; } @@ -87,7 +90,9 @@ public class PageUtils { } Page page = new Page<>(pageNum, pageSize); OrderItem orderItem = buildOrderItem(orderByColumn, isAsc); - page.addOrder(orderItem); + if (ObjectUtil.isNotNull(orderItem)) { + page.addOrder(orderItem); + } return page; } 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 index 27472a72a..04db787b8 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/RedisUtils.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/RedisUtils.java @@ -88,7 +88,30 @@ public class RedisUtils { * @param value 缓存的值 */ public static void setCacheObject(final String key, final T value) { - client.getBucket(key).set(value); + setCacheObject(key, value, false); + } + + /** + * 缓存基本的对象,保留当前对象 TTL 有效期 + * + * @param key 缓存的键值 + * @param value 缓存的值 + * @param isSaveTtl 是否保留TTL有效期(例如: set之前ttl剩余90 set之后还是为90) + * @since Redis 6.X 以上使用 setAndKeepTTL 兼容 5.X 方案 + */ + public static void setCacheObject(final String key, final T value, final boolean isSaveTtl) { + RBucket bucket = client.getBucket(key); + if (isSaveTtl) { + try { + bucket.setAndKeepTTL(value); + } catch (Exception e) { + long timeToLive = bucket.remainTimeToLive(); + bucket.set(value); + bucket.expire(timeToLive, TimeUnit.MILLISECONDS); + } + } else { + bucket.set(value); + } } /** diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/TreeBuildUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/TreeBuildUtils.java new file mode 100644 index 000000000..a8380a287 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/TreeBuildUtils.java @@ -0,0 +1,31 @@ +package com.ruoyi.common.utils; + +import cn.hutool.core.lang.tree.Tree; +import cn.hutool.core.lang.tree.TreeNodeConfig; +import cn.hutool.core.lang.tree.TreeUtil; +import cn.hutool.core.lang.tree.parser.NodeParser; + +import java.util.List; + +/** + * 扩展 hutool TreeUtil 封装系统树构建 + * + * @author Lion Li + */ +public class TreeBuildUtils extends TreeUtil { + + /** + * 根据前端定制差异化字段 + */ + public static final TreeNodeConfig DEFAULT_CONFIG = TreeNodeConfig.DEFAULT_CONFIG.setNameKey("label"); + + /** + * 默认树父节点id + */ + public static final Long DEFAULT_PARENT_ID = 0L; + + public static List> build(List list, NodeParser nodeParser) { + return TreeUtil.build(list, DEFAULT_PARENT_ID, DEFAULT_CONFIG, nodeParser); + } + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/ValidatorUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/ValidatorUtils.java new file mode 100644 index 000000000..c28cf80fa --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/ValidatorUtils.java @@ -0,0 +1,25 @@ +package com.ruoyi.common.utils; + +import javax.validation.ConstraintViolation; +import javax.validation.ConstraintViolationException; +import javax.validation.Validation; +import javax.validation.Validator; +import java.util.Set; + +/** + * Validator 校验框架工具 + * + * @author Lion Li + */ +public class ValidatorUtils { + + private static final Validator VALID = Validation.buildDefaultValidatorFactory().getValidator(); + + public static void validate(T object, Class... groups) { + Set> validate = VALID.validate(object, groups); + if (!validate.isEmpty()) { + throw new ConstraintViolationException("参数校验异常", validate); + } + } + +} 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 813fc979e..6c5dc5fc8 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 @@ -4,7 +4,9 @@ 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.excel.DefaultExcelListener; +import com.ruoyi.common.excel.ExcelListener; +import com.ruoyi.common.excel.ExcelResult; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.file.FileUtils; @@ -21,129 +23,133 @@ import java.util.List; */ public class ExcelUtil { - /** - * 对excel表单默认第一个索引名转换成list(EasyExcel) - * - * @param is 输入流 - * @return 转换后集合 - */ - public static List importExcel(InputStream is, Class clazz) { - return EasyExcel.read(is).head(clazz).autoCloseStream(false).sheet().doReadSync(); - } + /** + * 同步导入(适用于小数据量) + * + * @param is 输入流 + * @return 转换后集合 + */ + public static List importExcel(InputStream is, Class clazz) { + return EasyExcel.read(is).head(clazz).autoCloseStream(false).sheet().doReadSync(); + } - /** - * 对list数据源将其里面的数据导入到excel表单(EasyExcel) - * - * @param list 导出数据集合 - * @param sheetName 工作表的名称 - * @return 结果 - */ - public static void exportExcel(List list, String sheetName, Class clazz, HttpServletResponse response) { - try { - String filename = encodingFilename(sheetName); - response.reset(); - FileUtils.setAttachmentResponseHeader(response, filename); - response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8"); - ServletOutputStream os = response.getOutputStream(); - EasyExcel.write(os, clazz) - .autoCloseStream(false) - // 自动适配 - .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) - // 大数值自动转换 防止失真 - .registerConverter(new ExcelBigNumberConvert()) - .sheet(sheetName).doWrite(list); - } catch (IOException e) { - throw new RuntimeException("导出Excel异常"); - } - } - /** - * 解析导出值 0=男,1=女,2=未知 - * - * @param propertyValue 参数值 - * @param converterExp 翻译注解 - * @param separator 分隔符 - * @return 解析后值 - */ - public static String convertByExp(String propertyValue, String converterExp, String separator) { - StringBuilder propertyString = new StringBuilder(); - String[] convertSource = converterExp.split(","); - for (String item : convertSource) { - String[] itemArray = item.split("="); - if (StringUtils.containsAny(separator, propertyValue)) { - for (String value : propertyValue.split(separator)) { - if (itemArray[0].equals(value)) { - propertyString.append(itemArray[1] + separator); - break; - } - } - } else { - if (itemArray[0].equals(propertyValue)) { - return itemArray[1]; - } - } - } - return StringUtils.stripEnd(propertyString.toString(), separator); - } + /** + * 使用校验监听器 异步导入 同步返回 + * + * @param is 输入流 + * @param clazz 对象类型 + * @param isValidate 是否 Validator 检验 默认为是 + * @return 转换后集合 + */ + public static ExcelResult importExcel(InputStream is, Class clazz, boolean isValidate) { + DefaultExcelListener listener = new DefaultExcelListener<>(isValidate); + EasyExcel.read(is, clazz, listener).sheet().doRead(); + return listener.getExcelResult(); + } - /** - * 反向解析值 男=0,女=1,未知=2 - * - * @param propertyValue 参数值 - * @param converterExp 翻译注解 - * @param separator 分隔符 - * @return 解析后值 - */ - public static String reverseByExp(String propertyValue, String converterExp, String separator) { - StringBuilder propertyString = new StringBuilder(); - String[] convertSource = converterExp.split(","); - for (String item : convertSource) { - String[] itemArray = item.split("="); - if (StringUtils.containsAny(separator, propertyValue)) { - for (String value : propertyValue.split(separator)) { - if (itemArray[1].equals(value)) { - propertyString.append(itemArray[0] + separator); - break; - } - } - } else { - if (itemArray[1].equals(propertyValue)) { - return itemArray[0]; - } - } - } - return StringUtils.stripEnd(propertyString.toString(), separator); - } + /** + * 使用自定义监听器 异步导入 自定义返回 + * + * @param is 输入流 + * @param clazz 对象类型 + * @param listener 自定义监听器 + * @return 转换后集合 + */ + public static ExcelResult importExcel(InputStream is, Class clazz, ExcelListener listener) { + EasyExcel.read(is, clazz, listener).sheet().doRead(); + return listener.getExcelResult(); + } - /** - * 解析字典值 - * - * @param dictValue 字典值 - * @param dictType 字典类型 - * @param separator 分隔符 - * @return 字典标签 - */ - public static String convertDictByExp(String dictValue, String dictType, String separator) { - return DictUtils.getDictLabel(dictType, dictValue, separator); - } + /** + * 导出excel + * + * @param list 导出数据集合 + * @param sheetName 工作表的名称 + * @return 结果 + */ + public static void exportExcel(List list, String sheetName, Class clazz, HttpServletResponse response) { + try { + String filename = encodingFilename(sheetName); + response.reset(); + FileUtils.setAttachmentResponseHeader(response, filename); + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8"); + ServletOutputStream os = response.getOutputStream(); + EasyExcel.write(os, clazz) + .autoCloseStream(false) + // 自动适配 + .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) + // 大数值自动转换 防止失真 + .registerConverter(new ExcelBigNumberConvert()) + .sheet(sheetName).doWrite(list); + } catch (IOException e) { + throw new RuntimeException("导出Excel异常"); + } + } - /** - * 反向解析值字典值 - * - * @param dictLabel 字典标签 - * @param dictType 字典类型 - * @param separator 分隔符 - * @return 字典值 - */ - public static String reverseDictByExp(String dictLabel, String dictType, String separator) { - return DictUtils.getDictValue(dictType, dictLabel, separator); - } + /** + * 解析导出值 0=男,1=女,2=未知 + * + * @param propertyValue 参数值 + * @param converterExp 翻译注解 + * @param separator 分隔符 + * @return 解析后值 + */ + public static String convertByExp(String propertyValue, String converterExp, String separator) { + StringBuilder propertyString = new StringBuilder(); + String[] convertSource = converterExp.split(","); + for (String item : convertSource) { + String[] itemArray = item.split("="); + if (StringUtils.containsAny(separator, propertyValue)) { + for (String value : propertyValue.split(separator)) { + if (itemArray[0].equals(value)) { + propertyString.append(itemArray[1] + separator); + break; + } + } + } else { + if (itemArray[0].equals(propertyValue)) { + return itemArray[1]; + } + } + } + return StringUtils.stripEnd(propertyString.toString(), separator); + } - /** - * 编码文件名 - */ - public static String encodingFilename(String filename) { - return IdUtil.fastSimpleUUID() + "_" + filename + ".xlsx"; - } + /** + * 反向解析值 男=0,女=1,未知=2 + * + * @param propertyValue 参数值 + * @param converterExp 翻译注解 + * @param separator 分隔符 + * @return 解析后值 + */ + public static String reverseByExp(String propertyValue, String converterExp, String separator) { + StringBuilder propertyString = new StringBuilder(); + String[] convertSource = converterExp.split(","); + for (String item : convertSource) { + String[] itemArray = item.split("="); + if (StringUtils.containsAny(separator, propertyValue)) { + for (String value : propertyValue.split(separator)) { + if (itemArray[1].equals(value)) { + propertyString.append(itemArray[0] + separator); + break; + } + } + } else { + if (itemArray[1].equals(propertyValue)) { + return itemArray[0]; + } + } + } + return StringUtils.stripEnd(propertyString.toString(), separator); + } + + /** + * 编码文件名 + */ + public static String encodingFilename(String filename) { + return IdUtil.fastSimpleUUID() + "_" + filename + ".xlsx"; + } } 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 deleted file mode 100644 index 2f833e33e..000000000 --- a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/FeignTestController.java +++ /dev/null @@ -1,37 +0,0 @@ -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; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -/** - * feign测试controller - * - * @author Lion Li - * @deprecated 由于使用人数较少 决定与 3.4.0 版本移除 - */ -@Api(value = "feign测试", tags = {"feign测试"}) -@RequiredArgsConstructor(onConstructor_ = @Autowired) -@RestController -@RequestMapping("/feign/test") -public class FeignTestController { - - private final FeignTestService feignTestService; - - /** - * 搜索数据 - */ - @ApiOperation("测试使用feign请求数据") - @GetMapping("/search/{wd}") - public AjaxResult search(@PathVariable String wd) { - String search = feignTestService.search(wd); - return AjaxResult.success("操作成功",search); - } -} 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 903b982b1..e01b542e0 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 @@ -28,75 +28,75 @@ import java.util.concurrent.TimeUnit; @RequestMapping("/demo/cache") public class RedisCacheController { - /** - * 测试 @Cacheable - * - * 表示这个方法有了缓存的功能,方法的返回值会被缓存下来 - * 下一次调用该方法前,会去检查是否缓存中已经有值 - * 如果有就直接返回,不调用方法 - * 如果没有,就调用方法,然后把结果缓存起来 - * 这个注解「一般用在查询方法上」 - * - * 重点说明: 缓存注解严谨与其他筛选数据功能一起使用 - * 例如: 数据权限注解 会造成 缓存击穿 与 数据不一致问题 - * - * cacheNames 为配置文件内 groupId - */ - @ApiOperation("测试 @Cacheable") - @Cacheable(cacheNames = "redissonCacheMap", key = "#key", condition = "#key != null") - @GetMapping("/test1") - public AjaxResult test1(String key, String value){ - return AjaxResult.success("操作成功", value); - } + /** + * 测试 @Cacheable + *

+ * 表示这个方法有了缓存的功能,方法的返回值会被缓存下来 + * 下一次调用该方法前,会去检查是否缓存中已经有值 + * 如果有就直接返回,不调用方法 + * 如果没有,就调用方法,然后把结果缓存起来 + * 这个注解「一般用在查询方法上」 + *

+ * 重点说明: 缓存注解严谨与其他筛选数据功能一起使用 + * 例如: 数据权限注解 会造成 缓存击穿 与 数据不一致问题 + *

+ * cacheNames 为配置文件内 groupId + */ + @ApiOperation("测试 @Cacheable") + @Cacheable(cacheNames = "redissonCacheMap", key = "#key", condition = "#key != null") + @GetMapping("/test1") + public AjaxResult test1(String key, String value) { + return AjaxResult.success("操作成功", value); + } - /** - * 测试 @CachePut - * - * 加了@CachePut注解的方法,会把方法的返回值put到缓存里面缓存起来,供其它地方使用 - * 它「通常用在新增方法上」 - * - * cacheNames 为 配置文件内 groupId - */ - @ApiOperation("测试 @CachePut") - @CachePut(cacheNames = "redissonCacheMap", key = "#key", condition = "#key != null") - @GetMapping("/test2") - public AjaxResult test2(String key, String value){ - return AjaxResult.success("操作成功", value); - } + /** + * 测试 @CachePut + *

+ * 加了@CachePut注解的方法,会把方法的返回值put到缓存里面缓存起来,供其它地方使用 + * 它「通常用在新增方法上」 + *

+ * cacheNames 为 配置文件内 groupId + */ + @ApiOperation("测试 @CachePut") + @CachePut(cacheNames = "redissonCacheMap", key = "#key", condition = "#key != null") + @GetMapping("/test2") + public AjaxResult test2(String key, String value) { + return AjaxResult.success("操作成功", value); + } - /** - * 测试 @CacheEvict - * - * 使用了CacheEvict注解的方法,会清空指定缓存 - * 「一般用在更新或者删除的方法上」 - * - * cacheNames 为 配置文件内 groupId - */ - @ApiOperation("测试 @CacheEvict") - @CacheEvict(cacheNames = "redissonCacheMap", key = "#key", condition = "#key != null") - @GetMapping("/test3") - public AjaxResult test3(String key, String value){ - return AjaxResult.success("操作成功", value); - } + /** + * 测试 @CacheEvict + *

+ * 使用了CacheEvict注解的方法,会清空指定缓存 + * 「一般用在更新或者删除的方法上」 + *

+ * cacheNames 为 配置文件内 groupId + */ + @ApiOperation("测试 @CacheEvict") + @CacheEvict(cacheNames = "redissonCacheMap", key = "#key", condition = "#key != null") + @GetMapping("/test3") + public AjaxResult test3(String key, String value) { + return AjaxResult.success("操作成功", value); + } - /** - * 测试设置过期时间 - * 手动设置过期时间10秒 - * 11秒后获取 判断是否相等 - */ - @ApiOperation("测试设置过期时间") - @GetMapping("/test6") - public AjaxResult test6(String key, String value){ - RedisUtils.setCacheObject(key, value); - boolean flag = RedisUtils.expire(key, 10, TimeUnit.SECONDS); - System.out.println("***********" + flag); - try { - Thread.sleep(11 * 1000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - Object obj = RedisUtils.getCacheObject(key); - return AjaxResult.success("操作成功", value.equals(obj)); - } + /** + * 测试设置过期时间 + * 手动设置过期时间10秒 + * 11秒后获取 判断是否相等 + */ + @ApiOperation("测试设置过期时间") + @GetMapping("/test6") + public AjaxResult test6(String key, String value) { + RedisUtils.setCacheObject(key, value); + boolean flag = RedisUtils.expire(key, 10, TimeUnit.SECONDS); + System.out.println("***********" + flag); + try { + Thread.sleep(11 * 1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + Object obj = RedisUtils.getCacheObject(key); + return AjaxResult.success("操作成功", value.equals(obj)); + } } 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 a72024663..94ad3c3a3 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 @@ -9,7 +9,6 @@ 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; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -28,59 +27,50 @@ import java.time.LocalTime; @RequestMapping("/demo/redisLock") public class RedisLockController { - @Autowired - private LockTemplate lockTemplate; + @Autowired + private LockTemplate lockTemplate; - /** - * 测试lock4j 注解 - */ - @ApiOperation("测试lock4j 注解") - @Lock4j(keys = {"#key"}) - @GetMapping("/testLock4j") - public AjaxResult testLock4j(String key,String value){ - System.out.println("start:"+key+",time:"+ LocalTime.now().toString()); - try { - Thread.sleep(10000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - System.out.println("end :"+key+",time:"+LocalTime.now().toString()); - return AjaxResult.success("操作成功",value); - } + /** + * 测试lock4j 注解 + */ + @ApiOperation("测试lock4j 注解") + @Lock4j(keys = {"#key"}) + @GetMapping("/testLock4j") + public AjaxResult testLock4j(String key, String value) { + System.out.println("start:" + key + ",time:" + LocalTime.now().toString()); + try { + Thread.sleep(10000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println("end :" + key + ",time:" + LocalTime.now().toString()); + return AjaxResult.success("操作成功", value); + } - /** - * 测试lock4j 工具 - */ - @ApiOperation("测试lock4j 工具") - @GetMapping("/testLock4jLockTemaplate") - public AjaxResult testLock4jLockTemaplate(String key,String value){ - final LockInfo lockInfo = lockTemplate.lock(key, 30000L, 5000L, RedissonLockExecutor.class); - if (null == lockInfo) { - throw new RuntimeException("业务处理中,请稍后再试"); - } - // 获取锁成功,处理业务 - try { - try { - Thread.sleep(8000); - } catch (InterruptedException e) { - // - } - System.out.println("执行简单方法1 , 当前线程:" + Thread.currentThread().getName()); - } finally { - //释放锁 - lockTemplate.releaseLock(lockInfo); - } - //结束 - return AjaxResult.success("操作成功",value); - } + /** + * 测试lock4j 工具 + */ + @ApiOperation("测试lock4j 工具") + @GetMapping("/testLock4jLockTemaplate") + public AjaxResult testLock4jLockTemaplate(String key, String value) { + final LockInfo lockInfo = lockTemplate.lock(key, 30000L, 5000L, RedissonLockExecutor.class); + if (null == lockInfo) { + throw new RuntimeException("业务处理中,请稍后再试"); + } + // 获取锁成功,处理业务 + try { + try { + Thread.sleep(8000); + } catch (InterruptedException e) { + // + } + System.out.println("执行简单方法1 , 当前线程:" + Thread.currentThread().getName()); + } finally { + //释放锁 + lockTemplate.releaseLock(lockInfo); + } + //结束 + return AjaxResult.success("操作成功", value); + } - /** - * 测试spring-cache注解 - */ - @ApiOperation("测试spring-cache注解") - @Cacheable(value = "test", key = "#key") - @GetMapping("/testCache") - public AjaxResult testCache(String key) { - return AjaxResult.success("操作成功", 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 index 810b307dc..619a69028 100644 --- a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisPubSubController.java +++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisPubSubController.java @@ -4,6 +4,7 @@ import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.utils.RedisUtils; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; @@ -21,22 +22,22 @@ import org.springframework.web.bind.annotation.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("/pub") + public AjaxResult pub(@ApiParam("通道Key") String key, @ApiParam("发送内容") 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("操作成功"); - } + @ApiOperation("订阅消息") + @GetMapping("/sub") + public AjaxResult sub(@ApiParam("通道Key") 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/RedisRateLimiterController.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisRateLimiterController.java index 33d75093b..1eeab6114 100644 --- a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisRateLimiterController.java +++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisRateLimiterController.java @@ -22,37 +22,37 @@ import org.springframework.web.bind.annotation.RestController; @RequestMapping("/demo/rateLimiter") public class RedisRateLimiterController { - /** - * 测试全局限流 - * 全局影响 - */ - @ApiOperation("测试全局限流") - @RateLimiter(count = 2, time = 10) - @GetMapping("/test") - public AjaxResult test(String value){ - return AjaxResult.success("操作成功",value); - } + /** + * 测试全局限流 + * 全局影响 + */ + @ApiOperation("测试全局限流") + @RateLimiter(count = 2, time = 10) + @GetMapping("/test") + public AjaxResult test(String value) { + return AjaxResult.success("操作成功", value); + } - /** - * 测试请求IP限流 - * 同一IP请求受影响 - */ - @ApiOperation("测试请求IP限流") - @RateLimiter(count = 2, time = 10, limitType = LimitType.IP) - @GetMapping("/testip") - public AjaxResult testip(String value){ - return AjaxResult.success("操作成功",value); - } + /** + * 测试请求IP限流 + * 同一IP请求受影响 + */ + @ApiOperation("测试请求IP限流") + @RateLimiter(count = 2, time = 10, limitType = LimitType.IP) + @GetMapping("/testip") + public AjaxResult testip(String value) { + return AjaxResult.success("操作成功", value); + } - /** - * 测试集群实例限流 - * 启动两个后端服务互不影响 - */ - @ApiOperation("测试集群实例限流") - @RateLimiter(count = 2, time = 10, limitType = LimitType.CLUSTER) - @GetMapping("/testcluster") - public AjaxResult testcluster(String value){ - return AjaxResult.success("操作成功",value); - } + /** + * 测试集群实例限流 + * 启动两个后端服务互不影响 + */ + @ApiOperation("测试集群实例限流") + @RateLimiter(count = 2, time = 10, limitType = LimitType.CLUSTER) + @GetMapping("/testcluster") + public AjaxResult testcluster(String value) { + return AjaxResult.success("操作成功", value); + } } diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/Swagger3DemoController.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/Swagger3DemoController.java index a8efb64e4..6b73d64a8 100644 --- a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/Swagger3DemoController.java +++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/Swagger3DemoController.java @@ -21,18 +21,18 @@ import org.springframework.web.multipart.MultipartFile; @RequestMapping("/swagger/demo") public class Swagger3DemoController { - /** - * 上传请求 - * 必须使用 @RequestPart 注解标注为文件 - * dataType 必须为 "java.io.File" - */ - @ApiOperation(value = "通用上传请求") - @ApiImplicitParams({ - @ApiImplicitParam(name = "file", value = "文件", dataType = "java.io.File", required = true), - }) - @PostMapping(value = "/upload") - public AjaxResult upload(@RequestPart("file") MultipartFile file) { - return AjaxResult.success("操作成功", file.getOriginalFilename()); - } + /** + * 上传请求 + * 必须使用 @RequestPart 注解标注为文件 + * dataType 必须为 "java.io.File" + */ + @ApiOperation(value = "通用上传请求") + @ApiImplicitParams({ + @ApiImplicitParam(name = "file", value = "文件", dataType = "java.io.File", required = true), + }) + @PostMapping(value = "/upload") + public AjaxResult upload(@RequestPart("file") MultipartFile file) { + return AjaxResult.success("操作成功", file.getOriginalFilename()); + } } 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 ef117a11c..d6e691dbb 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 @@ -34,48 +34,48 @@ public class TestBatchController extends BaseController { /** * 新增批量方法 可完美替代 saveBatch 秒级插入上万数据 (对mysql负荷较大) */ - @ApiOperation(value = "新增批量方法") + @ApiOperation(value = "新增批量方法") @PostMapping("/add") // @DataSource(DataSourceType.SLAVE) public AjaxResult add() { - List list = new ArrayList<>(); - for (int i = 0; i < 1000; i++) { - list.add(new TestDemo().setOrderNum(-1L).setTestKey("批量新增").setValue("测试新增")); - } + List list = new ArrayList<>(); + for (int i = 0; i < 1000; i++) { + list.add(new TestDemo().setOrderNum(-1L).setTestKey("批量新增").setValue("测试新增")); + } return toAjax(iTestDemoService.saveAll(list) ? 1 : 0); } - /** - * 新增或更新 可完美替代 saveOrUpdateBatch 高性能 - */ - @ApiOperation(value = "新增或更新批量方法") - @PostMapping("/addOrUpdate") + /** + * 新增或更新 可完美替代 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); - } + 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); + } /** * 删除批量方法 */ - @ApiOperation(value = "删除批量方法") + @ApiOperation(value = "删除批量方法") @DeleteMapping() // @DataSource(DataSourceType.SLAVE) public AjaxResult remove() { return toAjax(iTestDemoService.remove(new LambdaQueryWrapper() - .eq(TestDemo::getOrderNum, -1L)) ? 1 : 0); + .eq(TestDemo::getOrderNum, -1L)) ? 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 a137a3d1e..7d558aede 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 @@ -1,6 +1,7 @@ package com.ruoyi.demo.controller; import cn.dev33.satoken.annotation.SaCheckPermission; +import cn.hutool.core.bean.BeanUtil; import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.RepeatSubmit; import com.ruoyi.common.core.controller.BaseController; @@ -10,16 +11,20 @@ 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.ValidatorUtils; +import com.ruoyi.common.excel.ExcelResult; import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.demo.domain.TestDemo; import com.ruoyi.demo.domain.bo.TestDemoBo; +import com.ruoyi.demo.domain.bo.TestDemoImportVo; import com.ruoyi.demo.domain.vo.TestDemoVo; import com.ruoyi.demo.service.ITestDemoService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.*; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletResponse; import javax.validation.constraints.NotEmpty; @@ -63,20 +68,35 @@ public class TestDemoController extends BaseController { return iTestDemoService.customPageList(bo); } - /** + @ApiOperation("导入测试-校验") + @ApiImplicitParams({ + @ApiImplicitParam(name = "file", value = "导入文件", dataType = "java.io.File", required = true), + }) + @Log(title = "测试单表", businessType = BusinessType.IMPORT) + @PreAuthorize("@ss.hasPermi('demo:demo:import')") + @PostMapping("/importData") + public AjaxResult importData(@RequestPart("file") MultipartFile file) throws Exception { + ExcelResult excelResult = ExcelUtil.importExcel(file.getInputStream(), TestDemoImportVo.class, true); + List volist = excelResult.getList(); + List list = BeanUtil.copyToList(volist, TestDemo.class); + iTestDemoService.saveAll(list); + return AjaxResult.success(excelResult.getAnalysis()); + } + + /** * 导出测试单表列表 */ @ApiOperation("导出测试单表列表") @SaCheckPermission("demo:demo:export") @Log(title = "测试单表", businessType = BusinessType.EXPORT) - @GetMapping("/export") + @PostMapping("/export") public void export(@Validated TestDemoBo bo, HttpServletResponse response) { List list = iTestDemoService.queryList(bo); - // 测试雪花id导出 + // 测试雪花id导出 // for (TestDemoVo vo : list) { // vo.setId(1234567891234567893L); // } - ExcelUtil.exportExcel(list, "测试单表", TestDemoVo.class, response); + ExcelUtil.exportExcel(list, "测试单表", TestDemoVo.class, response); } /** @@ -85,8 +105,9 @@ public class TestDemoController extends BaseController { @ApiOperation("获取测试单表详细信息") @SaCheckPermission("demo:demo:query") @GetMapping("/{id}") - public AjaxResult getInfo(@NotNull(message = "主键不能为空") - @PathVariable("id") Long id) { + public AjaxResult getInfo(@ApiParam("测试ID") + @NotNull(message = "主键不能为空") + @PathVariable("id") Long id) { return AjaxResult.success(iTestDemoService.queryById(id)); } @@ -98,7 +119,10 @@ public class TestDemoController extends BaseController { @Log(title = "测试单表", businessType = BusinessType.INSERT) @RepeatSubmit(interval = 2, timeUnit = TimeUnit.SECONDS, message = "不允许重复提交") @PostMapping() - public AjaxResult add(@Validated(AddGroup.class) @RequestBody TestDemoBo bo) { + public AjaxResult add(@RequestBody TestDemoBo bo) { + // 使用校验工具对标 @Validated(AddGroup.class) 注解 + // 用于在非 Controller 的地方校验对象 + ValidatorUtils.validate(bo, AddGroup.class); return toAjax(iTestDemoService.insertByBo(bo) ? 1 : 0); } @@ -121,8 +145,9 @@ public class TestDemoController extends BaseController { @SaCheckPermission("demo:demo:remove") @Log(title = "测试单表" , businessType = BusinessType.DELETE) @DeleteMapping("/{ids}") - public AjaxResult remove(@NotEmpty(message = "主键不能为空") - @PathVariable Long[] ids) { + public AjaxResult remove(@ApiParam("测试ID串") + @NotEmpty(message = "主键不能为空") + @PathVariable Long[] ids) { return toAjax(iTestDemoService.deleteWithValidByIds(Arrays.asList(ids), true) ? 1 : 0); } } 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 bb0695f78..40b031b51 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 @@ -4,16 +4,24 @@ import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.utils.MessageUtils; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import lombok.Data; +import org.hibernate.validator.constraints.Range; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + /** * 测试国际化 * * @author Lion Li */ +@Validated @Api(value = "测试国际化控制器", tags = {"测试国际化管理"}) @RestController @RequestMapping("/demo/i18n") @@ -27,7 +35,42 @@ public class TestI18nController { */ @ApiOperation("通过code获取国际化内容") @GetMapping() - public AjaxResult get(String code) { + public AjaxResult get(@ApiParam("国际化code") String code) { return AjaxResult.success(MessageUtils.message(code)); } + + /** + * Validator 校验国际化 + * 不传值 分别查看异常返回 + * + * 测试使用 not.null + */ + @ApiOperation("Validator 校验国际化") + @GetMapping("/test1") + public AjaxResult test1(@NotBlank(message = "{not.null}") String str) { + return AjaxResult.success(str); + } + + /** + * Bean 校验国际化 + * 不传值 分别查看异常返回 + * + * 测试使用 not.null + */ + @ApiOperation("Bean 校验国际化") + @GetMapping("/test2") + public AjaxResult test2(@Validated TestI18nBo bo) { + return AjaxResult.success(bo); + } + + @Data + public static class TestI18nBo { + + @NotBlank(message = "{not.null}") + private String name; + + @NotNull(message = "{not.null}") + @Range(min = 0, max = 100, message = "{length.not.valid}") + private Integer age; + } } 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 f1d3b3c51..f0231bb2c 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 @@ -15,6 +15,7 @@ import com.ruoyi.demo.domain.vo.TestTreeVo; import com.ruoyi.demo.service.ITestTreeService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; @@ -61,7 +62,7 @@ public class TestTreeController extends BaseController { @GetMapping("/export") public void export(@Validated TestTreeBo bo, HttpServletResponse response) { List list = iTestTreeService.queryList(bo); - ExcelUtil.exportExcel(list, "测试树表", TestTreeVo.class, response); + ExcelUtil.exportExcel(list, "测试树表", TestTreeVo.class, response); } /** @@ -70,8 +71,9 @@ public class TestTreeController extends BaseController { @ApiOperation("获取测试树表详细信息") @SaCheckPermission("demo:tree:query") @GetMapping("/{id}") - public AjaxResult getInfo(@NotNull(message = "主键不能为空") - @PathVariable("id") Long id) { + public AjaxResult getInfo(@ApiParam("测试树ID") + @NotNull(message = "主键不能为空") + @PathVariable("id") Long id) { return AjaxResult.success(iTestTreeService.queryById(id)); } @@ -106,8 +108,9 @@ public class TestTreeController extends BaseController { @SaCheckPermission("demo:tree:remove") @Log(title = "测试树表" , businessType = BusinessType.DELETE) @DeleteMapping("/{ids}") - public AjaxResult remove(@NotEmpty(message = "主键不能为空") - @PathVariable Long[] ids) { + public AjaxResult remove(@ApiParam("测试树ID串") + @NotEmpty(message = "主键不能为空") + @PathVariable Long[] ids) { return toAjax(iTestTreeService.deleteWithValidByIds(Arrays.asList(ids), true) ? 1 : 0); } } diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/bo/TestDemoImportVo.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/bo/TestDemoImportVo.java new file mode 100644 index 000000000..7185514fd --- /dev/null +++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/bo/TestDemoImportVo.java @@ -0,0 +1,61 @@ +package com.ruoyi.demo.domain.bo; + +import com.alibaba.excel.annotation.ExcelProperty; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * 测试单表业务对象 test_demo + * + * @author Lion Li + * @date 2021-07-26 + */ +@Data +@ApiModel("测试单表业务对象") +public class TestDemoImportVo { + + /** + * 部门id + */ + @ApiModelProperty("部门id") + @NotNull(message = "部门id不能为空") + @ExcelProperty(value = "部门id") + private Long deptId; + + /** + * 用户id + */ + @ApiModelProperty("用户id") + @NotNull(message = "用户id不能为空") + @ExcelProperty(value = "用户id") + private Long userId; + + /** + * 排序号 + */ + @ApiModelProperty("排序号") + @NotNull(message = "排序号不能为空") + @ExcelProperty(value = "排序号") + private Long orderNum; + + /** + * key键 + */ + @ApiModelProperty("key键") + @NotBlank(message = "key键不能为空") + @ExcelProperty(value = "key键") + private String testKey; + + /** + * 值 + */ + @ApiModelProperty("值") + @NotBlank(message = "值不能为空") + @ExcelProperty(value = "值") + private String value; + +} 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 deleted file mode 100644 index 50eb4ebf6..000000000 --- a/ruoyi-demo/src/main/java/com/ruoyi/demo/feign/FeignTestService.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.ruoyi.demo.feign; - -import com.ruoyi.demo.feign.constant.FeignTestConstant; -import com.ruoyi.demo.feign.fallback.FeignTestFallback; -import org.springframework.cloud.openfeign.FeignClient; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestParam; - -/** - * feign测试service - * 规范接口 Service 无感调用 - * 常量管理请求路径 更加规范 - * 自定义容错处理 安全可靠 (需自行配置熔断器) - * 增加 feign 的目的为使 http 请求接口化 - * - * @author Lion Li - * @deprecated 由于使用人数较少 决定与 3.4.0 版本移除 - */ -@FeignClient( - name = FeignTestConstant.BAIDU_NAME, - url = FeignTestConstant.BAIDU_URL, - fallback = FeignTestFallback.class) -public interface FeignTestService { - - @GetMapping("/s") - String search(@RequestParam("wd") String wd); -} diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/feign/constant/FeignTestConstant.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/feign/constant/FeignTestConstant.java deleted file mode 100644 index 28dfa8adb..000000000 --- a/ruoyi-demo/src/main/java/com/ruoyi/demo/feign/constant/FeignTestConstant.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.ruoyi.demo.feign.constant; - -/** - * @deprecated 由于使用人数较少 决定与 3.4.0 版本移除 - */ -@Deprecated -public class FeignTestConstant { - - public static final String BAIDU_NAME = "baidu"; - - public static final String BAIDU_URL = "http://www.baidu.com"; - -} 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 deleted file mode 100644 index 8e81ad7ad..000000000 --- a/ruoyi-demo/src/main/java/com/ruoyi/demo/feign/fallback/FeignTestFallback.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.ruoyi.demo.feign.fallback; - - -import com.ruoyi.demo.feign.FeignTestService; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Component; - -/** - * feign测试fallback - * 自定义封装结构体熔断 - * 需重写解码器 根据自定义实体 自行解析熔断 - * - * 熔断器需要自行添加配置 - * - * @see {com.ruoyi.framework.config.FeignConfig#errorDecoder()} - * @author Lion Li - * @deprecated 由于使用人数较少 决定与 3.4.0 版本移除 - */ -@Slf4j -@Component -public class FeignTestFallback implements FeignTestService { - - @Override - public String search(String wd) { - log.error("fallback"); - return "报错啦"; - } -} diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/feign/fallback/package-info.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/feign/fallback/package-info.java deleted file mode 100644 index 47983a0e1..000000000 --- a/ruoyi-demo/src/main/java/com/ruoyi/demo/feign/fallback/package-info.java +++ /dev/null @@ -1 +0,0 @@ -package com.ruoyi.demo.feign.fallback; \ No newline at end of file diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/feign/package-info.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/feign/package-info.java deleted file mode 100644 index 91e4b4a5b..000000000 --- a/ruoyi-demo/src/main/java/com/ruoyi/demo/feign/package-info.java +++ /dev/null @@ -1 +0,0 @@ -package com.ruoyi.demo.feign; \ No newline at end of file diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/mapper/TestDemoMapper.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/mapper/TestDemoMapper.java index efbbffc44..dccea6154 100644 --- a/ruoyi-demo/src/main/java/com/ruoyi/demo/mapper/TestDemoMapper.java +++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/mapper/TestDemoMapper.java @@ -2,11 +2,9 @@ package com.ruoyi.demo.mapper; import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.ruoyi.common.core.mybatisplus.cache.MybatisPlusRedisCache; import com.ruoyi.common.core.mybatisplus.core.BaseMapperPlus; import com.ruoyi.demo.domain.TestDemo; import com.ruoyi.demo.domain.vo.TestDemoVo; -import org.apache.ibatis.annotations.CacheNamespace; import org.apache.ibatis.annotations.Param; /** @@ -15,8 +13,6 @@ import org.apache.ibatis.annotations.Param; * @author Lion Li * @date 2021-07-26 */ -// 如使需切换数据源 请勿使用缓存 会造成数据不一致现象 -@CacheNamespace(implementation = MybatisPlusRedisCache.class, eviction = MybatisPlusRedisCache.class) public interface TestDemoMapper extends BaseMapperPlus { Page customPageList(@Param("page") Page page, @Param("ew") Wrapper wrapper); diff --git a/ruoyi-demo/src/main/resources/mapper/demo/package-info.md b/ruoyi-demo/src/main/resources/mapper/demo/package-info.md deleted file mode 100644 index e69de29bb..000000000 diff --git a/ruoyi-demo/src/main/resources/mapper/package-info.md b/ruoyi-demo/src/main/resources/mapper/package-info.md new file mode 100644 index 000000000..c938b1e50 --- /dev/null +++ b/ruoyi-demo/src/main/resources/mapper/package-info.md @@ -0,0 +1,3 @@ +java包使用 `.` 分割 resource 目录使用 `/` 分割 +
+此文件目的 防止文件夹粘连找不到 `xml` 文件 \ No newline at end of file diff --git a/ruoyi-extend/ruoyi-monitor-admin/pom.xml b/ruoyi-extend/ruoyi-monitor-admin/pom.xml index 33a78516d..fc321bd58 100644 --- a/ruoyi-extend/ruoyi-monitor-admin/pom.xml +++ b/ruoyi-extend/ruoyi-monitor-admin/pom.xml @@ -28,6 +28,12 @@ de.codecentric spring-boot-admin-starter-server + + + de.codecentric + spring-boot-admin-starter-client + + diff --git a/ruoyi-extend/ruoyi-monitor-admin/src/main/java/com/ruoyi/monitor/admin/config/SecurityConfig.java b/ruoyi-extend/ruoyi-monitor-admin/src/main/java/com/ruoyi/monitor/admin/config/SecurityConfig.java index ca9072c78..7335e2f25 100644 --- a/ruoyi-extend/ruoyi-monitor-admin/src/main/java/com/ruoyi/monitor/admin/config/SecurityConfig.java +++ b/ruoyi-extend/ruoyi-monitor-admin/src/main/java/com/ruoyi/monitor/admin/config/SecurityConfig.java @@ -34,6 +34,8 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { //授予对所有静态资产和登录页面的公共访问权限。 .antMatchers(adminContextPath + "/assets/**").permitAll() .antMatchers(adminContextPath + "/login").permitAll() + .antMatchers("/actuator").anonymous() + .antMatchers("/actuator/**").anonymous() //必须对每个其他请求进行身份验证 .anyRequest().authenticated().and() //配置登录和注销 diff --git a/ruoyi-extend/ruoyi-monitor-admin/src/main/resources/application-dev.yml b/ruoyi-extend/ruoyi-monitor-admin/src/main/resources/application-dev.yml new file mode 100644 index 000000000..829314b41 --- /dev/null +++ b/ruoyi-extend/ruoyi-monitor-admin/src/main/resources/application-dev.yml @@ -0,0 +1,14 @@ +--- # 监控配置 +spring: + boot: + admin: + # Spring Boot Admin Client 客户端的相关配置 + client: + # 增加客户端开关 + enabled: true + # 设置 Spring Boot Admin Server 地址 + url: http://localhost:9090/admin + instance: + prefer-ip: true # 注册实例时,优先使用 IP + username: ruoyi + password: 123456 diff --git a/ruoyi-extend/ruoyi-monitor-admin/src/main/resources/application-prod.yml b/ruoyi-extend/ruoyi-monitor-admin/src/main/resources/application-prod.yml new file mode 100644 index 000000000..e8cac1369 --- /dev/null +++ b/ruoyi-extend/ruoyi-monitor-admin/src/main/resources/application-prod.yml @@ -0,0 +1,14 @@ +--- # 监控配置 +spring: + boot: + admin: + # Spring Boot Admin Client 客户端的相关配置 + client: + # 增加客户端开关 + enabled: true + # 设置 Spring Boot Admin Server 地址 + url: http://172.30.0.90:9090/admin + instance: + prefer-ip: true # 注册实例时,优先使用 IP + username: ruoyi + password: 123456 diff --git a/ruoyi-extend/ruoyi-monitor-admin/src/main/resources/application.yml b/ruoyi-extend/ruoyi-monitor-admin/src/main/resources/application.yml index 631f3e772..bf0db5620 100644 --- a/ruoyi-extend/ruoyi-monitor-admin/src/main/resources/application.yml +++ b/ruoyi-extend/ruoyi-monitor-admin/src/main/resources/application.yml @@ -1,6 +1,12 @@ server: port: 9090 +spring: + application: + name: ruoyi-monitor-admin + profiles: + active: @profiles.active@ +--- # 监控中心服务端配置 spring: security: user: @@ -9,3 +15,17 @@ spring: boot: admin: context-path: /admin + +--- # Actuator 监控端点的配置项 +management: + endpoints: + web: + # Actuator 提供的 API 接口的根目录。默认为 /actuator + base-path: /actuator + exposure: + # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。 + # 生产环境不建议放开所有 根据项目需求放开即可 + include: @endpoints.include@ + endpoint: + logfile: + external-file: ./logs/ruoyi-monitor-admin.log diff --git a/ruoyi-extend/ruoyi-xxl-job-admin/pom.xml b/ruoyi-extend/ruoyi-xxl-job-admin/pom.xml index a2b198fc9..26892d424 100644 --- a/ruoyi-extend/ruoyi-xxl-job-admin/pom.xml +++ b/ruoyi-extend/ruoyi-xxl-job-admin/pom.xml @@ -71,6 +71,11 @@ ${mysql-connector-java.version} + + de.codecentric + spring-boot-admin-starter-client + + com.xuxueli diff --git a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/resources/application-dev.yml b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/resources/application-dev.yml index 065b34262..540a3237a 100644 --- a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/resources/application-dev.yml +++ b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/resources/application-dev.yml @@ -1,3 +1,18 @@ +--- # 监控配置 +spring: + boot: + admin: + # Spring Boot Admin Client 客户端的相关配置 + client: + # 增加客户端开关 + enabled: true + # 设置 Spring Boot Admin Server 地址 + url: http://localhost:9090/admin + instance: + prefer-ip: true # 注册实例时,优先使用 IP + username: ruoyi + password: 123456 + --- # 数据库配置 spring: datasource: diff --git a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/resources/application-prod.yml b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/resources/application-prod.yml index 2994909ac..bcec9d82e 100644 --- a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/resources/application-prod.yml +++ b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/resources/application-prod.yml @@ -1,3 +1,18 @@ +--- # 监控配置 +spring: + boot: + admin: + # Spring Boot Admin Client 客户端的相关配置 + client: + # 增加客户端开关 + enabled: true + # 设置 Spring Boot Admin Server 地址 + url: http://172.30.0.90:9090/admin + instance: + prefer-ip: true # 注册实例时,优先使用 IP + username: ruoyi + password: 123456 + --- # 数据库配置 spring: datasource: diff --git a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/resources/application.yml b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/resources/application.yml index edafdb01b..202272087 100644 --- a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/resources/application.yml +++ b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/resources/application.yml @@ -4,6 +4,8 @@ server: servlet: context-path: /xxl-job-admin spring: + application: + name: ruoyi-xxl-job-admin profiles: active: @profiles.active@ mvc: @@ -28,13 +30,22 @@ spring: suffix: .ftl templateLoaderPath: classpath:/templates/ ---- # 监控配置 +--- # Actuator 监控端点的配置项 management: health: mail: enabled: false - server: - base-path: /actuator + endpoints: + web: + # Actuator 提供的 API 接口的根目录。默认为 /actuator + base-path: /actuator + exposure: + # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。 + # 生产环境不建议放开所有 根据项目需求放开即可 + include: @endpoints.include@ + endpoint: + logfile: + external-file: ./logs/ruoyi-xxl-job-admin.log --- # xxljob系统配置 xxl: 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 393b2e650..dcf805877 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 @@ -7,6 +7,7 @@ import com.ruoyi.common.core.domain.entity.SysUser; 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 org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RepeatSubmitAspect.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RepeatSubmitAspect.java index bb8b0f19c..fd02a9be4 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RepeatSubmitAspect.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RepeatSubmitAspect.java @@ -1,13 +1,12 @@ package com.ruoyi.framework.aspectj; import cn.dev33.satoken.SaManager; -import cn.hutool.core.util.StrUtil; import cn.hutool.crypto.SecureUtil; -import com.baomidou.lock.LockInfo; -import com.baomidou.lock.LockTemplate; import com.ruoyi.common.annotation.RepeatSubmit; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.JsonUtils; +import com.ruoyi.common.utils.RedisUtils; import com.ruoyi.common.utils.ServletUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.framework.config.properties.RepeatSubmitProperties; @@ -18,8 +17,14 @@ import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import org.springframework.validation.BindingResult; +import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Collection; +import java.util.Map; +import java.util.concurrent.TimeUnit; /** * 防止重复提交 @@ -33,7 +38,6 @@ import javax.servlet.http.HttpServletRequest; public class RepeatSubmitAspect { private final RepeatSubmitProperties repeatSubmitProperties; - private final LockTemplate lockTemplate; @Before("@annotation(repeatSubmit)") public void doBefore(JoinPoint point, RepeatSubmit repeatSubmit) throws Throwable { @@ -46,7 +50,7 @@ public class RepeatSubmitAspect { throw new ServiceException("重复提交间隔时间不能小于'1'秒"); } HttpServletRequest request = ServletUtils.getRequest(); - String nowParams = StrUtil.join(",", point.getArgs()); + String nowParams = argsArrayToString(point.getArgs()); // 请求地址(作为存放cache的key值) String url = request.getRequestURI(); @@ -59,10 +63,58 @@ public class RepeatSubmitAspect { submitKey = SecureUtil.md5(submitKey + ":" + nowParams); // 唯一标识(指定key + 消息头) String cacheRepeatKey = Constants.REPEAT_SUBMIT_KEY + submitKey; - LockInfo lock = lockTemplate.lock(cacheRepeatKey, interval, interval / 2); - if (lock == null) { + String key = RedisUtils.getCacheObject(cacheRepeatKey); + if (key == null) { + RedisUtils.setCacheObject(cacheRepeatKey, "", interval, TimeUnit.MILLISECONDS); + } else { throw new ServiceException(repeatSubmit.message()); } } + /** + * 参数拼装 + */ + private String argsArrayToString(Object[] paramsArray) { + StringBuilder params = new StringBuilder(); + if (paramsArray != null && paramsArray.length > 0) { + for (Object o : paramsArray) { + if (StringUtils.isNotNull(o) && !isFilterObject(o)) { + try { + params.append(JsonUtils.toJsonString(o)).append(" "); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + return params.toString().trim(); + } + + /** + * 判断是否需要过滤的对象。 + * + * @param o 对象信息。 + * @return 如果是需要过滤的对象,则返回true;否则返回false。 + */ + @SuppressWarnings("rawtypes") + public boolean isFilterObject(final Object o) { + Class clazz = o.getClass(); + if (clazz.isArray()) { + return clazz.getComponentType().isAssignableFrom(MultipartFile.class); + } else if (Collection.class.isAssignableFrom(clazz)) { + Collection collection = (Collection) o; + for (Object value : collection) { + return value instanceof MultipartFile; + } + } else if (Map.class.isAssignableFrom(clazz)) { + Map map = (Map) o; + for (Object value : map.entrySet()) { + Map.Entry entry = (Map.Entry) value; + return entry.getValue() instanceof MultipartFile; + } + } + return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse + || o instanceof BindingResult; + } + } diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FeignConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FeignConfig.java deleted file mode 100644 index 8b432ad89..000000000 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FeignConfig.java +++ /dev/null @@ -1,95 +0,0 @@ -package com.ruoyi.framework.config; - -import feign.*; -import okhttp3.ConnectionPool; -import okhttp3.OkHttpClient; -import org.springframework.boot.autoconfigure.AutoConfigureBefore; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.cloud.openfeign.EnableFeignClients; -import org.springframework.cloud.openfeign.FeignAutoConfiguration; -import org.springframework.cloud.openfeign.support.SpringMvcContract; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import java.util.concurrent.TimeUnit; - -/** - * openfeign配置类 - * - * @author Lion Li - * @deprecated 由于使用人数较少 决定与 3.4.0 版本移除 - */ -@Deprecated -@EnableFeignClients("${feign.package}") -@Configuration -@ConditionalOnClass(Feign.class) -@AutoConfigureBefore(FeignAutoConfiguration.class) -public class FeignConfig { - - @Bean - public OkHttpClient okHttpClient(){ - return new OkHttpClient.Builder() - .readTimeout(60, TimeUnit.SECONDS) - .connectTimeout(60, TimeUnit.SECONDS) - .writeTimeout(120, TimeUnit.SECONDS) - .connectionPool(new ConnectionPool()) - .build(); - } - - @Bean - public Contract feignContract() { - return new SpringMvcContract(); - } - - @Bean - public Logger.Level feignLoggerLevel() { - return Logger.Level.BASIC; - } - - @Bean - public Request.Options feignRequestOptions() { - return new Request.Options(10, TimeUnit.SECONDS, 60,TimeUnit.SECONDS,true); - } - - @Bean - public Retryer feignRetry() { - return new Retryer.Default(); - } - -// /** -// * 自定义异常解码器 -// * 用于自定义返回体异常熔断 -// */ -// @Bean -// public ErrorDecoder errorDecoder() { -// return new CustomErrorDecoder(); -// } -// -// -// /** -// * 自定义返回体解码器 -// */ -// @Slf4j -// public static class CustomErrorDecoder implements ErrorDecoder { -// -// @Override -// public Exception decode(String methodKey, Response response) { -// Exception exception = null; -// try { -// // 获取原始的返回内容 -// String json = JsonUtils.toJsonString(response.body().asReader(StandardCharsets.UTF_8)); -// exception = new RuntimeException(json); -// // 将返回内容反序列化为Result,这里应根据自身项目作修改 -// AjaxResult result = JsonUtils.parseObject(json, AjaxResult.class); -// // 业务异常抛出简单的 RuntimeException,保留原来错误信息 -// if (result.getCode() != 200) { -// exception = new RuntimeException(result.getMsg()); -// } -// } catch (IOException e) { -// log.error(e.getMessage(), e); -// } -// return exception; -// } -// } - -} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FilterConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FilterConfig.java index 459020d87..6f3b099ab 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FilterConfig.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FilterConfig.java @@ -20,7 +20,6 @@ import java.util.Map; * @author Lion Li */ @Configuration -@ConditionalOnProperty(value = "xss.enabled", havingValue = "true") public class FilterConfig { @Autowired @@ -28,6 +27,7 @@ public class FilterConfig { @SuppressWarnings({"rawtypes", "unchecked"}) @Bean + @ConditionalOnProperty(value = "xss.enabled", havingValue = "true") public FilterRegistrationBean xssFilterRegistration() { FilterRegistrationBean registration = new FilterRegistrationBean(); registration.setDispatcherTypes(DispatcherType.REQUEST); diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/I18nConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/I18nConfig.java index 48b341beb..20b52a8e2 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/I18nConfig.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/I18nConfig.java @@ -1,7 +1,6 @@ package com.ruoyi.framework.config; import cn.hutool.core.util.StrUtil; -import org.jetbrains.annotations.NotNull; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.LocaleResolver; @@ -28,7 +27,6 @@ public class I18nConfig { */ static class I18nLocaleResolver implements LocaleResolver { - @NotNull @Override public Locale resolveLocale(HttpServletRequest httpServletRequest) { String language = httpServletRequest.getHeader("content-language"); @@ -41,7 +39,7 @@ public class I18nConfig { } @Override - public void setLocale(@NotNull HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) { + public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) { } } diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java index 937be3543..4a956a2e9 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java @@ -2,6 +2,7 @@ package com.ruoyi.framework.config; import cn.dev33.satoken.config.SaTokenConfig; import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j; +import com.github.xiaoymin.knife4j.spring.extension.OpenApiExtensionResolver; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.spring.SpringUtils; import com.ruoyi.framework.config.properties.SwaggerProperties; @@ -34,6 +35,9 @@ public class SwaggerConfig { @Autowired private SaTokenConfig saTokenConfig; + @Autowired + private OpenApiExtensionResolver openApiExtensionResolver; + /** * 创建API */ @@ -58,6 +62,7 @@ public class SwaggerConfig { // 设置安全模式,swagger可以设置访问token .securitySchemes(securitySchemes()) .securityContexts(securityContexts()) + .extensions(openApiExtensionResolver.buildExtensions(group.getName())) .pathMapping(swaggerProperties.getPathMapping()); String beanName = StringUtils.substringAfterLast(basePackage, ".") + "Docket"; SpringUtils.registerBean(beanName, docket); 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 index 68bc425d6..c1665d9b0 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/TLogConfig.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/TLogConfig.java @@ -1,7 +1,6 @@ package com.ruoyi.framework.config; import com.yomahub.tlog.core.aop.AspectLogAop; -import com.yomahub.tlog.feign.filter.TLogFeignFilter; import com.yomahub.tlog.spring.TLogPropertyInit; import com.yomahub.tlog.spring.TLogSpringAware; import com.yomahub.tlog.springboot.property.TLogProperty; @@ -41,9 +40,4 @@ public class TLogConfig { return new AspectLogAop(); } - @Bean - public TLogFeignFilter tLogFeignFilter() { - return new TLogFeignFilter(); - } - } diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ValidatorConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ValidatorConfig.java index 258e855cd..0a2007c81 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ValidatorConfig.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ValidatorConfig.java @@ -1,12 +1,14 @@ package com.ruoyi.framework.config; import org.hibernate.validator.HibernateValidator; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.MessageSource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; -import javax.validation.Validation; import javax.validation.Validator; -import javax.validation.ValidatorFactory; +import java.util.Properties; /** * 校验框架配置类 @@ -16,16 +18,26 @@ import javax.validation.ValidatorFactory; @Configuration public class ValidatorConfig { + @Autowired + private MessageSource messageSource; + /** * 配置校验框架 快速返回模式 */ @Bean public Validator validator() { - ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class) - .configure() - .failFast(true) - .buildValidatorFactory(); - return validatorFactory.getValidator(); + LocalValidatorFactoryBean factoryBean = new LocalValidatorFactoryBean(); + // 国际化 + factoryBean.setValidationMessageSource(messageSource); + // 设置使用 HibernateValidator 校验器 + factoryBean.setProviderClass(HibernateValidator.class); + Properties properties = new Properties(); + // 设置 快速异常返回 + properties.setProperty("hibernate.validator.fail_fast", "true"); + factoryBean.setValidationProperties(properties); + // 加载配置 + factoryBean.afterPropertiesSet(); + return factoryBean.getValidator(); } } diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/manager/ShutdownManager.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/manager/ShutdownManager.java index 4ed536690..ef77a219a 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/manager/ShutdownManager.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/manager/ShutdownManager.java @@ -14,7 +14,7 @@ import java.util.concurrent.ScheduledExecutorService; * * @author Lion Li */ -@Slf4j(topic = "sys-user") +@Slf4j @Component public class ShutdownManager { 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 d0f00c6da..2be7afa6b 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 @@ -16,7 +16,9 @@ import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; import javax.servlet.http.HttpServletRequest; +import javax.validation.ConstraintViolation; import javax.validation.ConstraintViolationException; +import java.util.stream.Collectors; /** * 全局异常处理器 @@ -104,7 +106,9 @@ public class GlobalExceptionHandler { @ExceptionHandler(BindException.class) public AjaxResult handleBindException(BindException e) { log.error(e.getMessage(), e); - String message = e.getAllErrors().get(0).getDefaultMessage(); + String message = e.getAllErrors().stream() + .map(DefaultMessageSourceResolvable::getDefaultMessage) + .collect(Collectors.joining(", ")); return AjaxResult.error(message); } @@ -114,7 +118,9 @@ public class GlobalExceptionHandler { @ExceptionHandler(ConstraintViolationException.class) public AjaxResult constraintViolationException(ConstraintViolationException e) { log.error(e.getMessage(), e); - String message = e.getConstraintViolations().iterator().next().getMessage(); + String message = e.getConstraintViolations().stream() + .map(ConstraintViolation::getMessage) + .collect(Collectors.joining(", ")); return AjaxResult.error(message); } diff --git a/ruoyi-generator/pom.xml b/ruoyi-generator/pom.xml index 668489f6e..045ecbaf8 100644 --- a/ruoyi-generator/pom.xml +++ b/ruoyi-generator/pom.xml @@ -20,7 +20,7 @@ org.apache.velocity - velocity + velocity-engine-core diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/controller/GenController.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/controller/GenController.java index 55c93d8d4..af85c847e 100644 --- a/ruoyi-generator/src/main/java/com/ruoyi/generator/controller/GenController.java +++ b/ruoyi-generator/src/main/java/com/ruoyi/generator/controller/GenController.java @@ -2,6 +2,7 @@ package com.ruoyi.generator.controller; import cn.dev33.satoken.annotation.SaCheckPermission; import cn.hutool.core.convert.Convert; +import cn.hutool.core.io.IoUtil; import com.ruoyi.common.annotation.Log; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; @@ -14,7 +15,6 @@ import com.ruoyi.generator.service.IGenTableService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; -import org.apache.commons.io.IOUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -201,6 +201,6 @@ public class GenController extends BaseController { response.setHeader("Content-Disposition", "attachment; filename=\"ruoyi.zip\""); response.addHeader("Content-Length", "" + data.length); response.setContentType("application/octet-stream; charset=UTF-8"); - IOUtils.write(data, response.getOutputStream()); + IoUtil.write(response.getOutputStream(), false, data); } } 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 62fe67a3a..b53393f0c 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,6 +2,7 @@ package com.ruoyi.generator.service; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.convert.Convert; +import cn.hutool.core.io.IoUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.constant.GenConstants; @@ -21,7 +22,7 @@ import com.ruoyi.generator.util.GenUtils; import com.ruoyi.generator.util.VelocityInitializer; import com.ruoyi.generator.util.VelocityUtils; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.io.IOUtils; +import org.apache.poi.util.IOUtils; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.Velocity; @@ -33,6 +34,7 @@ import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.StringWriter; +import java.nio.charset.StandardCharsets; import java.util.*; import java.util.stream.Collectors; import java.util.zip.ZipEntry; @@ -341,8 +343,8 @@ public class GenTableServiceImpl extends ServicePlusImpl dicts = new ArrayList(); for (GenTableColumn column : columns) { if (!column.isSuperColumn() && StringUtils.isNotEmpty(column.getDictType()) && StringUtils.equalsAny( - column.getHtmlType(), new String[]{GenConstants.HTML_SELECT, GenConstants.HTML_RADIO})) { + column.getHtmlType(), + new String[] { GenConstants.HTML_SELECT, GenConstants.HTML_RADIO, GenConstants.HTML_CHECKBOX })) { dicts.add("'" + column.getDictType() + "'"); } } diff --git a/ruoyi-generator/src/main/resources/mapper/package-info.md b/ruoyi-generator/src/main/resources/mapper/package-info.md new file mode 100644 index 000000000..c938b1e50 --- /dev/null +++ b/ruoyi-generator/src/main/resources/mapper/package-info.md @@ -0,0 +1,3 @@ +java包使用 `.` 分割 resource 目录使用 `/` 分割 +
+此文件目的 防止文件夹粘连找不到 `xml` 文件 \ No newline at end of file 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 13e22818f..d35642e15 100644 --- a/ruoyi-generator/src/main/resources/vm/java/controller.java.vm +++ b/ruoyi-generator/src/main/resources/vm/java/controller.java.vm @@ -28,6 +28,7 @@ import com.ruoyi.common.core.page.TableDataInfo; #elseif($table.tree) #end import io.swagger.annotations.Api; +import io.swagger.annotations.ApiParam; import io.swagger.annotations.ApiOperation; /** @@ -80,7 +81,8 @@ public class ${ClassName}Controller extends BaseController { @ApiOperation("获取${functionName}详细信息") @SaCheckPermission("${permissionPrefix}:query") @GetMapping("/{${pkColumn.javaField}}") - public AjaxResult<${ClassName}Vo> getInfo(@NotNull(message = "主键不能为空") + public AjaxResult<${ClassName}Vo> getInfo(@ApiParam("主键") + @NotNull(message = "主键不能为空") @PathVariable("${pkColumn.javaField}") ${pkColumn.javaType} ${pkColumn.javaField}) { return AjaxResult.success(i${ClassName}Service.queryById(${pkColumn.javaField})); } @@ -116,7 +118,8 @@ public class ${ClassName}Controller extends BaseController { @SaCheckPermission("${permissionPrefix}:remove") @Log(title = "${functionName}" , businessType = BusinessType.DELETE) @DeleteMapping("/{${pkColumn.javaField}s}") - public AjaxResult remove(@NotEmpty(message = "主键不能为空") + public AjaxResult remove(@ApiParam("主键串") + @NotEmpty(message = "主键不能为空") @PathVariable ${pkColumn.javaType}[] ${pkColumn.javaField}s) { return toAjax(i${ClassName}Service.deleteWithValidByIds(Arrays.asList(${pkColumn.javaField}s), true) ? 1 : 0); } diff --git a/ruoyi-generator/src/main/resources/vm/vue/index-tree.vue.vm b/ruoyi-generator/src/main/resources/vm/vue/index-tree.vue.vm index 24494adf3..7c530cb13 100644 --- a/ruoyi-generator/src/main/resources/vm/vue/index-tree.vue.vm +++ b/ruoyi-generator/src/main/resources/vm/vue/index-tree.vue.vm @@ -108,7 +108,11 @@ #elseif($column.list && $column.dictType && "" != $column.dictType) #elseif($column.list && "" != $javaField) @@ -296,8 +300,7 @@ export default { queryParams: { #foreach ($column in $columns) #if($column.query) - $column.javaField: null#if($velocityCount != $columns.size()),#end - + $column.javaField: null#if($foreach.count != $columns.size()),#end #end #end }, @@ -315,8 +318,7 @@ export default { #end $column.javaField: [ { required: true, message: "$comment不能为空", trigger: #if($column.htmlType == "select")"change"#else"blur"#end } - ]#if($velocityCount != $columns.size()),#end - + ]#if($foreach.count != $columns.size()),#end #end #end } @@ -379,14 +381,12 @@ export default { this.form = { #foreach ($column in $columns) #if($column.htmlType == "radio") - $column.javaField: #if($column.javaType == "Integer" || $column.javaType == "Long")0#else"0"#end#if($velocityCount != $columns.size()),#end + $column.javaField: #if($column.javaType == "Integer" || $column.javaType == "Long")0#else"0"#end#if($foreach.count != $columns.size()),#end #elseif($column.htmlType == "checkbox") - $column.javaField: []#if($velocityCount != $columns.size()),#end - + $column.javaField: []#if($foreach.count != $columns.size()),#end #else - $column.javaField: null#if($velocityCount != $columns.size()),#end - + $column.javaField: null#if($foreach.count != $columns.size()),#end #end #end }; diff --git a/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm b/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm index 7e28c2e9e..c0a5bf716 100644 --- a/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm +++ b/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm @@ -108,7 +108,6 @@ plain icon="el-icon-download" size="mini" - :loading="exportLoading" @click="handleExport" v-hasPermi="['${moduleName}:${businessName}:export']" >导出 @@ -137,7 +136,11 @@ #elseif($column.list && $column.dictType && "" != $column.dictType) #elseif($column.list && "" != $javaField) @@ -324,8 +327,6 @@ export default { buttonLoading: false, // 遮罩层 loading: true, - // 导出遮罩层 - exportLoading: false, // 选中数组 ids: [], #if($table.sub) @@ -363,8 +364,7 @@ export default { pageSize: 10, #foreach ($column in $columns) #if($column.query) - $column.javaField: undefined#if($velocityCount != $columns.size()),#end - + $column.javaField: undefined#if($foreach.count != $columns.size()),#end #end #end }, @@ -382,8 +382,7 @@ export default { #end $column.javaField: [ { required: true, message: "$comment不能为空", trigger: #if($column.htmlType == "select")"change"#else"blur"#end } - ]#if($velocityCount != $columns.size()),#end - + ]#if($foreach.count != $columns.size()),#end #end #end } @@ -427,14 +426,11 @@ export default { this.form = { #foreach ($column in $columns) #if($column.htmlType == "radio") - $column.javaField: #if($column.javaType == "Integer" || $column.javaType == "Long")0#else"0"#end#if($velocityCount != $columns.size()),#end - + $column.javaField: #if($column.javaType == "Integer" || $column.javaType == "Long")0#else"0"#end#if($foreach.count != $columns.size()),#end #elseif($column.htmlType == "checkbox") - $column.javaField: []#if($velocityCount != $columns.size()),#end - + $column.javaField: []#if($foreach.count != $columns.size()),#end #else - $column.javaField: undefined#if($velocityCount != $columns.size()),#end - + $column.javaField: undefined#if($foreach.count != $columns.size()),#end #end #end }; @@ -573,7 +569,9 @@ export default { #end /** 导出按钮操作 */ handleExport() { - this.#[[$download]]#.excel('/${moduleName}/${businessName}/export', this.queryParams); + this.download('${moduleName}/${businessName}/export', { + ...this.queryParams + }, `${businessName}_#[[${new Date().getTime()}]]#.xlsx`) } } }; diff --git a/ruoyi-oss/src/main/java/com/ruoyi/oss/constant/CloudConstant.java b/ruoyi-oss/src/main/java/com/ruoyi/oss/constant/OssConstant.java similarity index 73% rename from ruoyi-oss/src/main/java/com/ruoyi/oss/constant/CloudConstant.java rename to ruoyi-oss/src/main/java/com/ruoyi/oss/constant/OssConstant.java index 7bba1f4db..b5236bfe7 100644 --- a/ruoyi-oss/src/main/java/com/ruoyi/oss/constant/CloudConstant.java +++ b/ruoyi-oss/src/main/java/com/ruoyi/oss/constant/OssConstant.java @@ -8,7 +8,7 @@ import java.util.List; * * @author Lion Li */ -public class CloudConstant { +public class OssConstant { /** * OSS模块KEY @@ -18,12 +18,12 @@ public class CloudConstant { /** * 对象存储配置KEY */ - public static final String CLOUD_STORAGE_CONFIG_KEY = "CloudStorageConfig"; + public static final String OSS_CONFIG_KEY = "OssConfig"; /** * 缓存配置KEY */ - public static final String CACHE_CONFIG_KEY = SYS_OSS_KEY + CLOUD_STORAGE_CONFIG_KEY; + public static final String CACHE_CONFIG_KEY = SYS_OSS_KEY + OSS_CONFIG_KEY; /** * 预览列表资源开关Key diff --git a/ruoyi-oss/src/main/java/com/ruoyi/oss/enumd/CloudServiceEnumd.java b/ruoyi-oss/src/main/java/com/ruoyi/oss/enumd/OssEnumd.java similarity index 56% rename from ruoyi-oss/src/main/java/com/ruoyi/oss/enumd/CloudServiceEnumd.java rename to ruoyi-oss/src/main/java/com/ruoyi/oss/enumd/OssEnumd.java index ac8ad8184..4defca40e 100644 --- a/ruoyi-oss/src/main/java/com/ruoyi/oss/enumd/CloudServiceEnumd.java +++ b/ruoyi-oss/src/main/java/com/ruoyi/oss/enumd/OssEnumd.java @@ -1,10 +1,10 @@ package com.ruoyi.oss.enumd; import com.ruoyi.common.utils.StringUtils; -import com.ruoyi.oss.service.impl.AliyunCloudStorageStrategy; -import com.ruoyi.oss.service.impl.MinioCloudStorageStrategy; -import com.ruoyi.oss.service.impl.QcloudCloudStorageStrategy; -import com.ruoyi.oss.service.impl.QiniuCloudStorageStrategy; +import com.ruoyi.oss.service.impl.AliyunOssStrategy; +import com.ruoyi.oss.service.impl.MinioOssStrategy; +import com.ruoyi.oss.service.impl.QcloudOssStrategy; +import com.ruoyi.oss.service.impl.QiniuOssStrategy; import lombok.AllArgsConstructor; import lombok.Getter; @@ -15,34 +15,34 @@ import lombok.Getter; */ @Getter @AllArgsConstructor -public enum CloudServiceEnumd { +public enum OssEnumd { /** * 七牛云 */ - QINIU("qiniu", QiniuCloudStorageStrategy.class), + QINIU("qiniu", QiniuOssStrategy.class), /** * 阿里云 */ - ALIYUN("aliyun", AliyunCloudStorageStrategy.class), + ALIYUN("aliyun", AliyunOssStrategy.class), /** * 腾讯云 */ - QCLOUD("qcloud", QcloudCloudStorageStrategy.class), + QCLOUD("qcloud", QcloudOssStrategy.class), /** * minio */ - MINIO("minio", MinioCloudStorageStrategy.class); + MINIO("minio", MinioOssStrategy.class); private final String value; private final Class serviceClass; public static Class getServiceClass(String value) { - for (CloudServiceEnumd clazz : values()) { + for (OssEnumd clazz : values()) { if (clazz.getValue().equals(value)) { return clazz.getServiceClass(); } @@ -51,7 +51,7 @@ public enum CloudServiceEnumd { } public static String getServiceName(String value) { - for (CloudServiceEnumd clazz : values()) { + for (OssEnumd clazz : values()) { if (clazz.getValue().equals(value)) { return StringUtils.uncapitalize(clazz.getServiceClass().getSimpleName()); } diff --git a/ruoyi-oss/src/main/java/com/ruoyi/oss/factory/OssFactory.java b/ruoyi-oss/src/main/java/com/ruoyi/oss/factory/OssFactory.java index ecb269dd7..169159602 100644 --- a/ruoyi-oss/src/main/java/com/ruoyi/oss/factory/OssFactory.java +++ b/ruoyi-oss/src/main/java/com/ruoyi/oss/factory/OssFactory.java @@ -1,16 +1,15 @@ package com.ruoyi.oss.factory; -import cn.hutool.core.convert.Convert; import com.ruoyi.common.utils.JsonUtils; import com.ruoyi.common.utils.RedisUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.reflect.ReflectUtils; -import com.ruoyi.oss.constant.CloudConstant; -import com.ruoyi.oss.enumd.CloudServiceEnumd; +import com.ruoyi.oss.constant.OssConstant; +import com.ruoyi.oss.enumd.OssEnumd; import com.ruoyi.oss.exception.OssException; -import com.ruoyi.oss.properties.CloudStorageProperties; -import com.ruoyi.oss.service.ICloudStorageStrategy; -import com.ruoyi.oss.service.abstractd.AbstractCloudStorageStrategy; +import com.ruoyi.oss.properties.OssProperties; +import com.ruoyi.oss.service.IOssStrategy; +import com.ruoyi.oss.service.abstractd.AbstractOssStrategy; import lombok.extern.slf4j.Slf4j; import java.util.Map; @@ -24,24 +23,31 @@ import java.util.concurrent.ConcurrentHashMap; @Slf4j public class OssFactory { - static { - RedisUtils.subscribe(CloudConstant.CACHE_CONFIG_KEY, String.class, msg -> { - refreshService(msg); - log.info("订阅刷新OSS配置 => " + msg); - }); - } - /** * 服务实例缓存 */ - private static final Map SERVICES = new ConcurrentHashMap<>(); + private static final Map SERVICES = new ConcurrentHashMap<>(); + + /** + * 初始化工厂 + */ + public static void init() { + log.info("初始化OSS工厂"); + RedisUtils.subscribe(OssConstant.CACHE_CONFIG_KEY, String.class, type -> { + // 没有的实例不处理 + if (SERVICES.containsKey(type)) { + refreshService(type); + log.info("订阅刷新OSS配置 => " + type); + } + }); + } /** * 获取默认实例 */ - public static ICloudStorageStrategy instance() { + public static IOssStrategy instance() { // 获取redis 默认类型 - String type = Convert.toStr(RedisUtils.getCacheObject(CloudConstant.CACHE_CONFIG_KEY)); + String type = RedisUtils.getCacheObject(OssConstant.CACHE_CONFIG_KEY); if (StringUtils.isEmpty(type)) { throw new OssException("文件存储服务类型无法找到!"); } @@ -51,8 +57,8 @@ public class OssFactory { /** * 根据类型获取实例 */ - public static ICloudStorageStrategy instance(String type) { - ICloudStorageStrategy service = SERVICES.get(type); + public static IOssStrategy instance(String type) { + IOssStrategy service = SERVICES.get(type); if (service == null) { refreshService(type); service = SERVICES.get(type); @@ -61,14 +67,14 @@ public class OssFactory { } private static void refreshService(String type) { - Object json = RedisUtils.getCacheObject(CloudConstant.SYS_OSS_KEY + type); - CloudStorageProperties properties = JsonUtils.parseObject(json.toString(), CloudStorageProperties.class); + Object json = RedisUtils.getCacheObject(OssConstant.SYS_OSS_KEY + type); + OssProperties properties = JsonUtils.parseObject(json.toString(), OssProperties.class); if (properties == null) { throw new OssException("系统异常, '" + type + "'配置信息不存在!"); } // 获取redis配置信息 创建对象 并缓存 - ICloudStorageStrategy service = (ICloudStorageStrategy) ReflectUtils.newInstance(CloudServiceEnumd.getServiceClass(type)); - ((AbstractCloudStorageStrategy)service).init(properties); + IOssStrategy service = (IOssStrategy) ReflectUtils.newInstance(OssEnumd.getServiceClass(type)); + ((AbstractOssStrategy)service).init(properties); SERVICES.put(type, service); } diff --git a/ruoyi-oss/src/main/java/com/ruoyi/oss/properties/CloudStorageProperties.java b/ruoyi-oss/src/main/java/com/ruoyi/oss/properties/OssProperties.java similarity index 81% rename from ruoyi-oss/src/main/java/com/ruoyi/oss/properties/CloudStorageProperties.java rename to ruoyi-oss/src/main/java/com/ruoyi/oss/properties/OssProperties.java index 9d3f15afb..48a478b7a 100644 --- a/ruoyi-oss/src/main/java/com/ruoyi/oss/properties/CloudStorageProperties.java +++ b/ruoyi-oss/src/main/java/com/ruoyi/oss/properties/OssProperties.java @@ -2,15 +2,13 @@ package com.ruoyi.oss.properties; import lombok.Data; -import java.util.Date; - /** * OSS对象存储 配置属性 * * @author Lion Li */ @Data -public class CloudStorageProperties { +public class OssProperties { /** * 域名 @@ -47,9 +45,4 @@ public class CloudStorageProperties { */ private String isHttps; - /** - * 更新时间 - */ - private Date updateTime; - } diff --git a/ruoyi-oss/src/main/java/com/ruoyi/oss/service/ICloudStorageStrategy.java b/ruoyi-oss/src/main/java/com/ruoyi/oss/service/IOssStrategy.java similarity index 84% rename from ruoyi-oss/src/main/java/com/ruoyi/oss/service/ICloudStorageStrategy.java rename to ruoyi-oss/src/main/java/com/ruoyi/oss/service/IOssStrategy.java index 96ea53992..34d25e477 100644 --- a/ruoyi-oss/src/main/java/com/ruoyi/oss/service/ICloudStorageStrategy.java +++ b/ruoyi-oss/src/main/java/com/ruoyi/oss/service/IOssStrategy.java @@ -9,7 +9,7 @@ import java.io.InputStream; * * @author Lion Li */ -public interface ICloudStorageStrategy { +public interface IOssStrategy { void createBucket(); @@ -18,15 +18,6 @@ public interface ICloudStorageStrategy { */ String getServiceType(); - /** - * 文件路径 - * - * @param prefix 前缀 - * @param suffix 后缀 - * @return 返回上传路径 - */ - String getPath(String prefix, String suffix); - /** * 文件上传 * @@ -70,5 +61,4 @@ public interface ICloudStorageStrategy { */ UploadResult uploadSuffix(InputStream inputStream, String suffix, String contentType); - String getEndpointLink(); } diff --git a/ruoyi-oss/src/main/java/com/ruoyi/oss/service/abstractd/AbstractCloudStorageStrategy.java b/ruoyi-oss/src/main/java/com/ruoyi/oss/service/abstractd/AbstractOssStrategy.java similarity index 80% rename from ruoyi-oss/src/main/java/com/ruoyi/oss/service/abstractd/AbstractCloudStorageStrategy.java rename to ruoyi-oss/src/main/java/com/ruoyi/oss/service/abstractd/AbstractOssStrategy.java index 8f5e9625d..9fa52acb4 100644 --- a/ruoyi-oss/src/main/java/com/ruoyi/oss/service/abstractd/AbstractCloudStorageStrategy.java +++ b/ruoyi-oss/src/main/java/com/ruoyi/oss/service/abstractd/AbstractOssStrategy.java @@ -5,8 +5,8 @@ import cn.hutool.core.util.IdUtil; import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.oss.entity.UploadResult; -import com.ruoyi.oss.properties.CloudStorageProperties; -import com.ruoyi.oss.service.ICloudStorageStrategy; +import com.ruoyi.oss.properties.OssProperties; +import com.ruoyi.oss.service.IOssStrategy; import java.io.InputStream; @@ -15,11 +15,11 @@ import java.io.InputStream; * * @author Lion Li */ -public abstract class AbstractCloudStorageStrategy implements ICloudStorageStrategy { +public abstract class AbstractOssStrategy implements IOssStrategy { - protected CloudStorageProperties properties; + protected OssProperties properties; - public abstract void init(CloudStorageProperties properties); + public abstract void init(OssProperties properties); @Override public abstract void createBucket(); @@ -27,7 +27,6 @@ public abstract class AbstractCloudStorageStrategy implements ICloudStorageStrat @Override public abstract String getServiceType(); - @Override public String getPath(String prefix, String suffix) { // 生成uuid String uuid = IdUtil.fastSimpleUUID(); @@ -57,6 +56,5 @@ public abstract class AbstractCloudStorageStrategy implements ICloudStorageStrat @Override public abstract UploadResult uploadSuffix(InputStream inputStream, String suffix, String contentType); - @Override public abstract String getEndpointLink(); } diff --git a/ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/AliyunCloudStorageStrategy.java b/ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/AliyunOssStrategy.java similarity index 90% rename from ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/AliyunCloudStorageStrategy.java rename to ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/AliyunOssStrategy.java index 04ee67500..db9ad910e 100644 --- a/ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/AliyunCloudStorageStrategy.java +++ b/ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/AliyunOssStrategy.java @@ -9,10 +9,10 @@ import com.aliyun.oss.model.ObjectMetadata; import com.aliyun.oss.model.PutObjectRequest; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.oss.entity.UploadResult; -import com.ruoyi.oss.enumd.CloudServiceEnumd; +import com.ruoyi.oss.enumd.OssEnumd; import com.ruoyi.oss.exception.OssException; -import com.ruoyi.oss.properties.CloudStorageProperties; -import com.ruoyi.oss.service.abstractd.AbstractCloudStorageStrategy; +import com.ruoyi.oss.properties.OssProperties; +import com.ruoyi.oss.service.abstractd.AbstractOssStrategy; import java.io.ByteArrayInputStream; import java.io.InputStream; @@ -22,12 +22,12 @@ import java.io.InputStream; * * @author Lion Li */ -public class AliyunCloudStorageStrategy extends AbstractCloudStorageStrategy { +public class AliyunOssStrategy extends AbstractOssStrategy { private OSSClient client; @Override - public void init(CloudStorageProperties cloudStorageProperties) { + public void init(OssProperties cloudStorageProperties) { properties = cloudStorageProperties; try { ClientConfiguration configuration = new ClientConfiguration(); @@ -57,7 +57,7 @@ public class AliyunCloudStorageStrategy extends AbstractCloudStorageStrategy { @Override public String getServiceType() { - return CloudServiceEnumd.ALIYUN.getValue(); + return OssEnumd.ALIYUN.getValue(); } @Override diff --git a/ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/MinioCloudStorageStrategy.java b/ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/MinioOssStrategy.java similarity index 94% rename from ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/MinioCloudStorageStrategy.java rename to ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/MinioOssStrategy.java index 3bbf187c9..0423dcc8a 100644 --- a/ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/MinioCloudStorageStrategy.java +++ b/ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/MinioOssStrategy.java @@ -2,11 +2,11 @@ package com.ruoyi.oss.service.impl; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.oss.entity.UploadResult; -import com.ruoyi.oss.enumd.CloudServiceEnumd; +import com.ruoyi.oss.enumd.OssEnumd; import com.ruoyi.oss.enumd.PolicyType; import com.ruoyi.oss.exception.OssException; -import com.ruoyi.oss.properties.CloudStorageProperties; -import com.ruoyi.oss.service.abstractd.AbstractCloudStorageStrategy; +import com.ruoyi.oss.properties.OssProperties; +import com.ruoyi.oss.service.abstractd.AbstractOssStrategy; import io.minio.*; import org.springframework.http.MediaType; @@ -18,12 +18,12 @@ import java.io.InputStream; * * @author Lion Li */ -public class MinioCloudStorageStrategy extends AbstractCloudStorageStrategy { +public class MinioOssStrategy extends AbstractOssStrategy { private MinioClient minioClient; @Override - public void init(CloudStorageProperties cloudStorageProperties) { + public void init(OssProperties cloudStorageProperties) { properties = cloudStorageProperties; try { minioClient = MinioClient.builder() @@ -57,7 +57,7 @@ public class MinioCloudStorageStrategy extends AbstractCloudStorageStrategy { @Override public String getServiceType() { - return CloudServiceEnumd.MINIO.getValue(); + return OssEnumd.MINIO.getValue(); } @Override diff --git a/ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/QcloudCloudStorageStrategy.java b/ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/QcloudOssStrategy.java similarity index 91% rename from ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/QcloudCloudStorageStrategy.java rename to ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/QcloudOssStrategy.java index 9bd366e0d..156eb24c5 100644 --- a/ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/QcloudCloudStorageStrategy.java +++ b/ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/QcloudOssStrategy.java @@ -9,10 +9,10 @@ import com.qcloud.cos.model.*; import com.qcloud.cos.region.Region; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.oss.entity.UploadResult; -import com.ruoyi.oss.enumd.CloudServiceEnumd; +import com.ruoyi.oss.enumd.OssEnumd; import com.ruoyi.oss.exception.OssException; -import com.ruoyi.oss.properties.CloudStorageProperties; -import com.ruoyi.oss.service.abstractd.AbstractCloudStorageStrategy; +import com.ruoyi.oss.properties.OssProperties; +import com.ruoyi.oss.service.abstractd.AbstractOssStrategy; import java.io.ByteArrayInputStream; import java.io.InputStream; @@ -22,12 +22,12 @@ import java.io.InputStream; * * @author Lion Li */ -public class QcloudCloudStorageStrategy extends AbstractCloudStorageStrategy { +public class QcloudOssStrategy extends AbstractOssStrategy { private COSClient client; @Override - public void init(CloudStorageProperties cloudStorageProperties) { + public void init(OssProperties cloudStorageProperties) { properties = cloudStorageProperties; try { COSCredentials credentials = new BasicCOSCredentials( @@ -65,7 +65,7 @@ public class QcloudCloudStorageStrategy extends AbstractCloudStorageStrategy { @Override public String getServiceType() { - return CloudServiceEnumd.QCLOUD.getValue(); + return OssEnumd.QCLOUD.getValue(); } @Override diff --git a/ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/QiniuCloudStorageStrategy.java b/ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/QiniuOssStrategy.java similarity index 82% rename from ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/QiniuCloudStorageStrategy.java rename to ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/QiniuOssStrategy.java index e9b8dc096..bf90aa824 100644 --- a/ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/QiniuCloudStorageStrategy.java +++ b/ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/QiniuOssStrategy.java @@ -8,10 +8,10 @@ import com.qiniu.storage.Region; import com.qiniu.storage.UploadManager; import com.qiniu.util.Auth; import com.ruoyi.oss.entity.UploadResult; -import com.ruoyi.oss.enumd.CloudServiceEnumd; +import com.ruoyi.oss.enumd.OssEnumd; import com.ruoyi.oss.exception.OssException; -import com.ruoyi.oss.properties.CloudStorageProperties; -import com.ruoyi.oss.service.abstractd.AbstractCloudStorageStrategy; +import com.ruoyi.oss.properties.OssProperties; +import com.ruoyi.oss.service.abstractd.AbstractOssStrategy; import java.io.InputStream; @@ -20,14 +20,14 @@ import java.io.InputStream; * * @author Lion Li */ -public class QiniuCloudStorageStrategy extends AbstractCloudStorageStrategy { +public class QiniuOssStrategy extends AbstractOssStrategy { private UploadManager uploadManager; private BucketManager bucketManager; - private String token; + private Auth auth; @Override - public void init(CloudStorageProperties cloudStorageProperties) { + public void init(OssProperties cloudStorageProperties) { properties = cloudStorageProperties; try { Configuration config = new Configuration(getRegion(properties.getRegion())); @@ -35,9 +35,8 @@ public class QiniuCloudStorageStrategy extends AbstractCloudStorageStrategy { config.useHttpsDomains = false; config.useHttpsDomains = "Y".equals(properties.getIsHttps()); uploadManager = new UploadManager(config); - Auth auth = Auth.create(properties.getAccessKey(), properties.getSecretKey()); + auth = Auth.create(properties.getAccessKey(), properties.getSecretKey()); String bucketName = properties.getBucketName(); - token = auth.uploadToken(bucketName); bucketManager = new BucketManager(auth, config); if (!ArrayUtil.contains(bucketManager.buckets(), bucketName)) { @@ -63,15 +62,16 @@ public class QiniuCloudStorageStrategy extends AbstractCloudStorageStrategy { @Override public String getServiceType() { - return CloudServiceEnumd.QINIU.getValue(); + return OssEnumd.QINIU.getValue(); } @Override public UploadResult upload(byte[] data, String path, String contentType) { try { - Response res = uploadManager.put(data, path, token, null, contentType, false); + String token = auth.uploadToken(properties.getBucketName()); + Response res = uploadManager.put(data, path, token, null, contentType, false); if (!res.isOK()) { - throw new RuntimeException("上传七牛出错:" + res.toString()); + throw new RuntimeException("上传七牛出错:" + res.error); } } catch (Exception e) { throw new OssException("上传文件失败,请核对七牛配置信息:[" + e.getMessage() + "]"); @@ -85,7 +85,7 @@ public class QiniuCloudStorageStrategy extends AbstractCloudStorageStrategy { path = path.replace(getEndpointLink() + "/", ""); Response res = bucketManager.delete(properties.getBucketName(), path); if (!res.isOK()) { - throw new RuntimeException("删除七牛文件出错:" + res.toString()); + throw new RuntimeException("删除七牛文件出错:" + res.error); } } catch (Exception e) { throw new OssException(e.getMessage()); diff --git a/ruoyi-quartz/pom.xml b/ruoyi-quartz/pom.xml deleted file mode 100644 index 1480b8133..000000000 --- a/ruoyi-quartz/pom.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - ruoyi-vue-plus - com.ruoyi - 3.3.0 - - 4.0.0 - - ruoyi-quartz - - - quartz定时任务 - - - - - - - org.springframework.boot - spring-boot-starter-quartz - - - com.mchange - c3p0 - - - - - - - com.ruoyi - ruoyi-common - - - - - diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/config/ScheduleConfig.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/config/ScheduleConfig.java deleted file mode 100644 index c5fa2ec0f..000000000 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/config/ScheduleConfig.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.ruoyi.quartz.config; - -import org.springframework.context.annotation.Configuration; - -/** - * 定时任务配置 - * - * @deprecated 3.4.0删除 迁移至xxl-job - * @author Lion Li - */ -@Deprecated -@Configuration -public class ScheduleConfig { - -} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobController.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobController.java deleted file mode 100644 index 7a86393b5..000000000 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobController.java +++ /dev/null @@ -1,158 +0,0 @@ -package com.ruoyi.quartz.controller; - -import cn.dev33.satoken.annotation.SaCheckPermission; -import com.ruoyi.common.annotation.Log; -import com.ruoyi.common.constant.Constants; -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.enums.BusinessType; -import com.ruoyi.common.exception.job.TaskException; -import com.ruoyi.common.utils.StringUtils; -import com.ruoyi.common.utils.poi.ExcelUtil; -import com.ruoyi.quartz.domain.SysJob; -import com.ruoyi.quartz.service.ISysJobService; -import com.ruoyi.quartz.util.CronUtils; -import org.quartz.SchedulerException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.*; - -import javax.servlet.http.HttpServletResponse; -import java.util.List; - -/** - * 调度任务信息操作处理 - * - * @deprecated 3.4.0删除 迁移至xxl-job - * @author ruoyi - */ -@RestController -@RequestMapping("/monitor/job") -public class SysJobController extends BaseController -{ - @Autowired - private ISysJobService jobService; - - /** - * 查询定时任务列表 - */ - @SaCheckPermission("monitor:job:list") - @GetMapping("/list") - public TableDataInfo list(SysJob sysJob) - { - return jobService.selectPageJobList(sysJob); - } - - /** - * 导出定时任务列表 - */ - @SaCheckPermission("monitor:job:export") - @Log(title = "定时任务", businessType = BusinessType.EXPORT) - @GetMapping("/export") - public void export(SysJob sysJob, HttpServletResponse response) - { - List list = jobService.selectJobList(sysJob); - ExcelUtil.exportExcel(list, "定时任务", SysJob.class, response); - } - - /** - * 获取定时任务详细信息 - */ - @SaCheckPermission("monitor:job:query") - @GetMapping(value = "/{jobId}") - public AjaxResult getInfo(@PathVariable("jobId") Long jobId) - { - return AjaxResult.success(jobService.selectJobById(jobId)); - } - - /** - * 新增定时任务 - */ - @SaCheckPermission("monitor:job:add") - @Log(title = "定时任务", businessType = BusinessType.INSERT) - @PostMapping - public AjaxResult add(@RequestBody SysJob job) throws SchedulerException, TaskException - { - if (!CronUtils.isValid(job.getCronExpression())) - { - return error("新增任务'" + job.getJobName() + "'失败,Cron表达式不正确"); - } - else if (StringUtils.containsIgnoreCase(job.getInvokeTarget(), Constants.LOOKUP_RMI)) - { - return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'rmi://'调用"); - } - else if (StringUtils.containsIgnoreCase(job.getInvokeTarget(), Constants.LOOKUP_LDAP)) - { - return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'ldap://'调用"); - } - else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.HTTP, Constants.HTTPS })) - { - return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'http(s)//'调用"); - } - return toAjax(jobService.insertJob(job)); - } - - /** - * 修改定时任务 - */ - @SaCheckPermission("monitor:job:edit") - @Log(title = "定时任务", businessType = BusinessType.UPDATE) - @PutMapping - public AjaxResult edit(@RequestBody SysJob job) throws SchedulerException, TaskException - { - if (!CronUtils.isValid(job.getCronExpression())) - { - return error("修改任务'" + job.getJobName() + "'失败,Cron表达式不正确"); - } - else if (StringUtils.containsIgnoreCase(job.getInvokeTarget(), Constants.LOOKUP_RMI)) - { - return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'rmi://'调用"); - } - else if (StringUtils.containsIgnoreCase(job.getInvokeTarget(), Constants.LOOKUP_LDAP)) - { - return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'ldap://'调用"); - } - else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.HTTP, Constants.HTTPS })) - { - return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'http(s)//'调用"); - } - return toAjax(jobService.updateJob(job)); - } - - /** - * 定时任务状态修改 - */ - @SaCheckPermission("monitor:job:changeStatus") - @Log(title = "定时任务", businessType = BusinessType.UPDATE) - @PutMapping("/changeStatus") - public AjaxResult changeStatus(@RequestBody SysJob job) throws SchedulerException - { - SysJob newJob = jobService.selectJobById(job.getJobId()); - newJob.setStatus(job.getStatus()); - return toAjax(jobService.changeStatus(newJob)); - } - - /** - * 定时任务立即执行一次 - */ - @SaCheckPermission("monitor:job:changeStatus") - @Log(title = "定时任务", businessType = BusinessType.UPDATE) - @PutMapping("/run") - public AjaxResult run(@RequestBody SysJob job) throws SchedulerException - { - jobService.run(job); - return AjaxResult.success(); - } - - /** - * 删除定时任务 - */ - @SaCheckPermission("monitor:job:remove") - @Log(title = "定时任务", businessType = BusinessType.DELETE) - @DeleteMapping("/{jobIds}") - public AjaxResult remove(@PathVariable Long[] jobIds) throws SchedulerException, TaskException - { - jobService.deleteJobByIds(jobIds); - return AjaxResult.success(); - } -} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobLogController.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobLogController.java deleted file mode 100644 index 8ab3229d9..000000000 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobLogController.java +++ /dev/null @@ -1,87 +0,0 @@ -package com.ruoyi.quartz.controller; - -import cn.dev33.satoken.annotation.SaCheckPermission; -import com.ruoyi.common.annotation.Log; -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.enums.BusinessType; -import com.ruoyi.common.utils.poi.ExcelUtil; -import com.ruoyi.quartz.domain.SysJobLog; -import com.ruoyi.quartz.service.ISysJobLogService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.*; - -import javax.servlet.http.HttpServletResponse; -import java.util.List; - -/** - * 调度日志操作处理 - * - * @deprecated 3.4.0删除 迁移至xxl-job - * @author ruoyi - */ -@RestController -@RequestMapping("/monitor/jobLog") -public class SysJobLogController extends BaseController -{ - @Autowired - private ISysJobLogService jobLogService; - - /** - * 查询定时任务调度日志列表 - */ - - @SaCheckPermission("monitor:job:list") - @GetMapping("/list") - public TableDataInfo list(SysJobLog sysJobLog) - { - return jobLogService.selectPageJobLogList(sysJobLog); - } - - /** - * 导出定时任务调度日志列表 - */ - @SaCheckPermission("monitor:job:export") - @Log(title = "任务调度日志", businessType = BusinessType.EXPORT) - @GetMapping("/export") - public void export(SysJobLog sysJobLog, HttpServletResponse response) - { - List list = jobLogService.selectJobLogList(sysJobLog); - ExcelUtil.exportExcel(list, "调度日志", SysJobLog.class, response); - } - - /** - * 根据调度编号获取详细信息 - */ - @SaCheckPermission("monitor:job:query") - @GetMapping(value = "/{configId}") - public AjaxResult getInfo(@PathVariable Long jobLogId) - { - return AjaxResult.success(jobLogService.selectJobLogById(jobLogId)); - } - - - /** - * 删除定时任务调度日志 - */ - @SaCheckPermission("monitor:job:remove") - @Log(title = "定时任务调度日志", businessType = BusinessType.DELETE) - @DeleteMapping("/{jobLogIds}") - public AjaxResult remove(@PathVariable Long[] jobLogIds) - { - return toAjax(jobLogService.deleteJobLogByIds(jobLogIds)); - } - - /** - * 清空定时任务调度日志 - */ - @SaCheckPermission("monitor:job:remove") - @Log(title = "调度日志", businessType = BusinessType.CLEAN) - @DeleteMapping("/clean") - public AjaxResult clean() - { - jobLogService.cleanJobLog(); - return AjaxResult.success(); - } -} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/SysJob.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/SysJob.java deleted file mode 100644 index ee15e552e..000000000 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/SysJob.java +++ /dev/null @@ -1,140 +0,0 @@ -package com.ruoyi.quartz.domain; - -import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; -import com.alibaba.excel.annotation.ExcelProperty; -import com.baomidou.mybatisplus.annotation.*; -import com.fasterxml.jackson.annotation.JsonFormat; -import com.ruoyi.common.annotation.ExcelDictFormat; -import com.ruoyi.common.constant.ScheduleConstants; -import com.ruoyi.common.convert.ExcelDictConvert; -import com.ruoyi.common.utils.StringUtils; -import com.ruoyi.quartz.util.CronUtils; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.experimental.Accessors; - -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.Size; -import java.io.Serializable; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; - -/** - * 定时任务调度表 sys_job - * - * @deprecated 3.4.0删除 迁移至xxl-job - * @author ruoyi - */ - -@Data -@NoArgsConstructor -@Accessors(chain = true) -@TableName("sys_job") -@ExcelIgnoreUnannotated -public class SysJob implements Serializable { - private static final long serialVersionUID = 1L; - - /** - * 任务ID - */ - @ExcelProperty(value = "任务序号") - @TableId(value = "job_id", type = IdType.AUTO) - private Long jobId; - - /** - * 任务名称 - */ - @NotBlank(message = "任务名称不能为空") - @Size(min = 0, max = 64, message = "任务名称不能超过64个字符") - @ExcelProperty(value = "任务名称") - private String jobName; - - /** - * 任务组名 - */ - @ExcelProperty(value = "任务组名", converter = ExcelDictConvert.class) - @ExcelDictFormat(dictType = "sys_job_group") - private String jobGroup; - - /** - * 调用目标字符串 - */ - @NotBlank(message = "调用目标字符串不能为空") - @Size(min = 0, max = 500, message = "调用目标字符串长度不能超过500个字符") - @ExcelProperty(value = "调用目标字符串") - private String invokeTarget; - - /** - * cron执行表达式 - */ - @NotBlank(message = "Cron执行表达式不能为空") - @Size(min = 0, max = 255, message = "Cron执行表达式不能超过255个字符") - @ExcelProperty(value = "执行表达式") - private String cronExpression; - - /** - * cron计划策略 - */ - @ExcelProperty(value = "计划策略 ", converter = ExcelDictConvert.class) - @ExcelDictFormat(readConverterExp = "0=默认,1=立即触发执行,2=触发一次执行,3=不触发立即执行") - private String misfirePolicy = ScheduleConstants.MISFIRE_DEFAULT; - - /** - * 是否并发执行(0允许 1禁止) - */ - @ExcelProperty(value = "并发执行", converter = ExcelDictConvert.class) - @ExcelDictFormat(readConverterExp = "0=允许,1=禁止") - private String concurrent; - - /** - * 任务状态(0正常 1暂停) - */ - @ExcelProperty(value = "任务状态", converter = ExcelDictConvert.class) - @ExcelDictFormat(dictType = "sys_job_status") - private String status; - - /** - * 创建者 - */ - @TableField(fill = FieldFill.INSERT) - private String createBy; - - /** - * 创建时间 - */ - @TableField(fill = FieldFill.INSERT) - private Date createTime; - - /** - * 更新者 - */ - @TableField(fill = FieldFill.INSERT_UPDATE) - private String updateBy; - - /** - * 更新时间 - */ - @TableField(fill = FieldFill.INSERT_UPDATE) - private Date updateTime; - - /** - * 备注 - */ - private String remark; - - /** - * 请求参数 - */ - @TableField(exist = false) - private Map params = new HashMap<>(); - - @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") - public Date getNextValidTime() { - if (StringUtils.isNotEmpty(cronExpression)) { - return CronUtils.getNextExecution(cronExpression); - } - return null; - } - -} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/SysJobLog.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/SysJobLog.java deleted file mode 100644 index 2ea63df5c..000000000 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/SysJobLog.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.ruoyi.quartz.domain; - -import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; -import com.alibaba.excel.annotation.ExcelProperty; -import com.baomidou.mybatisplus.annotation.*; -import com.ruoyi.common.annotation.ExcelDictFormat; -import com.ruoyi.common.convert.ExcelDictConvert; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.experimental.Accessors; - -import java.util.Date; -import java.util.HashMap; -import java.util.Map; - -/** - * 定时任务调度日志表 sys_job_log - * - * @deprecated 3.4.0删除 迁移至xxl-job - * @author ruoyi - */ - -@Data -@NoArgsConstructor -@Accessors(chain = true) -@TableName("sys_job_log") -@ExcelIgnoreUnannotated -public class SysJobLog -{ - private static final long serialVersionUID = 1L; - - /** ID */ - @ExcelProperty(value = "日志序号") - @TableId(value = "job_log_id", type = IdType.AUTO) - private Long jobLogId; - - /** 任务名称 */ - @ExcelProperty(value = "任务名称") - private String jobName; - - /** 任务组名 */ - @ExcelProperty(value = "任务组名", converter = ExcelDictConvert.class) - @ExcelDictFormat(dictType = "sys_job_group") - private String jobGroup; - - /** 调用目标字符串 */ - @ExcelProperty(value = "调用目标字符串") - private String invokeTarget; - - /** 日志信息 */ - @ExcelProperty(value = "日志信息") - private String jobMessage; - - /** 执行状态(0正常 1失败) */ - @ExcelProperty(value = "执行状态", converter = ExcelDictConvert.class) - @ExcelDictFormat(dictType = "sys_common_status") - private String status; - - /** 异常信息 */ - @ExcelProperty(value = "异常信息") - private String exceptionInfo; - - /** - * 创建时间 - */ - @TableField(fill = FieldFill.INSERT) - private Date createTime; - - /** - * 请求参数 - */ - @TableField(exist = false) - private Map params = new HashMap<>(); - - /** 开始时间 */ - @TableField(exist = false) - private Date startTime; - - /** 停止时间 */ - @TableField(exist = false) - private Date stopTime; - -} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/SysJobLogMapper.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/SysJobLogMapper.java deleted file mode 100644 index 0bffa118c..000000000 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/SysJobLogMapper.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.ruoyi.quartz.mapper; - -import com.ruoyi.common.core.mybatisplus.core.BaseMapperPlus; -import com.ruoyi.quartz.domain.SysJobLog; - -/** - * 调度任务日志信息 数据层 - * - * @deprecated 3.4.0删除 迁移至xxl-job - * @author ruoyi - */ -public interface SysJobLogMapper extends BaseMapperPlus { - -} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/SysJobMapper.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/SysJobMapper.java deleted file mode 100644 index 13f2da7c7..000000000 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/SysJobMapper.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.ruoyi.quartz.mapper; - -import com.ruoyi.common.core.mybatisplus.core.BaseMapperPlus; -import com.ruoyi.quartz.domain.SysJob; - -/** - * 调度任务信息 数据层 - * - * @deprecated 3.4.0删除 迁移至xxl-job - * @author ruoyi - */ -public interface SysJobMapper extends BaseMapperPlus { - -} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/ISysJobLogService.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/ISysJobLogService.java deleted file mode 100644 index ff8451acc..000000000 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/ISysJobLogService.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.ruoyi.quartz.service; - -import com.baomidou.mybatisplus.extension.service.IService; -import com.ruoyi.common.core.page.TableDataInfo; -import com.ruoyi.quartz.domain.SysJobLog; - -import java.util.List; - -/** - * 定时任务调度日志信息信息 服务层 - * - * @deprecated 3.4.0删除 迁移至xxl-job - * @author ruoyi - */ -public interface ISysJobLogService extends IService { - - - TableDataInfo selectPageJobLogList(SysJobLog jobLog); - - /** - * 获取quartz调度器日志的计划任务 - * - * @param jobLog 调度日志信息 - * @return 调度任务日志集合 - */ - public List selectJobLogList(SysJobLog jobLog); - - /** - * 通过调度任务日志ID查询调度信息 - * - * @param jobLogId 调度任务日志ID - * @return 调度任务日志对象信息 - */ - public SysJobLog selectJobLogById(Long jobLogId); - - /** - * 新增任务日志 - * - * @param jobLog 调度日志信息 - */ - public void addJobLog(SysJobLog jobLog); - - /** - * 批量删除调度日志信息 - * - * @param logIds 需要删除的日志ID - * @return 结果 - */ - public int deleteJobLogByIds(Long[] logIds); - - /** - * 删除任务日志 - * - * @param jobId 调度日志ID - * @return 结果 - */ - public int deleteJobLogById(Long jobId); - - /** - * 清空任务日志 - */ - public void cleanJobLog(); -} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/ISysJobService.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/ISysJobService.java deleted file mode 100644 index cbe4621fd..000000000 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/ISysJobService.java +++ /dev/null @@ -1,107 +0,0 @@ -package com.ruoyi.quartz.service; - -import com.baomidou.mybatisplus.extension.service.IService; -import com.ruoyi.common.core.page.TableDataInfo; -import com.ruoyi.common.exception.job.TaskException; -import com.ruoyi.quartz.domain.SysJob; -import org.quartz.SchedulerException; - -import java.util.List; - -/** - * 定时任务调度信息信息 服务层 - * - * @deprecated 3.4.0删除 迁移至xxl-job - * @author ruoyi - */ -public interface ISysJobService extends IService { - /** - * 获取quartz调度器的计划任务 - * - * @param job 调度信息 - * @return 调度任务集合 - */ - public TableDataInfo selectPageJobList(SysJob job); - - public List selectJobList(SysJob job); - - /** - * 通过调度任务ID查询调度信息 - * - * @param jobId 调度任务ID - * @return 调度任务对象信息 - */ - public SysJob selectJobById(Long jobId); - - /** - * 暂停任务 - * - * @param job 调度信息 - * @return 结果 - */ - public int pauseJob(SysJob job) throws SchedulerException; - - /** - * 恢复任务 - * - * @param job 调度信息 - * @return 结果 - */ - public int resumeJob(SysJob job) throws SchedulerException; - - /** - * 删除任务后,所对应的trigger也将被删除 - * - * @param job 调度信息 - * @return 结果 - */ - public int deleteJob(SysJob job) throws SchedulerException; - - /** - * 批量删除调度信息 - * - * @param jobIds 需要删除的任务ID - * @return 结果 - */ - public void deleteJobByIds(Long[] jobIds) throws SchedulerException; - - /** - * 任务调度状态修改 - * - * @param job 调度信息 - * @return 结果 - */ - public int changeStatus(SysJob job) throws SchedulerException; - - /** - * 立即运行任务 - * - * @param job 调度信息 - * @return 结果 - */ - public void run(SysJob job) throws SchedulerException; - - /** - * 新增任务 - * - * @param job 调度信息 - * @return 结果 - */ - public int insertJob(SysJob job) throws SchedulerException, TaskException; - - /** - * 更新任务 - * - * @param job 调度信息 - * @return 结果 - */ - public int updateJob(SysJob job) throws SchedulerException, TaskException; - - /** - * 校验cron表达式是否有效 - * - * @param cronExpression 表达式 - * @return 结果 - */ - public boolean checkCronExpressionIsValid(String cronExpression); -} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/impl/SysJobLogServiceImpl.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/impl/SysJobLogServiceImpl.java deleted file mode 100644 index 76edb49bb..000000000 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/impl/SysJobLogServiceImpl.java +++ /dev/null @@ -1,114 +0,0 @@ -package com.ruoyi.quartz.service.impl; - -import com.ruoyi.common.utils.StringUtils; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl; -import com.ruoyi.common.core.page.TableDataInfo; -import com.ruoyi.common.utils.PageUtils; -import com.ruoyi.quartz.domain.SysJobLog; -import com.ruoyi.quartz.mapper.SysJobLogMapper; -import com.ruoyi.quartz.service.ISysJobLogService; -import org.springframework.stereotype.Service; - -import java.util.Arrays; -import java.util.List; -import java.util.Map; - -/** - * 定时任务调度日志信息 服务层 - * - * @deprecated 3.4.0删除 迁移至xxl-job - * @author ruoyi - */ -@Service -public class SysJobLogServiceImpl extends ServicePlusImpl implements ISysJobLogService { - - @Override - public TableDataInfo selectPageJobLogList(SysJobLog jobLog) { - Map params = jobLog.getParams(); - LambdaQueryWrapper lqw = new LambdaQueryWrapper() - .like(StringUtils.isNotBlank(jobLog.getJobName()), SysJobLog::getJobName, jobLog.getJobName()) - .eq(StringUtils.isNotBlank(jobLog.getJobGroup()), SysJobLog::getJobGroup, jobLog.getJobGroup()) - .eq(StringUtils.isNotBlank(jobLog.getStatus()), SysJobLog::getStatus, jobLog.getStatus()) - .like(StringUtils.isNotBlank(jobLog.getInvokeTarget()), SysJobLog::getInvokeTarget, jobLog.getInvokeTarget()) - .apply(StringUtils.isNotEmpty(params.get("beginTime")), - "date_format(create_time,'%y%m%d') >= date_format({0},'%y%m%d')", - params.get("beginTime")) - .apply(StringUtils.isNotEmpty(params.get("endTime")), - "date_format(create_time,'%y%m%d') <= date_format({0},'%y%m%d')", - params.get("endTime")); - return PageUtils.buildDataInfo(page(PageUtils.buildPage(), lqw)); - } - - /** - * 获取quartz调度器日志的计划任务 - * - * @param jobLog 调度日志信息 - * @return 调度任务日志集合 - */ - @Override - public List selectJobLogList(SysJobLog jobLog) { - Map params = jobLog.getParams(); - return list(new LambdaQueryWrapper() - .like(StringUtils.isNotBlank(jobLog.getJobName()), SysJobLog::getJobName, jobLog.getJobName()) - .eq(StringUtils.isNotBlank(jobLog.getJobGroup()), SysJobLog::getJobGroup, jobLog.getJobGroup()) - .eq(StringUtils.isNotBlank(jobLog.getStatus()), SysJobLog::getStatus, jobLog.getStatus()) - .like(StringUtils.isNotBlank(jobLog.getInvokeTarget()), SysJobLog::getInvokeTarget, jobLog.getInvokeTarget()) - .apply(StringUtils.isNotEmpty(params.get("beginTime")), - "date_format(create_time,'%y%m%d') >= date_format({0},'%y%m%d')", - params.get("beginTime")) - .apply(StringUtils.isNotEmpty(params.get("endTime")), - "date_format(create_time,'%y%m%d') <= date_format({0},'%y%m%d')", - params.get("endTime"))); - } - - /** - * 通过调度任务日志ID查询调度信息 - * - * @param jobLogId 调度任务日志ID - * @return 调度任务日志对象信息 - */ - @Override - public SysJobLog selectJobLogById(Long jobLogId) { - return getById(jobLogId); - } - - /** - * 新增任务日志 - * - * @param jobLog 调度日志信息 - */ - @Override - public void addJobLog(SysJobLog jobLog) { - baseMapper.insert(jobLog); - } - - /** - * 批量删除调度日志信息 - * - * @param logIds 需要删除的数据ID - * @return 结果 - */ - @Override - public int deleteJobLogByIds(Long[] logIds) { - return baseMapper.deleteBatchIds(Arrays.asList(logIds)); - } - - /** - * 删除任务日志 - * - * @param jobId 调度日志ID - */ - @Override - public int deleteJobLogById(Long jobId) { - return baseMapper.deleteById(jobId); - } - - /** - * 清空任务日志 - */ - @Override - public void cleanJobLog() { - remove(new LambdaQueryWrapper<>()); - } -} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/impl/SysJobServiceImpl.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/impl/SysJobServiceImpl.java deleted file mode 100644 index 6962cf1db..000000000 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/impl/SysJobServiceImpl.java +++ /dev/null @@ -1,247 +0,0 @@ -package com.ruoyi.quartz.service.impl; - -import com.ruoyi.common.utils.StringUtils; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.ruoyi.common.constant.ScheduleConstants; -import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl; -import com.ruoyi.common.core.page.TableDataInfo; -import com.ruoyi.common.exception.job.TaskException; -import com.ruoyi.common.utils.PageUtils; -import com.ruoyi.quartz.domain.SysJob; -import com.ruoyi.quartz.mapper.SysJobMapper; -import com.ruoyi.quartz.service.ISysJobService; -import com.ruoyi.quartz.util.CronUtils; -import com.ruoyi.quartz.util.ScheduleUtils; -import org.quartz.JobDataMap; -import org.quartz.JobKey; -import org.quartz.Scheduler; -import org.quartz.SchedulerException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import javax.annotation.PostConstruct; -import java.util.List; - -/** - * 定时任务调度信息 服务层 - * - * @deprecated 3.4.0删除 迁移至xxl-job - * @author ruoyi - */ -@Service -public class SysJobServiceImpl extends ServicePlusImpl implements ISysJobService { - @Autowired - private Scheduler scheduler; - - /** - * 项目启动时,初始化定时器 主要是防止手动修改数据库导致未同步到定时任务处理(注:不能手动修改数据库ID和任务组名,否则会导致脏数据) - */ - @PostConstruct - public void init() throws SchedulerException, TaskException { - scheduler.clear(); - List jobList = list(); - for (SysJob job : jobList) { - ScheduleUtils.createScheduleJob(scheduler, job); - } - } - - @Override - public TableDataInfo selectPageJobList(SysJob job) { - LambdaQueryWrapper lqw = new LambdaQueryWrapper() - .like(StringUtils.isNotBlank(job.getJobName()), SysJob::getJobName, job.getJobName()) - .eq(StringUtils.isNotBlank(job.getJobGroup()), SysJob::getJobGroup, job.getJobGroup()) - .eq(StringUtils.isNotBlank(job.getStatus()), SysJob::getStatus, job.getStatus()) - .like(StringUtils.isNotBlank(job.getInvokeTarget()), SysJob::getInvokeTarget, job.getInvokeTarget()); - return PageUtils.buildDataInfo(page(PageUtils.buildPage(), lqw)); - } - - /** - * 获取quartz调度器的计划任务列表 - * - * @param job 调度信息 - * @return - */ - @Override - public List selectJobList(SysJob job) { - return list(new LambdaQueryWrapper() - .like(StringUtils.isNotBlank(job.getJobName()), SysJob::getJobName, job.getJobName()) - .eq(StringUtils.isNotBlank(job.getJobGroup()), SysJob::getJobGroup, job.getJobGroup()) - .eq(StringUtils.isNotBlank(job.getStatus()), SysJob::getStatus, job.getStatus()) - .like(StringUtils.isNotBlank(job.getInvokeTarget()), SysJob::getInvokeTarget, job.getInvokeTarget())); - } - - /** - * 通过调度任务ID查询调度信息 - * - * @param jobId 调度任务ID - * @return 调度任务对象信息 - */ - @Override - public SysJob selectJobById(Long jobId) { - return getById(jobId); - } - - /** - * 暂停任务 - * - * @param job 调度信息 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public int pauseJob(SysJob job) throws SchedulerException { - Long jobId = job.getJobId(); - String jobGroup = job.getJobGroup(); - job.setStatus(ScheduleConstants.Status.PAUSE.getValue()); - int rows = baseMapper.updateById(job); - if (rows > 0) { - scheduler.pauseJob(ScheduleUtils.getJobKey(jobId, jobGroup)); - } - return rows; - } - - /** - * 恢复任务 - * - * @param job 调度信息 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public int resumeJob(SysJob job) throws SchedulerException { - Long jobId = job.getJobId(); - String jobGroup = job.getJobGroup(); - job.setStatus(ScheduleConstants.Status.NORMAL.getValue()); - int rows = baseMapper.updateById(job); - if (rows > 0) { - scheduler.resumeJob(ScheduleUtils.getJobKey(jobId, jobGroup)); - } - return rows; - } - - /** - * 删除任务后,所对应的trigger也将被删除 - * - * @param job 调度信息 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public int deleteJob(SysJob job) throws SchedulerException { - Long jobId = job.getJobId(); - String jobGroup = job.getJobGroup(); - int rows = baseMapper.deleteById(jobId); - if (rows > 0) { - scheduler.deleteJob(ScheduleUtils.getJobKey(jobId, jobGroup)); - } - return rows; - } - - /** - * 批量删除调度信息 - * - * @param jobIds 需要删除的任务ID - * @return 结果 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public void deleteJobByIds(Long[] jobIds) throws SchedulerException { - for (Long jobId : jobIds) { - SysJob job = getById(jobId); - deleteJob(job); - } - } - - /** - * 任务调度状态修改 - * - * @param job 调度信息 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public int changeStatus(SysJob job) throws SchedulerException { - int rows = 0; - String status = job.getStatus(); - if (ScheduleConstants.Status.NORMAL.getValue().equals(status)) { - rows = resumeJob(job); - } else if (ScheduleConstants.Status.PAUSE.getValue().equals(status)) { - rows = pauseJob(job); - } - return rows; - } - - /** - * 立即运行任务 - * - * @param job 调度信息 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public void run(SysJob job) throws SchedulerException { - Long jobId = job.getJobId(); - String jobGroup = job.getJobGroup(); - SysJob properties = selectJobById(job.getJobId()); - // 参数 - JobDataMap dataMap = new JobDataMap(); - dataMap.put(ScheduleConstants.TASK_PROPERTIES, properties); - scheduler.triggerJob(ScheduleUtils.getJobKey(jobId, jobGroup), dataMap); - } - - /** - * 新增任务 - * - * @param job 调度信息 调度信息 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public int insertJob(SysJob job) throws SchedulerException, TaskException { - job.setStatus(ScheduleConstants.Status.PAUSE.getValue()); - int rows = baseMapper.insert(job); - if (rows > 0) { - ScheduleUtils.createScheduleJob(scheduler, job); - } - return rows; - } - - /** - * 更新任务的时间表达式 - * - * @param job 调度信息 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public int updateJob(SysJob job) throws SchedulerException, TaskException { - SysJob properties = selectJobById(job.getJobId()); - int rows = baseMapper.updateById(job); - if (rows > 0) { - updateSchedulerJob(job, properties.getJobGroup()); - } - return rows; - } - - /** - * 更新任务 - * - * @param job 任务对象 - * @param jobGroup 任务组名 - */ - public void updateSchedulerJob(SysJob job, String jobGroup) throws SchedulerException, TaskException { - Long jobId = job.getJobId(); - // 判断是否存在 - JobKey jobKey = ScheduleUtils.getJobKey(jobId, jobGroup); - if (scheduler.checkExists(jobKey)) { - // 防止创建时存在数据问题 先移除,然后在执行创建操作 - scheduler.deleteJob(jobKey); - } - ScheduleUtils.createScheduleJob(scheduler, job); - } - - /** - * 校验cron表达式是否有效 - * - * @param cronExpression 表达式 - * @return 结果 - */ - @Override - public boolean checkCronExpressionIsValid(String cronExpression) { - return CronUtils.isValid(cronExpression); - } -} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java deleted file mode 100644 index 7fd55c5d9..000000000 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.ruoyi.quartz.task; - -import cn.hutool.core.lang.Console; -import com.ruoyi.common.utils.StringUtils; -import org.springframework.stereotype.Component; - -/** - * 定时任务调度测试 - * - * @deprecated 3.4.0删除 迁移至xxl-job - * @author ruoyi - */ -@Component("ryTask") -public class RyTask -{ - public void ryMultipleParams(String s, Boolean b, Long l, Double d, Integer i) - { - Console.log(StringUtils.format("执行多参方法: 字符串类型{},布尔类型{},长整型{},浮点型{},整形{}", s, b, l, d, i)); - } - - public void ryParams(String params) - { - Console.log("执行有参方法:" + params); - } - - public void ryNoParams() - { - Console.log("执行无参方法"); - } -} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/AbstractQuartzJob.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/AbstractQuartzJob.java deleted file mode 100644 index 1705433f3..000000000 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/AbstractQuartzJob.java +++ /dev/null @@ -1,109 +0,0 @@ -package com.ruoyi.quartz.util; - -import cn.hutool.core.bean.BeanUtil; -import cn.hutool.core.exceptions.ExceptionUtil; -import com.ruoyi.common.constant.Constants; -import com.ruoyi.common.constant.ScheduleConstants; -import com.ruoyi.common.utils.StringUtils; -import com.ruoyi.common.utils.spring.SpringUtils; -import com.ruoyi.quartz.domain.SysJob; -import com.ruoyi.quartz.domain.SysJobLog; -import com.ruoyi.quartz.service.ISysJobLogService; -import org.quartz.Job; -import org.quartz.JobExecutionContext; -import org.quartz.JobExecutionException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Date; - -/** - * 抽象quartz调用 - * - * @deprecated 3.4.0删除 迁移至xxl-job - * @author ruoyi - */ -public abstract class AbstractQuartzJob implements Job -{ - private static final Logger log = LoggerFactory.getLogger(AbstractQuartzJob.class); - - /** - * 线程本地变量 - */ - private static ThreadLocal threadLocal = new ThreadLocal<>(); - - @Override - public void execute(JobExecutionContext context) throws JobExecutionException - { - SysJob sysJob = new SysJob(); - BeanUtil.copyProperties(context.getMergedJobDataMap().get(ScheduleConstants.TASK_PROPERTIES),sysJob); - try - { - before(context, sysJob); - if (StringUtils.isNotNull(sysJob)) - { - doExecute(context, sysJob); - } - after(context, sysJob, null); - } - catch (Exception e) - { - log.error("任务执行异常 - :", e); - after(context, sysJob, e); - } - } - - /** - * 执行前 - * - * @param context 工作执行上下文对象 - * @param sysJob 系统计划任务 - */ - protected void before(JobExecutionContext context, SysJob sysJob) - { - threadLocal.set(new Date()); - } - - /** - * 执行后 - * - * @param context 工作执行上下文对象 - * @param sysJob 系统计划任务 - */ - protected void after(JobExecutionContext context, SysJob sysJob, Exception e) - { - Date startTime = threadLocal.get(); - threadLocal.remove(); - - final SysJobLog sysJobLog = new SysJobLog(); - sysJobLog.setJobName(sysJob.getJobName()); - sysJobLog.setJobGroup(sysJob.getJobGroup()); - sysJobLog.setInvokeTarget(sysJob.getInvokeTarget()); - sysJobLog.setStartTime(startTime); - sysJobLog.setStopTime(new Date()); - long runMs = sysJobLog.getStopTime().getTime() - sysJobLog.getStartTime().getTime(); - sysJobLog.setJobMessage(sysJobLog.getJobName() + " 总共耗时:" + runMs + "毫秒"); - if (e != null) - { - sysJobLog.setStatus(Constants.FAIL); - String errorMsg = StringUtils.substring(ExceptionUtil.stacktraceToString(e), 0, 2000); - sysJobLog.setExceptionInfo(errorMsg); - } - else - { - sysJobLog.setStatus(Constants.SUCCESS); - } - - // 写入数据库当中 - SpringUtils.getBean(ISysJobLogService.class).addJobLog(sysJobLog); - } - - /** - * 执行方法,由子类重载 - * - * @param context 工作执行上下文对象 - * @param sysJob 系统计划任务 - * @throws Exception 执行过程中的异常 - */ - protected abstract void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception; -} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/CronUtils.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/CronUtils.java deleted file mode 100644 index 2253af18c..000000000 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/CronUtils.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.ruoyi.quartz.util; - -import org.quartz.CronExpression; - -import java.text.ParseException; -import java.util.Date; - -/** - * cron表达式工具类 - * - * @deprecated 3.4.0删除 迁移至xxl-job - * @author ruoyi - * - */ -public class CronUtils -{ - /** - * 返回一个布尔值代表一个给定的Cron表达式的有效性 - * - * @param cronExpression Cron表达式 - * @return boolean 表达式是否有效 - */ - public static boolean isValid(String cronExpression) - { - return CronExpression.isValidExpression(cronExpression); - } - - /** - * 返回一个字符串值,表示该消息无效Cron表达式给出有效性 - * - * @param cronExpression Cron表达式 - * @return String 无效时返回表达式错误描述,如果有效返回null - */ - public static String getInvalidMessage(String cronExpression) - { - try - { - new CronExpression(cronExpression); - return null; - } - catch (ParseException pe) - { - return pe.getMessage(); - } - } - - /** - * 返回下一个执行时间根据给定的Cron表达式 - * - * @param cronExpression Cron表达式 - * @return Date 下次Cron表达式执行时间 - */ - public static Date getNextExecution(String cronExpression) - { - try - { - CronExpression cron = new CronExpression(cronExpression); - return cron.getNextValidTimeAfter(new Date(System.currentTimeMillis())); - } - catch (ParseException e) - { - throw new IllegalArgumentException(e.getMessage()); - } - } -} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/JobInvokeUtil.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/JobInvokeUtil.java deleted file mode 100644 index ed15d1f7c..000000000 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/JobInvokeUtil.java +++ /dev/null @@ -1,183 +0,0 @@ -package com.ruoyi.quartz.util; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.LinkedList; -import java.util.List; -import com.ruoyi.common.utils.StringUtils; -import com.ruoyi.common.utils.spring.SpringUtils; -import com.ruoyi.quartz.domain.SysJob; - -/** - * 任务执行工具 - * - * @deprecated 3.4.0删除 迁移至xxl-job - * @author ruoyi - */ -public class JobInvokeUtil -{ - /** - * 执行方法 - * - * @param sysJob 系统任务 - */ - public static void invokeMethod(SysJob sysJob) throws Exception - { - String invokeTarget = sysJob.getInvokeTarget(); - String beanName = getBeanName(invokeTarget); - String methodName = getMethodName(invokeTarget); - List methodParams = getMethodParams(invokeTarget); - - if (!isValidClassName(beanName)) - { - Object bean = SpringUtils.getBean(beanName); - invokeMethod(bean, methodName, methodParams); - } - else - { - Object bean = Class.forName(beanName).newInstance(); - invokeMethod(bean, methodName, methodParams); - } - } - - /** - * 调用任务方法 - * - * @param bean 目标对象 - * @param methodName 方法名称 - * @param methodParams 方法参数 - */ - private static void invokeMethod(Object bean, String methodName, List methodParams) - throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, - InvocationTargetException - { - if (StringUtils.isNotNull(methodParams) && methodParams.size() > 0) - { - Method method = bean.getClass().getDeclaredMethod(methodName, getMethodParamsType(methodParams)); - method.invoke(bean, getMethodParamsValue(methodParams)); - } - else - { - Method method = bean.getClass().getDeclaredMethod(methodName); - method.invoke(bean); - } - } - - /** - * 校验是否为为class包名 - * - * @param str 名称 - * @return true是 false否 - */ - public static boolean isValidClassName(String invokeTarget) - { - return StringUtils.countMatches(invokeTarget, ".") > 1; - } - - /** - * 获取bean名称 - * - * @param invokeTarget 目标字符串 - * @return bean名称 - */ - public static String getBeanName(String invokeTarget) - { - String beanName = StringUtils.substringBefore(invokeTarget, "("); - return StringUtils.substringBeforeLast(beanName, "."); - } - - /** - * 获取bean方法 - * - * @param invokeTarget 目标字符串 - * @return method方法 - */ - public static String getMethodName(String invokeTarget) - { - String methodName = StringUtils.substringBefore(invokeTarget, "("); - return StringUtils.substringAfterLast(methodName, "."); - } - - /** - * 获取method方法参数相关列表 - * - * @param invokeTarget 目标字符串 - * @return method方法相关参数列表 - */ - public static List getMethodParams(String invokeTarget) - { - String methodStr = StringUtils.substringBetween(invokeTarget, "(", ")"); - if (StringUtils.isEmpty(methodStr)) - { - return null; - } - String[] methodParams = methodStr.split(","); - List classs = new LinkedList<>(); - for (int i = 0; i < methodParams.length; i++) - { - String str = StringUtils.trimToEmpty(methodParams[i]); - // String字符串类型,包含' - if (StringUtils.contains(str, "'")) - { - classs.add(new Object[] { StringUtils.replace(str, "'", ""), String.class }); - } - // boolean布尔类型,等于true或者false - else if (StringUtils.equals(str, "true") || StringUtils.equalsIgnoreCase(str, "false")) - { - classs.add(new Object[] { Boolean.valueOf(str), Boolean.class }); - } - // long长整形,包含L - else if (StringUtils.containsIgnoreCase(str, "L")) - { - classs.add(new Object[] { Long.valueOf(StringUtils.replaceIgnoreCase(str, "L", "")), Long.class }); - } - // double浮点类型,包含D - else if (StringUtils.containsIgnoreCase(str, "D")) - { - classs.add(new Object[] { Double.valueOf(StringUtils.replaceIgnoreCase(str, "D", "")), Double.class }); - } - // 其他类型归类为整形 - else - { - classs.add(new Object[] { Integer.valueOf(str), Integer.class }); - } - } - return classs; - } - - /** - * 获取参数类型 - * - * @param methodParams 参数相关列表 - * @return 参数类型列表 - */ - public static Class[] getMethodParamsType(List methodParams) - { - Class[] classs = new Class[methodParams.size()]; - int index = 0; - for (Object[] os : methodParams) - { - classs[index] = (Class) os[1]; - index++; - } - return classs; - } - - /** - * 获取参数值 - * - * @param methodParams 参数相关列表 - * @return 参数值列表 - */ - public static Object[] getMethodParamsValue(List methodParams) - { - Object[] classs = new Object[methodParams.size()]; - int index = 0; - for (Object[] os : methodParams) - { - classs[index] = (Object) os[0]; - index++; - } - return classs; - } -} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/QuartzDisallowConcurrentExecution.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/QuartzDisallowConcurrentExecution.java deleted file mode 100644 index fc0ce7b9f..000000000 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/QuartzDisallowConcurrentExecution.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.ruoyi.quartz.util; - -import org.quartz.DisallowConcurrentExecution; -import org.quartz.JobExecutionContext; -import com.ruoyi.quartz.domain.SysJob; - -/** - * 定时任务处理(禁止并发执行) - * - * @deprecated 3.4.0删除 迁移至xxl-job - * @author ruoyi - * - */ -@DisallowConcurrentExecution -public class QuartzDisallowConcurrentExecution extends AbstractQuartzJob -{ - @Override - protected void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception - { - JobInvokeUtil.invokeMethod(sysJob); - } -} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/QuartzJobExecution.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/QuartzJobExecution.java deleted file mode 100644 index 404c26634..000000000 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/QuartzJobExecution.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.ruoyi.quartz.util; - -import org.quartz.JobExecutionContext; -import com.ruoyi.quartz.domain.SysJob; - -/** - * 定时任务处理(允许并发执行) - * - * @deprecated 3.4.0删除 迁移至xxl-job - * @author ruoyi - * - */ -public class QuartzJobExecution extends AbstractQuartzJob -{ - @Override - protected void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception - { - JobInvokeUtil.invokeMethod(sysJob); - } -} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/ScheduleUtils.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/ScheduleUtils.java deleted file mode 100644 index 182d1d698..000000000 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/ScheduleUtils.java +++ /dev/null @@ -1,114 +0,0 @@ -package com.ruoyi.quartz.util; - -import org.quartz.CronScheduleBuilder; -import org.quartz.CronTrigger; -import org.quartz.Job; -import org.quartz.JobBuilder; -import org.quartz.JobDetail; -import org.quartz.JobKey; -import org.quartz.Scheduler; -import org.quartz.SchedulerException; -import org.quartz.TriggerBuilder; -import org.quartz.TriggerKey; -import com.ruoyi.common.constant.ScheduleConstants; -import com.ruoyi.common.exception.job.TaskException; -import com.ruoyi.common.exception.job.TaskException.Code; -import com.ruoyi.quartz.domain.SysJob; - -/** - * 定时任务工具类 - * - * @deprecated 3.4.0删除 迁移至xxl-job - * @author ruoyi - * - */ -public class ScheduleUtils -{ - /** - * 得到quartz任务类 - * - * @param sysJob 执行计划 - * @return 具体执行任务类 - */ - private static Class getQuartzJobClass(SysJob sysJob) - { - boolean isConcurrent = "0".equals(sysJob.getConcurrent()); - return isConcurrent ? QuartzJobExecution.class : QuartzDisallowConcurrentExecution.class; - } - - /** - * 构建任务触发对象 - */ - public static TriggerKey getTriggerKey(Long jobId, String jobGroup) - { - return TriggerKey.triggerKey(ScheduleConstants.TASK_CLASS_NAME + jobId, jobGroup); - } - - /** - * 构建任务键对象 - */ - public static JobKey getJobKey(Long jobId, String jobGroup) - { - return JobKey.jobKey(ScheduleConstants.TASK_CLASS_NAME + jobId, jobGroup); - } - - /** - * 创建定时任务 - */ - public static void createScheduleJob(Scheduler scheduler, SysJob job) throws SchedulerException, TaskException - { - Class jobClass = getQuartzJobClass(job); - // 构建job信息 - Long jobId = job.getJobId(); - String jobGroup = job.getJobGroup(); - JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(getJobKey(jobId, jobGroup)).build(); - - // 表达式调度构建器 - CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression()); - cronScheduleBuilder = handleCronScheduleMisfirePolicy(job, cronScheduleBuilder); - - // 按新的cronExpression表达式构建一个新的trigger - CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(jobId, jobGroup)) - .withSchedule(cronScheduleBuilder).build(); - - // 放入参数,运行时的方法可以获取 - jobDetail.getJobDataMap().put(ScheduleConstants.TASK_PROPERTIES, job); - - // 判断是否存在 - if (scheduler.checkExists(getJobKey(jobId, jobGroup))) - { - // 防止创建时存在数据问题 先移除,然后在执行创建操作 - scheduler.deleteJob(getJobKey(jobId, jobGroup)); - } - - scheduler.scheduleJob(jobDetail, trigger); - - // 暂停任务 - if (job.getStatus().equals(ScheduleConstants.Status.PAUSE.getValue())) - { - scheduler.pauseJob(ScheduleUtils.getJobKey(jobId, jobGroup)); - } - } - - /** - * 设置定时任务策略 - */ - public static CronScheduleBuilder handleCronScheduleMisfirePolicy(SysJob job, CronScheduleBuilder cb) - throws TaskException - { - switch (job.getMisfirePolicy()) - { - case ScheduleConstants.MISFIRE_DEFAULT: - return cb; - case ScheduleConstants.MISFIRE_IGNORE_MISFIRES: - return cb.withMisfireHandlingInstructionIgnoreMisfires(); - case ScheduleConstants.MISFIRE_FIRE_AND_PROCEED: - return cb.withMisfireHandlingInstructionFireAndProceed(); - case ScheduleConstants.MISFIRE_DO_NOTHING: - return cb.withMisfireHandlingInstructionDoNothing(); - default: - throw new TaskException("The task misfire policy '" + job.getMisfirePolicy() - + "' cannot be used in cron schedule tasks", Code.CONFIG_ERROR); - } - } -} diff --git a/ruoyi-quartz/src/main/resources/mapper/quartz/SysJobLogMapper.xml b/ruoyi-quartz/src/main/resources/mapper/quartz/SysJobLogMapper.xml deleted file mode 100644 index 736a6992a..000000000 --- a/ruoyi-quartz/src/main/resources/mapper/quartz/SysJobLogMapper.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/ruoyi-quartz/src/main/resources/mapper/quartz/SysJobMapper.xml b/ruoyi-quartz/src/main/resources/mapper/quartz/SysJobMapper.xml deleted file mode 100644 index 0a6342ba1..000000000 --- a/ruoyi-quartz/src/main/resources/mapper/quartz/SysJobMapper.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysUserImportVo.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysUserImportVo.java index 16932ad68..d461332f2 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysUserImportVo.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysUserImportVo.java @@ -67,7 +67,7 @@ public class SysUserImportVo implements Serializable { * 帐号状态(0正常 1停用) */ @ExcelProperty(value = "帐号状态", converter = ExcelDictConvert.class) - @ExcelDictFormat(dictType = "sys_common_status") + @ExcelDictFormat(dictType = "sys_normal_disable") private String status; } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/listener/SysUserImportListener.java b/ruoyi-system/src/main/java/com/ruoyi/system/listener/SysUserImportListener.java new file mode 100644 index 000000000..d0fd7d0e6 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/listener/SysUserImportListener.java @@ -0,0 +1,109 @@ +package com.ruoyi.system.listener; + +import cn.hutool.core.bean.BeanUtil; +import com.alibaba.excel.context.AnalysisContext; +import com.alibaba.excel.event.AnalysisEventListener; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.excel.ExcelListener; +import com.ruoyi.common.excel.ExcelResult; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.spring.SpringUtils; +import com.ruoyi.system.domain.vo.SysUserImportVo; +import com.ruoyi.system.service.ISysConfigService; +import com.ruoyi.system.service.ISysUserService; +import lombok.extern.slf4j.Slf4j; + +import java.util.List; + +/** + * 系统用户自定义导入 + * + * @author Lion Li + */ +@Slf4j +public class SysUserImportListener extends AnalysisEventListener implements ExcelListener { + + private final ISysUserService userService; + + private final String password; + + private final Boolean isUpdateSupport; + + private final String operName; + + private int successNum = 0; + private int failureNum = 0; + private final StringBuilder successMsg = new StringBuilder(); + private final StringBuilder failureMsg = new StringBuilder(); + + public SysUserImportListener(Boolean isUpdateSupport) { + this.userService = SpringUtils.getBean(ISysUserService.class); + this.password = SpringUtils.getBean(ISysConfigService.class) + .selectConfigByKey("sys.user.initPassword"); + this.isUpdateSupport = isUpdateSupport; + this.operName = SecurityUtils.getUsername(); + } + + @Override + public void invoke(SysUserImportVo userVo, AnalysisContext context) { + SysUser user = this.userService.selectUserByUserName(userVo.getUserName()); + try { + // 验证是否存在这个用户 + if (StringUtils.isNull(user)) { + user = BeanUtil.toBean(userVo, SysUser.class); + user.setPassword(SecurityUtils.encryptPassword(password)); + user.setCreateBy(operName); + userService.insertUser(user); + successNum++; + successMsg.append("
").append(successNum).append("、账号 ").append(user.getUserName()).append(" 导入成功"); + } else if (isUpdateSupport) { + user.setUpdateBy(operName); + userService.updateUser(user); + successNum++; + successMsg.append("
").append(successNum).append("、账号 ").append(user.getUserName()).append(" 更新成功"); + } else { + failureNum++; + failureMsg.append("
").append(failureNum).append("、账号 ").append(user.getUserName()).append(" 已存在"); + } + } catch (Exception e) { + failureNum++; + String msg = "
" + failureNum + "、账号 " + user.getUserName() + " 导入失败:"; + failureMsg.append(msg).append(e.getMessage()); + log.error(msg, e); + } + } + + @Override + public void doAfterAllAnalysed(AnalysisContext context) { + + } + + @Override + public ExcelResult getExcelResult() { + return new ExcelResult() { + + @Override + public String getAnalysis() { + if (failureNum > 0) { + failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:"); + throw new ServiceException(failureMsg.toString()); + } else { + successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:"); + } + return successMsg.toString(); + } + + @Override + public List getList() { + return null; + } + + @Override + public List getErrorList() { + return null; + } + }; + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysMenuMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysMenuMapper.java index 8b5dcd6b1..f1a018ff6 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysMenuMapper.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysMenuMapper.java @@ -58,6 +58,6 @@ public interface SysMenuMapper extends BaseMapperPlus { * @param menuCheckStrictly 菜单树选择项是否关联显示 * @return 选中菜单列表 */ - List selectMenuListByRoleId(@Param("roleId") Long roleId, @Param("menuCheckStrictly") boolean menuCheckStrictly); + List selectMenuListByRoleId(@Param("roleId") Long roleId, @Param("menuCheckStrictly") boolean menuCheckStrictly); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/runner/SystemApplicationRunner.java b/ruoyi-system/src/main/java/com/ruoyi/system/runner/SystemApplicationRunner.java new file mode 100644 index 000000000..4080a1ac3 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/runner/SystemApplicationRunner.java @@ -0,0 +1,42 @@ +package com.ruoyi.system.runner; + +import com.ruoyi.common.config.RuoYiConfig; +import com.ruoyi.system.service.ISysConfigService; +import com.ruoyi.system.service.ISysDictTypeService; +import com.ruoyi.system.service.ISysOssConfigService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.stereotype.Component; + +/** + * 初始化 system 模块对应业务数据 + * + * @author Lion Li + */ +@Slf4j +@RequiredArgsConstructor(onConstructor_ = @Autowired) +@Component +public class SystemApplicationRunner implements ApplicationRunner { + + private final RuoYiConfig ruoyiConfig; + private final ISysConfigService configService; + private final ISysDictTypeService dictTypeService; + private final ISysOssConfigService ossConfigService; + + @Override + public void run(ApplicationArguments args) throws Exception { + ossConfigService.init(); + log.info("初始化OSS配置成功"); + if (ruoyiConfig.isCacheLazy()){ + return; + } + configService.loadingConfigCache(); + log.info("加载参数缓存数据成功"); + dictTypeService.loadingDictCache(); + log.info("加载字典缓存数据成功"); + } + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDeptService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDeptService.java index ea6afa2e5..bd8c5ffbf 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDeptService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDeptService.java @@ -1,7 +1,7 @@ package com.ruoyi.system.service; +import cn.hutool.core.lang.tree.Tree; import com.baomidou.mybatisplus.extension.service.IService; -import com.ruoyi.common.core.domain.TreeSelect; import com.ruoyi.common.core.domain.entity.SysDept; import java.util.List; @@ -20,21 +20,13 @@ public interface ISysDeptService extends IService { */ List selectDeptList(SysDept dept); - /** - * 构建前端所需要树结构 - * - * @param depts 部门列表 - * @return 树结构列表 - */ - List buildDeptTree(List depts); - /** * 构建前端所需要下拉树结构 * * @param depts 部门列表 * @return 下拉树结构列表 */ - List buildDeptTreeSelect(List depts); + List> buildDeptTreeSelect(List depts); /** * 根据角色ID查询部门树信息 diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysMenuService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysMenuService.java index eea882e67..9424052d6 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysMenuService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysMenuService.java @@ -1,7 +1,7 @@ package com.ruoyi.system.service; +import cn.hutool.core.lang.tree.Tree; import com.baomidou.mybatisplus.extension.service.IService; -import com.ruoyi.common.core.domain.TreeSelect; import com.ruoyi.common.core.domain.entity.SysMenu; import com.ruoyi.system.domain.vo.RouterVo; @@ -54,7 +54,7 @@ public interface ISysMenuService extends IService { * @param roleId 角色ID * @return 选中菜单列表 */ - List selectMenuListByRoleId(Long roleId); + List selectMenuListByRoleId(Long roleId); /** * 构建前端路由所需要的菜单 @@ -64,21 +64,13 @@ public interface ISysMenuService extends IService { */ List buildMenus(List menus); - /** - * 构建前端所需要树结构 - * - * @param menus 菜单列表 - * @return 树结构列表 - */ - List buildMenuTree(List menus); - /** * 构建前端所需要下拉树结构 * * @param menus 菜单列表 * @return 下拉树结构列表 */ - List buildMenuTreeSelect(List menus); + List> buildMenuTreeSelect(List menus); /** * 根据菜单ID查询信息 diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysOssConfigService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysOssConfigService.java index 759ec5b41..9d9fd5341 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysOssConfigService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysOssConfigService.java @@ -17,6 +17,11 @@ import java.util.Collection; */ public interface ISysOssConfigService extends IServicePlus { + /** + * 初始化OSS配置 + */ + void init(); + /** * 查询单个 */ diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigServiceImpl.java index a01bcd141..bbd09a1d7 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigServiceImpl.java @@ -7,6 +7,7 @@ import com.ruoyi.common.constant.Constants; import com.ruoyi.common.constant.UserConstants; import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl; import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.core.service.ConfigService; import com.ruoyi.common.enums.DataSourceType; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.PageUtils; @@ -17,7 +18,6 @@ import com.ruoyi.system.mapper.SysConfigMapper; import com.ruoyi.system.service.ISysConfigService; import org.springframework.stereotype.Service; -import javax.annotation.PostConstruct; import java.util.Arrays; import java.util.Collection; import java.util.List; @@ -29,29 +29,17 @@ import java.util.Map; * @author Lion Li */ @Service -public class SysConfigServiceImpl extends ServicePlusImpl implements ISysConfigService { - - /** - * 项目启动时,初始化参数到缓存 - */ - @PostConstruct - public void init() { - loadingConfigCache(); - } +public class SysConfigServiceImpl extends ServicePlusImpl implements ISysConfigService, ConfigService { @Override public TableDataInfo selectPageConfigList(SysConfig config) { Map params = config.getParams(); LambdaQueryWrapper lqw = new LambdaQueryWrapper() - .like(StringUtils.isNotBlank(config.getConfigName()), SysConfig::getConfigName, config.getConfigName()) - .eq(StringUtils.isNotBlank(config.getConfigType()), SysConfig::getConfigType, config.getConfigType()) - .like(StringUtils.isNotBlank(config.getConfigKey()), SysConfig::getConfigKey, config.getConfigKey()) - .apply(StringUtils.isNotEmpty(params.get("beginTime")), - "date_format(create_time,'%y%m%d') >= date_format({0},'%y%m%d')", - params.get("beginTime")) - .apply(StringUtils.isNotEmpty(params.get("endTime")), - "date_format(create_time,'%y%m%d') <= date_format({0},'%y%m%d')", - params.get("endTime")); + .like(StringUtils.isNotBlank(config.getConfigName()), SysConfig::getConfigName, config.getConfigName()) + .eq(StringUtils.isNotBlank(config.getConfigType()), SysConfig::getConfigType, config.getConfigType()) + .like(StringUtils.isNotBlank(config.getConfigKey()), SysConfig::getConfigKey, config.getConfigKey()) + .between(params.get("beginTime") != null && params.get("endTime") != null, + SysConfig::getCreateTime, params.get("beginTime"), params.get("endTime")); return PageUtils.buildDataInfo(page(PageUtils.buildPage(), lqw)); } @@ -75,12 +63,12 @@ public class SysConfigServiceImpl extends ServicePlusImpl() - .eq(SysConfig::getConfigKey, configKey)); + .eq(SysConfig::getConfigKey, configKey)); if (StringUtils.isNotNull(retConfig)) { RedisUtils.setCacheObject(getCacheKey(configKey), retConfig.getConfigValue()); return retConfig.getConfigValue(); @@ -112,15 +100,11 @@ public class SysConfigServiceImpl extends ServicePlusImpl selectConfigList(SysConfig config) { Map params = config.getParams(); LambdaQueryWrapper lqw = new LambdaQueryWrapper() - .like(StringUtils.isNotBlank(config.getConfigName()), SysConfig::getConfigName, config.getConfigName()) - .eq(StringUtils.isNotBlank(config.getConfigType()), SysConfig::getConfigType, config.getConfigType()) - .like(StringUtils.isNotBlank(config.getConfigKey()), SysConfig::getConfigKey, config.getConfigKey()) - .apply(StringUtils.isNotEmpty(params.get("beginTime")), - "date_format(create_time,'%y%m%d') >= date_format({0},'%y%m%d')", - params.get("beginTime")) - .apply(StringUtils.isNotEmpty(params.get("endTime")), - "date_format(create_time,'%y%m%d') <= date_format({0},'%y%m%d')", - params.get("endTime")); + .like(StringUtils.isNotBlank(config.getConfigName()), SysConfig::getConfigName, config.getConfigName()) + .eq(StringUtils.isNotBlank(config.getConfigType()), SysConfig::getConfigType, config.getConfigType()) + .like(StringUtils.isNotBlank(config.getConfigKey()), SysConfig::getConfigKey, config.getConfigKey()) + .between(params.get("beginTime") != null && params.get("endTime") != null, + SysConfig::getCreateTime, params.get("beginTime"), params.get("endTime")); return baseMapper.selectList(lqw); } @@ -217,6 +201,17 @@ public class SysConfigServiceImpl extends ServicePlusImpl buildDeptTree(List depts) { - List returnList = new ArrayList(); - List tempList = new ArrayList(); - for (SysDept dept : depts) { - tempList.add(dept.getDeptId()); - } - for (SysDept dept : depts) { - // 如果是顶级节点, 遍历该父节点的所有子节点 - if (!tempList.contains(dept.getParentId())) { - recursionFn(depts, dept); - returnList.add(dept); - } - } - if (returnList.isEmpty()) { - returnList = depts; - } - return returnList; - } - /** * 构建前端所需要下拉树结构 * @@ -85,9 +58,12 @@ public class SysDeptServiceImpl extends ServicePlusImpl buildDeptTreeSelect(List depts) { - List deptTrees = buildDeptTree(depts); - return deptTrees.stream().map(TreeSelect::new).collect(Collectors.toList()); + public List> buildDeptTreeSelect(List depts) { + return TreeBuildUtils.build(depts, (dept, tree) -> + tree.setId(dept.getDeptId()) + .setParentId(dept.getParentId()) + .setName(dept.getDeptName()) + .setWeight(dept.getOrderNum())); } /** @@ -122,8 +98,8 @@ public class SysDeptServiceImpl extends ServicePlusImpl() - .eq(SysDept::getStatus, 0) - .apply("find_in_set({0}, ancestors)", deptId)); + .eq(SysDept::getStatus, 0) + .apply("find_in_set({0}, ancestors)", deptId)); } /** @@ -135,8 +111,7 @@ public class SysDeptServiceImpl extends ServicePlusImpl() - .eq(SysDept::getParentId, deptId) - .last("limit 1")); + .eq(SysDept::getParentId, deptId)); return result > 0; } @@ -149,7 +124,7 @@ public class SysDeptServiceImpl extends ServicePlusImpl() - .eq(SysUser::getDeptId, deptId)); + .eq(SysUser::getDeptId, deptId)); return result > 0; } @@ -162,11 +137,11 @@ public class SysDeptServiceImpl extends ServicePlusImpl() - .eq(SysDept::getDeptName, dept.getDeptName()) - .eq(SysDept::getParentId, dept.getParentId()) - .last("limit 1")); - if (StringUtils.isNotNull(info) && info.getDeptId().longValue() != deptId.longValue()) { + long count = count(new LambdaQueryWrapper() + .eq(SysDept::getDeptName, dept.getDeptName()) + .eq(SysDept::getParentId, dept.getParentId()) + .ne(SysDept::getDeptId, deptId)); + if (count > 0) { return UserConstants.NOT_UNIQUE; } return UserConstants.UNIQUE; @@ -224,7 +199,7 @@ public class SysDeptServiceImpl extends ServicePlusImpl() - .set(SysDept::getStatus, "0") - .in(SysDept::getDeptId, Arrays.asList(deptIds))); + .set(SysDept::getStatus, "0") + .in(SysDept::getDeptId, Arrays.asList(deptIds))); } /** @@ -253,7 +228,7 @@ public class SysDeptServiceImpl extends ServicePlusImpl children = list(new LambdaQueryWrapper() - .apply("find_in_set({0},ancestors)", deptId)); + .apply("find_in_set({0},ancestors)", deptId)); for (SysDept child : children) { child.setAncestors(child.getAncestors().replaceFirst(oldAncestors, newAncestors)); } @@ -273,37 +248,4 @@ public class SysDeptServiceImpl extends ServicePlusImpl list, SysDept t) { - // 得到子节点列表 - List childList = getChildList(list, t); - t.setChildren(childList); - for (SysDept tChild : childList) { - if (hasChild(list, tChild)) { - recursionFn(list, tChild); - } - } - } - - /** - * 得到子节点列表 - */ - private List getChildList(List list, SysDept t) { - List tlist = new ArrayList(); - for (SysDept n : list) { - if (StringUtils.isNotNull(n.getParentId()) && n.getParentId().longValue() == t.getDeptId().longValue()) { - tlist.add(n); - } - } - return tlist; - } - - /** - * 判断是否有子节点 - */ - private boolean hasChild(List list, SysDept t) { - return getChildList(list, t).size() > 0; - } } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictDataServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictDataServiceImpl.java index 35908e3b1..d2ac2a02e 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictDataServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictDataServiceImpl.java @@ -1,11 +1,12 @@ package com.ruoyi.system.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.ruoyi.common.constant.Constants; import com.ruoyi.common.core.domain.entity.SysDictData; import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl; import com.ruoyi.common.core.page.TableDataInfo; -import com.ruoyi.common.utils.DictUtils; import com.ruoyi.common.utils.PageUtils; +import com.ruoyi.common.utils.RedisUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.system.mapper.SysDictDataMapper; import com.ruoyi.system.service.ISysDictDataService; @@ -85,7 +86,7 @@ public class SysDictDataServiceImpl extends ServicePlusImpl dictDatas = baseMapper.selectDictDataByType(data.getDictType()); - DictUtils.setDictCache(data.getDictType(), dictDatas); + RedisUtils.setCacheObject(getCacheKey(data.getDictType()), dictDatas); } } @@ -100,7 +101,7 @@ public class SysDictDataServiceImpl extends ServicePlusImpl 0) { List dictDatas = baseMapper.selectDictDataByType(data.getDictType()); - DictUtils.setDictCache(data.getDictType(), dictDatas); + RedisUtils.setCacheObject(getCacheKey(data.getDictType()), dictDatas); } return row; } @@ -116,8 +117,18 @@ public class SysDictDataServiceImpl extends ServicePlusImpl 0) { List dictDatas = baseMapper.selectDictDataByType(data.getDictType()); - DictUtils.setDictCache(data.getDictType(), dictDatas); + RedisUtils.setCacheObject(getCacheKey(data.getDictType()), dictDatas); } return row; } + + /** + * 设置cache key + * + * @param configKey 参数键 + * @return 缓存键key + */ + String getCacheKey(String configKey) { + return Constants.SYS_DICT_KEY + configKey; + } } 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 bb940c2b0..b520d4188 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 @@ -3,14 +3,16 @@ package com.ruoyi.system.service.impl; import cn.hutool.core.collection.CollUtil; 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.UserConstants; import com.ruoyi.common.core.domain.entity.SysDictData; import com.ruoyi.common.core.domain.entity.SysDictType; import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl; import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.core.service.DictService; import com.ruoyi.common.exception.ServiceException; -import com.ruoyi.common.utils.DictUtils; import com.ruoyi.common.utils.PageUtils; +import com.ruoyi.common.utils.RedisUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.system.mapper.SysDictDataMapper; import com.ruoyi.system.mapper.SysDictTypeMapper; @@ -19,8 +21,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import javax.annotation.PostConstruct; import java.util.Arrays; +import java.util.Collection; import java.util.List; import java.util.Map; @@ -30,32 +32,20 @@ import java.util.Map; * @author Lion Li */ @Service -public class SysDictTypeServiceImpl extends ServicePlusImpl implements ISysDictTypeService { +public class SysDictTypeServiceImpl extends ServicePlusImpl implements ISysDictTypeService, DictService { @Autowired private SysDictDataMapper dictDataMapper; - /** - * 项目启动时,初始化字典到缓存 - */ - @PostConstruct - public void init() { - loadingDictCache(); - } - @Override public TableDataInfo selectPageDictTypeList(SysDictType dictType) { Map params = dictType.getParams(); LambdaQueryWrapper lqw = new LambdaQueryWrapper() - .like(StringUtils.isNotBlank(dictType.getDictName()), SysDictType::getDictName, dictType.getDictName()) - .eq(StringUtils.isNotBlank(dictType.getStatus()), SysDictType::getStatus, dictType.getStatus()) - .like(StringUtils.isNotBlank(dictType.getDictType()), SysDictType::getDictType, dictType.getDictType()) - .apply(StringUtils.isNotEmpty(params.get("beginTime")), - "date_format(create_time,'%y%m%d') >= date_format({0},'%y%m%d')", - params.get("beginTime")) - .apply(StringUtils.isNotEmpty(params.get("endTime")), - "date_format(create_time,'%y%m%d') <= date_format({0},'%y%m%d')", - params.get("endTime")); + .like(StringUtils.isNotBlank(dictType.getDictName()), SysDictType::getDictName, dictType.getDictName()) + .eq(StringUtils.isNotBlank(dictType.getStatus()), SysDictType::getStatus, dictType.getStatus()) + .like(StringUtils.isNotBlank(dictType.getDictType()), SysDictType::getDictType, dictType.getDictType()) + .between(params.get("beginTime") != null && params.get("endTime") != null, + SysDictType::getCreateTime, params.get("beginTime"), params.get("endTime")); return PageUtils.buildDataInfo(page(PageUtils.buildPage(), lqw)); } @@ -69,15 +59,11 @@ public class SysDictTypeServiceImpl extends ServicePlusImpl selectDictTypeList(SysDictType dictType) { Map params = dictType.getParams(); return list(new LambdaQueryWrapper() - .like(StringUtils.isNotBlank(dictType.getDictName()), SysDictType::getDictName, dictType.getDictName()) - .eq(StringUtils.isNotBlank(dictType.getStatus()), SysDictType::getStatus, dictType.getStatus()) - .like(StringUtils.isNotBlank(dictType.getDictType()), SysDictType::getDictType, dictType.getDictType()) - .apply(StringUtils.isNotEmpty(params.get("beginTime")), - "date_format(create_time,'%y%m%d') >= date_format({0},'%y%m%d')", - params.get("beginTime")) - .apply(StringUtils.isNotEmpty(params.get("endTime")), - "date_format(create_time,'%y%m%d') <= date_format({0},'%y%m%d')", - params.get("endTime"))); + .like(StringUtils.isNotBlank(dictType.getDictName()), SysDictType::getDictName, dictType.getDictName()) + .eq(StringUtils.isNotBlank(dictType.getStatus()), SysDictType::getStatus, dictType.getStatus()) + .like(StringUtils.isNotBlank(dictType.getDictType()), SysDictType::getDictType, dictType.getDictType()) + .between(params.get("beginTime") != null && params.get("endTime") != null, + SysDictType::getCreateTime, params.get("beginTime"), params.get("endTime"))); } /** @@ -98,13 +84,13 @@ public class SysDictTypeServiceImpl extends ServicePlusImpl selectDictDataByType(String dictType) { - List dictDatas = DictUtils.getDictCache(dictType); - if (CollUtil.isNotEmpty(dictDatas)) { + List dictDatas = RedisUtils.getCacheObject(getCacheKey(dictType)); + if (StringUtils.isNotEmpty(dictDatas)) { return dictDatas; } dictDatas = dictDataMapper.selectDictDataByType(dictType); if (CollUtil.isNotEmpty(dictDatas)) { - DictUtils.setDictCache(dictType, dictDatas); + RedisUtils.setCacheObject(getCacheKey(dictType), dictDatas); return dictDatas; } return null; @@ -143,10 +129,10 @@ public class SysDictTypeServiceImpl extends ServicePlusImpl() - .eq(SysDictData::getDictType, dictType.getDictType())) > 0) { + .eq(SysDictData::getDictType, dictType.getDictType())) > 0) { throw new ServiceException(String.format("%1$s已分配,不能删除", dictType.getDictName())); } - DictUtils.removeDictCache(dictType.getDictType()); + RedisUtils.deleteObject(getCacheKey(dictType.getDictType())); } baseMapper.deleteBatchIds(Arrays.asList(dictIds)); } @@ -159,7 +145,7 @@ public class SysDictTypeServiceImpl extends ServicePlusImpl dictTypeList = list(); for (SysDictType dictType : dictTypeList) { List dictDatas = dictDataMapper.selectDictDataByType(dictType.getDictType()); - DictUtils.setDictCache(dictType.getDictType(), dictDatas); + RedisUtils.setCacheObject(getCacheKey(dictType.getDictType()), dictDatas); } } @@ -168,7 +154,8 @@ public class SysDictTypeServiceImpl extends ServicePlusImpl keys = RedisUtils.keys(Constants.SYS_DICT_KEY + "*"); + RedisUtils.deleteObject(keys); } /** @@ -190,7 +177,7 @@ public class SysDictTypeServiceImpl extends ServicePlusImpl 0) { - DictUtils.setDictCache(dict.getDictType(), null); + RedisUtils.setCacheObject(getCacheKey(dict.getDictType()), null); } return row; } @@ -206,12 +193,12 @@ public class SysDictTypeServiceImpl extends ServicePlusImpl() - .set(SysDictData::getDictType, dict.getDictType()) - .eq(SysDictData::getDictType, oldDict.getDictType())); + .set(SysDictData::getDictType, dict.getDictType()) + .eq(SysDictData::getDictType, oldDict.getDictType())); int row = baseMapper.updateById(dict); if (row > 0) { List dictDatas = dictDataMapper.selectDictDataByType(dict.getDictType()); - DictUtils.setDictCache(dict.getDictType(), dictDatas); + RedisUtils.setCacheObject(getCacheKey(dict.getDictType()), dictDatas); } return row; } @@ -225,12 +212,86 @@ public class SysDictTypeServiceImpl extends ServicePlusImpl() - .eq(SysDictType::getDictType, dict.getDictType()) - .last("limit 1")); - if (StringUtils.isNotNull(dictType) && dictType.getDictId().longValue() != dictId.longValue()) { + long count = count(new LambdaQueryWrapper() + .eq(SysDictType::getDictType, dict.getDictType()) + .ne(SysDictType::getDictId, dictId)); + if (count > 0) { return UserConstants.NOT_UNIQUE; } return UserConstants.UNIQUE; } + + /** + * 根据字典类型和字典值获取字典标签 + * + * @param dictType 字典类型 + * @param dictValue 字典值 + * @param separator 分隔符 + * @return 字典标签 + */ + @Override + public String getDictLabel(String dictType, String dictValue, String separator) { + StringBuilder propertyString = new StringBuilder(); + List datas = 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(); + } + } + } + return StringUtils.stripEnd(propertyString.toString(), separator); + } + + /** + * 根据字典类型和字典标签获取字典值 + * + * @param dictType 字典类型 + * @param dictLabel 字典标签 + * @param separator 分隔符 + * @return 字典值 + */ + @Override + public String getDictValue(String dictType, String dictLabel, String separator) { + StringBuilder propertyString = new StringBuilder(); + List datas = 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(); + } + } + } + return StringUtils.stripEnd(propertyString.toString(), separator); + } + + /** + * 设置cache key + * + * @param configKey 参数键 + * @return 缓存键key + */ + String getCacheKey(String configKey) { + return Constants.SYS_DICT_KEY + configKey; + } } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysLogininforServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysLogininforServiceImpl.java index dda5b5d1b..0ce33be0f 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysLogininforServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysLogininforServiceImpl.java @@ -90,16 +90,12 @@ public class SysLogininforServiceImpl extends ServicePlusImpl selectPageLogininforList(SysLogininfor logininfor) { Map params = logininfor.getParams(); LambdaQueryWrapper lqw = new LambdaQueryWrapper() - .like(StringUtils.isNotBlank(logininfor.getIpaddr()), SysLogininfor::getIpaddr, logininfor.getIpaddr()) - .eq(StringUtils.isNotBlank(logininfor.getStatus()), SysLogininfor::getStatus, logininfor.getStatus()) - .like(StringUtils.isNotBlank(logininfor.getUserName()), SysLogininfor::getUserName, logininfor.getUserName()) - .apply(StringUtils.isNotEmpty(params.get("beginTime")), - "date_format(login_time,'%y%m%d') >= date_format({0},'%y%m%d')", - params.get("beginTime")) - .apply(StringUtils.isNotEmpty(params.get("endTime")), - "date_format(login_time,'%y%m%d') <= date_format({0},'%y%m%d')", - params.get("endTime")); - return PageUtils.buildDataInfo(page(PageUtils.buildPage("info_id","desc"), lqw)); + .like(StringUtils.isNotBlank(logininfor.getIpaddr()), SysLogininfor::getIpaddr, logininfor.getIpaddr()) + .eq(StringUtils.isNotBlank(logininfor.getStatus()), SysLogininfor::getStatus, logininfor.getStatus()) + .like(StringUtils.isNotBlank(logininfor.getUserName()), SysLogininfor::getUserName, logininfor.getUserName()) + .between(params.get("beginTime") != null && params.get("endTime") != null, + SysLogininfor::getLoginTime, params.get("beginTime"), params.get("endTime")); + return PageUtils.buildDataInfo(page(PageUtils.buildPage("info_id", "desc"), lqw)); } /** @@ -123,16 +119,12 @@ public class SysLogininforServiceImpl extends ServicePlusImpl selectLogininforList(SysLogininfor logininfor) { Map params = logininfor.getParams(); return list(new LambdaQueryWrapper() - .like(StringUtils.isNotBlank(logininfor.getIpaddr()),SysLogininfor::getIpaddr,logininfor.getIpaddr()) - .eq(StringUtils.isNotBlank(logininfor.getStatus()),SysLogininfor::getStatus,logininfor.getStatus()) - .like(StringUtils.isNotBlank(logininfor.getUserName()),SysLogininfor::getUserName,logininfor.getUserName()) - .apply(StringUtils.isNotEmpty(params.get("beginTime")), - "date_format(login_time,'%y%m%d') >= date_format({0},'%y%m%d')", - params.get("beginTime")) - .apply(StringUtils.isNotEmpty(params.get("endTime")), - "date_format(login_time,'%y%m%d') <= date_format({0},'%y%m%d')", - params.get("endTime")) - .orderByDesc(SysLogininfor::getInfoId)); + .like(StringUtils.isNotBlank(logininfor.getIpaddr()), SysLogininfor::getIpaddr, logininfor.getIpaddr()) + .eq(StringUtils.isNotBlank(logininfor.getStatus()), SysLogininfor::getStatus, logininfor.getStatus()) + .like(StringUtils.isNotBlank(logininfor.getUserName()), SysLogininfor::getUserName, logininfor.getUserName()) + .between(params.get("beginTime") != null && params.get("endTime") != null, + SysLogininfor::getLoginTime, params.get("beginTime"), params.get("endTime")) + .orderByDesc(SysLogininfor::getInfoId)); } /** 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 643d304eb..9c3bfeb77 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 @@ -1,15 +1,16 @@ package com.ruoyi.system.service.impl; +import cn.hutool.core.lang.tree.Tree; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.constant.UserConstants; -import com.ruoyi.common.core.domain.TreeSelect; import com.ruoyi.common.core.domain.entity.SysMenu; import com.ruoyi.common.core.domain.entity.SysRole; import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.TreeBuildUtils; import com.ruoyi.system.domain.SysRoleMenu; import com.ruoyi.system.domain.vo.MetaVo; import com.ruoyi.system.domain.vo.RouterVo; @@ -21,7 +22,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.*; -import java.util.stream.Collectors; /** * 菜单 业务层处理 @@ -60,11 +60,11 @@ public class SysMenuServiceImpl extends ServicePlusImpl() - .like(StringUtils.isNotBlank(menu.getMenuName()), SysMenu::getMenuName, menu.getMenuName()) - .eq(StringUtils.isNotBlank(menu.getVisible()), SysMenu::getVisible, menu.getVisible()) - .eq(StringUtils.isNotBlank(menu.getStatus()), SysMenu::getStatus, menu.getStatus()) - .orderByAsc(SysMenu::getParentId) - .orderByAsc(SysMenu::getOrderNum)); + .like(StringUtils.isNotBlank(menu.getMenuName()), SysMenu::getMenuName, menu.getMenuName()) + .eq(StringUtils.isNotBlank(menu.getVisible()), SysMenu::getVisible, menu.getVisible()) + .eq(StringUtils.isNotBlank(menu.getStatus()), SysMenu::getStatus, menu.getStatus()) + .orderByAsc(SysMenu::getParentId) + .orderByAsc(SysMenu::getOrderNum)); } else { menu.getParams().put("userId", userId); menuList = baseMapper.selectMenuListByUserId(menu); @@ -114,7 +114,7 @@ public class SysMenuServiceImpl extends ServicePlusImpl selectMenuListByRoleId(Long roleId) { + public List selectMenuListByRoleId(Long roleId) { SysRole role = roleMapper.selectById(roleId); return baseMapper.selectMenuListByRoleId(roleId, role.isMenuCheckStrictly()); } @@ -170,32 +170,6 @@ public class SysMenuServiceImpl extends ServicePlusImpl buildMenuTree(List menus) { - List returnList = new ArrayList(); - List tempList = new ArrayList(); - for (SysMenu dept : menus) { - tempList.add(dept.getMenuId()); - } - for (SysMenu menu : menus) { - // 如果是顶级节点, 遍历该父节点的所有子节点 - if (!tempList.contains(menu.getParentId())) { - recursionFn(menus, menu); - returnList.add(menu); - } - } - if (returnList.isEmpty()) { - returnList = menus; - } - return returnList; - } - /** * 构建前端所需要下拉树结构 * @@ -203,9 +177,12 @@ public class SysMenuServiceImpl extends ServicePlusImpl buildMenuTreeSelect(List menus) { - List menuTrees = buildMenuTree(menus); - return menuTrees.stream().map(TreeSelect::new).collect(Collectors.toList()); + public List> buildMenuTreeSelect(List menus) { + return TreeBuildUtils.build(menus, (menu, tree) -> + tree.setId(menu.getMenuId()) + .setParentId(menu.getParentId()) + .setName(menu.getMenuName()) + .setWeight(menu.getOrderNum())); } /** @@ -285,11 +262,11 @@ public class SysMenuServiceImpl extends ServicePlusImpl() - .eq(SysMenu::getMenuName, menu.getMenuName()) - .eq(SysMenu::getParentId, menu.getParentId()) - .last("limit 1")); - if (StringUtils.isNotNull(info) && info.getMenuId().longValue() != menuId.longValue()) { + long count = count(new LambdaQueryWrapper() + .eq(SysMenu::getMenuName, menu.getMenuName()) + .eq(SysMenu::getParentId, menu.getParentId()) + .ne(SysMenu::getMenuId, menuId)); + if (count > 0) { return UserConstants.NOT_UNIQUE; } return UserConstants.UNIQUE; @@ -324,7 +301,7 @@ public class SysMenuServiceImpl extends ServicePlusImpl selectPageOperLogList(SysOperLog operLog) { Map params = operLog.getParams(); LambdaQueryWrapper lqw = new LambdaQueryWrapper() - .like(StringUtils.isNotBlank(operLog.getTitle()), SysOperLog::getTitle, operLog.getTitle()) - .eq(operLog.getBusinessType() != null && operLog.getBusinessType() > 0, - SysOperLog::getBusinessType, operLog.getBusinessType()) - .func(f -> { - if (ArrayUtil.isNotEmpty(operLog.getBusinessTypes())) { - f.in(SysOperLog::getBusinessType, Arrays.asList(operLog.getBusinessTypes())); - } - }) - .eq(operLog.getStatus() != null, - SysOperLog::getStatus, operLog.getStatus()) - .like(StringUtils.isNotBlank(operLog.getOperName()), SysOperLog::getOperName, operLog.getOperName()) - .apply(StringUtils.isNotEmpty(params.get("beginTime")), - "date_format(oper_time,'%y%m%d') >= date_format({0},'%y%m%d')", - params.get("beginTime")) - .apply(StringUtils.isNotEmpty(params.get("endTime")), - "date_format(oper_time,'%y%m%d') <= date_format({0},'%y%m%d')", - params.get("endTime")); + .like(StringUtils.isNotBlank(operLog.getTitle()), SysOperLog::getTitle, operLog.getTitle()) + .eq(operLog.getBusinessType() != null && operLog.getBusinessType() > 0, + SysOperLog::getBusinessType, operLog.getBusinessType()) + .func(f -> { + if (ArrayUtil.isNotEmpty(operLog.getBusinessTypes())) { + f.in(SysOperLog::getBusinessType, Arrays.asList(operLog.getBusinessTypes())); + } + }) + .eq(operLog.getStatus() != null, + SysOperLog::getStatus, operLog.getStatus()) + .like(StringUtils.isNotBlank(operLog.getOperName()), SysOperLog::getOperName, operLog.getOperName()) + .between(params.get("beginTime") != null && params.get("endTime") != null, + SysOperLog::getOperTime, params.get("beginTime"), params.get("endTime")); return PageUtils.buildDataInfo(page(PageUtils.buildPage("oper_id", "desc"), lqw)); } @@ -88,24 +84,20 @@ public class SysOperLogServiceImpl extends ServicePlusImpl selectOperLogList(SysOperLog operLog) { Map params = operLog.getParams(); return list(new LambdaQueryWrapper() - .like(StringUtils.isNotBlank(operLog.getTitle()), SysOperLog::getTitle, operLog.getTitle()) - .eq(operLog.getBusinessType() != null && operLog.getBusinessType() > 0, - SysOperLog::getBusinessType, operLog.getBusinessType()) - .func(f -> { - if (ArrayUtil.isNotEmpty(operLog.getBusinessTypes())) { - f.in(SysOperLog::getBusinessType, Arrays.asList(operLog.getBusinessTypes())); - } - }) - .eq(operLog.getStatus() != null && operLog.getStatus() > 0, - SysOperLog::getStatus, operLog.getStatus()) - .like(StringUtils.isNotBlank(operLog.getOperName()), SysOperLog::getOperName, operLog.getOperName()) - .apply(StringUtils.isNotEmpty(params.get("beginTime")), - "date_format(oper_time,'%y%m%d') >= date_format({0},'%y%m%d')", - params.get("beginTime")) - .apply(StringUtils.isNotEmpty(params.get("endTime")), - "date_format(oper_time,'%y%m%d') <= date_format({0},'%y%m%d')", - params.get("endTime")) - .orderByDesc(SysOperLog::getOperId)); + .like(StringUtils.isNotBlank(operLog.getTitle()), SysOperLog::getTitle, operLog.getTitle()) + .eq(operLog.getBusinessType() != null && operLog.getBusinessType() > 0, + SysOperLog::getBusinessType, operLog.getBusinessType()) + .func(f -> { + if (ArrayUtil.isNotEmpty(operLog.getBusinessTypes())) { + f.in(SysOperLog::getBusinessType, Arrays.asList(operLog.getBusinessTypes())); + } + }) + .eq(operLog.getStatus() != null && operLog.getStatus() > 0, + SysOperLog::getStatus, operLog.getStatus()) + .like(StringUtils.isNotBlank(operLog.getOperName()), SysOperLog::getOperName, operLog.getOperName()) + .between(params.get("beginTime") != null && params.get("endTime") != null, + SysOperLog::getOperTime, params.get("beginTime"), params.get("endTime")) + .orderByDesc(SysOperLog::getOperId)); } /** diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOssConfigServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOssConfigServiceImpl.java index df3f6d153..9940beaeb 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOssConfigServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOssConfigServiceImpl.java @@ -15,7 +15,8 @@ import com.ruoyi.common.utils.JsonUtils; import com.ruoyi.common.utils.PageUtils; import com.ruoyi.common.utils.RedisUtils; import com.ruoyi.common.utils.StringUtils; -import com.ruoyi.oss.constant.CloudConstant; +import com.ruoyi.oss.constant.OssConstant; +import com.ruoyi.oss.factory.OssFactory; import com.ruoyi.system.domain.SysOssConfig; import com.ruoyi.system.domain.bo.SysOssConfigBo; import com.ruoyi.system.domain.vo.SysOssConfigVo; @@ -27,7 +28,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import javax.annotation.PostConstruct; import java.util.Collection; import java.util.List; @@ -46,16 +46,19 @@ public class SysOssConfigServiceImpl extends ServicePlusImpl list = list(); + // 加载OSS初始化配置 for (SysOssConfig config : list) { String configKey = config.getConfigKey(); if ("0".equals(config.getStatus())) { - RedisUtils.setCacheObject(CloudConstant.CACHE_CONFIG_KEY, configKey); + RedisUtils.setCacheObject(OssConstant.CACHE_CONFIG_KEY, configKey); } setConfigCache(true, config); } + // 初始化OSS工厂 + OssFactory.init(); } @Override @@ -110,7 +113,7 @@ public class SysOssConfigServiceImpl extends ServicePlusImpl ids, Boolean isValid) { if (isValid) { - if (CollUtil.containsAny(ids, CloudConstant.SYSTEM_DATA_IDS)) { + if (CollUtil.containsAny(ids, OssConstant.SYSTEM_DATA_IDS)) { throw new ServiceException("系统内置, 不可删除!"); } } @@ -153,7 +156,7 @@ public class SysOssConfigServiceImpl extends ServicePlusImpl 0) { - RedisUtils.setCacheObject(CloudConstant.CACHE_CONFIG_KEY, sysOssConfig.getConfigKey()); + RedisUtils.setCacheObject(OssConstant.CACHE_CONFIG_KEY, sysOssConfig.getConfigKey()); } return row; } @@ -165,7 +168,7 @@ public class SysOssConfigServiceImpl extends ServicePlusImpl { + RedisUtils.publish(OssConstant.CACHE_CONFIG_KEY, config.getConfigKey(), msg -> { log.info("发布刷新OSS配置 => " + msg); }); } 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 b703ff690..c20cc4b76 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 @@ -10,7 +10,7 @@ import com.ruoyi.common.utils.PageUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.oss.entity.UploadResult; import com.ruoyi.oss.factory.OssFactory; -import com.ruoyi.oss.service.ICloudStorageStrategy; +import com.ruoyi.oss.service.IOssStrategy; import com.ruoyi.system.domain.SysOss; import com.ruoyi.system.domain.bo.SysOssBo; import com.ruoyi.system.domain.vo.SysOssVo; @@ -56,7 +56,7 @@ public class SysOssServiceImpl extends ServicePlusImpl list = listByIds(ids); for (SysOss sysOss : list) { - ICloudStorageStrategy storage = OssFactory.instance(sysOss.getService()); + IOssStrategy storage = OssFactory.instance(sysOss.getService()); storage.delete(sysOss.getUrl()); } return removeByIds(ids); diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysPostServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysPostServiceImpl.java index 9681b3db4..4e04f3a19 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysPostServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysPostServiceImpl.java @@ -93,9 +93,10 @@ public class SysPostServiceImpl extends ServicePlusImpl() - .eq(SysPost::getPostName, post.getPostName()).last("limit 1")); - if (StringUtils.isNotNull(info) && info.getPostId().longValue() != postId.longValue()) { + long count = count(new LambdaQueryWrapper() + .eq(SysPost::getPostName, post.getPostName()) + .ne(SysPost::getPostId, postId)); + if (count > 0) { return UserConstants.NOT_UNIQUE; } return UserConstants.UNIQUE; @@ -110,9 +111,10 @@ public class SysPostServiceImpl extends ServicePlusImpl() - .eq(SysPost::getPostCode, post.getPostCode()).last("limit 1")); - if (StringUtils.isNotNull(info) && info.getPostId().longValue() != postId.longValue()) { + long count = count(new LambdaQueryWrapper() + .eq(SysPost::getPostCode, post.getPostCode()) + .ne(SysPost::getPostId, postId)); + if (count > 0) { return UserConstants.NOT_UNIQUE; } return UserConstants.UNIQUE; diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java index 7dd14af8f..7bad29746 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java @@ -141,9 +141,10 @@ public class SysRoleServiceImpl extends ServicePlusImpl() - .eq(SysRole::getRoleName, role.getRoleName()).last("limit 1")); - if (StringUtils.isNotNull(info) && info.getRoleId().longValue() != roleId.longValue()) { + long count = count(new LambdaQueryWrapper() + .eq(SysRole::getRoleName, role.getRoleName()) + .ne(SysRole::getRoleId, roleId)); + if (count > 0) { return UserConstants.NOT_UNIQUE; } return UserConstants.UNIQUE; @@ -158,9 +159,10 @@ public class SysRoleServiceImpl extends ServicePlusImpl() - .eq(SysRole::getRoleKey, role.getRoleKey()).last("limit 1")); - if (StringUtils.isNotNull(info) && info.getRoleId().longValue() != roleId.longValue()) { + long count = count(new LambdaQueryWrapper() + .eq(SysRole::getRoleKey, role.getRoleKey()) + .ne(SysRole::getRoleId, roleId)); + if (count > 0) { return UserConstants.NOT_UNIQUE; } return UserConstants.UNIQUE; diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java index 788992a9d..62d497d45 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java @@ -8,6 +8,7 @@ import com.ruoyi.common.core.domain.entity.SysRole; import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl; import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.core.service.UserService; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.PageUtils; import com.ruoyi.common.utils.SecurityUtils; @@ -35,7 +36,7 @@ import java.util.List; */ @Slf4j @Service -public class SysUserServiceImpl extends ServicePlusImpl implements ISysUserService { +public class SysUserServiceImpl extends ServicePlusImpl implements ISysUserService, UserService { @Autowired private SysRoleMapper roleMapper; @@ -162,7 +163,7 @@ public class SysUserServiceImpl extends ServicePlusImpl().eq(SysUser::getUserName, userName).last("limit 1")); + long count = count(new LambdaQueryWrapper().eq(SysUser::getUserName, userName)); if (count > 0) { return UserConstants.NOT_UNIQUE; } @@ -178,10 +179,11 @@ public class SysUserServiceImpl extends ServicePlusImpl() + long count = count(new LambdaQueryWrapper() .select(SysUser::getUserId, SysUser::getPhonenumber) - .eq(SysUser::getPhonenumber, user.getPhonenumber()).last("limit 1")); - if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue()) { + .eq(SysUser::getPhonenumber, user.getPhonenumber()) + .ne(SysUser::getUserId, userId)); + if (count > 0) { return UserConstants.NOT_UNIQUE; } return UserConstants.UNIQUE; @@ -196,10 +198,11 @@ public class SysUserServiceImpl extends ServicePlusImpl() + long count = count(new LambdaQueryWrapper() .select(SysUser::getUserId, SysUser::getEmail) - .eq(SysUser::getEmail, user.getEmail()).last("limit 1")); - if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue()) { + .eq(SysUser::getEmail, user.getEmail()) + .ne(SysUser::getUserId, userId)); + if (count > 0) { return UserConstants.NOT_UNIQUE; } return UserConstants.UNIQUE; diff --git a/ruoyi-system/src/main/resources/mapper/package-info.md b/ruoyi-system/src/main/resources/mapper/package-info.md new file mode 100644 index 000000000..c938b1e50 --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/package-info.md @@ -0,0 +1,3 @@ +java包使用 `.` 分割 resource 目录使用 `/` 分割 +
+此文件目的 防止文件夹粘连找不到 `xml` 文件 \ No newline at end of file diff --git a/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml index 756eb53f7..bfb543673 100644 --- a/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml @@ -117,7 +117,7 @@ order by m.parent_id, m.order_num - select m.menu_id from sys_menu m left join sys_role_menu rm on m.menu_id = rm.menu_id @@ -147,4 +147,4 @@ and ur.user_id = #{userId} - \ No newline at end of file + diff --git a/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml index 04788f760..5d9a18568 100644 --- a/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml @@ -189,12 +189,12 @@ diff --git a/ruoyi-ui/.env.development b/ruoyi-ui/.env.development index 3b003aa38..232d9077b 100644 --- a/ruoyi-ui/.env.development +++ b/ruoyi-ui/.env.development @@ -7,6 +7,9 @@ ENV = 'development' # 若依管理系统/开发环境 VUE_APP_BASE_API = '/dev-api' +# 应用访问路径 例如使用前缀 /admin/ +VUE_APP_CONTEXT_PATH = '/' + # 监控地址 VUE_APP_MONITRO_ADMIN = 'http://localhost:9090/admin/login' diff --git a/ruoyi-ui/.env.production b/ruoyi-ui/.env.production index 2d0bb6184..928000bda 100644 --- a/ruoyi-ui/.env.production +++ b/ruoyi-ui/.env.production @@ -4,6 +4,9 @@ VUE_APP_TITLE = RuoYi-Vue-Plus后台管理系统 # 生产环境配置 ENV = 'production' +# 应用访问路径 例如使用前缀 /admin/ +VUE_APP_CONTEXT_PATH = '/' + # 监控地址 VUE_APP_MONITRO_ADMIN = '/admin/login' diff --git a/ruoyi-ui/.env.staging b/ruoyi-ui/.env.staging index 49ce55c95..903abe658 100644 --- a/ruoyi-ui/.env.staging +++ b/ruoyi-ui/.env.staging @@ -6,6 +6,9 @@ NODE_ENV = production # 测试环境配置 ENV = 'staging' +# 应用访问路径 例如使用前缀 /admin/ +VUE_APP_CONTEXT_PATH = '/' + # 监控地址 VUE_APP_MONITRO_ADMIN = '/admin/login' diff --git a/ruoyi-ui/package.json b/ruoyi-ui/package.json index 89d591b34..bad8e7723 100644 --- a/ruoyi-ui/package.json +++ b/ruoyi-ui/package.json @@ -37,17 +37,17 @@ }, "dependencies": { "@riophae/vue-treeselect": "0.4.0", - "axios": "0.21.0", + "axios": "0.24.0", "clipboard": "2.0.6", - "core-js": "3.8.1", + "core-js": "3.19.1", "echarts": "4.9.0", "element-ui": "2.15.6", "file-saver": "2.0.5", "fuse.js": "6.4.3", "highlight.js": "9.18.5", "js-beautify": "1.13.0", - "js-cookie": "2.2.1", - "jsencrypt": "3.0.0-rc.1", + "js-cookie": "3.0.1", + "jsencrypt": "3.2.1", "nprogress": "0.2.0", "quill": "1.3.7", "screenfull": "5.0.2", @@ -55,7 +55,7 @@ "vue": "2.6.12", "vue-count-to": "1.0.13", "vue-cropper": "0.5.5", - "vue-meta": "^2.4.0", + "vue-meta": "2.4.0", "vue-router": "3.4.9", "vuedraggable": "2.24.3", "vuex": "3.6.0" diff --git a/ruoyi-ui/src/api/login.js b/ruoyi-ui/src/api/login.js index abd49c7de..0327e6f9a 100644 --- a/ruoyi-ui/src/api/login.js +++ b/ruoyi-ui/src/api/login.js @@ -10,6 +10,9 @@ export function login(username, password, code, uuid) { } return request({ url: '/login', + headers: { + isToken: false + }, method: 'post', data: data }) @@ -47,7 +50,10 @@ export function logout() { export function getCodeImg() { return request({ url: '/captchaImage', + headers: { + isToken: false + }, method: 'get', timeout: 20000 }) -} \ No newline at end of file +} diff --git a/ruoyi-ui/src/api/monitor/job.js b/ruoyi-ui/src/api/monitor/job.js deleted file mode 100644 index 58c43434a..000000000 --- a/ruoyi-ui/src/api/monitor/job.js +++ /dev/null @@ -1,80 +0,0 @@ -import request from '@/utils/request' - -// 查询定时任务调度列表 -export function listJob(query) { - return request({ - url: '/monitor/job/list', - method: 'get', - params: query - }) -} - -// 查询定时任务调度详细 -export function getJob(jobId) { - return request({ - url: '/monitor/job/' + jobId, - method: 'get' - }) -} - -// 新增定时任务调度 -export function addJob(data) { - return request({ - url: '/monitor/job', - method: 'post', - data: data - }) -} - -// 修改定时任务调度 -export function updateJob(data) { - return request({ - url: '/monitor/job', - method: 'put', - data: data - }) -} - -// 删除定时任务调度 -export function delJob(jobId) { - return request({ - url: '/monitor/job/' + jobId, - method: 'delete' - }) -} - -// 导出定时任务调度 -export function exportJob(query) { - return request({ - url: '/monitor/job/export', - method: 'get', - params: query - }) -} - -// 任务状态修改 -export function changeJobStatus(jobId, status) { - const data = { - jobId, - status - } - return request({ - url: '/monitor/job/changeStatus', - method: 'put', - data: data - }) -} - - -// 定时任务立即执行一次 -export function runJob(jobId, jobGroup) { - const data = { - jobId, - jobGroup - } - return request({ - url: '/monitor/job/run', - method: 'put', - data: data - }) -} \ No newline at end of file diff --git a/ruoyi-ui/src/api/monitor/jobLog.js b/ruoyi-ui/src/api/monitor/jobLog.js deleted file mode 100644 index 6e0be6166..000000000 --- a/ruoyi-ui/src/api/monitor/jobLog.js +++ /dev/null @@ -1,26 +0,0 @@ -import request from '@/utils/request' - -// 查询调度日志列表 -export function listJobLog(query) { - return request({ - url: '/monitor/jobLog/list', - method: 'get', - params: query - }) -} - -// 删除调度日志 -export function delJobLog(jobLogId) { - return request({ - url: '/monitor/jobLog/' + jobLogId, - method: 'delete' - }) -} - -// 清空调度日志 -export function cleanJobLog() { - return request({ - url: '/monitor/jobLog/clean', - method: 'delete' - }) -} diff --git a/ruoyi-ui/src/api/monitor/server.js b/ruoyi-ui/src/api/monitor/server.js deleted file mode 100644 index feed7836c..000000000 --- a/ruoyi-ui/src/api/monitor/server.js +++ /dev/null @@ -1,9 +0,0 @@ -import request from '@/utils/request' - -// 查询服务器详细 -export function getServer() { - return request({ - url: '/monitor/server', - method: 'get' - }) -} \ No newline at end of file diff --git a/ruoyi-ui/src/api/system/post.js b/ruoyi-ui/src/api/system/post.js index 434cd3513..1a8e9ca04 100644 --- a/ruoyi-ui/src/api/system/post.js +++ b/ruoyi-ui/src/api/system/post.js @@ -42,12 +42,3 @@ export function delPost(postId) { method: 'delete' }) } - -// 导出岗位 -export function exportPost(query) { - return request({ - url: '/system/post/export', - method: 'get', - params: query - }) -} \ No newline at end of file diff --git a/ruoyi-ui/src/components/Breadcrumb/index.vue b/ruoyi-ui/src/components/Breadcrumb/index.vue index 1fbae5f3c..1696f5471 100644 --- a/ruoyi-ui/src/components/Breadcrumb/index.vue +++ b/ruoyi-ui/src/components/Breadcrumb/index.vue @@ -2,7 +2,7 @@ - {{ item.meta.title }} + {{ item.meta.title }} {{ item.meta.title }} diff --git a/ruoyi-ui/src/components/RightToolbar/index.vue b/ruoyi-ui/src/components/RightToolbar/index.vue index c7ab139d7..976974e4a 100644 --- a/ruoyi-ui/src/components/RightToolbar/index.vue +++ b/ruoyi-ui/src/components/RightToolbar/index.vue @@ -62,7 +62,7 @@ export default { }, // 右侧列表元素变化 dataChange(data) { - for (var item in this.columns) { + for (let item in this.columns) { const key = this.columns[item].key; this.columns[item].visible = !data.includes(key); } diff --git a/ruoyi-ui/src/components/RuoYi/Doc/index.vue b/ruoyi-ui/src/components/RuoYi/Doc/index.vue index e267f9021..a60fd213a 100644 --- a/ruoyi-ui/src/components/RuoYi/Doc/index.vue +++ b/ruoyi-ui/src/components/RuoYi/Doc/index.vue @@ -1,6 +1,6 @@ diff --git a/ruoyi-ui/src/components/RuoYi/Git/index.vue b/ruoyi-ui/src/components/RuoYi/Git/index.vue index 4d580e418..faecbc178 100644 --- a/ruoyi-ui/src/components/RuoYi/Git/index.vue +++ b/ruoyi-ui/src/components/RuoYi/Git/index.vue @@ -1,6 +1,6 @@ diff --git a/ruoyi-ui/src/components/SizeSelect/index.vue b/ruoyi-ui/src/components/SizeSelect/index.vue index e88065b49..069b5de9b 100644 --- a/ruoyi-ui/src/components/SizeSelect/index.vue +++ b/ruoyi-ui/src/components/SizeSelect/index.vue @@ -5,8 +5,7 @@ - {{ - item.label }} + {{ item.label }} diff --git a/ruoyi-ui/src/layout/components/Navbar.vue b/ruoyi-ui/src/layout/components/Navbar.vue index e6721b70e..9de102c16 100644 --- a/ruoyi-ui/src/layout/components/Navbar.vue +++ b/ruoyi-ui/src/layout/components/Navbar.vue @@ -102,7 +102,7 @@ export default { type: 'warning' }).then(() => { this.$store.dispatch('LogOut').then(() => { - location.href = this.$router.options.base + '/index'; + location.href = process.env.VUE_APP_CONTEXT_PATH + "index"; }) }).catch(() => {}); } diff --git a/ruoyi-ui/src/layout/components/Sidebar/Logo.vue b/ruoyi-ui/src/layout/components/Sidebar/Logo.vue index 416968737..b8d9d6b7c 100644 --- a/ruoyi-ui/src/layout/components/Sidebar/Logo.vue +++ b/ruoyi-ui/src/layout/components/Sidebar/Logo.vue @@ -29,7 +29,7 @@ export default { variables() { return variables; }, - sideTheme() { + sideTheme() { return this.$store.state.settings.sideTheme } }, diff --git a/ruoyi-ui/src/layout/components/TagsView/index.vue b/ruoyi-ui/src/layout/components/TagsView/index.vue index 99bb28969..20c4b55e6 100644 --- a/ruoyi-ui/src/layout/components/TagsView/index.vue +++ b/ruoyi-ui/src/layout/components/TagsView/index.vue @@ -152,31 +152,24 @@ export default { }) }, refreshSelectedTag(view) { - this.$store.dispatch('tagsView/delCachedView', view).then(() => { - const { fullPath } = view - this.$nextTick(() => { - this.$router.replace({ - path: '/redirect' + fullPath - }) - }) - }) + this.$tab.refreshPage(view); }, closeSelectedTag(view) { - this.$store.dispatch('tagsView/delView', view).then(({ visitedViews }) => { + this.$tab.closePage(view).then(({ visitedViews }) => { if (this.isActive(view)) { this.toLastView(visitedViews, view) } }) }, closeRightTags() { - this.$store.dispatch('tagsView/delRightTags', this.selectedTag).then(visitedViews => { + this.$tab.closeRightPage(this.selectedTag).then(visitedViews => { if (!visitedViews.find(i => i.fullPath === this.$route.fullPath)) { this.toLastView(visitedViews) } }) }, closeLeftTags() { - this.$store.dispatch('tagsView/delLeftTags', this.selectedTag).then(visitedViews => { + this.$tab.closeLeftPage(this.selectedTag).then(visitedViews => { if (!visitedViews.find(i => i.fullPath === this.$route.fullPath)) { this.toLastView(visitedViews) } @@ -184,12 +177,12 @@ export default { }, closeOthersTags() { this.$router.push(this.selectedTag).catch(()=>{}); - this.$store.dispatch('tagsView/delOthersViews', this.selectedTag).then(() => { + this.$tab.closeOtherPage(this.selectedTag).then(() => { this.moveToCurrentTag() }) }, closeAllTags(view) { - this.$store.dispatch('tagsView/delAllViews').then(({ visitedViews }) => { + this.$tab.closeAllPage().then(({ visitedViews }) => { if (this.affixTags.some(tag => tag.path === this.$route.path)) { return } diff --git a/ruoyi-ui/src/layout/index.vue b/ruoyi-ui/src/layout/index.vue index 214d86ffe..8be418409 100644 --- a/ruoyi-ui/src/layout/index.vue +++ b/ruoyi-ui/src/layout/index.vue @@ -98,7 +98,7 @@ export default { } .hideSidebar .fixed-header { - width: calc(100% - 54px) + width: calc(100% - 54px); } .mobile .fixed-header { diff --git a/ruoyi-ui/src/main.js b/ruoyi-ui/src/main.js index c6306a65c..29c402265 100644 --- a/ruoyi-ui/src/main.js +++ b/ruoyi-ui/src/main.js @@ -10,8 +10,9 @@ import '@/assets/styles/ruoyi.scss' // ruoyi css import App from './App' import store from './store' import router from './router' -import directive from './directive' //directive +import directive from './directive' // directive import plugins from './plugins' // plugins +import { download } from '@/utils/request' import './assets/icons' // icon import './permission' // permission control @@ -43,6 +44,7 @@ Vue.prototype.resetForm = resetForm Vue.prototype.addDateRange = addDateRange Vue.prototype.selectDictLabel = selectDictLabel Vue.prototype.selectDictLabels = selectDictLabels +Vue.prototype.download = download Vue.prototype.handleTree = handleTree // 全局组件挂载 diff --git a/ruoyi-ui/src/plugins/download.js b/ruoyi-ui/src/plugins/download.js index ec7bdd497..ac50dade2 100644 --- a/ruoyi-ui/src/plugins/download.js +++ b/ruoyi-ui/src/plugins/download.js @@ -1,51 +1,12 @@ -import { saveAs } from 'file-saver' import axios from 'axios' -import { getToken } from '@/utils/auth' import { Message } from 'element-ui' +import { saveAs } from 'file-saver' +import { getToken } from '@/utils/auth' +import { blobValidate } from "@/utils/ruoyi"; const baseURL = process.env.VUE_APP_BASE_API export default { - excel(url, params) { - // get请求映射params参数 - if (params) { - let urlparams = url + '?'; - for (const propName of Object.keys(params)) { - const value = params[propName]; - var part = encodeURIComponent(propName) + "="; - if (value !== null && typeof(value) !== "undefined") { - if (typeof value === 'object') { - for (const key of Object.keys(value)) { - if (value[key] !== null && typeof (value[key]) !== 'undefined') { - let params = propName + '[' + key + ']'; - let subPart = encodeURIComponent(params) + '='; - urlparams += subPart + encodeURIComponent(value[key]) + '&'; - } - } - } else { - urlparams += part + encodeURIComponent(value) + "&"; - } - } - } - urlparams = urlparams.slice(0, -1); - url = urlparams; - } - url = baseURL + url - axios({ - method: 'get', - url: url, - responseType: 'blob', - headers: { 'Authorization': 'Bearer ' + getToken() } - }).then(async (res) => { - const isLogin = await this.blobValidate(res.data); - if (isLogin) { - const blob = new Blob([res.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }) - this.saveAs(blob, decodeURI(res.headers['download-filename'])) - } else { - Message.error('无效的会话,或者会话已过期,请重新登录。'); - } - }) - }, oss(ossId) { var url = baseURL + '/system/oss/download/' + ossId axios({ @@ -54,7 +15,7 @@ export default { responseType: 'blob', headers: { 'Authorization': 'Bearer ' + getToken() } }).then(async (res) => { - const isLogin = await this.blobValidate(res.data); + const isLogin = await blobValidate(res.data); if (isLogin) { const blob = new Blob([res.data], { type: 'application/octet-stream' }) this.saveAs(blob, decodeURI(res.headers['download-filename'])) @@ -71,7 +32,7 @@ export default { responseType: 'blob', headers: { 'Authorization': 'Bearer ' + getToken() } }).then(async (res) => { - const isLogin = await this.blobValidate(res.data); + const isLogin = await blobValidate(res.data); if (isLogin) { const blob = new Blob([res.data], { type: 'application/zip' }) this.saveAs(blob, name) @@ -82,15 +43,6 @@ export default { }, saveAs(text, name, opts) { saveAs(text, name, opts); - }, - async blobValidate(data) { - try { - const text = await data.text(); - JSON.parse(text); - return false; - } catch (error) { - return true; - } - }, + } } diff --git a/ruoyi-ui/src/plugins/index.js b/ruoyi-ui/src/plugins/index.js index 7cc83a4c8..9bc6eacd3 100644 --- a/ruoyi-ui/src/plugins/index.js +++ b/ruoyi-ui/src/plugins/index.js @@ -1,3 +1,4 @@ +import tab from './tab' import auth from './auth' import cache from './cache' import modal from './modal' @@ -5,6 +6,8 @@ import download from './download' export default { install(Vue) { + // 页签操作 + Vue.prototype.$tab = tab // 认证对象 Vue.prototype.$auth = auth // 缓存对象 diff --git a/ruoyi-ui/src/plugins/tab.js b/ruoyi-ui/src/plugins/tab.js new file mode 100644 index 000000000..95a3848b6 --- /dev/null +++ b/ruoyi-ui/src/plugins/tab.js @@ -0,0 +1,66 @@ +import store from '@/store' +import router from '@/router'; + +export default { + // 刷新当前tab页签 + refreshPage(obj) { + const { path, matched } = router.currentRoute; + if (obj === undefined) { + matched.forEach((m) => { + if (m.components && m.components.default && m.components.default.name) { + if (!['Layout', 'ParentView'].includes(m.components.default.name)) { + obj = { name: m.components.default.name, path: path }; + } + } + }); + } + return store.dispatch('tagsView/delCachedView', obj).then(() => { + const { path } = obj + router.replace({ + path: '/redirect' + path + }) + }) + }, + // 关闭当前tab页签,打开新页签 + closeOpenPage(obj) { + store.dispatch("tagsView/delView", router.currentRoute); + if (obj !== undefined) { + return router.push(obj); + } + }, + // 关闭指定tab页签 + closePage(obj) { + if (obj === undefined) { + return store.dispatch('tagsView/delView', router.currentRoute).then(({ lastPath }) => { + return router.push(lastPath || '/'); + }); + } + return store.dispatch('tagsView/delView', obj); + }, + // 关闭所有tab页签 + closeAllPage() { + return store.dispatch('tagsView/delAllViews'); + }, + // 关闭左侧tab页签 + closeLeftPage(obj) { + return store.dispatch('tagsView/delLeftTags', obj || router.currentRoute); + }, + // 关闭右侧tab页签 + closeRightPage(obj) { + return store.dispatch('tagsView/delRightTags', obj || router.currentRoute); + }, + // 关闭其他tab页签 + closeOtherPage(obj) { + return store.dispatch('tagsView/delOthersViews', obj || router.currentRoute); + }, + // 添加tab页签 + openPage(title, url) { + var obj = { path: url, meta: { title: title } } + store.dispatch('tagsView/addView', obj); + return router.push(url); + }, + // 修改tab页签 + updatePage(obj) { + return store.dispatch('tagsView/updateVisitedView', obj); + } +} diff --git a/ruoyi-ui/src/router/index.js b/ruoyi-ui/src/router/index.js index cedf0b3aa..cda6d4c3a 100644 --- a/ruoyi-ui/src/router/index.js +++ b/ruoyi-ui/src/router/index.js @@ -95,7 +95,7 @@ export const constantRoutes = [ path: 'role/:userId(\\d+)', component: (resolve) => require(['@/views/system/user/authRole'], resolve), name: 'AuthRole', - meta: { title: '分配角色', activeMenu: '/system/user'} + meta: { title: '分配角色', activeMenu: '/system/user' } } ] }, @@ -108,7 +108,7 @@ export const constantRoutes = [ path: 'user/:roleId(\\d+)', component: (resolve) => require(['@/views/system/role/authUser'], resolve), name: 'AuthUser', - meta: { title: '分配用户', activeMenu: '/system/role'} + meta: { title: '分配用户', activeMenu: '/system/role' } } ] }, @@ -121,7 +121,7 @@ export const constantRoutes = [ path: 'index/:dictId(\\d+)', component: (resolve) => require(['@/views/system/dict/data'], resolve), name: 'Data', - meta: { title: '字典数据', activeMenu: '/system/dict'} + meta: { title: '字典数据', activeMenu: '/system/dict' } } ] }, @@ -138,19 +138,6 @@ export const constantRoutes = [ } ] }, - { - path: '/monitor/job-log', - component: Layout, - hidden: true, - children: [ - { - path: 'index', - component: (resolve) => require(['@/views/monitor/job/log'], resolve), - name: 'JobLog', - meta: { title: '调度日志', activeMenu: '/monitor/job'} - } - ] - }, { path: '/tool/gen-edit', component: Layout, @@ -160,14 +147,13 @@ export const constantRoutes = [ path: 'index', component: (resolve) => require(['@/views/tool/gen/editTable'], resolve), name: 'GenEdit', - meta: { title: '修改生成配置', activeMenu: '/tool/gen'} + meta: { title: '修改生成配置', activeMenu: '/tool/gen' } } ] } ] export default new Router({ - base: "", // 项目前缀 与 publicPath 同步 例如 /api mode: 'history', // 去掉url中的# scrollBehavior: () => ({ y: 0 }), routes: constantRoutes diff --git a/ruoyi-ui/src/store/modules/permission.js b/ruoyi-ui/src/store/modules/permission.js index dba9252f4..8d84fff81 100644 --- a/ruoyi-ui/src/store/modules/permission.js +++ b/ruoyi-ui/src/store/modules/permission.js @@ -1,7 +1,7 @@ import { constantRoutes } from '@/router' import { getRouters } from '@/api/menu' import Layout from '@/layout/index' -import ParentView from '@/components/ParentView'; +import ParentView from '@/components/ParentView' import InnerLink from '@/layout/components/InnerLink' const permission = { @@ -24,7 +24,7 @@ const permission = { // 顶部导航菜单默认添加统计报表栏指向首页 const index = [{ path: 'index', - meta: { title: '统计报表', icon: 'dashboard'} + meta: { title: '统计报表', icon: 'dashboard' } }] state.topbarRouters = routes.concat(index); }, diff --git a/ruoyi-ui/src/store/modules/settings.js b/ruoyi-ui/src/store/modules/settings.js index 5f36d8eee..2455a1e27 100644 --- a/ruoyi-ui/src/store/modules/settings.js +++ b/ruoyi-ui/src/store/modules/settings.js @@ -8,7 +8,7 @@ const state = { theme: storageSetting.theme || '#409EFF', sideTheme: storageSetting.sideTheme || sideTheme, showSettings: showSettings, - topNav: storageSetting.topNav === undefined ? topNav : storageSetting.topNav, + topNav: storageSetting.topNav === undefined ? topNav : storageSetting.topNav, tagsView: storageSetting.tagsView === undefined ? tagsView : storageSetting.tagsView, fixedHeader: storageSetting.fixedHeader === undefined ? fixedHeader : storageSetting.fixedHeader, sidebarLogo: storageSetting.sidebarLogo === undefined ? sidebarLogo : storageSetting.sidebarLogo, diff --git a/ruoyi-ui/src/store/modules/tagsView.js b/ruoyi-ui/src/store/modules/tagsView.js index ef2fe4caf..002c1d099 100644 --- a/ruoyi-ui/src/store/modules/tagsView.js +++ b/ruoyi-ui/src/store/modules/tagsView.js @@ -14,7 +14,7 @@ const mutations = { }, ADD_CACHED_VIEW: (state, view) => { if (state.cachedViews.includes(view.name)) return - if (!view.meta.noCache) { + if (view.meta && !view.meta.noCache) { state.cachedViews.push(view.name) } }, @@ -63,7 +63,7 @@ const mutations = { } } }, - + DEL_RIGHT_VIEWS: (state, view) => { const index = state.visitedViews.findIndex(v => v.path === view.path) if (index === -1) { diff --git a/ruoyi-ui/src/utils/dict/index.js b/ruoyi-ui/src/utils/dict/index.js index 66ddfef9e..d6fdb802c 100644 --- a/ruoyi-ui/src/utils/dict/index.js +++ b/ruoyi-ui/src/utils/dict/index.js @@ -5,7 +5,7 @@ export default function(Vue, options) { mergeOptions(options) Vue.mixin({ data() { - if (this.$options.dicts === undefined || this.$options.dicts === null) { + if (this.$options === undefined || this.$options.dicts === undefined || this.$options.dicts === null) { return {} } const dict = new Dict() diff --git a/ruoyi-ui/src/utils/index.js b/ruoyi-ui/src/utils/index.js index 918580f7b..df5db12b0 100644 --- a/ruoyi-ui/src/utils/index.js +++ b/ruoyi-ui/src/utils/index.js @@ -5,12 +5,12 @@ import { parseTime } from './ruoyi' */ export function formatDate(cellValue) { if (cellValue == null || cellValue == "") return ""; - var date = new Date(cellValue) + var date = new Date(cellValue) var year = date.getFullYear() var month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1 - var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate() - var hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours() - var minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes() + var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate() + var hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours() + var minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes() var seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds() return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds } @@ -330,7 +330,7 @@ export function makeMap(str, expectsLowerCase) { ? val => map[val.toLowerCase()] : val => map[val] } - + export const exportDefault = 'export default ' export const beautifierConf = { @@ -381,10 +381,10 @@ export function titleCase(str) { // 下划转驼峰 export function camelCase(str) { - return str.replace(/-[a-z]/g, str1 => str1.substr(-1).toUpperCase()) + return str.replace(/_[a-z]/g, str1 => str1.substr(-1).toUpperCase()) } export function isNumberStr(str) { return /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(str) } - + diff --git a/ruoyi-ui/src/utils/request.js b/ruoyi-ui/src/utils/request.js index e8b3b5f16..d376a76a5 100644 --- a/ruoyi-ui/src/utils/request.js +++ b/ruoyi-ui/src/utils/request.js @@ -1,8 +1,12 @@ import axios from 'axios' -import { Notification, MessageBox, Message } from 'element-ui' +import { Notification, MessageBox, Message, Loading } from 'element-ui' import store from '@/store' import { getToken } from '@/utils/auth' import errorCode from '@/utils/errorCode' +import { tansParams, blobValidate } from "@/utils/ruoyi"; +import { saveAs } from 'file-saver' + +let downloadLoadingInstance; axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8' // 对应国际化资源文件后缀 @@ -14,6 +18,7 @@ const service = axios.create({ // 超时 timeout: 10000 }) + // request拦截器 service.interceptors.request.use(config => { // 是否需要设置 token @@ -23,24 +28,7 @@ service.interceptors.request.use(config => { } // get请求映射params参数 if (config.method === 'get' && config.params) { - let url = config.url + '?'; - for (const propName of Object.keys(config.params)) { - const value = config.params[propName]; - var part = encodeURIComponent(propName) + "="; - if (value !== null && typeof(value) !== "undefined") { - if (typeof value === 'object') { - for (const key of Object.keys(value)) { - if (value[key] !== null && typeof (value[key]) !== 'undefined') { - let params = propName + '[' + key + ']'; - let subPart = encodeURIComponent(params) + '='; - url += subPart + encodeURIComponent(value[key]) + '&'; - } - } - } else { - url += part + encodeURIComponent(value) + "&"; - } - } - } + let url = config.url + '?' + tansParams(config.params); url = url.slice(0, -1); config.params = {}; config.url = url; @@ -57,6 +45,10 @@ service.interceptors.response.use(res => { const code = res.data.code || 200; // 获取错误信息 const msg = errorCode[code] || res.data.msg || errorCode['default'] + // 二进制数据则直接返回 + if(res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer'){ + return res.data + } if (code === 401) { MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', @@ -65,7 +57,7 @@ service.interceptors.response.use(res => { } ).then(() => { store.dispatch('LogOut').then(() => { - location.href = this.$router.options.base + '/index'; + location.href = process.env.VUE_APP_CONTEXT_PATH + "index"; }) }).catch(() => {}); return Promise.reject('无效的会话,或者会话已过期,请重新登录。') @@ -105,4 +97,27 @@ service.interceptors.response.use(res => { } ) +// 通用下载方法 +export function download(url, params, filename) { + downloadLoadingInstance = Loading.service({ text: "正在下载数据,请稍候", spinner: "el-icon-loading", background: "rgba(0, 0, 0, 0.7)", }) + return service.post(url, params, { + transformRequest: [(params) => { return tansParams(params) }], + headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, + responseType: 'blob' + }).then(async (data) => { + const isLogin = await blobValidate(data); + if (isLogin) { + const blob = new Blob([data]) + saveAs(blob, filename) + } else { + Message.error('无效的会话,或者会话已过期,请重新登录。'); + } + downloadLoadingInstance.close(); + }).catch((r) => { + console.error(r) + Message.error('下载文件出现错误,请联系管理员!') + downloadLoadingInstance.close(); + }) +} + export default service diff --git a/ruoyi-ui/src/utils/ruoyi.js b/ruoyi-ui/src/utils/ruoyi.js index 63bd379b7..4cc5e24ea 100644 --- a/ruoyi-ui/src/utils/ruoyi.js +++ b/ruoyi-ui/src/utils/ruoyi.js @@ -85,8 +85,8 @@ export function selectDictLabels(datas, value, separator) { var temp = value.split(currentSeparator); Object.keys(value.split(currentSeparator)).some((val) => { Object.keys(datas).some((key) => { - if (datas[key].dictValue == ('' + temp[val])) { - actions.push(datas[key].dictLabel + currentSeparator); + if (datas[key].value == ('' + temp[val])) { + actions.push(datas[key].label + currentSeparator); } }) }) @@ -181,3 +181,40 @@ export function handleTree(data, id, parentId, children) { } return tree; } + +/** +* 参数处理 +* @param {*} params 参数 +*/ +export function tansParams(params) { + let result = '' + for (const propName of Object.keys(params)) { + const value = params[propName]; + var part = encodeURIComponent(propName) + "="; + if (value !== null && typeof (value) !== "undefined") { + if (typeof value === 'object') { + for (const key of Object.keys(value)) { + if (value[key] !== null && typeof (value[key]) !== 'undefined') { + let params = propName + '[' + key + ']'; + var subPart = encodeURIComponent(params) + "="; + result += subPart + encodeURIComponent(value[key]) + "&"; + } + } + } else { + result += part + encodeURIComponent(value) + "&"; + } + } + } + return result +} + +// 验证是否为blob格式 +export async function blobValidate(data) { + try { + const text = await data.text(); + JSON.parse(text); + return false; + } catch (error) { + return true; + } +} diff --git a/ruoyi-ui/src/views/demo/demo/index.vue b/ruoyi-ui/src/views/demo/demo/index.vue index 678ae218a..65387c9a5 100644 --- a/ruoyi-ui/src/views/demo/demo/index.vue +++ b/ruoyi-ui/src/views/demo/demo/index.vue @@ -71,13 +71,22 @@ v-hasPermi="['demo:demo:remove']" >删除 + + 导入(校验) + 导出 @@ -165,11 +174,34 @@ 取 消 + + + + +

将文件拖到此处,或点击上传
+ + + diff --git a/ruoyi-ui/src/views/monitor/job/log.vue b/ruoyi-ui/src/views/monitor/job/log.vue deleted file mode 100644 index fca1af40e..000000000 --- a/ruoyi-ui/src/views/monitor/job/log.vue +++ /dev/null @@ -1,300 +0,0 @@ - - - diff --git a/ruoyi-ui/src/views/monitor/logininfor/index.vue b/ruoyi-ui/src/views/monitor/logininfor/index.vue index 5b113016d..98bd74357 100644 --- a/ruoyi-ui/src/views/monitor/logininfor/index.vue +++ b/ruoyi-ui/src/views/monitor/logininfor/index.vue @@ -6,8 +6,8 @@ v-model="queryParams.ipaddr" placeholder="请输入登录地址" clearable + size="small" style="width: 240px;" - size="small" @keyup.enter.native="handleQuery" /> @@ -16,8 +16,8 @@ v-model="queryParams.userName" placeholder="请输入用户名称" clearable + size="small" style="width: 240px;" - size="small" @keyup.enter.native="handleQuery" /> @@ -83,7 +83,6 @@ plain icon="el-icon-download" size="mini" - :loading="exportLoading" @click="handleExport" v-hasPermi="['monitor:logininfor:export']" >导出 @@ -132,8 +131,6 @@ export default { return { // 遮罩层 loading: true, - // 导出遮罩层 - exportLoading: false, // 选中数组 ids: [], // 非多个禁用 @@ -216,7 +213,9 @@ export default { }, /** 导出按钮操作 */ handleExport() { - this.$download.excel('/monitor/logininfor/export', this.queryParams); + this.download('monitor/logininfor/export', { + ...this.queryParams + }, `logininfor_${new Date().getTime()}.xlsx`) } } }; diff --git a/ruoyi-ui/src/views/monitor/operlog/index.vue b/ruoyi-ui/src/views/monitor/operlog/index.vue index 35fd2b812..9b8b7856b 100644 --- a/ruoyi-ui/src/views/monitor/operlog/index.vue +++ b/ruoyi-ui/src/views/monitor/operlog/index.vue @@ -6,8 +6,8 @@ v-model="queryParams.title" placeholder="请输入系统模块" clearable - style="width: 240px;" size="small" + style="width: 240px;" @keyup.enter.native="handleQuery" /> @@ -16,8 +16,8 @@ v-model="queryParams.operName" placeholder="请输入操作人员" clearable - style="width: 240px;" size="small" + style="width: 240px;" @keyup.enter.native="handleQuery" /> @@ -99,7 +99,6 @@ plain icon="el-icon-download" size="mini" - :loading="exportLoading" @click="handleExport" v-hasPermi="['monitor:operlog:export']" >导出 @@ -205,8 +204,6 @@ export default { return { // 遮罩层 loading: true, - // 导出遮罩层 - exportLoading: false, // 选中数组 ids: [], // 非多个禁用 @@ -303,7 +300,9 @@ export default { }, /** 导出按钮操作 */ handleExport() { - this.$download.excel('/monitor/operlog/export', this.queryParams); + this.download('monitor/operlog/export', { + ...this.queryParams + }, `operlog_${new Date().getTime()}.xlsx`) } } }; diff --git a/ruoyi-ui/src/views/register.vue b/ruoyi-ui/src/views/register.vue index 393f100d3..759931492 100644 --- a/ruoyi-ui/src/views/register.vue +++ b/ruoyi-ui/src/views/register.vue @@ -127,7 +127,8 @@ export default { register(this.registerForm).then(res => { const username = this.registerForm.username; this.$alert("恭喜你,您的账号 " + username + " 注册成功!", '系统提示', { - dangerouslyUseHTMLString: true + dangerouslyUseHTMLString: true, + type: 'success' }).then(() => { this.$router.push("/login"); }).catch(() => {}); diff --git a/ruoyi-ui/src/views/system/config/index.vue b/ruoyi-ui/src/views/system/config/index.vue index b03791755..9fde370f7 100644 --- a/ruoyi-ui/src/views/system/config/index.vue +++ b/ruoyi-ui/src/views/system/config/index.vue @@ -88,7 +88,6 @@ plain icon="el-icon-download" size="mini" - :loading="exportLoading" @click="handleExport" v-hasPermi="['system:config:export']" >导出 @@ -194,8 +193,6 @@ export default { return { // 遮罩层 loading: true, - // 导出遮罩层 - exportLoading: false, // 选中数组 ids: [], // 非单个禁用 @@ -334,7 +331,9 @@ export default { }, /** 导出按钮操作 */ handleExport() { - this.$download.excel('/system/config/export', this.queryParams); + this.download('system/config/export', { + ...this.queryParams + }, `config_${new Date().getTime()}.xlsx`) }, /** 刷新缓存按钮操作 */ handleRefreshCache() { diff --git a/ruoyi-ui/src/views/system/dept/index.vue b/ruoyi-ui/src/views/system/dept/index.vue index f9c7741e5..e215b1c8e 100644 --- a/ruoyi-ui/src/views/system/dept/index.vue +++ b/ruoyi-ui/src/views/system/dept/index.vue @@ -179,8 +179,6 @@ export default { isExpandAll: true, // 重新渲染表格状态 refreshTable: true, - // 是否展开 - expand: false, // 查询参数 queryParams: { deptName: undefined, @@ -276,7 +274,7 @@ export default { this.open = true; this.title = "添加部门"; listDept().then(response => { - this.deptOptions = this.handleTree(response.data, "deptId"); + this.deptOptions = this.handleTree(response.data, "deptId"); }); }, /** 展开/折叠操作 */ @@ -296,7 +294,7 @@ export default { this.title = "修改部门"; }); listDeptExcludeChild(row.deptId).then(response => { - this.deptOptions = this.handleTree(response.data, "deptId"); + this.deptOptions = this.handleTree(response.data, "deptId"); }); }, /** 提交按钮 */ diff --git a/ruoyi-ui/src/views/system/dict/data.vue b/ruoyi-ui/src/views/system/dict/data.vue index c7a90067e..bf538ad90 100644 --- a/ruoyi-ui/src/views/system/dict/data.vue +++ b/ruoyi-ui/src/views/system/dict/data.vue @@ -75,11 +75,19 @@ plain icon="el-icon-download" size="mini" - :loading="exportLoading" @click="handleExport" v-hasPermi="['system:dict:export']" >导出 + + 关闭 + @@ -193,8 +201,6 @@ export default { return { // 遮罩层 loading: true, - // 导出遮罩层 - exportLoading: false, // 选中数组 ids: [], // 非单个禁用 @@ -319,6 +325,11 @@ export default { this.queryParams.pageNum = 1; this.getList(); }, + /** 返回按钮操作 */ + handleClose() { + const obj = { path: "/system/dict" }; + this.$tab.closeOpenPage(obj); + }, /** 重置按钮操作 */ resetQuery() { this.resetForm("queryForm"); @@ -380,8 +391,10 @@ export default { }, /** 导出按钮操作 */ handleExport() { - this.$download.excel('/system/dict/data/export', this.queryParams); + this.download('system/dict/data/export', { + ...this.queryParams + }, `data_${new Date().getTime()}.xlsx`) } } }; - \ No newline at end of file + diff --git a/ruoyi-ui/src/views/system/dict/index.vue b/ruoyi-ui/src/views/system/dict/index.vue index 6daa8679c..92b78c98b 100644 --- a/ruoyi-ui/src/views/system/dict/index.vue +++ b/ruoyi-ui/src/views/system/dict/index.vue @@ -94,7 +94,6 @@ plain icon="el-icon-download" size="mini" - :loading="exportLoading" @click="handleExport" v-hasPermi="['system:dict:export']" >导出 @@ -202,8 +201,6 @@ export default { return { // 遮罩层 loading: true, - // 导出遮罩层 - exportLoading: false, // 选中数组 ids: [], // 非单个禁用 @@ -338,7 +335,9 @@ export default { }, /** 导出按钮操作 */ handleExport() { - this.$download.excel('/system/dict/type/export', this.queryParams); + this.download('system/dict/type/export', { + ...this.queryParams + }, `type_${new Date().getTime()}.xlsx`) }, /** 刷新缓存按钮操作 */ handleRefreshCache() { @@ -348,4 +347,4 @@ export default { } } }; - \ No newline at end of file + diff --git a/ruoyi-ui/src/views/system/menu/index.vue b/ruoyi-ui/src/views/system/menu/index.vue index a89e1ee71..d65773ad2 100644 --- a/ruoyi-ui/src/views/system/menu/index.vue +++ b/ruoyi-ui/src/views/system/menu/index.vue @@ -78,7 +78,8 @@ - + @@ -109,9 +109,9 @@ export default { }, /** 关闭按钮 */ close() { - this.$store.dispatch("tagsView/delView", this.$route); - this.$router.push({ path: "/system/user" }); + const obj = { path: "/system/user" }; + this.$tab.closeOpenPage(obj); }, }, }; - \ No newline at end of file + diff --git a/ruoyi-ui/src/views/system/user/index.vue b/ruoyi-ui/src/views/system/user/index.vue index 4faa25020..1ff9b906b 100644 --- a/ruoyi-ui/src/views/system/user/index.vue +++ b/ruoyi-ui/src/views/system/user/index.vue @@ -131,7 +131,6 @@ plain icon="el-icon-download" size="mini" - :loading="exportLoading" @click="handleExport" v-hasPermi="['system:user:export']" >导出 @@ -207,7 +206,7 @@ - + @@ -360,8 +359,6 @@ export default { return { // 遮罩层 loading: true, - // 导出遮罩层 - exportLoading: false, // 选中数组 ids: [], // 非单个禁用 @@ -643,7 +640,9 @@ export default { }, /** 导出按钮操作 */ handleExport() { - this.$download.excel('/system/user/export', this.queryParams); + this.download('system/user/export', { + ...this.queryParams + }, `user_${new Date().getTime()}.xlsx`) }, /** 导入按钮操作 */ handleImport() { @@ -652,7 +651,8 @@ export default { }, /** 下载模板操作 */ importTemplate() { - this.$download.excel('/system/user/importTemplate'); + this.download('system/user/importTemplate', { + }, `user_template_${new Date().getTime()}.xlsx`) }, // 文件上传中处理 handleFileUploadProgress(event, file, fileList) { @@ -672,4 +672,4 @@ export default { } } }; - \ No newline at end of file + diff --git a/ruoyi-ui/src/views/system/user/profile/resetPwd.vue b/ruoyi-ui/src/views/system/user/profile/resetPwd.vue index 119f1036f..0a8d216b1 100644 --- a/ruoyi-ui/src/views/system/user/profile/resetPwd.vue +++ b/ruoyi-ui/src/views/system/user/profile/resetPwd.vue @@ -29,7 +29,6 @@ export default { } }; return { - test: "1test", user: { oldPassword: undefined, newPassword: undefined, @@ -55,17 +54,14 @@ export default { submit() { this.$refs["form"].validate(valid => { if (valid) { - updateUserPwd(this.user.oldPassword, this.user.newPassword).then( - response => { - this.$modal.msgSuccess("修改成功"); - } - ); + updateUserPwd(this.user.oldPassword, this.user.newPassword).then(response => { + this.$modal.msgSuccess("修改成功"); + }); } }); }, close() { - this.$store.dispatch("tagsView/delView", this.$route); - this.$router.push({ path: "/index" }); + this.$tab.closePage(); } } }; diff --git a/ruoyi-ui/src/views/system/user/profile/userAvatar.vue b/ruoyi-ui/src/views/system/user/profile/userAvatar.vue index 08652c2f7..d094602a2 100644 --- a/ruoyi-ui/src/views/system/user/profile/userAvatar.vue +++ b/ruoyi-ui/src/views/system/user/profile/userAvatar.vue @@ -1,7 +1,7 @@