疯狂的狮子li
2020-07-20 1e79d6f56fbd9a054800f1c62fd95bacda37c6b3
同步升级3.0
已添加202个文件
已复制1个文件
已重命名78个文件
已删除190个文件
已修改3个文件
46901 ■■■■ 文件已修改
.gitignore 补丁 | 查看 | 原始文档 | blame | 历史
bin/clean.bat 补丁 | 查看 | 原始文档 | blame | 历史
bin/package.bat 补丁 | 查看 | 原始文档 | blame | 历史
bin/run.bat 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
doc/若依环境使用手册.docx 补丁 | 查看 | 原始文档 | blame | 历史
pom.xml 258 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/pom.xml 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/RuoYiServletInitializer.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/ServerController.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysLogininforController.java 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysOperlogController.java 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysUserOnlineController.java 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysConfigController.java 135 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDeptController.java 163 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictDataController.java 113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictTypeController.java 131 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysMenuController.java 153 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysNoticeController.java 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysPostController.java 130 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java 127 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java 154 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java 201 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/SwaggerController.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/TestController.java 175 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/core/config/SwaggerConfig.java 125 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/META-INF/spring-devtools.properties 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/application-dev.yml 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/application-prop.yml 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/application.yml 125 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/banner.txt 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/i18n/messages.properties 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/logback.xml 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/mybatis/mybatis-config.xml 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/pom.xml 141 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/annotation/DataScope.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/annotation/DataSource.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/annotation/Excel.java 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/annotation/Excels.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/annotation/Log.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/annotation/RepeatSubmit.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/config/RuoYiConfig.java 116 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/constant/GenConstants.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/constant/HttpStatus.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/constant/ScheduleConstants.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/constant/UserConstants.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/core/controller/BaseController.java 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/AjaxResult.java 148 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/BaseEntity.java 143 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/TreeEntity.java 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/TreeSelect.java 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDept.java 202 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDictData.java 176 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDictType.java 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysMenu.java 231 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysRole.java 198 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java 328 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginBody.java 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginUser.java 228 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/core/page/PageDomain.java 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/core/page/TableDataInfo.java 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/core/page/TableSupport.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisCache.java 227 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/core/text/CharsetKit.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/core/text/Convert.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/core/text/StrFormatter.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/enums/BusinessStatus.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/enums/BusinessType.java 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/enums/DataSourceType.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/enums/HttpMethod.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/enums/OperatorType.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/enums/UserStatus.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/exception/BaseException.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/exception/CustomException.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/exception/DemoModeException.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/exception/UtilException.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/exception/file/FileException.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/exception/file/FileNameLengthLimitExceededException.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/exception/file/FileSizeLimitExceededException.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/exception/file/InvalidExtensionException.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/exception/job/TaskException.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/exception/user/CaptchaException.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/exception/user/CaptchaExpireException.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/exception/user/UserException.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/exception/user/UserPasswordNotMatchException.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/filter/RepeatableFilter.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/filter/RepeatedlyRequestWrapper.java 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/filter/XssFilter.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/filter/XssHttpServletRequestWrapper.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/Arith.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/DictUtils.java 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/ExceptionUtil.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/LogUtils.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/MessageUtils.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/SecurityUtils.java 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/ServletUtils.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/StringUtils.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/Threads.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/VerifyCodeUtils.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/bean/BeanUtils.java 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUploadUtils.java 232 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUtils.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/file/MimeTypeUtils.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/html/EscapeUtil.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/html/HTMLFilter.java 569 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpHelper.java 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpUtils.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/ip/AddressUtils.java 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/ip/IpUtils.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java 875 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/reflect/ReflectUtils.java 406 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/sign/Base64.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/sign/Md5Utils.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/spring/SpringUtils.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/sql/SqlUtil.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/uuid/IdUtils.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/uuid/UUID.java 484 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/resources/application-dev.yml 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/resources/application-prop.yml 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/resources/application-test.yml 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/pom.xml 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/DataScopeAspect.java 165 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/DataSourceAspect.java 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java 217 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/config/ApplicationConfig.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/config/DruidConfig.java 126 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/config/FastJson2JsonRedisSerializer.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/config/FilterConfig.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/config/MyBatisConfig.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/config/RedisConfig.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/config/ServerConfig.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/config/ThreadPoolConfig.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/DruidProperties.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/datasource/DynamicDataSource.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/datasource/DynamicDataSourceContextHolder.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/RepeatSubmitInterceptor.java 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/impl/SameUrlDataInterceptor.java 107 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/manager/AsyncManager.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/manager/ShutdownManager.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/manager/factory/AsyncFactory.java 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/security/filter/JwtAuthenticationTokenFilter.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/security/handle/AuthenticationEntryPointImpl.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/security/handle/LogoutSuccessHandlerImpl.java 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/Server.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/Cpu.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/Jvm.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/Mem.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/Sys.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/SysFile.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java 117 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/PermissionService.java 169 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysPermissionService.java 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java 219 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/UserDetailsServiceImpl.java 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-generator/pom.xml 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-generator/src/main/java/com/ruoyi/generator/config/GenConfig.java 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-generator/src/main/java/com/ruoyi/generator/controller/GenController.java 186 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-generator/src/main/java/com/ruoyi/generator/domain/GenTable.java 271 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-generator/src/main/java/com/ruoyi/generator/domain/GenTableColumn.java 368 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-generator/src/main/java/com/ruoyi/generator/mapper/GenTableColumnMapper.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-generator/src/main/java/com/ruoyi/generator/mapper/GenTableMapper.java 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableColumnServiceImpl.java 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableServiceImpl.java 345 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-generator/src/main/java/com/ruoyi/generator/service/IGenTableColumnService.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-generator/src/main/java/com/ruoyi/generator/service/IGenTableService.java 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-generator/src/main/java/com/ruoyi/generator/util/GenUtils.java 242 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityInitializer.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityUtils.java 298 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-generator/src/main/resources/generator.yml 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-generator/src/main/resources/mapper/generator/GenTableColumnMapper.xml 120 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-generator/src/main/resources/mapper/generator/GenTableMapper.xml 181 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-generator/src/main/resources/vm/java/controller.java.vm 197 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-generator/src/main/resources/vm/java/domain.java.vm 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-generator/src/main/resources/vm/java/mapper.java.vm 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-generator/src/main/resources/vm/java/service.java.vm 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-generator/src/main/resources/vm/java/serviceImpl.java.vm 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-generator/src/main/resources/vm/js/api.js.vm 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-generator/src/main/resources/vm/sql/sql.vm 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-generator/src/main/resources/vm/vue/index-tree.vue.vm 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-generator/src/main/resources/vm/vue/index.vue.vm 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-generator/src/main/resources/vm/xml/mapper.xml.vm 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-quartz/pom.xml 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-quartz/src/main/java/com/ruoyi/quartz/config/MybatisPlusConfig.java 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-quartz/src/main/java/com/ruoyi/quartz/config/ScheduleConfig.java 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobController.java 142 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobLogController.java 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/SysJob.java 172 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/SysJobLog.java 155 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/SysJobLogMapper.java 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/SysJobMapper.java 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/ISysJobLogService.java 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/ISysJobService.java 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/impl/SysJobLogServiceImpl.java 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/impl/SysJobServiceImpl.java 254 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/AbstractQuartzJob.java 107 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/CronUtils.java 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/JobInvokeUtil.java 182 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/QuartzDisallowConcurrentExecution.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/QuartzJobExecution.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/ScheduleUtils.java 113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-quartz/src/main/resources/mapper/quartz/SysJobLogMapper.xml 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-quartz/src/main/resources/mapper/quartz/SysJobMapper.xml 111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/pom.xml 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysConfig.java 111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysLogininfor.java 144 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysNotice.java 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysOperLog.java 255 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysPost.java 123 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysRoleDept.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysRoleMenu.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUserOnline.java 113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUserPost.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUserRole.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/MetaVo.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/RouterVo.java 133 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysConfigMapper.java 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDeptMapper.java 117 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDictDataMapper.java 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDictTypeMapper.java 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysLogininforMapper.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysMenuMapper.java 116 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysNoticeMapper.java 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysOperLogMapper.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysPostMapper.java 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleDeptMapper.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMapper.java 107 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMenuMapper.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java 111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserPostMapper.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserRoleMapper.java 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysConfigService.java 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDeptService.java 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictDataService.java 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictTypeService.java 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysLogininforService.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysMenuService.java 136 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysNoticeService.java 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysOperLogService.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysPostService.java 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysRoleService.java 131 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserOnlineService.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java 167 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigServiceImpl.java 188 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java 306 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictDataServiceImpl.java 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictTypeServiceImpl.java 204 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysLogininforServiceImpl.java 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java 445 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysNoticeServiceImpl.java 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOperLogServiceImpl.java 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysPostServiceImpl.java 179 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java 318 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserOnlineServiceImpl.java 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java 457 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/SysConfigMapper.xml 112 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml 155 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/SysDictDataMapper.xml 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/SysDictTypeMapper.xml 105 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/SysLogininforMapper.xml 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml 185 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/SysNoticeMapper.xml 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/SysOperLogMapper.xml 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/SysPostMapper.xml 122 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/SysRoleDeptMapper.xml 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/SysRoleMapper.xml 145 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml 182 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/SysUserPostMapper.xml 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/SysUserRoleMapper.xml 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/package.json 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/utils/index.js 33 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/vue.config.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/bin/run-tomcat.bat 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/pom.xml 318 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/ry.sh 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/sql/quartz.sql 170 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/common/constant/Constants.java 126 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/common/constant/ScheduleConstants.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/common/core/lang/UUID.java 484 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/common/exception/job/TaskException.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/common/filter/RepeatableFilter.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/common/filter/RepeatedlyRequestWrapper.java 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/common/utils/DictUtils.java 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/common/utils/ExceptionUtil.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/common/utils/IdUtils.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/common/utils/SecurityUtils.java 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/common/utils/bean/BeanUtils.java 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/common/utils/file/FileUploadUtils.java 232 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/common/utils/html/HTMLFilter.java 569 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/common/utils/http/HttpHelper.java 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/common/utils/ip/AddressUtils.java 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/common/utils/job/AbstractQuartzJob.java 107 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/common/utils/job/CronUtils.java 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/common/utils/job/JobInvokeUtil.java 182 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/common/utils/job/QuartzDisallowConcurrentExecution.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/common/utils/job/QuartzJobExecution.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/common/utils/job/ScheduleUtils.java 113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java 875 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/common/utils/reflect/ReflectUtils.java 406 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/aspectj/DataScopeAspect.java 165 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/aspectj/DataSourceAspect.java 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java 217 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/DataScope.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/DataSource.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/Excel.java 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/Excels.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/Log.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/enums/BusinessStatus.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/enums/BusinessType.java 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/enums/DataSourceType.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/enums/OperatorType.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/config/ApplicationConfig.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/config/DruidConfig.java 126 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/config/GenConfig.java 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/config/RuoYiConfig.java 116 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/config/ScheduleConfig.java 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/interceptor/RepeatSubmitInterceptor.java 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/interceptor/annotation/RepeatSubmit.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/interceptor/impl/SameUrlDataInterceptor.java 107 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/manager/factory/AsyncFactory.java 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/redis/RedisCache.java 227 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/security/LoginBody.java 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/security/LoginUser.java 228 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/security/filter/JwtAuthenticationTokenFilter.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/security/handle/AuthenticationEntryPointImpl.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/security/handle/LogoutSuccessHandlerImpl.java 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/security/service/PermissionService.java 169 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/security/service/SysLoginService.java 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/security/service/SysPermissionService.java 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/security/service/TokenService.java 219 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/security/service/UserDetailsServiceImpl.java 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/task/RyTask.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/web/controller/BaseController.java 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/web/domain/AjaxResult.java 148 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/web/domain/BaseEntity.java 143 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/web/domain/TreeEntity.java 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/web/domain/TreeSelect.java 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java 117 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/web/page/PageDomain.java 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/web/page/TableDataInfo.java 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/web/page/TableSupport.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/common/CaptchaController.java 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/common/CommonController.java 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/monitor/controller/ServerController.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/monitor/controller/SysJobController.java 142 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/monitor/controller/SysJobLogController.java 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/monitor/controller/SysLogininforController.java 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/monitor/controller/SysOperlogController.java 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/monitor/controller/SysUserOnlineController.java 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/monitor/domain/SysJob.java 172 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/monitor/domain/SysJobLog.java 155 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/monitor/domain/SysLogininfor.java 144 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/monitor/domain/SysOperLog.java 255 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/monitor/domain/SysUserOnline.java 113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/monitor/mapper/SysJobLogMapper.java 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/monitor/mapper/SysJobMapper.java 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/monitor/mapper/SysLogininforMapper.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/monitor/mapper/SysOperLogMapper.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/monitor/service/ISysJobLogService.java 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/monitor/service/ISysJobService.java 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/monitor/service/ISysLogininforService.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/monitor/service/ISysOperLogService.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/monitor/service/impl/SysJobLogServiceImpl.java 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/monitor/service/impl/SysJobServiceImpl.java 254 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/monitor/service/impl/SysLogininforServiceImpl.java 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/monitor/service/impl/SysOperLogServiceImpl.java 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/controller/SysConfigController.java 133 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/controller/SysDeptController.java 163 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/controller/SysDictDataController.java 113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/controller/SysDictTypeController.java 131 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/controller/SysLoginController.java 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/controller/SysMenuController.java 153 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/controller/SysNoticeController.java 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/controller/SysPostController.java 130 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/controller/SysProfileController.java 127 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/controller/SysRoleController.java 154 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/controller/SysUserController.java 201 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/domain/SysConfig.java 111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/domain/SysDept.java 202 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/domain/SysDictData.java 176 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/domain/SysDictType.java 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/domain/SysMenu.java 231 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/domain/SysNotice.java 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/domain/SysPost.java 123 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/domain/SysRole.java 198 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/domain/SysRoleDept.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/domain/SysRoleMenu.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/domain/SysUser.java 326 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/domain/SysUserPost.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/domain/SysUserRole.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/domain/vo/MetaVo.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/domain/vo/RouterVo.java 133 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysConfigMapper.java 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysDeptMapper.java 117 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysDictDataMapper.java 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysDictTypeMapper.java 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysMenuMapper.java 116 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysNoticeMapper.java 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysPostMapper.java 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysRoleDeptMapper.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysRoleMapper.java 107 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysRoleMenuMapper.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysUserMapper.java 113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysUserPostMapper.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysUserRoleMapper.java 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/service/ISysConfigService.java 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/service/ISysDeptService.java 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/service/ISysDictDataService.java 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/service/ISysDictTypeService.java 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/service/ISysMenuService.java 136 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/service/ISysNoticeService.java 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/service/ISysPostService.java 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/service/ISysRoleService.java 131 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/service/ISysUserOnlineService.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/service/ISysUserService.java 167 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysConfigServiceImpl.java 185 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysDeptServiceImpl.java 306 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysDictDataServiceImpl.java 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysDictTypeServiceImpl.java 204 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysMenuServiceImpl.java 445 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysNoticeServiceImpl.java 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysPostServiceImpl.java 179 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysRoleServiceImpl.java 318 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysUserOnlineServiceImpl.java 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysUserServiceImpl.java 457 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/tool/gen/controller/GenController.java 186 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/tool/gen/domain/GenTable.java 271 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/tool/gen/domain/GenTableColumn.java 368 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/tool/gen/mapper/GenTableColumnMapper.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/tool/gen/mapper/GenTableMapper.java 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/tool/gen/service/GenTableColumnServiceImpl.java 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/tool/gen/service/GenTableServiceImpl.java 345 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/tool/gen/service/IGenTableColumnService.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/tool/gen/service/IGenTableService.java 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/tool/gen/util/GenUtils.java 242 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/tool/gen/util/VelocityInitializer.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/tool/gen/util/VelocityUtils.java 293 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/tool/swagger/TestController.java 175 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/resources/application.yml 136 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/resources/mybatis/monitor/SysLogininforMapper.xml 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/resources/mybatis/monitor/SysOperLogMapper.xml 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/resources/mybatis/system/SysConfigMapper.xml 112 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/resources/mybatis/system/SysDeptMapper.xml 155 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/resources/mybatis/system/SysDictDataMapper.xml 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/resources/mybatis/system/SysDictTypeMapper.xml 105 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/resources/mybatis/system/SysJobLogMapper.xml 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/resources/mybatis/system/SysJobMapper.xml 111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/resources/mybatis/system/SysMenuMapper.xml 185 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/resources/mybatis/system/SysNoticeMapper.xml 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/resources/mybatis/system/SysPostMapper.xml 122 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/resources/mybatis/system/SysRoleDeptMapper.xml 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/resources/mybatis/system/SysRoleMapper.xml 145 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/resources/mybatis/system/SysRoleMenuMapper.xml 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/resources/mybatis/system/SysUserMapper.xml 182 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/resources/mybatis/system/SysUserPostMapper.xml 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/resources/mybatis/system/SysUserRoleMapper.xml 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/resources/mybatis/tool/GenTableColumnMapper.xml 120 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/resources/mybatis/tool/GenTableMapper.xml 181 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/resources/vm/java/controller.java.vm 197 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/resources/vm/java/domain.java.vm 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ry.sh 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
sql/quartz.sql 170 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
sql/ry_20200629.sql 补丁 | 查看 | 原始文档 | blame | 历史
.gitignore
bin/clean.bat
bin/package.bat
bin/run.bat
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,14 @@
@echo off
echo.
echo [信息] è¿è¡ŒWeb工程。
echo.
cd %~dp0
cd ../ruoyi-admin/target
set JAVA_OPTS=-Xms256m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m
java -jar %JAVA_OPTS% ruoyi-admin.jar
cd bin
pause
doc/ÈôÒÀ»·¾³Ê¹ÓÃÊÖ²á.docx
Binary files differ
pom.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,258 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.ruoyi</groupId>
    <artifactId>ruoyi</artifactId>
    <version>3.0.0</version>
    <name>ruoyi</name>
    <url>http://www.ruoyi.vip</url>
    <description>若依管理系统</description>
    <properties>
        <ruoyi.version>3.0.0</ruoyi.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <mybatis.boot.version>1.3.2</mybatis.boot.version>
        <druid.version>1.1.14</druid.version>
        <bitwalker.version>1.19</bitwalker.version>
        <swagger.version>2.9.2</swagger.version>
        <pagehelper.boot.version>1.2.5</pagehelper.boot.version>
        <fastjson.version>1.2.70</fastjson.version>
        <oshi.version>3.9.1</oshi.version>
        <commons.io.version>2.5</commons.io.version>
        <commons.fileupload.version>1.3.3</commons.fileupload.version>
        <poi.version>3.17</poi.version>
        <velocity.version>1.7</velocity.version>
        <jwt.version>0.9.0</jwt.version>
        <mybatis-plus.version>3.3.0</mybatis-plus.version>
        <hutool.version>5.1.0</hutool.version>
    </properties>
    <!-- ä¾èµ–声明 -->
    <dependencyManagement>
        <dependencies>
            <!-- SpringBoot的依赖配置-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.1.1.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--阿里数据库连接池 -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid-spring-boot-starter</artifactId>
                <version>${druid.version}</version>
            </dependency>
            <!-- è§£æžå®¢æˆ·ç«¯æ“ä½œç³»ç»Ÿã€æµè§ˆå™¨ç­‰ -->
            <dependency>
                <groupId>eu.bitwalker</groupId>
                <artifactId>UserAgentUtils</artifactId>
                <version>${bitwalker.version}</version>
            </dependency>
            <!-- pagehelper åˆ†é¡µæ’ä»¶ -->
            <dependency>
                <groupId>com.github.pagehelper</groupId>
                <artifactId>pagehelper-spring-boot-starter</artifactId>
                <version>${pagehelper.boot.version}</version>
                <exclusions>
                    <exclusion>
                        <groupId>org.mybatis</groupId>
                        <artifactId>mybatis</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <!-- èŽ·å–ç³»ç»Ÿä¿¡æ¯ -->
            <dependency>
                <groupId>com.github.oshi</groupId>
                <artifactId>oshi-core</artifactId>
                <version>${oshi.version}</version>
            </dependency>
            <!-- swagger2-->
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger2</artifactId>
                <version>${swagger.version}</version>
                <exclusions>
                    <exclusion>
                        <groupId>io.swagger</groupId>
                        <artifactId>swagger-annotations</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>io.swagger</groupId>
                        <artifactId>swagger-models</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <!-- swagger2-UI-->
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger-ui</artifactId>
                <version>${swagger.version}</version>
            </dependency>
            <!--io常用工具类 -->
            <dependency>
                <groupId>commons-io</groupId>
                <artifactId>commons-io</artifactId>
                <version>${commons.io.version}</version>
            </dependency>
            <!--文件上传工具类 -->
            <dependency>
                <groupId>commons-fileupload</groupId>
                <artifactId>commons-fileupload</artifactId>
                <version>${commons.fileupload.version}</version>
            </dependency>
            <!-- excel工具 -->
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi-ooxml</artifactId>
                <version>${poi.version}</version>
            </dependency>
            <!--velocity代码生成使用模板 -->
            <dependency>
                <groupId>org.apache.velocity</groupId>
                <artifactId>velocity</artifactId>
                <version>${velocity.version}</version>
            </dependency>
            <!-- é˜¿é‡ŒJSON解析器 -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>${fastjson.version}</version>
            </dependency>
            <!--Token生成与解析-->
            <dependency>
                <groupId>io.jsonwebtoken</groupId>
                <artifactId>jjwt</artifactId>
                <version>${jwt.version}</version>
            </dependency>
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>${mybatis-plus.version}</version>
            </dependency>
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-extension</artifactId>
                <version>${mybatis-plus.version}</version>
            </dependency>
            <dependency>
                <groupId>cn.hutool</groupId>
                <artifactId>hutool-all</artifactId>
                <version>${hutool.version}</version>
            </dependency>
            <!-- å®šæ—¶ä»»åŠ¡-->
            <dependency>
                <groupId>com.ruoyi</groupId>
                <artifactId>ruoyi-quartz</artifactId>
                <version>${ruoyi.version}</version>
            </dependency>
            <!-- ä»£ç ç”Ÿæˆ-->
            <dependency>
                <groupId>com.ruoyi</groupId>
                <artifactId>ruoyi-generator</artifactId>
                <version>${ruoyi.version}</version>
            </dependency>
            <!-- æ ¸å¿ƒæ¨¡å—-->
            <dependency>
                <groupId>com.ruoyi</groupId>
                <artifactId>ruoyi-framework</artifactId>
                <version>${ruoyi.version}</version>
            </dependency>
            <!-- ç³»ç»Ÿæ¨¡å—-->
            <dependency>
                <groupId>com.ruoyi</groupId>
                <artifactId>ruoyi-system</artifactId>
                <version>${ruoyi.version}</version>
            </dependency>
            <!-- é€šç”¨å·¥å…·-->
            <dependency>
                <groupId>com.ruoyi</groupId>
                <artifactId>ruoyi-common</artifactId>
                <version>${ruoyi.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <modules>
        <module>ruoyi-admin</module>
        <module>ruoyi-framework</module>
        <module>ruoyi-system</module>
        <module>ruoyi-quartz</module>
        <module>ruoyi-generator</module>
        <module>ruoyi-common</module>
    </modules>
    <packaging>pom</packaging>
    <dependencies>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <encoding>${project.build.sourceEncoding}</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <repositories>
        <repository>
            <id>public</id>
            <name>aliyun nexus</name>
            <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
            <releases>
                <enabled>true</enabled>
            </releases>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>public</id>
            <name>aliyun nexus</name>
            <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>
</project>
ruoyi-admin/pom.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,108 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>ruoyi</artifactId>
        <groupId>com.ruoyi</groupId>
        <version>3.0.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <packaging>jar</packaging>
    <artifactId>ruoyi-admin</artifactId>
    <description>
        web服务入口
    </description>
    <dependencies>
        <!-- spring-boot-devtools -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional> <!-- è¡¨ç¤ºä¾èµ–不会传递 -->
        </dependency>
        <!-- swagger2-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
        </dependency>
        <!--防止进入swagger页面报类型转换错误,排除2.9.2中的引用,手动增加1.5.21版本-->
        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-annotations</artifactId>
            <version>1.5.21</version>
        </dependency>
        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-models</artifactId>
            <version>1.5.21</version>
        </dependency>
        <!-- swagger2-UI-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
        </dependency>
         <!-- Mysql驱动包 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!-- æ ¸å¿ƒæ¨¡å—-->
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>ruoyi-framework</artifactId>
        </dependency>
        <!-- å®šæ—¶ä»»åŠ¡-->
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>ruoyi-quartz</artifactId>
        </dependency>
        <!-- ä»£ç ç”Ÿæˆ-->
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>ruoyi-generator</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.1.1.RELEASE</version>
                <configuration>
                    <fork>true</fork> <!-- å¦‚果没有该配置,devtools不会生效 -->
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.0.0</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                    <warName>${project.artifactId}</warName>
                </configuration>
           </plugin>
        </plugins>
        <finalName>${project.artifactId}</finalName>
    </build>
</project>
ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java
ruoyi-admin/src/main/java/com/ruoyi/RuoYiServletInitializer.java
ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,62 @@
package com.ruoyi.web.controller.common;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.VerifyCodeUtils;
import com.ruoyi.common.utils.sign.Base64;
import com.ruoyi.common.utils.uuid.IdUtils;
/**
 * éªŒè¯ç æ“ä½œå¤„理
 *
 * @author ruoyi
 */
@RestController
public class CaptchaController
{
    @Autowired
    private RedisCache redisCache;
    /**
     * ç”ŸæˆéªŒè¯ç 
     */
    @GetMapping("/captchaImage")
    public AjaxResult getCode(HttpServletResponse response) throws IOException
    {
        // ç”Ÿæˆéšæœºå­—串
        String verifyCode = VerifyCodeUtils.generateVerifyCode(4);
        // å”¯ä¸€æ ‡è¯†
        String uuid = IdUtils.simpleUUID();
        String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid;
        redisCache.setCacheObject(verifyKey, verifyCode, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
        // ç”Ÿæˆå›¾ç‰‡
        int w = 111, h = 36;
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        VerifyCodeUtils.outputImage(w, h, stream, verifyCode);
        try
        {
            AjaxResult ajax = AjaxResult.success();
            ajax.put("uuid", uuid);
            ajax.put("img", Base64.encode(stream.toByteArray()));
            return ajax;
        }
        catch (Exception e)
        {
            e.printStackTrace();
            return AjaxResult.error(e.getMessage());
        }
        finally
        {
            stream.close();
        }
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,109 @@
package com.ruoyi.web.controller.common;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.framework.config.ServerConfig;
/**
 * é€šç”¨è¯·æ±‚处理
 *
 * @author ruoyi
 */
@RestController
public class CommonController
{
    private static final Logger log = LoggerFactory.getLogger(CommonController.class);
    @Autowired
    private ServerConfig serverConfig;
    /**
     * é€šç”¨ä¸‹è½½è¯·æ±‚
     *
     * @param fileName æ–‡ä»¶åç§°
     * @param delete æ˜¯å¦åˆ é™¤
     */
    @GetMapping("common/download")
    public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request)
    {
        try
        {
            if (!FileUtils.isValidFilename(fileName))
            {
                throw new Exception(StringUtils.format("文件名称({})非法,不允许下载。 ", fileName));
            }
            String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1);
            String filePath = RuoYiConfig.getDownloadPath() + fileName;
            response.setCharacterEncoding("utf-8");
            response.setContentType("multipart/form-data");
            response.setHeader("Content-Disposition",
                    "attachment;fileName=" + FileUtils.setFileDownloadHeader(request, realFileName));
            FileUtils.writeBytes(filePath, response.getOutputStream());
            if (delete)
            {
                FileUtils.deleteFile(filePath);
            }
        }
        catch (Exception e)
        {
            log.error("下载文件失败", e);
        }
    }
    /**
     * é€šç”¨ä¸Šä¼ è¯·æ±‚
     */
    @PostMapping("/common/upload")
    public AjaxResult uploadFile(MultipartFile file) throws Exception
    {
        try
        {
            // ä¸Šä¼ æ–‡ä»¶è·¯å¾„
            String filePath = RuoYiConfig.getUploadPath();
            // ä¸Šä¼ å¹¶è¿”回新文件名称
            String fileName = FileUploadUtils.upload(filePath, file);
            String url = serverConfig.getUrl() + fileName;
            AjaxResult ajax = AjaxResult.success();
            ajax.put("fileName", fileName);
            ajax.put("url", url);
            return ajax;
        }
        catch (Exception e)
        {
            return AjaxResult.error(e.getMessage());
        }
    }
    /**
     * æœ¬åœ°èµ„源通用下载
     */
    @GetMapping("/common/download/resource")
    public void resourceDownload(String name, HttpServletRequest request, HttpServletResponse response) throws Exception
    {
        // æœ¬åœ°èµ„源路径
        String localPath = RuoYiConfig.getProfile();
        // æ•°æ®åº“资源地址
        String downloadPath = localPath + StringUtils.substringAfter(name, Constants.RESOURCE_PREFIX);
        // ä¸‹è½½åç§°
        String downloadName = StringUtils.substringAfterLast(downloadPath, "/");
        response.setCharacterEncoding("utf-8");
        response.setContentType("multipart/form-data");
        response.setHeader("Content-Disposition",
                "attachment;fileName=" + FileUtils.setFileDownloadHeader(request, downloadName));
        FileUtils.writeBytes(downloadPath, response.getOutputStream());
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/ServerController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,28 @@
package com.ruoyi.web.controller.monitor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.framework.web.domain.Server;
/**
 * æœåŠ¡å™¨ç›‘æŽ§
 *
 * @author ruoyi
 */
@RestController
@RequestMapping("/monitor/server")
public class ServerController extends BaseController
{
    @PreAuthorize("@ss.hasPermi('monitor:server:list')")
    @GetMapping()
    public AjaxResult getInfo() throws Exception
    {
        Server server = new Server();
        server.copyTo();
        return AjaxResult.success(server);
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysLogininforController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,67 @@
package com.ruoyi.web.controller.monitor;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
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;
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.system.domain.SysLogininfor;
import com.ruoyi.system.service.ISysLogininforService;
/**
 * ç³»ç»Ÿè®¿é—®è®°å½•
 *
 * @author ruoyi
 */
@RestController
@RequestMapping("/monitor/logininfor")
public class SysLogininforController extends BaseController
{
    @Autowired
    private ISysLogininforService logininforService;
    @PreAuthorize("@ss.hasPermi('monitor:logininfor:list')")
    @GetMapping("/list")
    public TableDataInfo list(SysLogininfor logininfor)
    {
        startPage();
        List<SysLogininfor> list = logininforService.selectLogininforList(logininfor);
        return getDataTable(list);
    }
    @Log(title = "登陆日志", businessType = BusinessType.EXPORT)
    @PreAuthorize("@ss.hasPermi('monitor:logininfor:export')")
    @GetMapping("/export")
    public AjaxResult export(SysLogininfor logininfor)
    {
        List<SysLogininfor> list = logininforService.selectLogininforList(logininfor);
        ExcelUtil<SysLogininfor> util = new ExcelUtil<SysLogininfor>(SysLogininfor.class);
        return util.exportExcel(list, "登陆日志");
    }
    @PreAuthorize("@ss.hasPermi('monitor:logininfor:remove')")
    @Log(title = "登陆日志", businessType = BusinessType.DELETE)
    @DeleteMapping("/{infoIds}")
    public AjaxResult remove(@PathVariable Long[] infoIds)
    {
        return toAjax(logininforService.deleteLogininforByIds(infoIds));
    }
    @PreAuthorize("@ss.hasPermi('monitor:logininfor:remove')")
    @Log(title = "登陆日志", businessType = BusinessType.CLEAN)
    @DeleteMapping("/clean")
    public AjaxResult clean()
    {
        logininforService.cleanLogininfor();
        return AjaxResult.success();
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysOperlogController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,66 @@
package com.ruoyi.web.controller.monitor;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
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;
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.system.domain.SysOperLog;
import com.ruoyi.system.service.ISysOperLogService;
/**
 * æ“ä½œæ—¥å¿—记录
 *
 * @author ruoyi
 */
@RestController
@RequestMapping("/monitor/operlog")
public class SysOperlogController extends BaseController
{
    @Autowired
    private ISysOperLogService operLogService;
    @PreAuthorize("@ss.hasPermi('monitor:operlog:list')")
    @GetMapping("/list")
    public TableDataInfo list(SysOperLog operLog)
    {
        startPage();
        List<SysOperLog> list = operLogService.selectOperLogList(operLog);
        return getDataTable(list);
    }
    @Log(title = "操作日志", businessType = BusinessType.EXPORT)
    @PreAuthorize("@ss.hasPermi('monitor:operlog:export')")
    @GetMapping("/export")
    public AjaxResult export(SysOperLog operLog)
    {
        List<SysOperLog> list = operLogService.selectOperLogList(operLog);
        ExcelUtil<SysOperLog> util = new ExcelUtil<SysOperLog>(SysOperLog.class);
        return util.exportExcel(list, "操作日志");
    }
    @PreAuthorize("@ss.hasPermi('monitor:operlog:remove')")
    @DeleteMapping("/{operIds}")
    public AjaxResult remove(@PathVariable Long[] operIds)
    {
        return toAjax(operLogService.deleteOperLogByIds(operIds));
    }
    @Log(title = "操作日志", businessType = BusinessType.CLEAN)
    @PreAuthorize("@ss.hasPermi('monitor:operlog:remove')")
    @DeleteMapping("/clean")
    public AjaxResult clean()
    {
        operLogService.cleanOperLog();
        return AjaxResult.success();
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysUserOnlineController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,92 @@
package com.ruoyi.web.controller.monitor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
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;
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.domain.model.LoginUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.SysUserOnline;
import com.ruoyi.system.service.ISysUserOnlineService;
/**
 * åœ¨çº¿ç”¨æˆ·ç›‘控
 *
 * @author ruoyi
 */
@RestController
@RequestMapping("/monitor/online")
public class SysUserOnlineController extends BaseController
{
    @Autowired
    private ISysUserOnlineService userOnlineService;
    @Autowired
    private RedisCache redisCache;
    @PreAuthorize("@ss.hasPermi('monitor:online:list')")
    @GetMapping("/list")
    public TableDataInfo list(String ipaddr, String userName)
    {
        Collection<String> keys = redisCache.keys(Constants.LOGIN_TOKEN_KEY + "*");
        List<SysUserOnline> userOnlineList = new ArrayList<SysUserOnline>();
        for (String key : keys)
        {
            LoginUser user = redisCache.getCacheObject(key);
            if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName))
            {
                if (StringUtils.equals(ipaddr, user.getIpaddr()) && StringUtils.equals(userName, user.getUsername()))
                {
                    userOnlineList.add(userOnlineService.selectOnlineByInfo(ipaddr, userName, user));
                }
            }
            else if (StringUtils.isNotEmpty(ipaddr))
            {
                if (StringUtils.equals(ipaddr, user.getIpaddr()))
                {
                    userOnlineList.add(userOnlineService.selectOnlineByIpaddr(ipaddr, user));
                }
            }
            else if (StringUtils.isNotEmpty(userName) && StringUtils.isNotNull(user.getUser()))
            {
                if (StringUtils.equals(userName, user.getUsername()))
                {
                    userOnlineList.add(userOnlineService.selectOnlineByUserName(userName, user));
                }
            }
            else
            {
                userOnlineList.add(userOnlineService.loginUserToUserOnline(user));
            }
        }
        Collections.reverse(userOnlineList);
        userOnlineList.removeAll(Collections.singleton(null));
        return getDataTable(userOnlineList);
    }
    /**
     * å¼ºé€€ç”¨æˆ·
     */
    @PreAuthorize("@ss.hasPermi('monitor:online:forceLogout')")
    @Log(title = "在线用户", businessType = BusinessType.DELETE)
    @DeleteMapping("/{tokenId}")
    public AjaxResult forceLogout(@PathVariable String tokenId)
    {
        redisCache.deleteObject(Constants.LOGIN_TOKEN_KEY + tokenId);
        return AjaxResult.success();
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysConfigController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,135 @@
package com.ruoyi.web.controller.system;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
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;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.SysConfig;
import com.ruoyi.system.service.ISysConfigService;
/**
 * å‚数配置 ä¿¡æ¯æ“ä½œå¤„理
 *
 * @author ruoyi
 */
@RestController
@RequestMapping("/system/config")
public class SysConfigController extends BaseController
{
    @Autowired
    private ISysConfigService configService;
    /**
     * èŽ·å–å‚æ•°é…ç½®åˆ—è¡¨
     */
    @PreAuthorize("@ss.hasPermi('system:config:list')")
    @GetMapping("/list")
    public TableDataInfo list(SysConfig config)
    {
        startPage();
        List<SysConfig> list = configService.selectConfigList(config);
        return getDataTable(list);
    }
    @Log(title = "参数管理", businessType = BusinessType.EXPORT)
    @PreAuthorize("@ss.hasPermi('system:config:export')")
    @GetMapping("/export")
    public AjaxResult export(SysConfig config)
    {
        List<SysConfig> list = configService.selectConfigList(config);
        ExcelUtil<SysConfig> util = new ExcelUtil<SysConfig>(SysConfig.class);
        return util.exportExcel(list, "参数数据");
    }
    /**
     * æ ¹æ®å‚数编号获取详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:config:query')")
    @GetMapping(value = "/{configId}")
    public AjaxResult getInfo(@PathVariable Long configId)
    {
        return AjaxResult.success(configService.selectConfigById(configId));
    }
    /**
     * æ ¹æ®å‚数键名查询参数值
     */
    @GetMapping(value = "/configKey/{configKey}")
    public AjaxResult getConfigKey(@PathVariable String configKey)
    {
        return AjaxResult.success(configService.selectConfigByKey(configKey));
    }
    /**
     * æ–°å¢žå‚数配置
     */
    @PreAuthorize("@ss.hasPermi('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() + "'失败,参数键名已存在");
        }
        config.setCreateBy(SecurityUtils.getUsername());
        return toAjax(configService.insertConfig(config));
    }
    /**
     * ä¿®æ”¹å‚数配置
     */
    @PreAuthorize("@ss.hasPermi('system:config:edit')")
    @Log(title = "参数管理", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@Validated @RequestBody SysConfig config)
    {
        if (UserConstants.NOT_UNIQUE.equals(configService.checkConfigKeyUnique(config)))
        {
            return AjaxResult.error("修改参数'" + config.getConfigName() + "'失败,参数键名已存在");
        }
        config.setUpdateBy(SecurityUtils.getUsername());
        return toAjax(configService.updateConfig(config));
    }
    /**
     * åˆ é™¤å‚数配置
     */
    @PreAuthorize("@ss.hasPermi('system:config:remove')")
    @Log(title = "参数管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/{configIds}")
    public AjaxResult remove(@PathVariable Long[] configIds)
    {
        return toAjax(configService.deleteConfigByIds(configIds));
    }
    /**
     * æ¸…空缓存
     */
    @PreAuthorize("@ss.hasPermi('system:config:remove')")
    @Log(title = "参数管理", businessType = BusinessType.CLEAN)
    @DeleteMapping("/clearCache")
    public AjaxResult clearCache()
    {
        configService.clearCache();
        return AjaxResult.success();
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDeptController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,163 @@
package com.ruoyi.web.controller.system;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
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.entity.SysDept;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.service.ISysDeptService;
/**
 * éƒ¨é—¨ä¿¡æ¯
 *
 * @author ruoyi
 */
@RestController
@RequestMapping("/system/dept")
public class SysDeptController extends BaseController
{
    @Autowired
    private ISysDeptService deptService;
    /**
     * èŽ·å–éƒ¨é—¨åˆ—è¡¨
     */
    @PreAuthorize("@ss.hasPermi('system:dept:list')")
    @GetMapping("/list")
    public AjaxResult list(SysDept dept)
    {
        List<SysDept> depts = deptService.selectDeptList(dept);
        return AjaxResult.success(depts);
    }
    /**
     * æŸ¥è¯¢éƒ¨é—¨åˆ—表(排除节点)
     */
    @PreAuthorize("@ss.hasPermi('system:dept:list')")
    @GetMapping("/list/exclude/{deptId}")
    public AjaxResult excludeChild(@PathVariable(value = "deptId", required = false) Long deptId)
    {
        List<SysDept> depts = deptService.selectDeptList(new SysDept());
        Iterator<SysDept> it = depts.iterator();
        while (it.hasNext())
        {
            SysDept d = (SysDept) it.next();
            if (d.getDeptId().intValue() == deptId
                    || ArrayUtils.contains(StringUtils.split(d.getAncestors(), ","), deptId + ""))
            {
                it.remove();
            }
        }
        return AjaxResult.success(depts);
    }
    /**
     * æ ¹æ®éƒ¨é—¨ç¼–号获取详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:dept:query')")
    @GetMapping(value = "/{deptId}")
    public AjaxResult getInfo(@PathVariable Long deptId)
    {
        return AjaxResult.success(deptService.selectDeptById(deptId));
    }
    /**
     * èŽ·å–éƒ¨é—¨ä¸‹æ‹‰æ ‘åˆ—è¡¨
     */
    @GetMapping("/treeselect")
    public AjaxResult treeselect(SysDept dept)
    {
        List<SysDept> depts = deptService.selectDeptList(dept);
        return AjaxResult.success(deptService.buildDeptTreeSelect(depts));
    }
    /**
     * åŠ è½½å¯¹åº”è§’è‰²éƒ¨é—¨åˆ—è¡¨æ ‘
     */
    @GetMapping(value = "/roleDeptTreeselect/{roleId}")
    public AjaxResult roleDeptTreeselect(@PathVariable("roleId") Long roleId)
    {
        List<SysDept> depts = deptService.selectDeptList(new SysDept());
        AjaxResult ajax = AjaxResult.success();
        ajax.put("checkedKeys", deptService.selectDeptListByRoleId(roleId));
        ajax.put("depts", deptService.buildDeptTreeSelect(depts));
        return ajax;
    }
    /**
     * æ–°å¢žéƒ¨é—¨
     */
    @PreAuthorize("@ss.hasPermi('system:dept:add')")
    @Log(title = "部门管理", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@Validated @RequestBody SysDept dept)
    {
        if (UserConstants.NOT_UNIQUE.equals(deptService.checkDeptNameUnique(dept)))
        {
            return AjaxResult.error("新增部门'" + dept.getDeptName() + "'失败,部门名称已存在");
        }
        dept.setCreateBy(SecurityUtils.getUsername());
        return toAjax(deptService.insertDept(dept));
    }
    /**
     * ä¿®æ”¹éƒ¨é—¨
     */
    @PreAuthorize("@ss.hasPermi('system:dept:edit')")
    @Log(title = "部门管理", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@Validated @RequestBody SysDept dept)
    {
        if (UserConstants.NOT_UNIQUE.equals(deptService.checkDeptNameUnique(dept)))
        {
            return AjaxResult.error("修改部门'" + dept.getDeptName() + "'失败,部门名称已存在");
        }
        else if (dept.getParentId().equals(dept.getDeptId()))
        {
            return AjaxResult.error("修改部门'" + dept.getDeptName() + "'失败,上级部门不能是自己");
        }
        else if (StringUtils.equals(UserConstants.DEPT_DISABLE, dept.getStatus())
                && deptService.selectNormalChildrenDeptById(dept.getDeptId()) > 0)
        {
            return AjaxResult.error("该部门包含未停用的子部门!");
        }
        dept.setUpdateBy(SecurityUtils.getUsername());
        return toAjax(deptService.updateDept(dept));
    }
    /**
     * åˆ é™¤éƒ¨é—¨
     */
    @PreAuthorize("@ss.hasPermi('system:dept:remove')")
    @Log(title = "部门管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/{deptId}")
    public AjaxResult remove(@PathVariable Long deptId)
    {
        if (deptService.hasChildByDeptId(deptId))
        {
            return AjaxResult.error("存在下级部门,不允许删除");
        }
        if (deptService.checkDeptExistUser(deptId))
        {
            return AjaxResult.error("部门存在用户,不允许删除");
        }
        return toAjax(deptService.deleteDeptById(deptId));
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictDataController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,113 @@
package com.ruoyi.web.controller.system;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
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.domain.entity.SysDictData;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.service.ISysDictDataService;
import com.ruoyi.system.service.ISysDictTypeService;
/**
 * æ•°æ®å­—典信息
 *
 * @author ruoyi
 */
@RestController
@RequestMapping("/system/dict/data")
public class SysDictDataController extends BaseController
{
    @Autowired
    private ISysDictDataService dictDataService;
    @Autowired
    private ISysDictTypeService dictTypeService;
    @PreAuthorize("@ss.hasPermi('system:dict:list')")
    @GetMapping("/list")
    public TableDataInfo list(SysDictData dictData)
    {
        startPage();
        List<SysDictData> list = dictDataService.selectDictDataList(dictData);
        return getDataTable(list);
    }
    @Log(title = "字典数据", businessType = BusinessType.EXPORT)
    @PreAuthorize("@ss.hasPermi('system:dict:export')")
    @GetMapping("/export")
    public AjaxResult export(SysDictData dictData)
    {
        List<SysDictData> list = dictDataService.selectDictDataList(dictData);
        ExcelUtil<SysDictData> util = new ExcelUtil<SysDictData>(SysDictData.class);
        return util.exportExcel(list, "字典数据");
    }
    /**
     * æŸ¥è¯¢å­—典数据详细
     */
    @PreAuthorize("@ss.hasPermi('system:dict:query')")
    @GetMapping(value = "/{dictCode}")
    public AjaxResult getInfo(@PathVariable Long dictCode)
    {
        return AjaxResult.success(dictDataService.selectDictDataById(dictCode));
    }
    /**
     * æ ¹æ®å­—典类型查询字典数据信息
     */
    @GetMapping(value = "/type/{dictType}")
    public AjaxResult dictType(@PathVariable String dictType)
    {
        return AjaxResult.success(dictTypeService.selectDictDataByType(dictType));
    }
    /**
     * æ–°å¢žå­—典类型
     */
    @PreAuthorize("@ss.hasPermi('system:dict:add')")
    @Log(title = "字典数据", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@Validated @RequestBody SysDictData dict)
    {
        dict.setCreateBy(SecurityUtils.getUsername());
        return toAjax(dictDataService.insertDictData(dict));
    }
    /**
     * ä¿®æ”¹ä¿å­˜å­—典类型
     */
    @PreAuthorize("@ss.hasPermi('system:dict:edit')")
    @Log(title = "字典数据", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@Validated @RequestBody SysDictData dict)
    {
        dict.setUpdateBy(SecurityUtils.getUsername());
        return toAjax(dictDataService.updateDictData(dict));
    }
    /**
     * åˆ é™¤å­—典类型
     */
    @PreAuthorize("@ss.hasPermi('system:dict:remove')")
    @Log(title = "字典类型", businessType = BusinessType.DELETE)
    @DeleteMapping("/{dictCodes}")
    public AjaxResult remove(@PathVariable Long[] dictCodes)
    {
        return toAjax(dictDataService.deleteDictDataByIds(dictCodes));
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictTypeController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,131 @@
package com.ruoyi.web.controller.system;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
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.entity.SysDictType;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.service.ISysDictTypeService;
/**
 * æ•°æ®å­—典信息
 *
 * @author ruoyi
 */
@RestController
@RequestMapping("/system/dict/type")
public class SysDictTypeController extends BaseController
{
    @Autowired
    private ISysDictTypeService dictTypeService;
    @PreAuthorize("@ss.hasPermi('system:dict:list')")
    @GetMapping("/list")
    public TableDataInfo list(SysDictType dictType)
    {
        startPage();
        List<SysDictType> list = dictTypeService.selectDictTypeList(dictType);
        return getDataTable(list);
    }
    @Log(title = "字典类型", businessType = BusinessType.EXPORT)
    @PreAuthorize("@ss.hasPermi('system:dict:export')")
    @GetMapping("/export")
    public AjaxResult export(SysDictType dictType)
    {
        List<SysDictType> list = dictTypeService.selectDictTypeList(dictType);
        ExcelUtil<SysDictType> util = new ExcelUtil<SysDictType>(SysDictType.class);
        return util.exportExcel(list, "字典类型");
    }
    /**
     * æŸ¥è¯¢å­—典类型详细
     */
    @PreAuthorize("@ss.hasPermi('system:dict:query')")
    @GetMapping(value = "/{dictId}")
    public AjaxResult getInfo(@PathVariable Long dictId)
    {
        return AjaxResult.success(dictTypeService.selectDictTypeById(dictId));
    }
    /**
     * æ–°å¢žå­—典类型
     */
    @PreAuthorize("@ss.hasPermi('system:dict:add')")
    @Log(title = "字典类型", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@Validated @RequestBody SysDictType dict)
    {
        if (UserConstants.NOT_UNIQUE.equals(dictTypeService.checkDictTypeUnique(dict)))
        {
            return AjaxResult.error("新增字典'" + dict.getDictName() + "'失败,字典类型已存在");
        }
        dict.setCreateBy(SecurityUtils.getUsername());
        return toAjax(dictTypeService.insertDictType(dict));
    }
    /**
     * ä¿®æ”¹å­—典类型
     */
    @PreAuthorize("@ss.hasPermi('system:dict:edit')")
    @Log(title = "字典类型", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@Validated @RequestBody SysDictType dict)
    {
        if (UserConstants.NOT_UNIQUE.equals(dictTypeService.checkDictTypeUnique(dict)))
        {
            return AjaxResult.error("修改字典'" + dict.getDictName() + "'失败,字典类型已存在");
        }
        dict.setUpdateBy(SecurityUtils.getUsername());
        return toAjax(dictTypeService.updateDictType(dict));
    }
    /**
     * åˆ é™¤å­—典类型
     */
    @PreAuthorize("@ss.hasPermi('system:dict:remove')")
    @Log(title = "字典类型", businessType = BusinessType.DELETE)
    @DeleteMapping("/{dictIds}")
    public AjaxResult remove(@PathVariable Long[] dictIds)
    {
        return toAjax(dictTypeService.deleteDictTypeByIds(dictIds));
    }
    /**
     * æ¸…空缓存
     */
    @PreAuthorize("@ss.hasPermi('system:dict:remove')")
    @Log(title = "字典类型", businessType = BusinessType.CLEAN)
    @DeleteMapping("/clearCache")
    public AjaxResult clearCache()
    {
        dictTypeService.clearCache();
        return AjaxResult.success();
    }
    /**
     * èŽ·å–å­—å…¸é€‰æ‹©æ¡†åˆ—è¡¨
     */
    @GetMapping("/optionselect")
    public AjaxResult optionselect()
    {
        List<SysDictType> dictTypes = dictTypeService.selectDictTypeAll();
        return AjaxResult.success(dictTypes);
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,94 @@
package com.ruoyi.web.controller.system;
import java.util.List;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysMenu;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginBody;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.framework.web.service.SysLoginService;
import com.ruoyi.framework.web.service.SysPermissionService;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.system.service.ISysMenuService;
/**
 * ç™»å½•验证
 *
 * @author ruoyi
 */
@RestController
public class SysLoginController
{
    @Autowired
    private SysLoginService loginService;
    @Autowired
    private ISysMenuService menuService;
    @Autowired
    private SysPermissionService permissionService;
    @Autowired
    private TokenService tokenService;
    /**
     * ç™»å½•方法
     *
     * @param loginBody ç™»å½•信息
     * @return ç»“æžœ
     */
    @PostMapping("/login")
    public AjaxResult login(@RequestBody LoginBody loginBody)
    {
        AjaxResult ajax = AjaxResult.success();
        // ç”Ÿæˆä»¤ç‰Œ
        String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
                loginBody.getUuid());
        ajax.put(Constants.TOKEN, token);
        return ajax;
    }
    /**
     * èŽ·å–ç”¨æˆ·ä¿¡æ¯
     *
     * @return ç”¨æˆ·ä¿¡æ¯
     */
    @GetMapping("getInfo")
    public AjaxResult getInfo()
    {
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        SysUser user = loginUser.getUser();
        // è§’色集合
        Set<String> roles = permissionService.getRolePermission(user);
        // æƒé™é›†åˆ
        Set<String> permissions = permissionService.getMenuPermission(user);
        AjaxResult ajax = AjaxResult.success();
        ajax.put("user", user);
        ajax.put("roles", roles);
        ajax.put("permissions", permissions);
        return ajax;
    }
    /**
     * èŽ·å–è·¯ç”±ä¿¡æ¯
     *
     * @return è·¯ç”±ä¿¡æ¯
     */
    @GetMapping("getRouters")
    public AjaxResult getRouters()
    {
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        // ç”¨æˆ·ä¿¡æ¯
        SysUser user = loginUser.getUser();
        List<SysMenu> menus = menuService.selectMenuTreeByUserId(user.getUserId());
        return AjaxResult.success(menuService.buildMenus(menus));
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysMenuController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,153 @@
package com.ruoyi.web.controller.system;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.Constants;
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.entity.SysMenu;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.system.service.ISysMenuService;
/**
 * èœå•信息
 *
 * @author ruoyi
 */
@RestController
@RequestMapping("/system/menu")
public class SysMenuController extends BaseController
{
    @Autowired
    private ISysMenuService menuService;
    @Autowired
    private TokenService tokenService;
    /**
     * èŽ·å–èœå•åˆ—è¡¨
     */
    @PreAuthorize("@ss.hasPermi('system:menu:list')")
    @GetMapping("/list")
    public AjaxResult list(SysMenu menu)
    {
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        Long userId = loginUser.getUser().getUserId();
        List<SysMenu> menus = menuService.selectMenuList(menu, userId);
        return AjaxResult.success(menus);
    }
    /**
     * æ ¹æ®èœå•编号获取详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:menu:query')")
    @GetMapping(value = "/{menuId}")
    public AjaxResult getInfo(@PathVariable Long menuId)
    {
        return AjaxResult.success(menuService.selectMenuById(menuId));
    }
    /**
     * èŽ·å–èœå•ä¸‹æ‹‰æ ‘åˆ—è¡¨
     */
    @GetMapping("/treeselect")
    public AjaxResult treeselect(SysMenu menu)
    {
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        Long userId = loginUser.getUser().getUserId();
        List<SysMenu> menus = menuService.selectMenuList(menu, userId);
        return AjaxResult.success(menuService.buildMenuTreeSelect(menus));
    }
    /**
     * åŠ è½½å¯¹åº”è§’è‰²èœå•åˆ—è¡¨æ ‘
     */
    @GetMapping(value = "/roleMenuTreeselect/{roleId}")
    public AjaxResult roleMenuTreeselect(@PathVariable("roleId") Long roleId)
    {
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        List<SysMenu> menus = menuService.selectMenuList(loginUser.getUser().getUserId());
        AjaxResult ajax = AjaxResult.success();
        ajax.put("checkedKeys", menuService.selectMenuListByRoleId(roleId));
        ajax.put("menus", menuService.buildMenuTreeSelect(menus));
        return ajax;
    }
    /**
     * æ–°å¢žèœå•
     */
    @PreAuthorize("@ss.hasPermi('system:menu:add')")
    @Log(title = "菜单管理", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@Validated @RequestBody SysMenu menu)
    {
        if (UserConstants.NOT_UNIQUE.equals(menuService.checkMenuNameUnique(menu)))
        {
            return AjaxResult.error("新增菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
        }
        else if (UserConstants.YES_FRAME.equals(menu.getIsFrame())
                && !StringUtils.startsWithAny(menu.getPath(), Constants.HTTP, Constants.HTTPS))
        {
            return AjaxResult.error("新增菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头");
        }
        menu.setCreateBy(SecurityUtils.getUsername());
        return toAjax(menuService.insertMenu(menu));
    }
    /**
     * ä¿®æ”¹èœå•
     */
    @PreAuthorize("@ss.hasPermi('system:menu:edit')")
    @Log(title = "菜单管理", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@Validated @RequestBody SysMenu menu)
    {
        if (UserConstants.NOT_UNIQUE.equals(menuService.checkMenuNameUnique(menu)))
        {
            return AjaxResult.error("修改菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
        }
        else if (UserConstants.YES_FRAME.equals(menu.getIsFrame())
                && !StringUtils.startsWithAny(menu.getPath(), Constants.HTTP, Constants.HTTPS))
        {
            return AjaxResult.error("新增菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头");
        }
        menu.setUpdateBy(SecurityUtils.getUsername());
        return toAjax(menuService.updateMenu(menu));
    }
    /**
     * åˆ é™¤èœå•
     */
    @PreAuthorize("@ss.hasPermi('system:menu:remove')")
    @Log(title = "菜单管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/{menuId}")
    public AjaxResult remove(@PathVariable("menuId") Long menuId)
    {
        if (menuService.hasChildByMenuId(menuId))
        {
            return AjaxResult.error("存在子菜单,不允许删除");
        }
        if (menuService.checkMenuExistRole(menuId))
        {
            return AjaxResult.error("菜单已分配,不允许删除");
        }
        return toAjax(menuService.deleteMenuById(menuId));
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysNoticeController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,92 @@
package com.ruoyi.web.controller.system;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
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.SecurityUtils;
import com.ruoyi.system.domain.SysNotice;
import com.ruoyi.system.service.ISysNoticeService;
/**
 * å…¬å‘Š ä¿¡æ¯æ“ä½œå¤„ç†
 *
 * @author ruoyi
 */
@RestController
@RequestMapping("/system/notice")
public class SysNoticeController extends BaseController
{
    @Autowired
    private ISysNoticeService noticeService;
    /**
     * èŽ·å–é€šçŸ¥å…¬å‘Šåˆ—è¡¨
     */
    @PreAuthorize("@ss.hasPermi('system:notice:list')")
    @GetMapping("/list")
    public TableDataInfo list(SysNotice notice)
    {
        startPage();
        List<SysNotice> list = noticeService.selectNoticeList(notice);
        return getDataTable(list);
    }
    /**
     * æ ¹æ®é€šçŸ¥å…¬å‘Šç¼–号获取详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:notice:query')")
    @GetMapping(value = "/{noticeId}")
    public AjaxResult getInfo(@PathVariable Long noticeId)
    {
        return AjaxResult.success(noticeService.selectNoticeById(noticeId));
    }
    /**
     * æ–°å¢žé€šçŸ¥å…¬å‘Š
     */
    @PreAuthorize("@ss.hasPermi('system:notice:add')")
    @Log(title = "通知公告", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@Validated @RequestBody SysNotice notice)
    {
        notice.setCreateBy(SecurityUtils.getUsername());
        return toAjax(noticeService.insertNotice(notice));
    }
    /**
     * ä¿®æ”¹é€šçŸ¥å…¬å‘Š
     */
    @PreAuthorize("@ss.hasPermi('system:notice:edit')")
    @Log(title = "通知公告", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@Validated @RequestBody SysNotice notice)
    {
        notice.setUpdateBy(SecurityUtils.getUsername());
        return toAjax(noticeService.updateNotice(notice));
    }
    /**
     * åˆ é™¤é€šçŸ¥å…¬å‘Š
     */
    @PreAuthorize("@ss.hasPermi('system:notice:remove')")
    @Log(title = "通知公告", businessType = BusinessType.DELETE)
    @DeleteMapping("/{noticeIds}")
    public AjaxResult remove(@PathVariable Long[] noticeIds)
    {
        return toAjax(noticeService.deleteNoticeByIds(noticeIds));
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysPostController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,130 @@
package com.ruoyi.web.controller.system;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
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.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.SysPost;
import com.ruoyi.system.service.ISysPostService;
/**
 * å²—位信息操作处理
 *
 * @author ruoyi
 */
@RestController
@RequestMapping("/system/post")
public class SysPostController extends BaseController
{
    @Autowired
    private ISysPostService postService;
    /**
     * èŽ·å–å²—ä½åˆ—è¡¨
     */
    @PreAuthorize("@ss.hasPermi('system:post:list')")
    @GetMapping("/list")
    public TableDataInfo list(SysPost post)
    {
        startPage();
        List<SysPost> list = postService.selectPostList(post);
        return getDataTable(list);
    }
    @Log(title = "岗位管理", businessType = BusinessType.EXPORT)
    @PreAuthorize("@ss.hasPermi('system:post:export')")
    @GetMapping("/export")
    public AjaxResult export(SysPost post)
    {
        List<SysPost> list = postService.selectPostList(post);
        ExcelUtil<SysPost> util = new ExcelUtil<SysPost>(SysPost.class);
        return util.exportExcel(list, "岗位数据");
    }
    /**
     * æ ¹æ®å²—位编号获取详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:post:query')")
    @GetMapping(value = "/{postId}")
    public AjaxResult getInfo(@PathVariable Long postId)
    {
        return AjaxResult.success(postService.selectPostById(postId));
    }
    /**
     * æ–°å¢žå²—位
     */
    @PreAuthorize("@ss.hasPermi('system:post:add')")
    @Log(title = "岗位管理", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@Validated @RequestBody SysPost post)
    {
        if (UserConstants.NOT_UNIQUE.equals(postService.checkPostNameUnique(post)))
        {
            return AjaxResult.error("新增岗位'" + post.getPostName() + "'失败,岗位名称已存在");
        }
        else if (UserConstants.NOT_UNIQUE.equals(postService.checkPostCodeUnique(post)))
        {
            return AjaxResult.error("新增岗位'" + post.getPostName() + "'失败,岗位编码已存在");
        }
        post.setCreateBy(SecurityUtils.getUsername());
        return toAjax(postService.insertPost(post));
    }
    /**
     * ä¿®æ”¹å²—位
     */
    @PreAuthorize("@ss.hasPermi('system:post:edit')")
    @Log(title = "岗位管理", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@Validated @RequestBody SysPost post)
    {
        if (UserConstants.NOT_UNIQUE.equals(postService.checkPostNameUnique(post)))
        {
            return AjaxResult.error("修改岗位'" + post.getPostName() + "'失败,岗位名称已存在");
        }
        else if (UserConstants.NOT_UNIQUE.equals(postService.checkPostCodeUnique(post)))
        {
            return AjaxResult.error("修改岗位'" + post.getPostName() + "'失败,岗位编码已存在");
        }
        post.setUpdateBy(SecurityUtils.getUsername());
        return toAjax(postService.updatePost(post));
    }
    /**
     * åˆ é™¤å²—位
     */
    @PreAuthorize("@ss.hasPermi('system:post:remove')")
    @Log(title = "岗位管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/{postIds}")
    public AjaxResult remove(@PathVariable Long[] postIds)
    {
        return toAjax(postService.deletePostByIds(postIds));
    }
    /**
     * èŽ·å–å²—ä½é€‰æ‹©æ¡†åˆ—è¡¨
     */
    @GetMapping("/optionselect")
    public AjaxResult optionselect()
    {
        List<SysPost> posts = postService.selectPostAll();
        return AjaxResult.success(posts);
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,127 @@
package com.ruoyi.web.controller.system;
import java.io.IOException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.system.service.ISysUserService;
/**
 * ä¸ªäººä¿¡æ¯ ä¸šåŠ¡å¤„ç†
 *
 * @author ruoyi
 */
@RestController
@RequestMapping("/system/user/profile")
public class SysProfileController extends BaseController
{
    @Autowired
    private ISysUserService userService;
    @Autowired
    private TokenService tokenService;
    /**
     * ä¸ªäººä¿¡æ¯
     */
    @GetMapping
    public AjaxResult profile()
    {
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        SysUser user = loginUser.getUser();
        AjaxResult ajax = AjaxResult.success(user);
        ajax.put("roleGroup", userService.selectUserRoleGroup(loginUser.getUsername()));
        ajax.put("postGroup", userService.selectUserPostGroup(loginUser.getUsername()));
        return ajax;
    }
    /**
     * ä¿®æ”¹ç”¨æˆ·
     */
    @Log(title = "个人信息", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult updateProfile(@RequestBody SysUser user)
    {
        if (userService.updateUserProfile(user) > 0)
        {
            LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
            // æ›´æ–°ç¼“存用户信息
            loginUser.getUser().setNickName(user.getNickName());
            loginUser.getUser().setPhonenumber(user.getPhonenumber());
            loginUser.getUser().setEmail(user.getEmail());
            loginUser.getUser().setSex(user.getSex());
            tokenService.setLoginUser(loginUser);
            return AjaxResult.success();
        }
        return AjaxResult.error("修改个人信息异常,请联系管理员");
    }
    /**
     * é‡ç½®å¯†ç 
     */
    @Log(title = "个人信息", businessType = BusinessType.UPDATE)
    @PutMapping("/updatePwd")
    public AjaxResult updatePwd(String oldPassword, String newPassword)
    {
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        String userName = loginUser.getUsername();
        String password = loginUser.getPassword();
        if (!SecurityUtils.matchesPassword(oldPassword, password))
        {
            return AjaxResult.error("修改密码失败,旧密码错误");
        }
        if (SecurityUtils.matchesPassword(newPassword, password))
        {
            return AjaxResult.error("新密码不能与旧密码相同");
        }
        if (userService.resetUserPwd(userName, SecurityUtils.encryptPassword(newPassword)) > 0)
        {
            // æ›´æ–°ç¼“存用户密码
            loginUser.getUser().setPassword(SecurityUtils.encryptPassword(newPassword));
            tokenService.setLoginUser(loginUser);
            return AjaxResult.success();
        }
        return AjaxResult.error("修改密码异常,请联系管理员");
    }
    /**
     * å¤´åƒä¸Šä¼ 
     */
    @Log(title = "用户头像", businessType = BusinessType.UPDATE)
    @PostMapping("/avatar")
    public AjaxResult avatar(@RequestParam("avatarfile") MultipartFile file) throws IOException
    {
        if (!file.isEmpty())
        {
            LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
            String avatar = FileUploadUtils.upload(RuoYiConfig.getAvatarPath(), file);
            if (userService.updateUserAvatar(loginUser.getUsername(), avatar))
            {
                AjaxResult ajax = AjaxResult.success();
                ajax.put("imgUrl", avatar);
                // æ›´æ–°ç¼“存用户头像
                loginUser.getUser().setAvatar(avatar);
                tokenService.setLoginUser(loginUser);
                return ajax;
            }
        }
        return AjaxResult.error("上传图片异常,请联系管理员");
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,154 @@
package com.ruoyi.web.controller.system;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
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.entity.SysRole;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.service.ISysRoleService;
/**
 * è§’色信息
 *
 * @author ruoyi
 */
@RestController
@RequestMapping("/system/role")
public class SysRoleController extends BaseController
{
    @Autowired
    private ISysRoleService roleService;
    @PreAuthorize("@ss.hasPermi('system:role:list')")
    @GetMapping("/list")
    public TableDataInfo list(SysRole role)
    {
        startPage();
        List<SysRole> list = roleService.selectRoleList(role);
        return getDataTable(list);
    }
    @Log(title = "角色管理", businessType = BusinessType.EXPORT)
    @PreAuthorize("@ss.hasPermi('system:role:export')")
    @GetMapping("/export")
    public AjaxResult export(SysRole role)
    {
        List<SysRole> list = roleService.selectRoleList(role);
        ExcelUtil<SysRole> util = new ExcelUtil<SysRole>(SysRole.class);
        return util.exportExcel(list, "角色数据");
    }
    /**
     * æ ¹æ®è§’色编号获取详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:role:query')")
    @GetMapping(value = "/{roleId}")
    public AjaxResult getInfo(@PathVariable Long roleId)
    {
        return AjaxResult.success(roleService.selectRoleById(roleId));
    }
    /**
     * æ–°å¢žè§’色
     */
    @PreAuthorize("@ss.hasPermi('system:role:add')")
    @Log(title = "角色管理", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@Validated @RequestBody SysRole role)
    {
        if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleNameUnique(role)))
        {
            return AjaxResult.error("新增角色'" + role.getRoleName() + "'失败,角色名称已存在");
        }
        else if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleKeyUnique(role)))
        {
            return AjaxResult.error("新增角色'" + role.getRoleName() + "'失败,角色权限已存在");
        }
        role.setCreateBy(SecurityUtils.getUsername());
        return toAjax(roleService.insertRole(role));
    }
    /**
     * ä¿®æ”¹ä¿å­˜è§’色
     */
    @PreAuthorize("@ss.hasPermi('system:role:edit')")
    @Log(title = "角色管理", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@Validated @RequestBody SysRole role)
    {
        roleService.checkRoleAllowed(role);
        if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleNameUnique(role)))
        {
            return AjaxResult.error("修改角色'" + role.getRoleName() + "'失败,角色名称已存在");
        }
        else if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleKeyUnique(role)))
        {
            return AjaxResult.error("修改角色'" + role.getRoleName() + "'失败,角色权限已存在");
        }
        role.setUpdateBy(SecurityUtils.getUsername());
        return toAjax(roleService.updateRole(role));
    }
    /**
     * ä¿®æ”¹ä¿å­˜æ•°æ®æƒé™
     */
    @PreAuthorize("@ss.hasPermi('system:role:edit')")
    @Log(title = "角色管理", businessType = BusinessType.UPDATE)
    @PutMapping("/dataScope")
    public AjaxResult dataScope(@RequestBody SysRole role)
    {
        roleService.checkRoleAllowed(role);
        return toAjax(roleService.authDataScope(role));
    }
    /**
     * çŠ¶æ€ä¿®æ”¹
     */
    @PreAuthorize("@ss.hasPermi('system:role:edit')")
    @Log(title = "角色管理", businessType = BusinessType.UPDATE)
    @PutMapping("/changeStatus")
    public AjaxResult changeStatus(@RequestBody SysRole role)
    {
        roleService.checkRoleAllowed(role);
        role.setUpdateBy(SecurityUtils.getUsername());
        return toAjax(roleService.updateRoleStatus(role));
    }
    /**
     * åˆ é™¤è§’色
     */
    @PreAuthorize("@ss.hasPermi('system:role:remove')")
    @Log(title = "角色管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/{roleIds}")
    public AjaxResult remove(@PathVariable Long[] roleIds)
    {
        return toAjax(roleService.deleteRoleByIds(roleIds));
    }
    /**
     * èŽ·å–è§’è‰²é€‰æ‹©æ¡†åˆ—è¡¨
     */
    @PreAuthorize("@ss.hasPermi('system:role:query')")
    @GetMapping("/optionselect")
    public AjaxResult optionselect()
    {
        return AjaxResult.success(roleService.selectRoleAll());
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,201 @@
package com.ruoyi.web.controller.system;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
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.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.system.service.ISysPostService;
import com.ruoyi.system.service.ISysRoleService;
import com.ruoyi.system.service.ISysUserService;
/**
 * ç”¨æˆ·ä¿¡æ¯
 *
 * @author ruoyi
 */
@RestController
@RequestMapping("/system/user")
public class SysUserController extends BaseController
{
    @Autowired
    private ISysUserService userService;
    @Autowired
    private ISysRoleService roleService;
    @Autowired
    private ISysPostService postService;
    @Autowired
    private TokenService tokenService;
    /**
     * èŽ·å–ç”¨æˆ·åˆ—è¡¨
     */
    @PreAuthorize("@ss.hasPermi('system:user:list')")
    @GetMapping("/list")
    public TableDataInfo list(SysUser user)
    {
        startPage();
        List<SysUser> list = userService.selectUserList(user);
        return getDataTable(list);
    }
    @Log(title = "用户管理", businessType = BusinessType.EXPORT)
    @PreAuthorize("@ss.hasPermi('system:user:export')")
    @GetMapping("/export")
    public AjaxResult export(SysUser user)
    {
        List<SysUser> list = userService.selectUserList(user);
        ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
        return util.exportExcel(list, "用户数据");
    }
    @Log(title = "用户管理", businessType = BusinessType.IMPORT)
    @PreAuthorize("@ss.hasPermi('system:user:import')")
    @PostMapping("/importData")
    public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception
    {
        ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
        List<SysUser> userList = util.importExcel(file.getInputStream());
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        String operName = loginUser.getUsername();
        String message = userService.importUser(userList, updateSupport, operName);
        return AjaxResult.success(message);
    }
    @GetMapping("/importTemplate")
    public AjaxResult importTemplate()
    {
        ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
        return util.importTemplateExcel("用户数据");
    }
    /**
     * æ ¹æ®ç”¨æˆ·ç¼–号获取详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:user:query')")
    @GetMapping(value = { "/", "/{userId}" })
    public AjaxResult getInfo(@PathVariable(value = "userId", required = false) Long userId)
    {
        AjaxResult ajax = AjaxResult.success();
        List<SysRole> roles = roleService.selectRoleAll();
        ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
        ajax.put("posts", postService.selectPostAll());
        if (StringUtils.isNotNull(userId))
        {
            ajax.put(AjaxResult.DATA_TAG, userService.selectUserById(userId));
            ajax.put("postIds", postService.selectPostListByUserId(userId));
            ajax.put("roleIds", roleService.selectRoleListByUserId(userId));
        }
        return ajax;
    }
    /**
     * æ–°å¢žç”¨æˆ·
     */
    @PreAuthorize("@ss.hasPermi('system:user:add')")
    @Log(title = "用户管理", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@Validated @RequestBody SysUser user)
    {
        if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(user.getUserName())))
        {
            return AjaxResult.error("新增用户'" + user.getUserName() + "'失败,登录账号已存在");
        }
        else if (UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user)))
        {
            return AjaxResult.error("新增用户'" + user.getUserName() + "'失败,手机号码已存在");
        }
        else if (UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user)))
        {
            return AjaxResult.error("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在");
        }
        user.setCreateBy(SecurityUtils.getUsername());
        user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
        return toAjax(userService.insertUser(user));
    }
    /**
     * ä¿®æ”¹ç”¨æˆ·
     */
    @PreAuthorize("@ss.hasPermi('system:user:edit')")
    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@Validated @RequestBody SysUser user)
    {
        userService.checkUserAllowed(user);
        if (UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user)))
        {
            return AjaxResult.error("修改用户'" + user.getUserName() + "'失败,手机号码已存在");
        }
        else if (UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user)))
        {
            return AjaxResult.error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在");
        }
        user.setUpdateBy(SecurityUtils.getUsername());
        return toAjax(userService.updateUser(user));
    }
    /**
     * åˆ é™¤ç”¨æˆ·
     */
    @PreAuthorize("@ss.hasPermi('system:user:remove')")
    @Log(title = "用户管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/{userIds}")
    public AjaxResult remove(@PathVariable Long[] userIds)
    {
        return toAjax(userService.deleteUserByIds(userIds));
    }
    /**
     * é‡ç½®å¯†ç 
     */
    @PreAuthorize("@ss.hasPermi('system:user:edit')")
    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
    @PutMapping("/resetPwd")
    public AjaxResult resetPwd(@RequestBody SysUser user)
    {
        userService.checkUserAllowed(user);
        user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
        user.setUpdateBy(SecurityUtils.getUsername());
        return toAjax(userService.resetPwd(user));
    }
    /**
     * çŠ¶æ€ä¿®æ”¹
     */
    @PreAuthorize("@ss.hasPermi('system:user:edit')")
    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
    @PutMapping("/changeStatus")
    public AjaxResult changeStatus(@RequestBody SysUser user)
    {
        userService.checkUserAllowed(user);
        user.setUpdateBy(SecurityUtils.getUsername());
        return toAjax(userService.updateUserStatus(user));
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/SwaggerController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,24 @@
package com.ruoyi.web.controller.tool;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import com.ruoyi.common.core.controller.BaseController;
/**
 * swagger æŽ¥å£
 *
 * @author ruoyi
 */
@Controller
@RequestMapping("/tool/swagger")
public class SwaggerController extends BaseController
{
    @PreAuthorize("@ss.hasPermi('tool:swagger:view')")
    @GetMapping()
    public String index()
    {
        return redirect("/swagger-ui.html");
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/TestController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,175 @@
package com.ruoyi.web.controller.tool;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.StringUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
/**
 * swagger ç”¨æˆ·æµ‹è¯•方法
 *
 * @author ruoyi
 */
@Api("用户信息管理")
@RestController
@RequestMapping("/test/user")
public class TestController extends BaseController
{
    private final static Map<Integer, UserEntity> users = new LinkedHashMap<Integer, UserEntity>();
    {
        users.put(1, new UserEntity(1, "admin", "admin123", "15888888888"));
        users.put(2, new UserEntity(2, "ry", "admin123", "15666666666"));
    }
    @ApiOperation("获取用户列表")
    @GetMapping("/list")
    public AjaxResult userList()
    {
        List<UserEntity> userList = new ArrayList<UserEntity>(users.values());
        return AjaxResult.success(userList);
    }
    @ApiOperation("获取用户详细")
    @ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path")
    @GetMapping("/{userId}")
    public AjaxResult getUser(@PathVariable Integer userId)
    {
        if (!users.isEmpty() && users.containsKey(userId))
        {
            return AjaxResult.success(users.get(userId));
        }
        else
        {
            return AjaxResult.error("用户不存在");
        }
    }
    @ApiOperation("新增用户")
    @ApiImplicitParam(name = "userEntity", value = "新增用户信息", dataType = "UserEntity")
    @PostMapping("/save")
    public AjaxResult save(UserEntity user)
    {
        if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId()))
        {
            return AjaxResult.error("用户ID不能为空");
        }
        return AjaxResult.success(users.put(user.getUserId(), user));
    }
    @ApiOperation("更新用户")
    @ApiImplicitParam(name = "userEntity", value = "新增用户信息", dataType = "UserEntity")
    @PutMapping("/update")
    public AjaxResult update(UserEntity user)
    {
        if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId()))
        {
            return AjaxResult.error("用户ID不能为空");
        }
        if (users.isEmpty() || !users.containsKey(user.getUserId()))
        {
            return AjaxResult.error("用户不存在");
        }
        users.remove(user.getUserId());
        return AjaxResult.success(users.put(user.getUserId(), user));
    }
    @ApiOperation("删除用户信息")
    @ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path")
    @DeleteMapping("/{userId}")
    public AjaxResult delete(@PathVariable Integer userId)
    {
        if (!users.isEmpty() && users.containsKey(userId))
        {
            users.remove(userId);
            return AjaxResult.success();
        }
        else
        {
            return AjaxResult.error("用户不存在");
        }
    }
}
@ApiModel("用户实体")
class UserEntity
{
    @ApiModelProperty("用户ID")
    private Integer userId;
    @ApiModelProperty("用户名称")
    private String username;
    @ApiModelProperty("用户密码")
    private String password;
    @ApiModelProperty("用户手机")
    private String mobile;
    public UserEntity()
    {
    }
    public UserEntity(Integer userId, String username, String password, String mobile)
    {
        this.userId = userId;
        this.username = username;
        this.password = password;
        this.mobile = mobile;
    }
    public Integer getUserId()
    {
        return userId;
    }
    public void setUserId(Integer userId)
    {
        this.userId = userId;
    }
    public String getUsername()
    {
        return username;
    }
    public void setUsername(String username)
    {
        this.username = username;
    }
    public String getPassword()
    {
        return password;
    }
    public void setPassword(String password)
    {
        this.password = password;
    }
    public String getMobile()
    {
        return mobile;
    }
    public void setMobile(String mobile)
    {
        this.mobile = mobile;
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/core/config/SwaggerConfig.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,125 @@
package com.ruoyi.web.core.config;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.ruoyi.common.config.RuoYiConfig;
import io.swagger.annotations.ApiOperation;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.ApiKey;
import springfox.documentation.service.AuthorizationScope;
import springfox.documentation.service.Contact;
import springfox.documentation.service.SecurityReference;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
 * Swagger2的接口配置
 *
 * @author ruoyi
 */
@Configuration
@EnableSwagger2
public class SwaggerConfig
{
    /** ç³»ç»ŸåŸºç¡€é…ç½® */
    @Autowired
    private RuoYiConfig ruoyiConfig;
    /** æ˜¯å¦å¼€å¯swagger */
    @Value("${swagger.enabled}")
    private boolean enabled;
    /** è®¾ç½®è¯·æ±‚的统一前缀 */
    @Value("${swagger.pathMapping}")
    private String pathMapping;
    /**
     * åˆ›å»ºAPI
     */
    @Bean
    public Docket createRestApi()
    {
        return new Docket(DocumentationType.SWAGGER_2)
                // æ˜¯å¦å¯ç”¨Swagger
                .enable(enabled)
                // ç”¨æ¥åˆ›å»ºè¯¥API的基本信息,展示在文档的页面中(自定义展示的信息)
                .apiInfo(apiInfo())
                // è®¾ç½®å“ªäº›æŽ¥å£æš´éœ²ç»™Swagger展示
                .select()
                // æ‰«ææ‰€æœ‰æœ‰æ³¨è§£çš„api,用这种方式更灵活
                .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
                // æ‰«ææŒ‡å®šåŒ…中的swagger注解
                // .apis(RequestHandlerSelectors.basePackage("com.ruoyi.project.tool.swagger"))
                // æ‰«ææ‰€æœ‰ .apis(RequestHandlerSelectors.any())
                .paths(PathSelectors.any())
                .build()
                /* è®¾ç½®å®‰å…¨æ¨¡å¼ï¼Œswagger可以设置访问token */
                .securitySchemes(securitySchemes())
                .securityContexts(securityContexts())
                .pathMapping(pathMapping);
    }
    /**
     * å®‰å…¨æ¨¡å¼ï¼Œè¿™é‡ŒæŒ‡å®štoken通过Authorization头请求头传递
     */
    private List<ApiKey> securitySchemes()
    {
        List<ApiKey> apiKeyList = new ArrayList<ApiKey>();
        apiKeyList.add(new ApiKey("Authorization", "Authorization", "header"));
        return apiKeyList;
    }
    /**
     * å®‰å…¨ä¸Šä¸‹æ–‡
     */
    private List<SecurityContext> securityContexts()
    {
        List<SecurityContext> securityContexts = new ArrayList<>();
        securityContexts.add(
                SecurityContext.builder()
                        .securityReferences(defaultAuth())
                        .forPaths(PathSelectors.regex("^(?!auth).*$"))
                        .build());
        return securityContexts;
    }
    /**
     * é»˜è®¤çš„安全上引用
     */
    private List<SecurityReference> defaultAuth()
    {
        AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
        AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
        authorizationScopes[0] = authorizationScope;
        List<SecurityReference> securityReferences = new ArrayList<>();
        securityReferences.add(new SecurityReference("Authorization", authorizationScopes));
        return securityReferences;
    }
    /**
     * æ·»åŠ æ‘˜è¦ä¿¡æ¯
     */
    private ApiInfo apiInfo()
    {
        // ç”¨ApiInfoBuilder进行定制
        return new ApiInfoBuilder()
                // è®¾ç½®æ ‡é¢˜
                .title("标题:若依管理系统_接口文档")
                // æè¿°
                .description("描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...")
                // ä½œè€…信息
                .contact(new Contact(ruoyiConfig.getName(), null, null))
                // ç‰ˆæœ¬
                .version("版本号:" + ruoyiConfig.getVersion())
                .build();
    }
}
ruoyi-admin/src/main/resources/META-INF/spring-devtools.properties
ruoyi-admin/src/main/resources/application-dev.yml
ruoyi-admin/src/main/resources/application-prop.yml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,77 @@
# æ•°æ®æºé…ç½®
spring:
    datasource:
        type: com.alibaba.druid.pool.DruidDataSource
        driverClassName: com.mysql.cj.jdbc.Driver
        druid:
            # ä¸»åº“数据源
            master:
                url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true
                username: root
                password: root
            # ä»Žåº“数据源
            slave:
                # ä»Žæ•°æ®æºå¼€å…³/默认关闭
                enabled: false
                url:
                username:
                password:
            # åˆå§‹è¿žæŽ¥æ•°
            initialSize: 5
            # æœ€å°è¿žæŽ¥æ± æ•°é‡
            minIdle: 10
            # æœ€å¤§è¿žæŽ¥æ± æ•°é‡
            maxActive: 20
            # é…ç½®èŽ·å–è¿žæŽ¥ç­‰å¾…è¶…æ—¶çš„æ—¶é—´
            maxWait: 60000
            # é…ç½®é—´éš”多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
            timeBetweenEvictionRunsMillis: 60000
            # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å°ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
            minEvictableIdleTimeMillis: 300000
            # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å¤§ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
            maxEvictableIdleTimeMillis: 900000
            # é…ç½®æ£€æµ‹è¿žæŽ¥æ˜¯å¦æœ‰æ•ˆ
            validationQuery: SELECT 1 FROM DUAL
            testWhileIdle: true
            testOnBorrow: false
            testOnReturn: false
            webStatFilter:
                enabled: true
            statViewServlet:
                enabled: true
                # è®¾ç½®ç™½åå•,不填则允许所有访问
                allow:
                url-pattern: /druid/*
                # æŽ§åˆ¶å°ç®¡ç†ç”¨æˆ·åå’Œå¯†ç 
                login-username:
                login-password:
            filter:
                stat:
                    enabled: true
                    # æ…¢SQL记录
                    log-slow-sql: true
                    slow-sql-millis: 1000
                    merge-sql: true
                wall:
                    config:
                        multi-statement-allow: true
    # redis é…ç½®
    redis:
        # åœ°å€
        host: 192.168.0.222
        # ç«¯å£ï¼Œé»˜è®¤ä¸º6379
        port: 6379
        # å¯†ç 
        password:
        # è¿žæŽ¥è¶…æ—¶æ—¶é—´
        timeout: 10s
        lettuce:
            pool:
                # è¿žæŽ¥æ± ä¸­çš„æœ€å°ç©ºé—²è¿žæŽ¥
                min-idle: 0
                # è¿žæŽ¥æ± ä¸­çš„æœ€å¤§ç©ºé—²è¿žæŽ¥
                max-idle: 8
                # è¿žæŽ¥æ± çš„æœ€å¤§æ•°æ®åº“连接数
                max-active: 8
                # #连接池最大阻塞等待时间(使用负值表示没有限制)
                max-wait: -1ms
ruoyi-admin/src/main/resources/application.yml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,125 @@
# é¡¹ç›®ç›¸å…³é…ç½®
ruoyi:
  # åç§°
  name: RuoYi
  # ç‰ˆæœ¬
  version: 3.0.0
  # ç‰ˆæƒå¹´ä»½
  copyrightYear: 2019
  # å®žä¾‹æ¼”示开关
  demoEnabled: true
  # æ–‡ä»¶è·¯å¾„ ç¤ºä¾‹ï¼ˆ Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
  profile: D:/ruoyi/uploadPath
  # èŽ·å–ip地址开关
  addressEnabled: false
# å¼€å‘环境配置
server:
  # æœåŠ¡å™¨çš„HTTP端口,默认为8080
  port: 8081
  servlet:
    # åº”用的访问路径
    context-path: /
  undertow:
    # è®¾ç½®IO线程数, å®ƒä¸»è¦æ‰§è¡Œéžé˜»å¡žçš„任务,它们会负责多个连接, é»˜è®¤è®¾ç½®æ¯ä¸ªCPU核心一个线程
    io-threads: 8
    # é˜»å¡žä»»åŠ¡çº¿ç¨‹æ± , å½“执行类似servlet请求阻塞操作, undertow会从这个线程池中取得线程,它的值设置取决于系统的负载
    worker-threads: 256
    # ä»¥ä¸‹çš„配置会影响buffer,这些buffer会用于服务器连接的IO操作,有点类似netty的池化内存管理
    # æ¯å—buffer的空间大小,越小的空间被利用越充分
    buffer-size: 512
    # æ˜¯å¦åˆ†é…çš„直接内存
    direct-buffers: true
# æ—¥å¿—配置
logging:
  level:
    com.ruoyi: debug
    org.springframework: warn
# Spring配置
spring:
  # èµ„源信息
  messages:
    # å›½é™…化资源文件路径
    basename: i18n/messages
  profiles:
    active: dev
  # æ–‡ä»¶ä¸Šä¼ 
  servlet:
     multipart:
       # å•个文件大小
       max-file-size:  10MB
       # è®¾ç½®æ€»ä¸Šä¼ çš„æ–‡ä»¶å¤§å°
       max-request-size:  20MB
  # æœåŠ¡æ¨¡å—
  devtools:
    restart:
      # çƒ­éƒ¨ç½²å¼€å…³
      enabled: true
# token配置
token:
    # ä»¤ç‰Œè‡ªå®šä¹‰æ ‡è¯†
    header: Authorization
    # ä»¤ç‰Œå¯†é’¥
    secret: abcdefghijklmnopqrstuvwxyz
    # ä»¤ç‰Œæœ‰æ•ˆæœŸï¼ˆé»˜è®¤30分钟)
    expireTime: 30
# MyBatis配置
mybatis-plus:
  mapper-locations: classpath*:mapper/**/*Mapper.xml
  #实体扫描,多个package用逗号或者分号分隔
  typeAliasesPackage: com.ruoyi.**.domain
  configuration:
    map-underscore-to-camel-case: true
    cache-enabled: true
  global-config:
    banner: false
    #刷新mapper è°ƒè¯•神器
    refresh: true
    db-config:
      #主键类型  0:"数据库ID自增", 1:"用户输入ID",2:"全局唯一ID (数字类型唯一ID)", 3:"全局唯一ID UUID";
      id-type: auto
      #字段策略 0:"忽略判断",1:"非 NULL åˆ¤æ–­"),2:"非空判断"
      field-strategy: not_empty
      #驼峰下划线转换
      db-column-underline: true
      #数据库大写下划线转换
      #capital-mode: true
      #序列接口实现类配置
      #key-generator: com.baomidou.springboot.xxx
      #逻辑删除配置
      logic-delete-value: 1
      logic-not-delete-value: 0
      #数据库类型
      db-type: mysql
    #自定义SQL注入器
    #sql-injector: com.baomidou.mybatisplus.mapper.LogicSqlInjector
    #自定义填充策略接口实现
    #meta-object-handler: com.baomidou.springboot.xxx
# PageHelper分页插件
pagehelper:
  helperDialect: mysql
  reasonable: true
  supportMethodsArguments: true
  params: count=countSql
# Swagger配置
swagger:
  # æ˜¯å¦å¼€å¯swagger
  enabled: true
  # è¯·æ±‚前缀
  pathMapping: /dev-api
# é˜²æ­¢XSS攻击
xss:
  # è¿‡æ»¤å¼€å…³
  enabled: true
  # æŽ’除链接(多个用逗号分隔)
  excludes: /system/notice/*
  # åŒ¹é…é“¾æŽ¥
  urlPatterns: /system/*,/monitor/*,/tool/*
ruoyi-admin/src/main/resources/banner.txt
ruoyi-admin/src/main/resources/i18n/messages.properties
ruoyi-admin/src/main/resources/logback.xml
ruoyi-admin/src/main/resources/mybatis/mybatis-config.xml
ruoyi-common/pom.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,141 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>ruoyi</artifactId>
        <groupId>com.ruoyi</groupId>
        <version>3.0.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>ruoyi-common</artifactId>
    <description>
        common通用工具
    </description>
    <dependencies>
        <!-- Spring框架基本的核心工具 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
        </dependency>
        <!-- SpringWeb模块 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
        </dependency>
        <!-- spring security å®‰å…¨è®¤è¯ -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <!-- pagehelper åˆ†é¡µæ’ä»¶ -->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
        </dependency>
        <!-- è‡ªå®šä¹‰éªŒè¯æ³¨è§£ -->
        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
        </dependency>
        <!--常用工具类 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>
        <!-- JSON工具类 -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>
        <!-- é˜¿é‡ŒJSON解析器 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
        </dependency>
        <!-- io常用工具类 -->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
        </dependency>
        <!-- æ–‡ä»¶ä¸Šä¼ å·¥å…·ç±» -->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
        </dependency>
        <!-- excel工具 -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
        </dependency>
        <!-- yml解析器 -->
        <dependency>
            <groupId>org.yaml</groupId>
            <artifactId>snakeyaml</artifactId>
        </dependency>
        <!--Token生成与解析-->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
        </dependency>
        <!-- redis ç¼“存操作 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <!-- pool å¯¹è±¡æ±  -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>
        <!-- è§£æžå®¢æˆ·ç«¯æ“ä½œç³»ç»Ÿã€æµè§ˆå™¨ç­‰ -->
        <dependency>
            <groupId>eu.bitwalker</groupId>
            <artifactId>UserAgentUtils</artifactId>
        </dependency>
        <!-- servlet包 -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-extension</artifactId>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>
</project>
ruoyi-common/src/main/java/com/ruoyi/common/annotation/DataScope.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,28 @@
package com.ruoyi.common.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
 * æ•°æ®æƒé™è¿‡æ»¤æ³¨è§£
 *
 * @author ruoyi
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataScope
{
    /**
     * éƒ¨é—¨è¡¨çš„别名
     */
    public String deptAlias() default "";
    /**
     * ç”¨æˆ·è¡¨çš„别名
     */
    public String userAlias() default "";
}
ruoyi-common/src/main/java/com/ruoyi/common/annotation/DataSource.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,28 @@
package com.ruoyi.common.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import com.ruoyi.common.enums.DataSourceType;
/**
 * è‡ªå®šä¹‰å¤šæ•°æ®æºåˆ‡æ¢æ³¨è§£
 *
 * ä¼˜å…ˆçº§ï¼šå…ˆæ–¹æ³•,后类,如果方法覆盖了类上的数据源类型,以方法的为准,否则以类上的为准
 *
 * @author ruoyi
 */
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface DataSource
{
    /**
     * åˆ‡æ¢æ•°æ®æºåç§°
     */
    public DataSourceType value() default DataSourceType.MASTER;
}
ruoyi-common/src/main/java/com/ruoyi/common/annotation/Excel.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,118 @@
package com.ruoyi.common.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
 * è‡ªå®šä¹‰å¯¼å‡ºExcel数据注解
 *
 * @author ruoyi
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Excel
{
    /**
     * å¯¼å‡ºæ—¶åœ¨excel中排序
     */
    public int sort() default Integer.MAX_VALUE;
    /**
     * å¯¼å‡ºåˆ°Excel中的名字.
     */
    public String name() default "";
    /**
     * æ—¥æœŸæ ¼å¼, å¦‚: yyyy-MM-dd
     */
    public String dateFormat() default "";
    /**
     * è¯»å–内容转表达式 (如: 0=男,1=女,2=未知)
     */
    public String readConverterExp() default "";
    /**
     * å¯¼å‡ºç±»åž‹ï¼ˆ0数字 1字符串)
     */
    public ColumnType cellType() default ColumnType.STRING;
    /**
     * å¯¼å‡ºæ—¶åœ¨excel中每个列的高度 å•位为字符
     */
    public double height() default 14;
    /**
     * å¯¼å‡ºæ—¶åœ¨excel中每个列的宽 å•位为字符
     */
    public double width() default 16;
    /**
     * æ–‡å­—后缀,如% 90 å˜æˆ90%
     */
    public String suffix() default "";
    /**
     * å½“值为空时,字段的默认值
     */
    public String defaultValue() default "";
    /**
     * æç¤ºä¿¡æ¯
     */
    public String prompt() default "";
    /**
     * è®¾ç½®åªèƒ½é€‰æ‹©ä¸èƒ½è¾“入的列内容.
     */
    public String[] combo() default {};
    /**
     * æ˜¯å¦å¯¼å‡ºæ•°æ®,应对需求:有时我们需要导出一份模板,这是标题需要但内容需要用户手工填写.
     */
    public boolean isExport() default true;
    /**
     * å¦ä¸€ä¸ªç±»ä¸­çš„属性名称,支持多级获取,以小数点隔开
     */
    public String targetAttr() default "";
    /**
     * å­—段类型(0:导出导入;1:仅导出;2:仅导入)
     */
    Type type() default Type.ALL;
    public enum Type
    {
        ALL(0), EXPORT(1), IMPORT(2);
        private final int value;
        Type(int value)
        {
            this.value = value;
        }
        public int value()
        {
            return this.value;
        }
    }
    public enum ColumnType
    {
        NUMERIC(0), STRING(1);
        private final int value;
        ColumnType(int value)
        {
            this.value = value;
        }
        public int value()
        {
            return this.value;
        }
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/annotation/Excels.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,18 @@
package com.ruoyi.common.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
 * Excel注解集
 *
 * @author ruoyi
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Excels
{
    Excel[] value();
}
ruoyi-common/src/main/java/com/ruoyi/common/annotation/Log.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,41 @@
package com.ruoyi.common.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.enums.OperatorType;
/**
 * è‡ªå®šä¹‰æ“ä½œæ—¥å¿—记录注解
 *
 * @author ruoyi
 *
 */
@Target({ ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Log
{
    /**
     * æ¨¡å—
     */
    public String title() default "";
    /**
     * åŠŸèƒ½
     */
    public BusinessType businessType() default BusinessType.OTHER;
    /**
     * æ“ä½œäººç±»åˆ«
     */
    public OperatorType operatorType() default OperatorType.MANAGE;
    /**
     * æ˜¯å¦ä¿å­˜è¯·æ±‚的参数
     */
    public boolean isSaveRequestData() default true;
}
ruoyi-common/src/main/java/com/ruoyi/common/annotation/RepeatSubmit.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,23 @@
package com.ruoyi.common.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
 * è‡ªå®šä¹‰æ³¨è§£é˜²æ­¢è¡¨å•重复提交
 *
 * @author ruoyi
 *
 */
@Inherited
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RepeatSubmit
{
}
ruoyi-common/src/main/java/com/ruoyi/common/config/RuoYiConfig.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,116 @@
package com.ruoyi.common.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
 * è¯»å–项目相关配置
 *
 * @author ruoyi
 */
@Component
@ConfigurationProperties(prefix = "ruoyi")
public class RuoYiConfig
{
    /** é¡¹ç›®åç§° */
    private String name;
    /** ç‰ˆæœ¬ */
    private String version;
    /** ç‰ˆæƒå¹´ä»½ */
    private String copyrightYear;
    /** å®žä¾‹æ¼”示开关 */
    private boolean demoEnabled;
    /** ä¸Šä¼ è·¯å¾„ */
    private static String profile;
    /** èŽ·å–åœ°å€å¼€å…³ */
    private static boolean addressEnabled;
    public String getName()
    {
        return name;
    }
    public void setName(String name)
    {
        this.name = name;
    }
    public String getVersion()
    {
        return version;
    }
    public void setVersion(String version)
    {
        this.version = version;
    }
    public String getCopyrightYear()
    {
        return copyrightYear;
    }
    public void setCopyrightYear(String copyrightYear)
    {
        this.copyrightYear = copyrightYear;
    }
    public boolean isDemoEnabled()
    {
        return demoEnabled;
    }
    public void setDemoEnabled(boolean demoEnabled)
    {
        this.demoEnabled = demoEnabled;
    }
    public static String getProfile()
    {
        return profile;
    }
    public void setProfile(String profile)
    {
        RuoYiConfig.profile = profile;
    }
    public static boolean isAddressEnabled()
    {
        return addressEnabled;
    }
    public void setAddressEnabled(boolean addressEnabled)
    {
        RuoYiConfig.addressEnabled = addressEnabled;
    }
    /**
     * èŽ·å–å¤´åƒä¸Šä¼ è·¯å¾„
     */
    public static String getAvatarPath()
    {
        return getProfile() + "/avatar";
    }
    /**
     * èŽ·å–ä¸‹è½½è·¯å¾„
     */
    public static String getDownloadPath()
    {
        return getProfile() + "/download/";
    }
    /**
     * èŽ·å–ä¸Šä¼ è·¯å¾„
     */
    public static String getUploadPath()
    {
        return getProfile() + "/upload";
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,124 @@
package com.ruoyi.common.constant;
/**
 * é€šç”¨å¸¸é‡ä¿¡æ¯
 *
 * @author ruoyi
 */
public class Constants
{
    /**
     * UTF-8 å­—符集
     */
    public static final String UTF8 = "UTF-8";
    /**
     * GBK å­—符集
     */
    public static final String GBK = "GBK";
    /**
     * http请求
     */
    public static final String HTTP = "http://";
    /**
     * https请求
     */
    public static final String HTTPS = "https://";
    /**
     * é€šç”¨æˆåŠŸæ ‡è¯†
     */
    public static final String SUCCESS = "0";
    /**
     * é€šç”¨å¤±è´¥æ ‡è¯†
     */
    public static final String FAIL = "1";
    /**
     * ç™»å½•成功
     */
    public static final String LOGIN_SUCCESS = "Success";
    /**
     * æ³¨é”€
     */
    public static final String LOGOUT = "Logout";
    /**
     * ç™»å½•失败
     */
    public static final String LOGIN_FAIL = "Error";
    /**
     * éªŒè¯ç  redis key
     */
    public static final String CAPTCHA_CODE_KEY = "captcha_codes:";
    /**
     * ç™»å½•用户 redis key
     */
    public static final String LOGIN_TOKEN_KEY = "login_tokens:";
    /**
     * éªŒè¯ç æœ‰æ•ˆæœŸï¼ˆåˆ†é’Ÿï¼‰
     */
    public static final Integer CAPTCHA_EXPIRATION = 2;
    /**
     * ä»¤ç‰Œ
     */
    public static final String TOKEN = "token";
    /**
     * ä»¤ç‰Œå‰ç¼€
     */
    public static final String TOKEN_PREFIX = "Bearer ";
    /**
     * ä»¤ç‰Œå‰ç¼€
     */
    public static final String LOGIN_USER_KEY = "login_user_key";
    /**
     * ç”¨æˆ·ID
     */
    public static final String JWT_USERID = "userid";
    /**
     * ç”¨æˆ·åç§°
     */
    public static final String JWT_USERNAME = "sub";
    /**
     * ç”¨æˆ·å¤´åƒ
     */
    public static final String JWT_AVATAR = "avatar";
    /**
     * åˆ›å»ºæ—¶é—´
     */
    public static final String JWT_CREATED = "created";
    /**
     * ç”¨æˆ·æƒé™
     */
    public static final String JWT_AUTHORITIES = "authorities";
    /**
     * å‚数管理 cache key
     */
    public static final String SYS_CONFIG_KEY = "sys_config:";
    /**
     * å­—典管理 cache key
     */
    public static final String SYS_DICT_KEY = "sys_dict:";
    /**
     * èµ„源映射路径 å‰ç¼€
     */
    public static final String RESOURCE_PREFIX = "/profile";
}
ruoyi-common/src/main/java/com/ruoyi/common/constant/GenConstants.java
ruoyi-common/src/main/java/com/ruoyi/common/constant/HttpStatus.java
ruoyi-common/src/main/java/com/ruoyi/common/constant/ScheduleConstants.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,50 @@
package com.ruoyi.common.constant;
/**
 * ä»»åŠ¡è°ƒåº¦é€šç”¨å¸¸é‡
 *
 * @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;
        }
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/constant/UserConstants.java
ruoyi-common/src/main/java/com/ruoyi/common/core/controller/BaseController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,94 @@
package com.ruoyi.common.core.controller;
import java.beans.PropertyEditorSupport;
import java.util.Date;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.PageDomain;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.page.TableSupport;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.sql.SqlUtil;
/**
 * web层通用数据处理
 *
 * @author ruoyi
 */
public class BaseController
{
    protected final Logger logger = LoggerFactory.getLogger(BaseController.class);
    /**
     * å°†å‰å°ä¼ é€’过来的日期格式的字符串,自动转化为Date类型
     */
    @InitBinder
    public void initBinder(WebDataBinder binder)
    {
        // Date ç±»åž‹è½¬æ¢
        binder.registerCustomEditor(Date.class, new PropertyEditorSupport()
        {
            @Override
            public void setAsText(String text)
            {
                setValue(DateUtils.parseDate(text));
            }
        });
    }
    /**
     * è®¾ç½®è¯·æ±‚分页数据
     */
    protected void startPage()
    {
        PageDomain pageDomain = TableSupport.buildPageRequest();
        Integer pageNum = pageDomain.getPageNum();
        Integer pageSize = pageDomain.getPageSize();
        if (StringUtils.isNotNull(pageNum) && StringUtils.isNotNull(pageSize))
        {
            String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());
            PageHelper.startPage(pageNum, pageSize, orderBy);
        }
    }
    /**
     * å“åº”请求分页数据
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    protected TableDataInfo getDataTable(List<?> list)
    {
        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(HttpStatus.SUCCESS);
        rspData.setMsg("查询成功");
        rspData.setRows(list);
        rspData.setTotal(new PageInfo(list).getTotal());
        return rspData;
    }
    /**
     * å“åº”返回结果
     *
     * @param rows å½±å“è¡Œæ•°
     * @return æ“ä½œç»“æžœ
     */
    protected AjaxResult toAjax(int rows)
    {
        return rows > 0 ? AjaxResult.success() : AjaxResult.error();
    }
    /**
     * é¡µé¢è·³è½¬
     */
    public String redirect(String url)
    {
        return StringUtils.format("redirect:{}", url);
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/AjaxResult.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,148 @@
package com.ruoyi.common.core.domain;
import java.util.HashMap;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.utils.StringUtils;
/**
 * æ“ä½œæ¶ˆæ¯æé†’
 *
 * @author ruoyi
 */
public class AjaxResult extends HashMap<String, Object>
{
    private static final long serialVersionUID = 1L;
    /** çŠ¶æ€ç  */
    public static final String CODE_TAG = "code";
    /** è¿”回内容 */
    public static final String MSG_TAG = "msg";
    /** æ•°æ®å¯¹è±¡ */
    public static final String DATA_TAG = "data";
    /**
     * åˆå§‹åŒ–一个新创建的 AjaxResult å¯¹è±¡ï¼Œä½¿å…¶è¡¨ç¤ºä¸€ä¸ªç©ºæ¶ˆæ¯ã€‚
     */
    public AjaxResult()
    {
    }
    /**
     * åˆå§‹åŒ–一个新创建的 AjaxResult å¯¹è±¡
     *
     * @param code çŠ¶æ€ç 
     * @param msg è¿”回内容
     */
    public AjaxResult(int code, String msg)
    {
        super.put(CODE_TAG, code);
        super.put(MSG_TAG, msg);
    }
    /**
     * åˆå§‹åŒ–一个新创建的 AjaxResult å¯¹è±¡
     *
     * @param code çŠ¶æ€ç 
     * @param msg è¿”回内容
     * @param data æ•°æ®å¯¹è±¡
     */
    public AjaxResult(int code, String msg, Object data)
    {
        super.put(CODE_TAG, code);
        super.put(MSG_TAG, msg);
        if (StringUtils.isNotNull(data))
        {
            super.put(DATA_TAG, data);
        }
    }
    /**
     * è¿”回成功消息
     *
     * @return æˆåŠŸæ¶ˆæ¯
     */
    public static AjaxResult success()
    {
        return AjaxResult.success("操作成功");
    }
    /**
     * è¿”回成功数据
     *
     * @return æˆåŠŸæ¶ˆæ¯
     */
    public static AjaxResult success(Object data)
    {
        return AjaxResult.success("操作成功", data);
    }
    /**
     * è¿”回成功消息
     *
     * @param msg è¿”回内容
     * @return æˆåŠŸæ¶ˆæ¯
     */
    public static AjaxResult success(String msg)
    {
        return AjaxResult.success(msg, null);
    }
    /**
     * è¿”回成功消息
     *
     * @param msg è¿”回内容
     * @param data æ•°æ®å¯¹è±¡
     * @return æˆåŠŸæ¶ˆæ¯
     */
    public static AjaxResult success(String msg, Object data)
    {
        return new AjaxResult(HttpStatus.SUCCESS, msg, data);
    }
    /**
     * è¿”回错误消息
     *
     * @return
     */
    public static AjaxResult error()
    {
        return AjaxResult.error("操作失败");
    }
    /**
     * è¿”回错误消息
     *
     * @param msg è¿”回内容
     * @return è­¦å‘Šæ¶ˆæ¯
     */
    public static AjaxResult error(String msg)
    {
        return AjaxResult.error(msg, null);
    }
    /**
     * è¿”回错误消息
     *
     * @param msg è¿”回内容
     * @param data æ•°æ®å¯¹è±¡
     * @return è­¦å‘Šæ¶ˆæ¯
     */
    public static AjaxResult error(String msg, Object data)
    {
        return new AjaxResult(HttpStatus.ERROR, msg, data);
    }
    /**
     * è¿”回错误消息
     *
     * @param code çŠ¶æ€ç 
     * @param msg è¿”回内容
     * @return è­¦å‘Šæ¶ˆæ¯
     */
    public static AjaxResult error(int code, String msg)
    {
        return new AjaxResult(code, msg, null);
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/BaseEntity.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,143 @@
package com.ruoyi.common.core.domain;
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
/**
 * Entity基类
 *
 * @author ruoyi
 */
public class BaseEntity implements Serializable
{
    private static final long serialVersionUID = 1L;
    /** æœç´¢å€¼ */
    private String searchValue;
    /** åˆ›å»ºè€… */
    private String createBy;
    /** åˆ›å»ºæ—¶é—´ */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createTime;
    /** æ›´æ–°è€… */
    private String updateBy;
    /** æ›´æ–°æ—¶é—´ */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date updateTime;
    /** å¤‡æ³¨ */
    private String remark;
    /** å¼€å§‹æ—¶é—´ */
    @JsonIgnore
    private String beginTime;
    /** ç»“束时间 */
    @JsonIgnore
    private String endTime;
    /** è¯·æ±‚参数 */
    private Map<String, Object> params;
    public String getSearchValue()
    {
        return searchValue;
    }
    public void setSearchValue(String searchValue)
    {
        this.searchValue = searchValue;
    }
    public String getCreateBy()
    {
        return createBy;
    }
    public void setCreateBy(String createBy)
    {
        this.createBy = createBy;
    }
    public Date getCreateTime()
    {
        return createTime;
    }
    public void setCreateTime(Date createTime)
    {
        this.createTime = createTime;
    }
    public String getUpdateBy()
    {
        return updateBy;
    }
    public void setUpdateBy(String updateBy)
    {
        this.updateBy = updateBy;
    }
    public Date getUpdateTime()
    {
        return updateTime;
    }
    public void setUpdateTime(Date updateTime)
    {
        this.updateTime = updateTime;
    }
    public String getRemark()
    {
        return remark;
    }
    public void setRemark(String remark)
    {
        this.remark = remark;
    }
    public String getBeginTime()
    {
        return beginTime;
    }
    public void setBeginTime(String beginTime)
    {
        this.beginTime = beginTime;
    }
    public String getEndTime()
    {
        return endTime;
    }
    public void setEndTime(String endTime)
    {
        this.endTime = endTime;
    }
    public Map<String, Object> getParams()
    {
        if (params == null)
        {
            params = new HashMap<>();
        }
        return params;
    }
    public void setParams(Map<String, Object> params)
    {
        this.params = params;
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/TreeEntity.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,79 @@
package com.ruoyi.common.core.domain;
import java.util.ArrayList;
import java.util.List;
/**
 * Tree基类
 *
 * @author ruoyi
 */
public class TreeEntity extends BaseEntity
{
    private static final long serialVersionUID = 1L;
    /** çˆ¶èœå•名称 */
    private String parentName;
    /** çˆ¶èœå•ID */
    private Long parentId;
    /** æ˜¾ç¤ºé¡ºåº */
    private Integer orderNum;
    /** ç¥–级列表 */
    private String ancestors;
    /** å­éƒ¨é—¨ */
    private List<?> children = new ArrayList<>();
    public String getParentName()
    {
        return parentName;
    }
    public void setParentName(String parentName)
    {
        this.parentName = parentName;
    }
    public Long getParentId()
    {
        return parentId;
    }
    public void setParentId(Long parentId)
    {
        this.parentId = parentId;
    }
    public Integer getOrderNum()
    {
        return orderNum;
    }
    public void setOrderNum(Integer orderNum)
    {
        this.orderNum = orderNum;
    }
    public String getAncestors()
    {
        return ancestors;
    }
    public void setAncestors(String ancestors)
    {
        this.ancestors = ancestors;
    }
    public List<?> getChildren()
    {
        return children;
    }
    public void setChildren(List<?> children)
    {
        this.children = children;
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/TreeSelect.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,77 @@
package com.ruoyi.common.core.domain;
import java.io.Serializable;
import java.util.List;
import java.util.stream.Collectors;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysMenu;
/**
 * Treeselect树结构实体类
 *
 * @author ruoyi
 */
public class TreeSelect implements Serializable
{
    private static final long serialVersionUID = 1L;
    /** èŠ‚ç‚¹ID */
    private Long id;
    /** èŠ‚ç‚¹åç§° */
    private String label;
    /** å­èŠ‚ç‚¹ */
    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    private List<TreeSelect> children;
    public TreeSelect()
    {
    }
    public TreeSelect(SysDept dept)
    {
        this.id = dept.getDeptId();
        this.label = dept.getDeptName();
        this.children = dept.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList());
    }
    public TreeSelect(SysMenu menu)
    {
        this.id = menu.getMenuId();
        this.label = menu.getMenuName();
        this.children = menu.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList());
    }
    public Long getId()
    {
        return id;
    }
    public void setId(Long id)
    {
        this.id = id;
    }
    public String getLabel()
    {
        return label;
    }
    public void setLabel(String label)
    {
        this.label = label;
    }
    public List<TreeSelect> getChildren()
    {
        return children;
    }
    public void setChildren(List<TreeSelect> children)
    {
        this.children = children;
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDept.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,202 @@
package com.ruoyi.common.core.domain.entity;
import java.util.ArrayList;
import java.util.List;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.core.domain.BaseEntity;
/**
 * éƒ¨é—¨è¡¨ sys_dept
 *
 * @author ruoyi
 */
public class SysDept extends BaseEntity
{
    private static final long serialVersionUID = 1L;
    /** éƒ¨é—¨ID */
    private Long deptId;
    /** çˆ¶éƒ¨é—¨ID */
    private Long parentId;
    /** ç¥–级列表 */
    private String ancestors;
    /** éƒ¨é—¨åç§° */
    private String deptName;
    /** æ˜¾ç¤ºé¡ºåº */
    private String orderNum;
    /** è´Ÿè´£äºº */
    private String leader;
    /** è”系电话 */
    private String phone;
    /** é‚®ç®± */
    private String email;
    /** éƒ¨é—¨çŠ¶æ€:0正常,1停用 */
    private String status;
    /** åˆ é™¤æ ‡å¿—(0代表存在 2代表删除) */
    private String delFlag;
    /** çˆ¶éƒ¨é—¨åç§° */
    private String parentName;
    /** å­éƒ¨é—¨ */
    private List<SysDept> children = new ArrayList<SysDept>();
    public Long getDeptId()
    {
        return deptId;
    }
    public void setDeptId(Long deptId)
    {
        this.deptId = deptId;
    }
    public Long getParentId()
    {
        return parentId;
    }
    public void setParentId(Long parentId)
    {
        this.parentId = parentId;
    }
    public String getAncestors()
    {
        return ancestors;
    }
    public void setAncestors(String ancestors)
    {
        this.ancestors = ancestors;
    }
    @NotBlank(message = "部门名称不能为空")
    @Size(min = 0, max = 30, message = "部门名称长度不能超过30个字符")
    public String getDeptName()
    {
        return deptName;
    }
    public void setDeptName(String deptName)
    {
        this.deptName = deptName;
    }
    @NotBlank(message = "显示顺序不能为空")
    public String getOrderNum()
    {
        return orderNum;
    }
    public void setOrderNum(String orderNum)
    {
        this.orderNum = orderNum;
    }
    public String getLeader()
    {
        return leader;
    }
    public void setLeader(String leader)
    {
        this.leader = leader;
    }
    @Size(min = 0, max = 11, message = "联系电话长度不能超过11个字符")
    public String getPhone()
    {
        return phone;
    }
    public void setPhone(String phone)
    {
        this.phone = phone;
    }
    @Email(message = "邮箱格式不正确")
    @Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符")
    public String getEmail()
    {
        return email;
    }
    public void setEmail(String email)
    {
        this.email = email;
    }
    public String getStatus()
    {
        return status;
    }
    public void setStatus(String status)
    {
        this.status = status;
    }
    public String getDelFlag()
    {
        return delFlag;
    }
    public void setDelFlag(String delFlag)
    {
        this.delFlag = delFlag;
    }
    public String getParentName()
    {
        return parentName;
    }
    public void setParentName(String parentName)
    {
        this.parentName = parentName;
    }
    public List<SysDept> getChildren()
    {
        return children;
    }
    public void setChildren(List<SysDept> children)
    {
        this.children = children;
    }
    @Override
    public String toString() {
        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
            .append("deptId", getDeptId())
            .append("parentId", getParentId())
            .append("ancestors", getAncestors())
            .append("deptName", getDeptName())
            .append("orderNum", getOrderNum())
            .append("leader", getLeader())
            .append("phone", getPhone())
            .append("email", getEmail())
            .append("status", getStatus())
            .append("delFlag", getDelFlag())
            .append("createBy", getCreateBy())
            .append("createTime", getCreateTime())
            .append("updateBy", getUpdateBy())
            .append("updateTime", getUpdateTime())
            .toString();
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDictData.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,176 @@
package com.ruoyi.common.core.domain.entity;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.annotation.Excel.ColumnType;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.BaseEntity;
/**
 * å­—典数据表 sys_dict_data
 *
 * @author ruoyi
 */
public class SysDictData extends BaseEntity
{
    private static final long serialVersionUID = 1L;
    /** å­—典编码 */
    @Excel(name = "字典编码", cellType = ColumnType.NUMERIC)
    private Long dictCode;
    /** å­—典排序 */
    @Excel(name = "字典排序", cellType = ColumnType.NUMERIC)
    private Long dictSort;
    /** å­—典标签 */
    @Excel(name = "字典标签")
    private String dictLabel;
    /** å­—典键值 */
    @Excel(name = "字典键值")
    private String dictValue;
    /** å­—典类型 */
    @Excel(name = "字典类型")
    private String dictType;
    /** æ ·å¼å±žæ€§ï¼ˆå…¶ä»–样式扩展) */
    private String cssClass;
    /** è¡¨æ ¼å­—典样式 */
    private String listClass;
    /** æ˜¯å¦é»˜è®¤ï¼ˆY是 N否) */
    @Excel(name = "是否默认", readConverterExp = "Y=是,N=否")
    private String isDefault;
    /** çŠ¶æ€ï¼ˆ0正常 1停用) */
    @Excel(name = "状态", readConverterExp = "0=正常,1=停用")
    private String status;
    public Long getDictCode()
    {
        return dictCode;
    }
    public void setDictCode(Long dictCode)
    {
        this.dictCode = dictCode;
    }
    public Long getDictSort()
    {
        return dictSort;
    }
    public void setDictSort(Long dictSort)
    {
        this.dictSort = dictSort;
    }
    @NotBlank(message = "字典标签不能为空")
    @Size(min = 0, max = 100, message = "字典标签长度不能超过100个字符")
    public String getDictLabel()
    {
        return dictLabel;
    }
    public void setDictLabel(String dictLabel)
    {
        this.dictLabel = dictLabel;
    }
    @NotBlank(message = "字典键值不能为空")
    @Size(min = 0, max = 100, message = "字典键值长度不能超过100个字符")
    public String getDictValue()
    {
        return dictValue;
    }
    public void setDictValue(String dictValue)
    {
        this.dictValue = dictValue;
    }
    @NotBlank(message = "字典类型不能为空")
    @Size(min = 0, max = 100, message = "字典类型长度不能超过100个字符")
    public String getDictType()
    {
        return dictType;
    }
    public void setDictType(String dictType)
    {
        this.dictType = dictType;
    }
    @Size(min = 0, max = 100, message = "样式属性长度不能超过100个字符")
    public String getCssClass()
    {
        return cssClass;
    }
    public void setCssClass(String cssClass)
    {
        this.cssClass = cssClass;
    }
    public String getListClass()
    {
        return listClass;
    }
    public void setListClass(String listClass)
    {
        this.listClass = listClass;
    }
    public boolean getDefault()
    {
        return UserConstants.YES.equals(this.isDefault) ? true : false;
    }
    public String getIsDefault()
    {
        return isDefault;
    }
    public void setIsDefault(String isDefault)
    {
        this.isDefault = isDefault;
    }
    public String getStatus()
    {
        return status;
    }
    public void setStatus(String status)
    {
        this.status = status;
    }
    @Override
    public String toString() {
        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
            .append("dictCode", getDictCode())
            .append("dictSort", getDictSort())
            .append("dictLabel", getDictLabel())
            .append("dictValue", getDictValue())
            .append("dictType", getDictType())
            .append("cssClass", getCssClass())
            .append("listClass", getListClass())
            .append("isDefault", getIsDefault())
            .append("status", getStatus())
            .append("createBy", getCreateBy())
            .append("createTime", getCreateTime())
            .append("updateBy", getUpdateBy())
            .append("updateTime", getUpdateTime())
            .append("remark", getRemark())
            .toString();
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDictType.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,94 @@
package com.ruoyi.common.core.domain.entity;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.annotation.Excel.ColumnType;
import com.ruoyi.common.core.domain.BaseEntity;
/**
 * å­—典类型表 sys_dict_type
 *
 * @author ruoyi
 */
public class SysDictType extends BaseEntity
{
    private static final long serialVersionUID = 1L;
    /** å­—典主键 */
    @Excel(name = "字典主键", cellType = ColumnType.NUMERIC)
    private Long dictId;
    /** å­—典名称 */
    @Excel(name = "字典名称")
    private String dictName;
    /** å­—典类型 */
    @Excel(name = "字典类型")
    private String dictType;
    /** çŠ¶æ€ï¼ˆ0正常 1停用) */
    @Excel(name = "状态", readConverterExp = "0=正常,1=停用")
    private String status;
    public Long getDictId()
    {
        return dictId;
    }
    public void setDictId(Long dictId)
    {
        this.dictId = dictId;
    }
    @NotBlank(message = "字典名称不能为空")
    @Size(min = 0, max = 100, message = "字典类型名称长度不能超过100个字符")
    public String getDictName()
    {
        return dictName;
    }
    public void setDictName(String dictName)
    {
        this.dictName = dictName;
    }
    @NotBlank(message = "字典类型不能为空")
    @Size(min = 0, max = 100, message = "字典类型类型长度不能超过100个字符")
    public String getDictType()
    {
        return dictType;
    }
    public void setDictType(String dictType)
    {
        this.dictType = dictType;
    }
    public String getStatus()
    {
        return status;
    }
    public void setStatus(String status)
    {
        this.status = status;
    }
    @Override
    public String toString() {
        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
            .append("dictId", getDictId())
            .append("dictName", getDictName())
            .append("dictType", getDictType())
            .append("status", getStatus())
            .append("createBy", getCreateBy())
            .append("createTime", getCreateTime())
            .append("updateBy", getUpdateBy())
            .append("updateTime", getUpdateTime())
            .append("remark", getRemark())
            .toString();
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysMenu.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,231 @@
package com.ruoyi.common.core.domain.entity;
import java.util.ArrayList;
import java.util.List;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.core.domain.BaseEntity;
/**
 * èœå•权限表 sys_menu
 *
 * @author ruoyi
 */
public class SysMenu extends BaseEntity
{
    private static final long serialVersionUID = 1L;
    /** èœå•ID */
    private Long menuId;
    /** èœå•名称 */
    private String menuName;
    /** çˆ¶èœå•名称 */
    private String parentName;
    /** çˆ¶èœå•ID */
    private Long parentId;
    /** æ˜¾ç¤ºé¡ºåº */
    private String orderNum;
    /** è·¯ç”±åœ°å€ */
    private String path;
    /** ç»„件路径 */
    private String component;
    /** æ˜¯å¦ä¸ºå¤–链(0是 1否) */
    private String isFrame;
    /** ç±»åž‹ï¼ˆM目录 C菜单 F按钮) */
    private String menuType;
    /** æ˜¾ç¤ºçŠ¶æ€ï¼ˆ0显示 1隐藏) */
    private String visible;
    /** èœå•状态(0显示 1隐藏) */
    private String status;
    /** æƒé™å­—符串 */
    private String perms;
    /** èœå•图标 */
    private String icon;
    /** å­èœå• */
    private List<SysMenu> children = new ArrayList<SysMenu>();
    public Long getMenuId()
    {
        return menuId;
    }
    public void setMenuId(Long menuId)
    {
        this.menuId = menuId;
    }
    @NotBlank(message = "菜单名称不能为空")
    @Size(min = 0, max = 50, message = "菜单名称长度不能超过50个字符")
    public String getMenuName()
    {
        return menuName;
    }
    public void setMenuName(String menuName)
    {
        this.menuName = menuName;
    }
    public String getParentName()
    {
        return parentName;
    }
    public void setParentName(String parentName)
    {
        this.parentName = parentName;
    }
    public Long getParentId()
    {
        return parentId;
    }
    public void setParentId(Long parentId)
    {
        this.parentId = parentId;
    }
    @NotBlank(message = "显示顺序不能为空")
    public String getOrderNum()
    {
        return orderNum;
    }
    public void setOrderNum(String orderNum)
    {
        this.orderNum = orderNum;
    }
    @Size(min = 0, max = 200, message = "路由地址不能超过200个字符")
    public String getPath()
    {
        return path;
    }
    public void setPath(String path)
    {
        this.path = path;
    }
    @Size(min = 0, max = 200, message = "组件路径不能超过255个字符")
    public String getComponent()
    {
        return component;
    }
    public void setComponent(String component)
    {
        this.component = component;
    }
    public String getIsFrame()
    {
        return isFrame;
    }
    public void setIsFrame(String isFrame)
    {
        this.isFrame = isFrame;
    }
    @NotBlank(message = "菜单类型不能为空")
    public String getMenuType()
    {
        return menuType;
    }
    public void setMenuType(String menuType)
    {
        this.menuType = menuType;
    }
    public String getVisible()
    {
        return visible;
    }
    public void setVisible(String visible)
    {
        this.visible = visible;
    }
    public String getStatus()
    {
        return status;
    }
    public void setStatus(String status)
    {
        this.status = status;
    }
    @Size(min = 0, max = 100, message = "权限标识长度不能超过100个字符")
    public String getPerms()
    {
        return perms;
    }
    public void setPerms(String perms)
    {
        this.perms = perms;
    }
    public String getIcon()
    {
        return icon;
    }
    public void setIcon(String icon)
    {
        this.icon = icon;
    }
    public List<SysMenu> getChildren()
    {
        return children;
    }
    public void setChildren(List<SysMenu> children)
    {
        this.children = children;
    }
    @Override
    public String toString() {
        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
            .append("menuId", getMenuId())
            .append("menuName", getMenuName())
            .append("parentId", getParentId())
            .append("orderNum", getOrderNum())
            .append("path", getPath())
            .append("component", getComponent())
            .append("isFrame", getIsFrame())
            .append("menuType", getMenuType())
            .append("visible", getVisible())
            .append("status ", getStatus())
            .append("perms", getPerms())
            .append("icon", getIcon())
            .append("createBy", getCreateBy())
            .append("createTime", getCreateTime())
            .append("updateBy", getUpdateBy())
            .append("updateTime", getUpdateTime())
            .append("remark", getRemark())
            .toString();
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysRole.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,198 @@
package com.ruoyi.common.core.domain.entity;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.annotation.Excel.ColumnType;
import com.ruoyi.common.core.domain.BaseEntity;
/**
 * è§’色表 sys_role
 *
 * @author ruoyi
 */
public class SysRole extends BaseEntity
{
    private static final long serialVersionUID = 1L;
    /** è§’色ID */
    @Excel(name = "角色序号", cellType = ColumnType.NUMERIC)
    private Long roleId;
    /** è§’色名称 */
    @Excel(name = "角色名称")
    private String roleName;
    /** è§’色权限 */
    @Excel(name = "角色权限")
    private String roleKey;
    /** è§’色排序 */
    @Excel(name = "角色排序")
    private String roleSort;
    /** æ•°æ®èŒƒå›´ï¼ˆ1:所有数据权限;2:自定义数据权限;3:本部门数据权限;4:本部门及以下数据权限) */
    @Excel(name = "数据范围", readConverterExp = "1=所有数据权限,2=自定义数据权限,3=本部门数据权限,4=本部门及以下数据权限")
    private String dataScope;
    /** è§’色状态(0正常 1停用) */
    @Excel(name = "角色状态", readConverterExp = "0=正常,1=停用")
    private String status;
    /** åˆ é™¤æ ‡å¿—(0代表存在 2代表删除) */
    private String delFlag;
    /** ç”¨æˆ·æ˜¯å¦å­˜åœ¨æ­¤è§’色标识 é»˜è®¤ä¸å­˜åœ¨ */
    private boolean flag = false;
    /** èœå•组 */
    private Long[] menuIds;
    /** éƒ¨é—¨ç»„(数据权限) */
    private Long[] deptIds;
    public SysRole()
    {
    }
    public SysRole(Long roleId)
    {
        this.roleId = roleId;
    }
    public Long getRoleId()
    {
        return roleId;
    }
    public void setRoleId(Long roleId)
    {
        this.roleId = roleId;
    }
    public boolean isAdmin()
    {
        return isAdmin(this.roleId);
    }
    public static boolean isAdmin(Long roleId)
    {
        return roleId != null && 1L == roleId;
    }
    @NotBlank(message = "角色名称不能为空")
    @Size(min = 0, max = 30, message = "角色名称长度不能超过30个字符")
    public String getRoleName()
    {
        return roleName;
    }
    public void setRoleName(String roleName)
    {
        this.roleName = roleName;
    }
    @NotBlank(message = "权限字符不能为空")
    @Size(min = 0, max = 100, message = "权限字符长度不能超过100个字符")
    public String getRoleKey()
    {
        return roleKey;
    }
    public void setRoleKey(String roleKey)
    {
        this.roleKey = roleKey;
    }
    @NotBlank(message = "显示顺序不能为空")
    public String getRoleSort()
    {
        return roleSort;
    }
    public void setRoleSort(String roleSort)
    {
        this.roleSort = roleSort;
    }
    public String getDataScope()
    {
        return dataScope;
    }
    public void setDataScope(String dataScope)
    {
        this.dataScope = dataScope;
    }
    public String getStatus()
    {
        return status;
    }
    public void setStatus(String status)
    {
        this.status = status;
    }
    public String getDelFlag()
    {
        return delFlag;
    }
    public void setDelFlag(String delFlag)
    {
        this.delFlag = delFlag;
    }
    public boolean isFlag()
    {
        return flag;
    }
    public void setFlag(boolean flag)
    {
        this.flag = flag;
    }
    public Long[] getMenuIds()
    {
        return menuIds;
    }
    public void setMenuIds(Long[] menuIds)
    {
        this.menuIds = menuIds;
    }
    public Long[] getDeptIds()
    {
        return deptIds;
    }
    public void setDeptIds(Long[] deptIds)
    {
        this.deptIds = deptIds;
    }
    @Override
    public String toString() {
        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
            .append("roleId", getRoleId())
            .append("roleName", getRoleName())
            .append("roleKey", getRoleKey())
            .append("roleSort", getRoleSort())
            .append("dataScope", getDataScope())
            .append("status", getStatus())
            .append("delFlag", getDelFlag())
            .append("createBy", getCreateBy())
            .append("createTime", getCreateTime())
            .append("updateBy", getUpdateBy())
            .append("updateTime", getUpdateTime())
            .append("remark", getRemark())
            .toString();
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,328 @@
package com.ruoyi.common.core.domain.entity;
import java.util.Date;
import java.util.List;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.annotation.Excel.ColumnType;
import com.ruoyi.common.annotation.Excel.Type;
import com.ruoyi.common.annotation.Excels;
import com.ruoyi.common.core.domain.BaseEntity;
/**
 * ç”¨æˆ·å¯¹è±¡ sys_user
 *
 * @author ruoyi
 */
public class SysUser extends BaseEntity
{
    private static final long serialVersionUID = 1L;
    /** ç”¨æˆ·ID */
    @Excel(name = "用户序号", cellType = ColumnType.NUMERIC, prompt = "用户编号")
    private Long userId;
    /** éƒ¨é—¨ID */
    @Excel(name = "部门编号", type = Type.IMPORT)
    private Long deptId;
    /** ç”¨æˆ·è´¦å· */
    @Excel(name = "登录名称")
    private String userName;
    /** ç”¨æˆ·æ˜µç§° */
    @Excel(name = "用户名称")
    private String nickName;
    /** ç”¨æˆ·é‚®ç®± */
    @Excel(name = "用户邮箱")
    private String email;
    /** æ‰‹æœºå·ç  */
    @Excel(name = "手机号码")
    private String phonenumber;
    /** ç”¨æˆ·æ€§åˆ« */
    @Excel(name = "用户性别", readConverterExp = "0=男,1=女,2=未知")
    private String sex;
    /** ç”¨æˆ·å¤´åƒ */
    private String avatar;
    /** å¯†ç  */
    private String password;
    /** ç›åР坆 */
    private String salt;
    /** å¸å·çŠ¶æ€ï¼ˆ0正常 1停用) */
    @Excel(name = "帐号状态", readConverterExp = "0=正常,1=停用")
    private String status;
    /** åˆ é™¤æ ‡å¿—(0代表存在 2代表删除) */
    private String delFlag;
    /** æœ€åŽç™»é™†IP */
    @Excel(name = "最后登陆IP", type = Type.EXPORT)
    private String loginIp;
    /** æœ€åŽç™»é™†æ—¶é—´ */
    @Excel(name = "最后登陆时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Type.EXPORT)
    private Date loginDate;
    /** éƒ¨é—¨å¯¹è±¡ */
    @Excels({
        @Excel(name = "部门名称", targetAttr = "deptName", type = Type.EXPORT),
        @Excel(name = "部门负责人", targetAttr = "leader", type = Type.EXPORT)
    })
    private SysDept dept;
    /** è§’色对象 */
    private List<SysRole> roles;
    /** è§’色组 */
    private Long[] roleIds;
    /** å²—位组 */
    private Long[] postIds;
    public SysUser()
    {
    }
    public SysUser(Long userId)
    {
        this.userId = userId;
    }
    public Long getUserId()
    {
        return userId;
    }
    public void setUserId(Long userId)
    {
        this.userId = userId;
    }
    public boolean isAdmin()
    {
        return isAdmin(this.userId);
    }
    public static boolean isAdmin(Long userId)
    {
        return userId != null && 1L == userId;
    }
    public Long getDeptId()
    {
        return deptId;
    }
    public void setDeptId(Long deptId)
    {
        this.deptId = deptId;
    }
    @Size(min = 0, max = 30, message = "用户昵称长度不能超过30个字符")
    public String getNickName()
    {
        return nickName;
    }
    public void setNickName(String nickName)
    {
        this.nickName = nickName;
    }
    @NotBlank(message = "用户账号不能为空")
    @Size(min = 0, max = 30, message = "用户账号长度不能超过30个字符")
    public String getUserName()
    {
        return userName;
    }
    public void setUserName(String userName)
    {
        this.userName = userName;
    }
    @Email(message = "邮箱格式不正确")
    @Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符")
    public String getEmail()
    {
        return email;
    }
    public void setEmail(String email)
    {
        this.email = email;
    }
    @Size(min = 0, max = 11, message = "手机号码长度不能超过11个字符")
    public String getPhonenumber()
    {
        return phonenumber;
    }
    public void setPhonenumber(String phonenumber)
    {
        this.phonenumber = phonenumber;
    }
    public String getSex()
    {
        return sex;
    }
    public void setSex(String sex)
    {
        this.sex = sex;
    }
    public String getAvatar()
    {
        return avatar;
    }
    public void setAvatar(String avatar)
    {
        this.avatar = avatar;
    }
    @JsonIgnore
    @JsonProperty
    public String getPassword()
    {
        return password;
    }
    public void setPassword(String password)
    {
        this.password = password;
    }
    public String getSalt()
    {
        return salt;
    }
    public void setSalt(String salt)
    {
        this.salt = salt;
    }
    public String getStatus()
    {
        return status;
    }
    public void setStatus(String status)
    {
        this.status = status;
    }
    public String getDelFlag()
    {
        return delFlag;
    }
    public void setDelFlag(String delFlag)
    {
        this.delFlag = delFlag;
    }
    public String getLoginIp()
    {
        return loginIp;
    }
    public void setLoginIp(String loginIp)
    {
        this.loginIp = loginIp;
    }
    public Date getLoginDate()
    {
        return loginDate;
    }
    public void setLoginDate(Date loginDate)
    {
        this.loginDate = loginDate;
    }
    public SysDept getDept()
    {
        return dept;
    }
    public void setDept(SysDept dept)
    {
        this.dept = dept;
    }
    public List<SysRole> getRoles()
    {
        return roles;
    }
    public void setRoles(List<SysRole> roles)
    {
        this.roles = roles;
    }
    public Long[] getRoleIds()
    {
        return roleIds;
    }
    public void setRoleIds(Long[] roleIds)
    {
        this.roleIds = roleIds;
    }
    public Long[] getPostIds()
    {
        return postIds;
    }
    public void setPostIds(Long[] postIds)
    {
        this.postIds = postIds;
    }
    @Override
    public String toString() {
        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
            .append("userId", getUserId())
            .append("deptId", getDeptId())
            .append("userName", getUserName())
            .append("nickName", getNickName())
            .append("email", getEmail())
            .append("phonenumber", getPhonenumber())
            .append("sex", getSex())
            .append("avatar", getAvatar())
            .append("password", getPassword())
            .append("salt", getSalt())
            .append("status", getStatus())
            .append("delFlag", getDelFlag())
            .append("loginIp", getLoginIp())
            .append("loginDate", getLoginDate())
            .append("createBy", getCreateBy())
            .append("createTime", getCreateTime())
            .append("updateBy", getUpdateBy())
            .append("updateTime", getUpdateTime())
            .append("remark", getRemark())
            .append("dept", getDept())
            .toString();
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginBody.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,69 @@
package com.ruoyi.common.core.domain.model;
/**
 * ç”¨æˆ·ç™»å½•对象
 *
 * @author ruoyi
 */
public class LoginBody
{
    /**
     * ç”¨æˆ·å
     */
    private String username;
    /**
     * ç”¨æˆ·å¯†ç 
     */
    private String password;
    /**
     * éªŒè¯ç 
     */
    private String code;
    /**
     * å”¯ä¸€æ ‡è¯†
     */
    private String uuid = "";
    public String getUsername()
    {
        return username;
    }
    public void setUsername(String username)
    {
        this.username = username;
    }
    public String getPassword()
    {
        return password;
    }
    public void setPassword(String password)
    {
        this.password = password;
    }
    public String getCode()
    {
        return code;
    }
    public void setCode(String code)
    {
        this.code = code;
    }
    public String getUuid()
    {
        return uuid;
    }
    public void setUuid(String uuid)
    {
        this.uuid = uuid;
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginUser.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,228 @@
package com.ruoyi.common.core.domain.model;
import java.util.Collection;
import java.util.Set;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.ruoyi.common.core.domain.entity.SysUser;
/**
 * ç™»å½•用户身份权限
 *
 * @author ruoyi
 */
public class LoginUser implements UserDetails
{
    private static final long serialVersionUID = 1L;
    /**
     * ç”¨æˆ·å”¯ä¸€æ ‡è¯†
     */
    private String token;
    /**
     * ç™»é™†æ—¶é—´
     */
    private Long loginTime;
    /**
     * è¿‡æœŸæ—¶é—´
     */
    private Long expireTime;
    /**
     * ç™»å½•IP地址
     */
    private String ipaddr;
    /**
     * ç™»å½•地点
     */
    private String loginLocation;
    /**
     * æµè§ˆå™¨ç±»åž‹
     */
    private String browser;
    /**
     * æ“ä½œç³»ç»Ÿ
     */
    private String os;
    /**
     * æƒé™åˆ—表
     */
    private Set<String> permissions;
    /**
     * ç”¨æˆ·ä¿¡æ¯
     */
    private SysUser user;
    public String getToken()
    {
        return token;
    }
    public void setToken(String token)
    {
        this.token = token;
    }
    public LoginUser()
    {
    }
    public LoginUser(SysUser user, Set<String> permissions)
    {
        this.user = user;
        this.permissions = permissions;
    }
    @JsonIgnore
    @Override
    public String getPassword()
    {
        return user.getPassword();
    }
    @Override
    public String getUsername()
    {
        return user.getUserName();
    }
    /**
     * è´¦æˆ·æ˜¯å¦æœªè¿‡æœŸ,过期无法验证
     */
    @JsonIgnore
    @Override
    public boolean isAccountNonExpired()
    {
        return true;
    }
    /**
     * æŒ‡å®šç”¨æˆ·æ˜¯å¦è§£é”,锁定的用户无法进行身份验证
     *
     * @return
     */
    @JsonIgnore
    @Override
    public boolean isAccountNonLocked()
    {
        return true;
    }
    /**
     * æŒ‡ç¤ºæ˜¯å¦å·²è¿‡æœŸçš„用户的凭据(密码),过期的凭据防止认证
     *
     * @return
     */
    @JsonIgnore
    @Override
    public boolean isCredentialsNonExpired()
    {
        return true;
    }
    /**
     * æ˜¯å¦å¯ç”¨ ,禁用的用户不能身份验证
     *
     * @return
     */
    @JsonIgnore
    @Override
    public boolean isEnabled()
    {
        return true;
    }
    public Long getLoginTime()
    {
        return loginTime;
    }
    public void setLoginTime(Long loginTime)
    {
        this.loginTime = loginTime;
    }
    public String getIpaddr()
    {
        return ipaddr;
    }
    public void setIpaddr(String ipaddr)
    {
        this.ipaddr = ipaddr;
    }
    public String getLoginLocation()
    {
        return loginLocation;
    }
    public void setLoginLocation(String loginLocation)
    {
        this.loginLocation = loginLocation;
    }
    public String getBrowser()
    {
        return browser;
    }
    public void setBrowser(String browser)
    {
        this.browser = browser;
    }
    public String getOs()
    {
        return os;
    }
    public void setOs(String os)
    {
        this.os = os;
    }
    public Long getExpireTime()
    {
        return expireTime;
    }
    public void setExpireTime(Long expireTime)
    {
        this.expireTime = expireTime;
    }
    public Set<String> getPermissions()
    {
        return permissions;
    }
    public void setPermissions(Set<String> permissions)
    {
        this.permissions = permissions;
    }
    public SysUser getUser()
    {
        return user;
    }
    public void setUser(SysUser user)
    {
        this.user = user;
    }
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities()
    {
        return null;
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/core/page/PageDomain.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,72 @@
package com.ruoyi.common.core.page;
import com.ruoyi.common.utils.StringUtils;
/**
 * åˆ†é¡µæ•°æ®
 *
 * @author ruoyi
 */
public class PageDomain
{
    /** å½“前记录起始索引 */
    private Integer pageNum;
    /** æ¯é¡µæ˜¾ç¤ºè®°å½•æ•° */
    private Integer pageSize;
    /** æŽ’序列 */
    private String orderByColumn;
    /** æŽ’序的方向 "desc" æˆ–者 "asc". */
    private String isAsc;
    public String getOrderBy()
    {
        if (StringUtils.isEmpty(orderByColumn))
        {
            return "";
        }
        return StringUtils.toUnderScoreCase(orderByColumn) + " " + isAsc;
    }
    public Integer getPageNum()
    {
        return pageNum;
    }
    public void setPageNum(Integer pageNum)
    {
        this.pageNum = pageNum;
    }
    public Integer getPageSize()
    {
        return pageSize;
    }
    public void setPageSize(Integer pageSize)
    {
        this.pageSize = pageSize;
    }
    public String getOrderByColumn()
    {
        return orderByColumn;
    }
    public void setOrderByColumn(String orderByColumn)
    {
        this.orderByColumn = orderByColumn;
    }
    public String getIsAsc()
    {
        return isAsc;
    }
    public void setIsAsc(String isAsc)
    {
        this.isAsc = isAsc;
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/core/page/TableDataInfo.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,85 @@
package com.ruoyi.common.core.page;
import java.io.Serializable;
import java.util.List;
/**
 * è¡¨æ ¼åˆ†é¡µæ•°æ®å¯¹è±¡
 *
 * @author ruoyi
 */
public class TableDataInfo implements Serializable
{
    private static final long serialVersionUID = 1L;
    /** æ€»è®°å½•æ•° */
    private long total;
    /** åˆ—表数据 */
    private List<?> rows;
    /** æ¶ˆæ¯çŠ¶æ€ç  */
    private int code;
    /** æ¶ˆæ¯å†…容 */
    private String msg;
    /**
     * è¡¨æ ¼æ•°æ®å¯¹è±¡
     */
    public TableDataInfo()
    {
    }
    /**
     * åˆ†é¡µ
     *
     * @param list åˆ—表数据
     * @param total æ€»è®°å½•æ•°
     */
    public TableDataInfo(List<?> list, int total)
    {
        this.rows = list;
        this.total = total;
    }
    public long getTotal()
    {
        return total;
    }
    public void setTotal(long total)
    {
        this.total = total;
    }
    public List<?> getRows()
    {
        return rows;
    }
    public void setRows(List<?> rows)
    {
        this.rows = rows;
    }
    public int getCode()
    {
        return code;
    }
    public void setCode(int code)
    {
        this.code = code;
    }
    public String getMsg()
    {
        return msg;
    }
    public void setMsg(String msg)
    {
        this.msg = msg;
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/core/page/TableSupport.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,49 @@
package com.ruoyi.common.core.page;
import com.ruoyi.common.utils.ServletUtils;
/**
 * è¡¨æ ¼æ•°æ®å¤„理
 *
 * @author ruoyi
 */
public class TableSupport
{
    /**
     * å½“前记录起始索引
     */
    public static final String PAGE_NUM = "pageNum";
    /**
     * æ¯é¡µæ˜¾ç¤ºè®°å½•æ•°
     */
    public static final String PAGE_SIZE = "pageSize";
    /**
     * æŽ’序列
     */
    public static final String ORDER_BY_COLUMN = "orderByColumn";
    /**
     * æŽ’序的方向 "desc" æˆ–者 "asc".
     */
    public static final String IS_ASC = "isAsc";
    /**
     * å°è£…分页对象
     */
    public static PageDomain getPageDomain()
    {
        PageDomain pageDomain = new PageDomain();
        pageDomain.setPageNum(ServletUtils.getParameterToInt(PAGE_NUM));
        pageDomain.setPageSize(ServletUtils.getParameterToInt(PAGE_SIZE));
        pageDomain.setOrderByColumn(ServletUtils.getParameter(ORDER_BY_COLUMN));
        pageDomain.setIsAsc(ServletUtils.getParameter(IS_ASC));
        return pageDomain;
    }
    public static PageDomain buildPageRequest()
    {
        return getPageDomain();
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisCache.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,227 @@
package com.ruoyi.common.core.redis;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
/**
 * spring redis å·¥å…·ç±»
 *
 * @author ruoyi
 **/
@SuppressWarnings(value = { "unchecked", "rawtypes" })
@Component
public class RedisCache
{
    @Autowired
    public RedisTemplate redisTemplate;
    /**
     * ç¼“存基本的对象,Integer、String、实体类等
     *
     * @param key ç¼“存的键值
     * @param value ç¼“存的值
     */
    public <T> void setCacheObject(final String key, final T value)
    {
        redisTemplate.opsForValue().set(key, value);
    }
    /**
     * ç¼“存基本的对象,Integer、String、实体类等
     *
     * @param key ç¼“存的键值
     * @param value ç¼“存的值
     * @param timeout æ—¶é—´
     * @param timeUnit æ—¶é—´é¢—粒度
     */
    public <T> void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit)
    {
        redisTemplate.opsForValue().set(key, value, timeout, timeUnit);
    }
    /**
     * è®¾ç½®æœ‰æ•ˆæ—¶é—´
     *
     * @param key Redis键
     * @param timeout è¶…æ—¶æ—¶é—´
     * @return true=设置成功;false=设置失败
     */
    public boolean expire(final String key, final long timeout)
    {
        return expire(key, timeout, TimeUnit.SECONDS);
    }
    /**
     * è®¾ç½®æœ‰æ•ˆæ—¶é—´
     *
     * @param key Redis键
     * @param timeout è¶…æ—¶æ—¶é—´
     * @param unit æ—¶é—´å•位
     * @return true=设置成功;false=设置失败
     */
    public boolean expire(final String key, final long timeout, final TimeUnit unit)
    {
        return redisTemplate.expire(key, timeout, unit);
    }
    /**
     * èŽ·å¾—ç¼“å­˜çš„åŸºæœ¬å¯¹è±¡ã€‚
     *
     * @param key ç¼“存键值
     * @return ç¼“存键值对应的数据
     */
    public <T> T getCacheObject(final String key)
    {
        ValueOperations<String, T> operation = redisTemplate.opsForValue();
        return operation.get(key);
    }
    /**
     * åˆ é™¤å•个对象
     *
     * @param key
     */
    public boolean deleteObject(final String key)
    {
        return redisTemplate.delete(key);
    }
    /**
     * åˆ é™¤é›†åˆå¯¹è±¡
     *
     * @param collection å¤šä¸ªå¯¹è±¡
     * @return
     */
    public long deleteObject(final Collection collection)
    {
        return redisTemplate.delete(collection);
    }
    /**
     * ç¼“å­˜List数据
     *
     * @param key ç¼“存的键值
     * @param values å¾…缓存的List数据
     * @return ç¼“存的对象
     */
    public <T> long setCacheList(final String key, final List<T> dataList)
    {
        Long count = redisTemplate.opsForList().rightPushAll(key, dataList);
        return count == null ? 0 : count;
    }
    /**
     * èŽ·å¾—ç¼“å­˜çš„list对象
     *
     * @param key ç¼“存的键值
     * @return ç¼“存键值对应的数据
     */
    public <T> List<T> getCacheList(final String key)
    {
        return redisTemplate.opsForList().range(key, 0, -1);
    }
    /**
     * ç¼“å­˜Set
     *
     * @param key ç¼“存键值
     * @param dataSet ç¼“存的数据
     * @return ç¼“存数据的对象
     */
    public <T> long setCacheSet(final String key, final Set<T> dataSet)
    {
        Long count = redisTemplate.opsForSet().add(key, dataSet);
        return count == null ? 0 : count;
    }
    /**
     * èŽ·å¾—ç¼“å­˜çš„set
     *
     * @param key
     * @return
     */
    public <T> Set<T> getCacheSet(final String key)
    {
        return redisTemplate.opsForSet().members(key);
    }
    /**
     * ç¼“å­˜Map
     *
     * @param key
     * @param dataMap
     */
    public <T> void setCacheMap(final String key, final Map<String, T> dataMap)
    {
        if (dataMap != null) {
            redisTemplate.opsForHash().putAll(key, dataMap);
        }
    }
    /**
     * èŽ·å¾—ç¼“å­˜çš„Map
     *
     * @param key
     * @return
     */
    public <T> Map<String, T> getCacheMap(final String key)
    {
        return redisTemplate.opsForHash().entries(key);
    }
    /**
     * å¾€Hash中存入数据
     *
     * @param key Redis键
     * @param hKey Hash键
     * @param value å€¼
     */
    public <T> void setCacheMapValue(final String key, final String hKey, final T value)
    {
        redisTemplate.opsForHash().put(key, hKey, value);
    }
    /**
     * èŽ·å–Hash中的数据
     *
     * @param key Redis键
     * @param hKey Hash键
     * @return Hash中的对象
     */
    public <T> T getCacheMapValue(final String key, final String hKey)
    {
        HashOperations<String, String, T> opsForHash = redisTemplate.opsForHash();
        return opsForHash.get(key, hKey);
    }
    /**
     * èŽ·å–å¤šä¸ªHash中的数据
     *
     * @param key Redis键
     * @param hKeys Hash键集合
     * @return Hash对象集合
     */
    public <T> List<T> getMultiCacheMapValue(final String key, final Collection<Object> hKeys)
    {
        return redisTemplate.opsForHash().multiGet(key, hKeys);
    }
    /**
     * èŽ·å¾—ç¼“å­˜çš„åŸºæœ¬å¯¹è±¡åˆ—è¡¨
     *
     * @param pattern å­—符串前缀
     * @return å¯¹è±¡åˆ—表
     */
    public Collection<String> keys(final String pattern)
    {
        return redisTemplate.keys(pattern);
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/core/text/CharsetKit.java
ruoyi-common/src/main/java/com/ruoyi/common/core/text/Convert.java
ruoyi-common/src/main/java/com/ruoyi/common/core/text/StrFormatter.java
ruoyi-common/src/main/java/com/ruoyi/common/enums/BusinessStatus.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
package com.ruoyi.common.enums;
/**
 * æ“ä½œçŠ¶æ€
 *
 * @author ruoyi
 *
 */
public enum BusinessStatus
{
    /**
     * æˆåŠŸ
     */
    SUCCESS,
    /**
     * å¤±è´¥
     */
    FAIL,
}
ruoyi-common/src/main/java/com/ruoyi/common/enums/BusinessType.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,59 @@
package com.ruoyi.common.enums;
/**
 * ä¸šåŠ¡æ“ä½œç±»åž‹
 *
 * @author ruoyi
 */
public enum BusinessType
{
    /**
     * å…¶å®ƒ
     */
    OTHER,
    /**
     * æ–°å¢ž
     */
    INSERT,
    /**
     * ä¿®æ”¹
     */
    UPDATE,
    /**
     * åˆ é™¤
     */
    DELETE,
    /**
     * æŽˆæƒ
     */
    GRANT,
    /**
     * å¯¼å‡º
     */
    EXPORT,
    /**
     * å¯¼å…¥
     */
    IMPORT,
    /**
     * å¼ºé€€
     */
    FORCE,
    /**
     * ç”Ÿæˆä»£ç 
     */
    GENCODE,
    /**
     * æ¸…空数据
     */
    CLEAN,
}
ruoyi-common/src/main/java/com/ruoyi/common/enums/DataSourceType.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,19 @@
package com.ruoyi.common.enums;
/**
 * æ•°æ®æº
 *
 * @author ruoyi
 */
public enum DataSourceType
{
    /**
     * ä¸»åº“
     */
    MASTER,
    /**
     * ä»Žåº“
     */
    SLAVE
}
ruoyi-common/src/main/java/com/ruoyi/common/enums/HttpMethod.java
ruoyi-common/src/main/java/com/ruoyi/common/enums/OperatorType.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,24 @@
package com.ruoyi.common.enums;
/**
 * æ“ä½œäººç±»åˆ«
 *
 * @author ruoyi
 */
public enum OperatorType
{
    /**
     * å…¶å®ƒ
     */
    OTHER,
    /**
     * åŽå°ç”¨æˆ·
     */
    MANAGE,
    /**
     * æ‰‹æœºç«¯ç”¨æˆ·
     */
    MOBILE
}
ruoyi-common/src/main/java/com/ruoyi/common/enums/UserStatus.java
ruoyi-common/src/main/java/com/ruoyi/common/exception/BaseException.java
ruoyi-common/src/main/java/com/ruoyi/common/exception/CustomException.java
ruoyi-common/src/main/java/com/ruoyi/common/exception/DemoModeException.java
ruoyi-common/src/main/java/com/ruoyi/common/exception/UtilException.java
ruoyi-common/src/main/java/com/ruoyi/common/exception/file/FileException.java
ruoyi-common/src/main/java/com/ruoyi/common/exception/file/FileNameLengthLimitExceededException.java
ruoyi-common/src/main/java/com/ruoyi/common/exception/file/FileSizeLimitExceededException.java
ruoyi-common/src/main/java/com/ruoyi/common/exception/file/InvalidExtensionException.java
ruoyi-common/src/main/java/com/ruoyi/common/exception/job/TaskException.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,34 @@
package com.ruoyi.common.exception.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
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/exception/user/CaptchaException.java
ruoyi-common/src/main/java/com/ruoyi/common/exception/user/CaptchaExpireException.java
ruoyi-common/src/main/java/com/ruoyi/common/exception/user/UserException.java
ruoyi-common/src/main/java/com/ruoyi/common/exception/user/UserPasswordNotMatchException.java
ruoyi-common/src/main/java/com/ruoyi/common/filter/RepeatableFilter.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,52 @@
package com.ruoyi.common.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import org.springframework.http.MediaType;
import com.ruoyi.common.utils.StringUtils;
/**
 * Repeatable è¿‡æ»¤å™¨
 *
 * @author ruoyi
 */
public class RepeatableFilter implements Filter
{
    @Override
    public void init(FilterConfig filterConfig) throws ServletException
    {
    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException
    {
        ServletRequest requestWrapper = null;
        if (request instanceof HttpServletRequest && StringUtils.equalsAnyIgnoreCase(request.getContentType(),
                MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_JSON_UTF8_VALUE))
        {
            requestWrapper = new RepeatedlyRequestWrapper((HttpServletRequest) request, response);
        }
        if (null == requestWrapper)
        {
            chain.doFilter(request, response);
        }
        else
        {
            chain.doFilter(requestWrapper, response);
        }
    }
    @Override
    public void destroy()
    {
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/filter/RepeatedlyRequestWrapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,72 @@
package com.ruoyi.common.filter;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import com.ruoyi.common.utils.http.HttpHelper;
/**
 * æž„建可重复读取inputStream的request
 *
 * @author ruoyi
 */
public class RepeatedlyRequestWrapper extends HttpServletRequestWrapper
{
    private final byte[] body;
    public RepeatedlyRequestWrapper(HttpServletRequest request, ServletResponse response) throws IOException
    {
        super(request);
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        body = HttpHelper.getBodyString(request).getBytes("UTF-8");
    }
    @Override
    public BufferedReader getReader() throws IOException
    {
        return new BufferedReader(new InputStreamReader(getInputStream()));
    }
    @Override
    public ServletInputStream getInputStream() throws IOException
    {
        final ByteArrayInputStream bais = new ByteArrayInputStream(body);
        return new ServletInputStream()
        {
            @Override
            public int read() throws IOException
            {
                return bais.read();
            }
            @Override
            public boolean isFinished()
            {
                return false;
            }
            @Override
            public boolean isReady()
            {
                return false;
            }
            @Override
            public void setReadListener(ReadListener readListener)
            {
            }
        };
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/filter/XssFilter.java
ruoyi-common/src/main/java/com/ruoyi/common/filter/XssHttpServletRequestWrapper.java
ruoyi-common/src/main/java/com/ruoyi/common/utils/Arith.java
ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java
ruoyi-common/src/main/java/com/ruoyi/common/utils/DictUtils.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,65 @@
package com.ruoyi.common.utils;
import java.util.Collection;
import java.util.List;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.spring.SpringUtils;
/**
 * å­—典工具类
 *
 * @author ruoyi
 */
public class DictUtils
{
    /**
     * è®¾ç½®å­—典缓存
     *
     * @param key å‚æ•°é”®
     * @param dictDatas å­—典数据列表
     */
    public static void setDictCache(String key, List<SysDictData> dictDatas)
    {
        SpringUtils.getBean(RedisCache.class).setCacheObject(getCacheKey(key), dictDatas);
    }
    /**
     * èŽ·å–å­—å…¸ç¼“å­˜
     *
     * @param key å‚æ•°é”®
     * @return dictDatas å­—典数据列表
     */
    public static List<SysDictData> getDictCache(String key)
    {
        Object cacheObj = SpringUtils.getBean(RedisCache.class).getCacheObject(getCacheKey(key));
        if (StringUtils.isNotNull(cacheObj))
        {
            List<SysDictData> DictDatas = StringUtils.cast(cacheObj);
            return DictDatas;
        }
        return null;
    }
    /**
     * æ¸…空字典缓存
     */
    public static void clearDictCache()
    {
        Collection<String> keys = SpringUtils.getBean(RedisCache.class).keys(Constants.SYS_DICT_KEY + "*");
        SpringUtils.getBean(RedisCache.class).deleteObject(keys);
    }
    /**
     * è®¾ç½®cache key
     *
     * @param configKey å‚æ•°é”®
     * @return ç¼“存键key
     */
    public static String getCacheKey(String configKey)
    {
        return Constants.SYS_DICT_KEY + configKey;
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/utils/ExceptionUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,40 @@
package com.ruoyi.common.utils;
import java.io.PrintWriter;
import java.io.StringWriter;
import org.apache.commons.lang3.exception.ExceptionUtils;
/**
 * é”™è¯¯ä¿¡æ¯å¤„理类。
 *
 * @author ruoyi
 */
public class ExceptionUtil
{
    /**
     * èŽ·å–exception的详细错误信息。
     */
    public static String getExceptionMessage(Throwable e)
    {
        StringWriter sw = new StringWriter();
        e.printStackTrace(new PrintWriter(sw, true));
        String str = sw.toString();
        return str;
    }
    public static String getRootErrorMseeage(Exception e)
    {
        Throwable root = ExceptionUtils.getRootCause(e);
        root = (root == null ? e : root);
        if (root == null)
        {
            return "";
        }
        String msg = root.getMessage();
        if (msg == null)
        {
            return "null";
        }
        return StringUtils.defaultString(msg);
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/utils/LogUtils.java
ruoyi-common/src/main/java/com/ruoyi/common/utils/MessageUtils.java
ruoyi-common/src/main/java/com/ruoyi/common/utils/SecurityUtils.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,90 @@
package com.ruoyi.common.utils;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.exception.CustomException;
/**
 * å®‰å…¨æœåŠ¡å·¥å…·ç±»
 *
 * @author ruoyi
 */
public class SecurityUtils
{
    /**
     * èŽ·å–ç”¨æˆ·è´¦æˆ·
     **/
    public static String getUsername()
    {
        try
        {
            return getLoginUser().getUsername();
        }
        catch (Exception e)
        {
            throw new CustomException("获取用户账户异常", HttpStatus.UNAUTHORIZED);
        }
    }
    /**
     * èŽ·å–ç”¨æˆ·
     **/
    public static LoginUser getLoginUser()
    {
        try
        {
            return (LoginUser) getAuthentication().getPrincipal();
        }
        catch (Exception e)
        {
            throw new CustomException("获取用户信息异常", HttpStatus.UNAUTHORIZED);
        }
    }
    /**
     * èŽ·å–Authentication
     */
    public static Authentication getAuthentication()
    {
        return SecurityContextHolder.getContext().getAuthentication();
    }
    /**
     * ç”ŸæˆBCryptPasswordEncoder密码
     *
     * @param password å¯†ç 
     * @return åŠ å¯†å­—ç¬¦ä¸²
     */
    public static String encryptPassword(String password)
    {
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        return passwordEncoder.encode(password);
    }
    /**
     * åˆ¤æ–­å¯†ç æ˜¯å¦ç›¸åŒ
     *
     * @param rawPassword çœŸå®žå¯†ç 
     * @param encodedPassword åŠ å¯†åŽå­—ç¬¦
     * @return ç»“æžœ
     */
    public static boolean matchesPassword(String rawPassword, String encodedPassword)
    {
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        return passwordEncoder.matches(rawPassword, encodedPassword);
    }
    /**
     * æ˜¯å¦ä¸ºç®¡ç†å‘˜
     *
     * @param userId ç”¨æˆ·ID
     * @return ç»“æžœ
     */
    public static boolean isAdmin(Long userId)
    {
        return userId != null && 1L == userId;
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/utils/ServletUtils.java
ruoyi-common/src/main/java/com/ruoyi/common/utils/StringUtils.java
ruoyi-common/src/main/java/com/ruoyi/common/utils/Threads.java
ruoyi-common/src/main/java/com/ruoyi/common/utils/VerifyCodeUtils.java
ruoyi-common/src/main/java/com/ruoyi/common/utils/bean/BeanUtils.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,110 @@
package com.ruoyi.common.utils.bean;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * Bean å·¥å…·ç±»
 *
 * @author ruoyi
 */
public class BeanUtils extends org.springframework.beans.BeanUtils
{
    /** Bean方法名中属性名开始的下标 */
    private static final int BEAN_METHOD_PROP_INDEX = 3;
    /** * åŒ¹é…getter方法的正则表达式 */
    private static final Pattern GET_PATTERN = Pattern.compile("get(\\p{javaUpperCase}\\w*)");
    /** * åŒ¹é…setter方法的正则表达式 */
    private static final Pattern SET_PATTERN = Pattern.compile("set(\\p{javaUpperCase}\\w*)");
    /**
     * Bean属性复制工具方法。
     *
     * @param dest ç›®æ ‡å¯¹è±¡
     * @param src æºå¯¹è±¡
     */
    public static void copyBeanProp(Object dest, Object src)
    {
        try
        {
            copyProperties(src, dest);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
    /**
     * èŽ·å–å¯¹è±¡çš„setter方法。
     *
     * @param obj å¯¹è±¡
     * @return å¯¹è±¡çš„setter方法列表
     */
    public static List<Method> getSetterMethods(Object obj)
    {
        // setter方法列表
        List<Method> setterMethods = new ArrayList<Method>();
        // èŽ·å–æ‰€æœ‰æ–¹æ³•
        Method[] methods = obj.getClass().getMethods();
        // æŸ¥æ‰¾setter方法
        for (Method method : methods)
        {
            Matcher m = SET_PATTERN.matcher(method.getName());
            if (m.matches() && (method.getParameterTypes().length == 1))
            {
                setterMethods.add(method);
            }
        }
        // è¿”回setter方法列表
        return setterMethods;
    }
    /**
     * èŽ·å–å¯¹è±¡çš„getter方法。
     *
     * @param obj å¯¹è±¡
     * @return å¯¹è±¡çš„getter方法列表
     */
    public static List<Method> getGetterMethods(Object obj)
    {
        // getter方法列表
        List<Method> getterMethods = new ArrayList<Method>();
        // èŽ·å–æ‰€æœ‰æ–¹æ³•
        Method[] methods = obj.getClass().getMethods();
        // æŸ¥æ‰¾getter方法
        for (Method method : methods)
        {
            Matcher m = GET_PATTERN.matcher(method.getName());
            if (m.matches() && (method.getParameterTypes().length == 0))
            {
                getterMethods.add(method);
            }
        }
        // è¿”回getter方法列表
        return getterMethods;
    }
    /**
     * æ£€æŸ¥Bean方法名中的属性名是否相等。<br>
     * å¦‚getName()和setName()属性名一样,getName()和setAge()属性名不一样。
     *
     * @param m1 æ–¹æ³•名1
     * @param m2 æ–¹æ³•名2
     * @return å±žæ€§åä¸€æ ·è¿”回true,否则返回false
     */
    public static boolean isMethodPropEquals(String m1, String m2)
    {
        return m1.substring(BEAN_METHOD_PROP_INDEX).equals(m2.substring(BEAN_METHOD_PROP_INDEX));
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUploadUtils.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,232 @@
package com.ruoyi.common.utils.file;
import java.io.File;
import java.io.IOException;
import org.apache.commons.io.FilenameUtils;
import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.exception.file.FileNameLengthLimitExceededException;
import com.ruoyi.common.exception.file.FileSizeLimitExceededException;
import com.ruoyi.common.exception.file.InvalidExtensionException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
/**
 * æ–‡ä»¶ä¸Šä¼ å·¥å…·ç±»
 *
 * @author ruoyi
 */
public class FileUploadUtils
{
    /**
     * é»˜è®¤å¤§å° 50M
     */
    public static final long DEFAULT_MAX_SIZE = 50 * 1024 * 1024;
    /**
     * é»˜è®¤çš„æ–‡ä»¶åæœ€å¤§é•¿åº¦ 100
     */
    public static final int DEFAULT_FILE_NAME_LENGTH = 100;
    /**
     * é»˜è®¤ä¸Šä¼ çš„地址
     */
    private static String defaultBaseDir = RuoYiConfig.getProfile();
    public static void setDefaultBaseDir(String defaultBaseDir)
    {
        FileUploadUtils.defaultBaseDir = defaultBaseDir;
    }
    public static String getDefaultBaseDir()
    {
        return defaultBaseDir;
    }
    /**
     * ä»¥é»˜è®¤é…ç½®è¿›è¡Œæ–‡ä»¶ä¸Šä¼ 
     *
     * @param file ä¸Šä¼ çš„æ–‡ä»¶
     * @return æ–‡ä»¶åç§°
     * @throws Exception
     */
    public static final String upload(MultipartFile file) throws IOException
    {
        try
        {
            return upload(getDefaultBaseDir(), file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION);
        }
        catch (Exception e)
        {
            throw new IOException(e.getMessage(), e);
        }
    }
    /**
     * æ ¹æ®æ–‡ä»¶è·¯å¾„上传
     *
     * @param baseDir ç›¸å¯¹åº”用的基目录
     * @param file ä¸Šä¼ çš„æ–‡ä»¶
     * @return æ–‡ä»¶åç§°
     * @throws IOException
     */
    public static final String upload(String baseDir, MultipartFile file) throws IOException
    {
        try
        {
            return upload(baseDir, file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION);
        }
        catch (Exception e)
        {
            throw new IOException(e.getMessage(), e);
        }
    }
    /**
     * æ–‡ä»¶ä¸Šä¼ 
     *
     * @param baseDir ç›¸å¯¹åº”用的基目录
     * @param file ä¸Šä¼ çš„æ–‡ä»¶
     * @param extension ä¸Šä¼ æ–‡ä»¶ç±»åž‹
     * @return è¿”回上传成功的文件名
     * @throws FileSizeLimitExceededException å¦‚果超出最大大小
     * @throws FileNameLengthLimitExceededException æ–‡ä»¶åå¤ªé•¿
     * @throws IOException æ¯”如读写文件出错时
     * @throws InvalidExtensionException æ–‡ä»¶æ ¡éªŒå¼‚常
     */
    public static final String upload(String baseDir, MultipartFile file, String[] allowedExtension)
            throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException,
            InvalidExtensionException
    {
        int fileNamelength = file.getOriginalFilename().length();
        if (fileNamelength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH)
        {
            throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH);
        }
        assertAllowed(file, allowedExtension);
        String fileName = extractFilename(file);
        File desc = getAbsoluteFile(baseDir, fileName);
        file.transferTo(desc);
        String pathFileName = getPathFileName(baseDir, fileName);
        return pathFileName;
    }
    /**
     * ç¼–码文件名
     */
    public static final String extractFilename(MultipartFile file)
    {
        String fileName = file.getOriginalFilename();
        String extension = getExtension(file);
        fileName = DateUtils.datePath() + "/" + IdUtils.fastUUID() + "." + extension;
        return fileName;
    }
    private static final File getAbsoluteFile(String uploadDir, String fileName) throws IOException
    {
        File desc = new File(uploadDir + File.separator + fileName);
        if (!desc.getParentFile().exists())
        {
            desc.getParentFile().mkdirs();
        }
        // è§£å†³undertow文件上传bug,因底层实现不同,无需创建新文件
//        if (!desc.exists())
//        {
//            desc.createNewFile();
//        }
        return desc;
    }
    private static final String getPathFileName(String uploadDir, String fileName) throws IOException
    {
        int dirLastIndex = RuoYiConfig.getProfile().length() + 1;
        String currentDir = StringUtils.substring(uploadDir, dirLastIndex);
        String pathFileName = Constants.RESOURCE_PREFIX + "/" + currentDir + "/" + fileName;
        return pathFileName;
    }
    /**
     * æ–‡ä»¶å¤§å°æ ¡éªŒ
     *
     * @param file ä¸Šä¼ çš„æ–‡ä»¶
     * @return
     * @throws FileSizeLimitExceededException å¦‚果超出最大大小
     * @throws InvalidExtensionException
     */
    public static final void assertAllowed(MultipartFile file, String[] allowedExtension)
            throws FileSizeLimitExceededException, InvalidExtensionException
    {
        long size = file.getSize();
        if (DEFAULT_MAX_SIZE != -1 && size > DEFAULT_MAX_SIZE)
        {
            throw new FileSizeLimitExceededException(DEFAULT_MAX_SIZE / 1024 / 1024);
        }
        String fileName = file.getOriginalFilename();
        String extension = getExtension(file);
        if (allowedExtension != null && !isAllowedExtension(extension, allowedExtension))
        {
            if (allowedExtension == MimeTypeUtils.IMAGE_EXTENSION)
            {
                throw new InvalidExtensionException.InvalidImageExtensionException(allowedExtension, extension,
                        fileName);
            }
            else if (allowedExtension == MimeTypeUtils.FLASH_EXTENSION)
            {
                throw new InvalidExtensionException.InvalidFlashExtensionException(allowedExtension, extension,
                        fileName);
            }
            else if (allowedExtension == MimeTypeUtils.MEDIA_EXTENSION)
            {
                throw new InvalidExtensionException.InvalidMediaExtensionException(allowedExtension, extension,
                        fileName);
            }
            else
            {
                throw new InvalidExtensionException(allowedExtension, extension, fileName);
            }
        }
    }
    /**
     * åˆ¤æ–­MIME类型是否是允许的MIME类型
     *
     * @param extension
     * @param allowedExtension
     * @return
     */
    public static final boolean isAllowedExtension(String extension, String[] allowedExtension)
    {
        for (String str : allowedExtension)
        {
            if (str.equalsIgnoreCase(extension))
            {
                return true;
            }
        }
        return false;
    }
    /**
     * èŽ·å–æ–‡ä»¶åçš„åŽç¼€
     *
     * @param file è¡¨å•文件
     * @return åŽç¼€å
     */
    public static final String getExtension(MultipartFile file)
    {
        String extension = FilenameUtils.getExtension(file.getOriginalFilename());
        if (StringUtils.isEmpty(extension))
        {
            extension = MimeTypeUtils.getExtension(file.getContentType());
        }
        return extension;
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUtils.java
ruoyi-common/src/main/java/com/ruoyi/common/utils/file/MimeTypeUtils.java
ruoyi-common/src/main/java/com/ruoyi/common/utils/html/EscapeUtil.java
ruoyi-common/src/main/java/com/ruoyi/common/utils/html/HTMLFilter.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,569 @@
package com.ruoyi.common.utils.html;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * HTML过滤器,用于去除XSS漏洞隐患。
 *
 * @author ruoyi
 */
public final class HTMLFilter
{
    /**
     * regex flag union representing /si modifiers in php
     **/
    private static final int REGEX_FLAGS_SI = Pattern.CASE_INSENSITIVE | Pattern.DOTALL;
    private static final Pattern P_COMMENTS = Pattern.compile("<!--(.*?)-->", Pattern.DOTALL);
    private static final Pattern P_COMMENT = Pattern.compile("^!--(.*)--$", REGEX_FLAGS_SI);
    private static final Pattern P_TAGS = Pattern.compile("<(.*?)>", Pattern.DOTALL);
    private static final Pattern P_END_TAG = Pattern.compile("^/([a-z0-9]+)", REGEX_FLAGS_SI);
    private static final Pattern P_START_TAG = Pattern.compile("^([a-z0-9]+)(.*?)(/?)$", REGEX_FLAGS_SI);
    private static final Pattern P_QUOTED_ATTRIBUTES = Pattern.compile("([a-z0-9]+)=([\"'])(.*?)\\2", REGEX_FLAGS_SI);
    private static final Pattern P_UNQUOTED_ATTRIBUTES = Pattern.compile("([a-z0-9]+)(=)([^\"\\s']+)", REGEX_FLAGS_SI);
    private static final Pattern P_PROTOCOL = Pattern.compile("^([^:]+):", REGEX_FLAGS_SI);
    private static final Pattern P_ENTITY = Pattern.compile("&#(\\d+);?");
    private static final Pattern P_ENTITY_UNICODE = Pattern.compile("&#x([0-9a-f]+);?");
    private static final Pattern P_ENCODE = Pattern.compile("%([0-9a-f]{2});?");
    private static final Pattern P_VALID_ENTITIES = Pattern.compile("&([^&;]*)(?=(;|&|$))");
    private static final Pattern P_VALID_QUOTES = Pattern.compile("(>|^)([^<]+?)(<|$)", Pattern.DOTALL);
    private static final Pattern P_END_ARROW = Pattern.compile("^>");
    private static final Pattern P_BODY_TO_END = Pattern.compile("<([^>]*?)(?=<|$)");
    private static final Pattern P_XML_CONTENT = Pattern.compile("(^|>)([^<]*?)(?=>)");
    private static final Pattern P_STRAY_LEFT_ARROW = Pattern.compile("<([^>]*?)(?=<|$)");
    private static final Pattern P_STRAY_RIGHT_ARROW = Pattern.compile("(^|>)([^<]*?)(?=>)");
    private static final Pattern P_AMP = Pattern.compile("&");
    private static final Pattern P_QUOTE = Pattern.compile("\"");
    private static final Pattern P_LEFT_ARROW = Pattern.compile("<");
    private static final Pattern P_RIGHT_ARROW = Pattern.compile(">");
    private static final Pattern P_BOTH_ARROWS = Pattern.compile("<>");
    // @xxx could grow large... maybe use sesat's ReferenceMap
    private static final ConcurrentMap<String, Pattern> P_REMOVE_PAIR_BLANKS = new ConcurrentHashMap<>();
    private static final ConcurrentMap<String, Pattern> P_REMOVE_SELF_BLANKS = new ConcurrentHashMap<>();
    /**
     * set of allowed html elements, along with allowed attributes for each element
     **/
    private final Map<String, List<String>> vAllowed;
    /**
     * counts of open tags for each (allowable) html element
     **/
    private final Map<String, Integer> vTagCounts = new HashMap<>();
    /**
     * html elements which must always be self-closing (e.g. "<img />")
     **/
    private final String[] vSelfClosingTags;
    /**
     * html elements which must always have separate opening and closing tags (e.g. "<b></b>")
     **/
    private final String[] vNeedClosingTags;
    /**
     * set of disallowed html elements
     **/
    private final String[] vDisallowed;
    /**
     * attributes which should be checked for valid protocols
     **/
    private final String[] vProtocolAtts;
    /**
     * allowed protocols
     **/
    private final String[] vAllowedProtocols;
    /**
     * tags which should be removed if they contain no content (e.g. "<b></b>" or "<b />")
     **/
    private final String[] vRemoveBlanks;
    /**
     * entities allowed within html markup
     **/
    private final String[] vAllowedEntities;
    /**
     * flag determining whether comments are allowed in input String.
     */
    private final boolean stripComment;
    private final boolean encodeQuotes;
    /**
     * flag determining whether to try to make tags when presented with "unbalanced" angle brackets (e.g. "<b text </b>"
     * becomes "<b> text </b>"). If set to false, unbalanced angle brackets will be html escaped.
     */
    private final boolean alwaysMakeTags;
    /**
     * Default constructor.
     */
    public HTMLFilter()
    {
        vAllowed = new HashMap<>();
        final ArrayList<String> a_atts = new ArrayList<>();
        a_atts.add("href");
        a_atts.add("target");
        vAllowed.put("a", a_atts);
        final ArrayList<String> img_atts = new ArrayList<>();
        img_atts.add("src");
        img_atts.add("width");
        img_atts.add("height");
        img_atts.add("alt");
        vAllowed.put("img", img_atts);
        final ArrayList<String> no_atts = new ArrayList<>();
        vAllowed.put("b", no_atts);
        vAllowed.put("strong", no_atts);
        vAllowed.put("i", no_atts);
        vAllowed.put("em", no_atts);
        vSelfClosingTags = new String[] { "img" };
        vNeedClosingTags = new String[] { "a", "b", "strong", "i", "em" };
        vDisallowed = new String[] {};
        vAllowedProtocols = new String[] { "http", "mailto", "https" }; // no ftp.
        vProtocolAtts = new String[] { "src", "href" };
        vRemoveBlanks = new String[] { "a", "b", "strong", "i", "em" };
        vAllowedEntities = new String[] { "amp", "gt", "lt", "quot" };
        stripComment = true;
        encodeQuotes = true;
        alwaysMakeTags = true;
    }
    /**
     * Map-parameter configurable constructor.
     *
     * @param conf map containing configuration. keys match field names.
     */
    @SuppressWarnings("unchecked")
    public HTMLFilter(final Map<String, Object> conf)
    {
        assert conf.containsKey("vAllowed") : "configuration requires vAllowed";
        assert conf.containsKey("vSelfClosingTags") : "configuration requires vSelfClosingTags";
        assert conf.containsKey("vNeedClosingTags") : "configuration requires vNeedClosingTags";
        assert conf.containsKey("vDisallowed") : "configuration requires vDisallowed";
        assert conf.containsKey("vAllowedProtocols") : "configuration requires vAllowedProtocols";
        assert conf.containsKey("vProtocolAtts") : "configuration requires vProtocolAtts";
        assert conf.containsKey("vRemoveBlanks") : "configuration requires vRemoveBlanks";
        assert conf.containsKey("vAllowedEntities") : "configuration requires vAllowedEntities";
        vAllowed = Collections.unmodifiableMap((HashMap<String, List<String>>) conf.get("vAllowed"));
        vSelfClosingTags = (String[]) conf.get("vSelfClosingTags");
        vNeedClosingTags = (String[]) conf.get("vNeedClosingTags");
        vDisallowed = (String[]) conf.get("vDisallowed");
        vAllowedProtocols = (String[]) conf.get("vAllowedProtocols");
        vProtocolAtts = (String[]) conf.get("vProtocolAtts");
        vRemoveBlanks = (String[]) conf.get("vRemoveBlanks");
        vAllowedEntities = (String[]) conf.get("vAllowedEntities");
        stripComment = conf.containsKey("stripComment") ? (Boolean) conf.get("stripComment") : true;
        encodeQuotes = conf.containsKey("encodeQuotes") ? (Boolean) conf.get("encodeQuotes") : true;
        alwaysMakeTags = conf.containsKey("alwaysMakeTags") ? (Boolean) conf.get("alwaysMakeTags") : true;
    }
    private void reset()
    {
        vTagCounts.clear();
    }
    // ---------------------------------------------------------------
    // my versions of some PHP library functions
    public static String chr(final int decimal)
    {
        return String.valueOf((char) decimal);
    }
    public static String htmlSpecialChars(final String s)
    {
        String result = s;
        result = regexReplace(P_AMP, "&amp;", result);
        result = regexReplace(P_QUOTE, "&quot;", result);
        result = regexReplace(P_LEFT_ARROW, "&lt;", result);
        result = regexReplace(P_RIGHT_ARROW, "&gt;", result);
        return result;
    }
    // ---------------------------------------------------------------
    /**
     * given a user submitted input String, filter out any invalid or restricted html.
     *
     * @param input text (i.e. submitted by a user) than may contain html
     * @return "clean" version of input, with only valid, whitelisted html elements allowed
     */
    public String filter(final String input)
    {
        reset();
        String s = input;
        s = escapeComments(s);
        s = balanceHTML(s);
        s = checkTags(s);
        s = processRemoveBlanks(s);
        s = validateEntities(s);
        return s;
    }
    public boolean isAlwaysMakeTags()
    {
        return alwaysMakeTags;
    }
    public boolean isStripComments()
    {
        return stripComment;
    }
    private String escapeComments(final String s)
    {
        final Matcher m = P_COMMENTS.matcher(s);
        final StringBuffer buf = new StringBuffer();
        if (m.find())
        {
            final String match = m.group(1); // (.*?)
            m.appendReplacement(buf, Matcher.quoteReplacement("<!--" + htmlSpecialChars(match) + "-->"));
        }
        m.appendTail(buf);
        return buf.toString();
    }
    private String balanceHTML(String s)
    {
        if (alwaysMakeTags)
        {
            //
            // try and form html
            //
            s = regexReplace(P_END_ARROW, "", s);
            s = regexReplace(P_BODY_TO_END, "<$1>", s);
            s = regexReplace(P_XML_CONTENT, "$1<$2", s);
        }
        else
        {
            //
            // escape stray brackets
            //
            s = regexReplace(P_STRAY_LEFT_ARROW, "&lt;$1", s);
            s = regexReplace(P_STRAY_RIGHT_ARROW, "$1$2&gt;<", s);
            //
            // the last regexp causes '<>' entities to appear
            // (we need to do a lookahead assertion so that the last bracket can
            // be used in the next pass of the regexp)
            //
            s = regexReplace(P_BOTH_ARROWS, "", s);
        }
        return s;
    }
    private String checkTags(String s)
    {
        Matcher m = P_TAGS.matcher(s);
        final StringBuffer buf = new StringBuffer();
        while (m.find())
        {
            String replaceStr = m.group(1);
            replaceStr = processTag(replaceStr);
            m.appendReplacement(buf, Matcher.quoteReplacement(replaceStr));
        }
        m.appendTail(buf);
        // these get tallied in processTag
        // (remember to reset before subsequent calls to filter method)
        final StringBuilder sBuilder = new StringBuilder(buf.toString());
        for (String key : vTagCounts.keySet())
        {
            for (int ii = 0; ii < vTagCounts.get(key); ii++)
            {
                sBuilder.append("</").append(key).append(">");
            }
        }
        s = sBuilder.toString();
        return s;
    }
    private String processRemoveBlanks(final String s)
    {
        String result = s;
        for (String tag : vRemoveBlanks)
        {
            if (!P_REMOVE_PAIR_BLANKS.containsKey(tag))
            {
                P_REMOVE_PAIR_BLANKS.putIfAbsent(tag, Pattern.compile("<" + tag + "(\\s[^>]*)?></" + tag + ">"));
            }
            result = regexReplace(P_REMOVE_PAIR_BLANKS.get(tag), "", result);
            if (!P_REMOVE_SELF_BLANKS.containsKey(tag))
            {
                P_REMOVE_SELF_BLANKS.putIfAbsent(tag, Pattern.compile("<" + tag + "(\\s[^>]*)?/>"));
            }
            result = regexReplace(P_REMOVE_SELF_BLANKS.get(tag), "", result);
        }
        return result;
    }
    private static String regexReplace(final Pattern regex_pattern, final String replacement, final String s)
    {
        Matcher m = regex_pattern.matcher(s);
        return m.replaceAll(replacement);
    }
    private String processTag(final String s)
    {
        // ending tags
        Matcher m = P_END_TAG.matcher(s);
        if (m.find())
        {
            final String name = m.group(1).toLowerCase();
            if (allowed(name))
            {
                if (false == inArray(name, vSelfClosingTags))
                {
                    if (vTagCounts.containsKey(name))
                    {
                        vTagCounts.put(name, vTagCounts.get(name) - 1);
                        return "</" + name + ">";
                    }
                }
            }
        }
        // starting tags
        m = P_START_TAG.matcher(s);
        if (m.find())
        {
            final String name = m.group(1).toLowerCase();
            final String body = m.group(2);
            String ending = m.group(3);
            // debug( "in a starting tag, name='" + name + "'; body='" + body + "'; ending='" + ending + "'" );
            if (allowed(name))
            {
                final StringBuilder params = new StringBuilder();
                final Matcher m2 = P_QUOTED_ATTRIBUTES.matcher(body);
                final Matcher m3 = P_UNQUOTED_ATTRIBUTES.matcher(body);
                final List<String> paramNames = new ArrayList<>();
                final List<String> paramValues = new ArrayList<>();
                while (m2.find())
                {
                    paramNames.add(m2.group(1)); // ([a-z0-9]+)
                    paramValues.add(m2.group(3)); // (.*?)
                }
                while (m3.find())
                {
                    paramNames.add(m3.group(1)); // ([a-z0-9]+)
                    paramValues.add(m3.group(3)); // ([^\"\\s']+)
                }
                String paramName, paramValue;
                for (int ii = 0; ii < paramNames.size(); ii++)
                {
                    paramName = paramNames.get(ii).toLowerCase();
                    paramValue = paramValues.get(ii);
                    // debug( "paramName='" + paramName + "'" );
                    // debug( "paramValue='" + paramValue + "'" );
                    // debug( "allowed? " + vAllowed.get( name ).contains( paramName ) );
                    if (allowedAttribute(name, paramName))
                    {
                        if (inArray(paramName, vProtocolAtts))
                        {
                            paramValue = processParamProtocol(paramValue);
                        }
                        params.append(' ').append(paramName).append("=\"").append(paramValue).append("\"");
                    }
                }
                if (inArray(name, vSelfClosingTags))
                {
                    ending = " /";
                }
                if (inArray(name, vNeedClosingTags))
                {
                    ending = "";
                }
                if (ending == null || ending.length() < 1)
                {
                    if (vTagCounts.containsKey(name))
                    {
                        vTagCounts.put(name, vTagCounts.get(name) + 1);
                    }
                    else
                    {
                        vTagCounts.put(name, 1);
                    }
                }
                else
                {
                    ending = " /";
                }
                return "<" + name + params + ending + ">";
            }
            else
            {
                return "";
            }
        }
        // comments
        m = P_COMMENT.matcher(s);
        if (!stripComment && m.find())
        {
            return "<" + m.group() + ">";
        }
        return "";
    }
    private String processParamProtocol(String s)
    {
        s = decodeEntities(s);
        final Matcher m = P_PROTOCOL.matcher(s);
        if (m.find())
        {
            final String protocol = m.group(1);
            if (!inArray(protocol, vAllowedProtocols))
            {
                // bad protocol, turn into local anchor link instead
                s = "#" + s.substring(protocol.length() + 1);
                if (s.startsWith("#//"))
                {
                    s = "#" + s.substring(3);
                }
            }
        }
        return s;
    }
    private String decodeEntities(String s)
    {
        StringBuffer buf = new StringBuffer();
        Matcher m = P_ENTITY.matcher(s);
        while (m.find())
        {
            final String match = m.group(1);
            final int decimal = Integer.decode(match).intValue();
            m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal)));
        }
        m.appendTail(buf);
        s = buf.toString();
        buf = new StringBuffer();
        m = P_ENTITY_UNICODE.matcher(s);
        while (m.find())
        {
            final String match = m.group(1);
            final int decimal = Integer.valueOf(match, 16).intValue();
            m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal)));
        }
        m.appendTail(buf);
        s = buf.toString();
        buf = new StringBuffer();
        m = P_ENCODE.matcher(s);
        while (m.find())
        {
            final String match = m.group(1);
            final int decimal = Integer.valueOf(match, 16).intValue();
            m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal)));
        }
        m.appendTail(buf);
        s = buf.toString();
        s = validateEntities(s);
        return s;
    }
    private String validateEntities(final String s)
    {
        StringBuffer buf = new StringBuffer();
        // validate entities throughout the string
        Matcher m = P_VALID_ENTITIES.matcher(s);
        while (m.find())
        {
            final String one = m.group(1); // ([^&;]*)
            final String two = m.group(2); // (?=(;|&|$))
            m.appendReplacement(buf, Matcher.quoteReplacement(checkEntity(one, two)));
        }
        m.appendTail(buf);
        return encodeQuotes(buf.toString());
    }
    private String encodeQuotes(final String s)
    {
        if (encodeQuotes)
        {
            StringBuffer buf = new StringBuffer();
            Matcher m = P_VALID_QUOTES.matcher(s);
            while (m.find())
            {
                final String one = m.group(1); // (>|^)
                final String two = m.group(2); // ([^<]+?)
                final String three = m.group(3); // (<|$)
                // ä¸æ›¿æ¢åŒå¼•号为&quot;,防止json格式无效 regexReplace(P_QUOTE, "&quot;", two)
                m.appendReplacement(buf, Matcher.quoteReplacement(one + two + three));
            }
            m.appendTail(buf);
            return buf.toString();
        }
        else
        {
            return s;
        }
    }
    private String checkEntity(final String preamble, final String term)
    {
        return ";".equals(term) && isValidEntity(preamble) ? '&' + preamble : "&amp;" + preamble;
    }
    private boolean isValidEntity(final String entity)
    {
        return inArray(entity, vAllowedEntities);
    }
    private static boolean inArray(final String s, final String[] array)
    {
        for (String item : array)
        {
            if (item != null && item.equals(s))
            {
                return true;
            }
        }
        return false;
    }
    private boolean allowed(final String name)
    {
        return (vAllowed.isEmpty() || vAllowed.containsKey(name)) && !inArray(name, vDisallowed);
    }
    private boolean allowedAttribute(final String name, final String paramName)
    {
        return allowed(name) && (vAllowed.isEmpty() || vAllowed.get(name).contains(paramName));
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpHelper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,55 @@
package com.ruoyi.common.utils.http;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import javax.servlet.ServletRequest;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
 * é€šç”¨http工具封装
 *
 * @author ruoyi
 */
public class HttpHelper
{
    private static final Logger LOGGER = LoggerFactory.getLogger(HttpHelper.class);
    public static String getBodyString(ServletRequest request)
    {
        StringBuilder sb = new StringBuilder();
        BufferedReader reader = null;
        try (InputStream inputStream = request.getInputStream())
        {
            reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));
            String line = "";
            while ((line = reader.readLine()) != null)
            {
                sb.append(line);
            }
        }
        catch (IOException e)
        {
            LOGGER.warn("getBodyString出现问题!");
        }
        finally
        {
            if (reader != null)
            {
                try
                {
                    reader.close();
                }
                catch (IOException e)
                {
                    LOGGER.error(ExceptionUtils.getMessage(e));
                }
            }
        }
        return sb.toString();
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpUtils.java
ruoyi-common/src/main/java/com/ruoyi/common/utils/ip/AddressUtils.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,56 @@
package com.ruoyi.common.utils.ip;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.http.HttpUtils;
/**
 * èŽ·å–åœ°å€ç±»
 *
 * @author ruoyi
 */
public class AddressUtils
{
    private static final Logger log = LoggerFactory.getLogger(AddressUtils.class);
    // IP地址查询
    public static final String IP_URL = "http://whois.pconline.com.cn/ipJson.jsp";
    // æœªçŸ¥åœ°å€
    public static final String UNKNOWN = "XX XX";
    public static String getRealAddressByIP(String ip)
    {
        String address = UNKNOWN;
        // å†…网不查询
        if (IpUtils.internalIp(ip))
        {
            return "内网IP";
        }
        if (RuoYiConfig.isAddressEnabled())
        {
            try
            {
                String rspStr = HttpUtils.sendGet(IP_URL, "ip=" + ip + "&json=true", Constants.GBK);
                if (StringUtils.isEmpty(rspStr))
                {
                    log.error("获取地理位置异常 {}", ip);
                    return UNKNOWN;
                }
                JSONObject obj = JSONObject.parseObject(rspStr);
                String region = obj.getString("pro");
                String city = obj.getString("city");
                return String.format("%s %s", region, city);
            }
            catch (Exception e)
            {
                log.error("获取地理位置异常 {}", ip);
            }
        }
        return address;
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/utils/ip/IpUtils.java
ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,875 @@
package com.ruoyi.common.utils.poi;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.DataValidation;
import org.apache.poi.ss.usermodel.DataValidationConstraint;
import org.apache.poi.ss.usermodel.DataValidationHelper;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFDataValidation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.annotation.Excel.ColumnType;
import com.ruoyi.common.annotation.Excel.Type;
import com.ruoyi.common.annotation.Excels;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.exception.CustomException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.reflect.ReflectUtils;
/**
 * Excel相关处理
 *
 * @author ruoyi
 */
public class ExcelUtil<T>
{
    private static final Logger log = LoggerFactory.getLogger(ExcelUtil.class);
    /**
     * Excel sheet最大行数,默认65536
     */
    public static final int sheetSize = 65536;
    /**
     * å·¥ä½œè¡¨åç§°
     */
    private String sheetName;
    /**
     * å¯¼å‡ºç±»åž‹ï¼ˆEXPORT:导出数据;IMPORT:导入模板)
     */
    private Type type;
    /**
     * å·¥ä½œè–„对象
     */
    private Workbook wb;
    /**
     * å·¥ä½œè¡¨å¯¹è±¡
     */
    private Sheet sheet;
    /**
     * æ ·å¼åˆ—表
     */
    private Map<String, CellStyle> styles;
    /**
     * å¯¼å…¥å¯¼å‡ºæ•°æ®åˆ—表
     */
    private List<T> list;
    /**
     * æ³¨è§£åˆ—表
     */
    private List<Object[]> fields;
    /**
     * å®žä½“对象
     */
    public Class<T> clazz;
    public ExcelUtil(Class<T> clazz)
    {
        this.clazz = clazz;
    }
    public void init(List<T> list, String sheetName, Type type)
    {
        if (list == null)
        {
            list = new ArrayList<T>();
        }
        this.list = list;
        this.sheetName = sheetName;
        this.type = type;
        createExcelField();
        createWorkbook();
    }
    /**
     * å¯¹excel表单默认第一个索引名转换成list
     *
     * @param is è¾“入流
     * @return è½¬æ¢åŽé›†åˆ
     */
    public List<T> importExcel(InputStream is) throws Exception
    {
        return importExcel(StringUtils.EMPTY, is);
    }
    /**
     * å¯¹excel表单指定表格索引名转换成list
     *
     * @param sheetName è¡¨æ ¼ç´¢å¼•名
     * @param is è¾“入流
     * @return è½¬æ¢åŽé›†åˆ
     */
    public List<T> importExcel(String sheetName, InputStream is) throws Exception
    {
        this.type = Type.IMPORT;
        this.wb = WorkbookFactory.create(is);
        List<T> list = new ArrayList<T>();
        Sheet sheet = null;
        if (StringUtils.isNotEmpty(sheetName))
        {
            // å¦‚果指定sheet名,则取指定sheet中的内容.
            sheet = wb.getSheet(sheetName);
        }
        else
        {
            // å¦‚果传入的sheet名不存在则默认指向第1个sheet.
            sheet = wb.getSheetAt(0);
        }
        if (sheet == null)
        {
            throw new IOException("文件sheet不存在");
        }
        int rows = sheet.getPhysicalNumberOfRows();
        if (rows > 0)
        {
            // å®šä¹‰ä¸€ä¸ªmap用于存放excel列的序号和field.
            Map<String, Integer> cellMap = new HashMap<String, Integer>();
            // èŽ·å–è¡¨å¤´
            Row heard = sheet.getRow(0);
            for (int i = 0; i < heard.getPhysicalNumberOfCells(); i++)
            {
                Cell cell = heard.getCell(i);
                if (StringUtils.isNotNull(cell))
                {
                    String value = this.getCellValue(heard, i).toString();
                    cellMap.put(value, i);
                }
                else
                {
                    cellMap.put(null, i);
                }
            }
            // æœ‰æ•°æ®æ—¶æ‰å¤„理 å¾—到类的所有field.
            Field[] allFields = clazz.getDeclaredFields();
            // å®šä¹‰ä¸€ä¸ªmap用于存放列的序号和field.
            Map<Integer, Field> fieldsMap = new HashMap<Integer, Field>();
            for (int col = 0; col < allFields.length; col++)
            {
                Field field = allFields[col];
                Excel attr = field.getAnnotation(Excel.class);
                if (attr != null && (attr.type() == Type.ALL || attr.type() == type))
                {
                    // è®¾ç½®ç±»çš„私有字段属性可访问.
                    field.setAccessible(true);
                    Integer column = cellMap.get(attr.name());
                    fieldsMap.put(column, field);
                }
            }
            for (int i = 1; i < rows; i++)
            {
                // ä»Žç¬¬2行开始取数据,默认第一行是表头.
                Row row = sheet.getRow(i);
                T entity = null;
                for (Map.Entry<Integer, Field> entry : fieldsMap.entrySet())
                {
                    Object val = this.getCellValue(row, entry.getKey());
                    // å¦‚果不存在实例则新建.
                    entity = (entity == null ? clazz.newInstance() : entity);
                    // ä»Žmap中得到对应列的field.
                    Field field = fieldsMap.get(entry.getKey());
                    // å–得类型,并根据对象类型设置值.
                    Class<?> fieldType = field.getType();
                    if (String.class == fieldType)
                    {
                        String s = Convert.toStr(val);
                        if (StringUtils.endsWith(s, ".0"))
                        {
                            val = StringUtils.substringBefore(s, ".0");
                        }
                        else
                        {
                            val = Convert.toStr(val);
                        }
                    }
                    else if ((Integer.TYPE == fieldType) || (Integer.class == fieldType))
                    {
                        val = Convert.toInt(val);
                    }
                    else if ((Long.TYPE == fieldType) || (Long.class == fieldType))
                    {
                        val = Convert.toLong(val);
                    }
                    else if ((Double.TYPE == fieldType) || (Double.class == fieldType))
                    {
                        val = Convert.toDouble(val);
                    }
                    else if ((Float.TYPE == fieldType) || (Float.class == fieldType))
                    {
                        val = Convert.toFloat(val);
                    }
                    else if (BigDecimal.class == fieldType)
                    {
                        val = Convert.toBigDecimal(val);
                    }
                    else if (Date.class == fieldType)
                    {
                        if (val instanceof String)
                        {
                            val = DateUtils.parseDate(val);
                        }
                        else if (val instanceof Double)
                        {
                            val = DateUtil.getJavaDate((Double) val);
                        }
                    }
                    if (StringUtils.isNotNull(fieldType))
                    {
                        Excel attr = field.getAnnotation(Excel.class);
                        String propertyName = field.getName();
                        if (StringUtils.isNotEmpty(attr.targetAttr()))
                        {
                            propertyName = field.getName() + "." + attr.targetAttr();
                        }
                        else if (StringUtils.isNotEmpty(attr.readConverterExp()))
                        {
                            val = reverseByExp(String.valueOf(val), attr.readConverterExp());
                        }
                        ReflectUtils.invokeSetter(entity, propertyName, val);
                    }
                }
                list.add(entity);
            }
        }
        return list;
    }
    /**
     * å¯¹list数据源将其里面的数据导入到excel表单
     *
     * @param list å¯¼å‡ºæ•°æ®é›†åˆ
     * @param sheetName å·¥ä½œè¡¨çš„名称
     * @return ç»“æžœ
     */
    public AjaxResult exportExcel(List<T> list, String sheetName)
    {
        this.init(list, sheetName, Type.EXPORT);
        return exportExcel();
    }
    /**
     * å¯¹list数据源将其里面的数据导入到excel表单
     *
     * @param sheetName å·¥ä½œè¡¨çš„名称
     * @return ç»“æžœ
     */
    public AjaxResult importTemplateExcel(String sheetName)
    {
        this.init(null, sheetName, Type.IMPORT);
        return exportExcel();
    }
    /**
     * å¯¹list数据源将其里面的数据导入到excel表单
     *
     * @return ç»“æžœ
     */
    public AjaxResult exportExcel()
    {
        OutputStream out = null;
        try
        {
            // å–出一共有多少个sheet.
            double sheetNo = Math.ceil(list.size() / sheetSize);
            for (int index = 0; index <= sheetNo; index++)
            {
                createSheet(sheetNo, index);
                // äº§ç”Ÿä¸€è¡Œ
                Row row = sheet.createRow(0);
                int column = 0;
                // å†™å…¥å„个字段的列头名称
                for (Object[] os : fields)
                {
                    Excel excel = (Excel) os[1];
                    this.createCell(excel, row, column++);
                }
                if (Type.EXPORT.equals(type))
                {
                    fillExcelData(index, row);
                }
            }
            String filename = encodingFilename(sheetName);
            out = new FileOutputStream(getAbsoluteFile(filename));
            wb.write(out);
            return AjaxResult.success(filename);
        }
        catch (Exception e)
        {
            log.error("导出Excel异常{}", e.getMessage());
            throw new CustomException("导出Excel失败,请联系网站管理员!");
        }
        finally
        {
            if (wb != null)
            {
                try
                {
                    wb.close();
                }
                catch (IOException e1)
                {
                    e1.printStackTrace();
                }
            }
            if (out != null)
            {
                try
                {
                    out.close();
                }
                catch (IOException e1)
                {
                    e1.printStackTrace();
                }
            }
        }
    }
    /**
     * å¡«å……excel数据
     *
     * @param index åºå·
     * @param row å•元格行
     */
    public void fillExcelData(int index, Row row)
    {
        int startNo = index * sheetSize;
        int endNo = Math.min(startNo + sheetSize, list.size());
        for (int i = startNo; i < endNo; i++)
        {
            row = sheet.createRow(i + 1 - startNo);
            // å¾—到导出对象.
            T vo = (T) list.get(i);
            int column = 0;
            for (Object[] os : fields)
            {
                Field field = (Field) os[0];
                Excel excel = (Excel) os[1];
                // è®¾ç½®å®žä½“类私有属性可访问
                field.setAccessible(true);
                this.addCell(excel, row, vo, field, column++);
            }
        }
    }
    /**
     * åˆ›å»ºè¡¨æ ¼æ ·å¼
     *
     * @param wb å·¥ä½œè–„对象
     * @return æ ·å¼åˆ—表
     */
    private Map<String, CellStyle> createStyles(Workbook wb)
    {
        // å†™å…¥å„条记录,每条记录对应excel表中的一行
        Map<String, CellStyle> styles = new HashMap<String, CellStyle>();
        CellStyle style = wb.createCellStyle();
        style.setAlignment(HorizontalAlignment.CENTER);
        style.setVerticalAlignment(VerticalAlignment.CENTER);
        style.setBorderRight(BorderStyle.THIN);
        style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
        style.setBorderLeft(BorderStyle.THIN);
        style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
        style.setBorderTop(BorderStyle.THIN);
        style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
        style.setBorderBottom(BorderStyle.THIN);
        style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
        Font dataFont = wb.createFont();
        dataFont.setFontName("Arial");
        dataFont.setFontHeightInPoints((short) 10);
        style.setFont(dataFont);
        styles.put("data", style);
        style = wb.createCellStyle();
        style.cloneStyleFrom(styles.get("data"));
        style.setAlignment(HorizontalAlignment.CENTER);
        style.setVerticalAlignment(VerticalAlignment.CENTER);
        style.setFillForegroundColor(IndexedColors.GREY_50_PERCENT.getIndex());
        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        Font headerFont = wb.createFont();
        headerFont.setFontName("Arial");
        headerFont.setFontHeightInPoints((short) 10);
        headerFont.setBold(true);
        headerFont.setColor(IndexedColors.WHITE.getIndex());
        style.setFont(headerFont);
        styles.put("header", style);
        return styles;
    }
    /**
     * åˆ›å»ºå•元格
     */
    public Cell createCell(Excel attr, Row row, int column)
    {
        // åˆ›å»ºåˆ—
        Cell cell = row.createCell(column);
        // å†™å…¥åˆ—信息
        cell.setCellValue(attr.name());
        setDataValidation(attr, row, column);
        cell.setCellStyle(styles.get("header"));
        return cell;
    }
    /**
     * è®¾ç½®å•元格信息
     *
     * @param value å•元格值
     * @param attr æ³¨è§£ç›¸å…³
     * @param cell å•元格信息
     */
    public void setCellVo(Object value, Excel attr, Cell cell)
    {
        if (ColumnType.STRING == attr.cellType())
        {
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(StringUtils.isNull(value) ? attr.defaultValue() : value + attr.suffix());
        }
        else if (ColumnType.NUMERIC == attr.cellType())
        {
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(Integer.parseInt(value + ""));
        }
    }
    /**
     * åˆ›å»ºè¡¨æ ¼æ ·å¼
     */
    public void setDataValidation(Excel attr, Row row, int column)
    {
        if (attr.name().indexOf("注:") >= 0)
        {
            sheet.setColumnWidth(column, 6000);
        }
        else
        {
            // è®¾ç½®åˆ—宽
            sheet.setColumnWidth(column, (int) ((attr.width() + 0.72) * 256));
            row.setHeight((short) (attr.height() * 20));
        }
        // å¦‚果设置了提示信息则鼠标放上去提示.
        if (StringUtils.isNotEmpty(attr.prompt()))
        {
            // è¿™é‡Œé»˜è®¤è®¾äº†2-101列提示.
            setXSSFPrompt(sheet, "", attr.prompt(), 1, 100, column, column);
        }
        // å¦‚果设置了combo属性则本列只能选择不能输入
        if (attr.combo().length > 0)
        {
            // è¿™é‡Œé»˜è®¤è®¾äº†2-101列只能选择不能输入.
            setXSSFValidation(sheet, attr.combo(), 1, 100, column, column);
        }
    }
    /**
     * æ·»åŠ å•å…ƒæ ¼
     */
    public Cell addCell(Excel attr, Row row, T vo, Field field, int column)
    {
        Cell cell = null;
        try
        {
            // è®¾ç½®è¡Œé«˜
            row.setHeight((short) (attr.height() * 20));
            // æ ¹æ®Excel中设置情况决定是否导出,有些情况需要保持为空,希望用户填写这一列.
            if (attr.isExport())
            {
                // åˆ›å»ºcell
                cell = row.createCell(column);
                cell.setCellStyle(styles.get("data"));
                // ç”¨äºŽè¯»å–对象中的属性
                Object value = getTargetValue(vo, field, attr);
                String dateFormat = attr.dateFormat();
                String readConverterExp = attr.readConverterExp();
                if (StringUtils.isNotEmpty(dateFormat) && StringUtils.isNotNull(value))
                {
                    cell.setCellValue(DateUtils.parseDateToStr(dateFormat, (Date) value));
                }
                else if (StringUtils.isNotEmpty(readConverterExp) && StringUtils.isNotNull(value))
                {
                    cell.setCellValue(convertByExp(String.valueOf(value), readConverterExp));
                }
                else
                {
                    // è®¾ç½®åˆ—类型
                    setCellVo(value, attr, cell);
                }
            }
        }
        catch (Exception e)
        {
            log.error("导出Excel失败{}", e);
        }
        return cell;
    }
    /**
     * è®¾ç½® POI XSSFSheet å•元格提示
     *
     * @param sheet è¡¨å•
     * @param promptTitle æç¤ºæ ‡é¢˜
     * @param promptContent æç¤ºå†…容
     * @param firstRow å¼€å§‹è¡Œ
     * @param endRow ç»“束行
     * @param firstCol å¼€å§‹åˆ—
     * @param endCol ç»“束列
     */
    public void setXSSFPrompt(Sheet sheet, String promptTitle, String promptContent, int firstRow, int endRow,
            int firstCol, int endCol)
    {
        DataValidationHelper helper = sheet.getDataValidationHelper();
        DataValidationConstraint constraint = helper.createCustomConstraint("DD1");
        CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol);
        DataValidation dataValidation = helper.createValidation(constraint, regions);
        dataValidation.createPromptBox(promptTitle, promptContent);
        dataValidation.setShowPromptBox(true);
        sheet.addValidationData(dataValidation);
    }
    /**
     * è®¾ç½®æŸäº›åˆ—的值只能输入预制的数据,显示下拉框.
     *
     * @param sheet è¦è®¾ç½®çš„sheet.
     * @param textlist ä¸‹æ‹‰æ¡†æ˜¾ç¤ºçš„内容
     * @param firstRow å¼€å§‹è¡Œ
     * @param endRow ç»“束行
     * @param firstCol å¼€å§‹åˆ—
     * @param endCol ç»“束列
     * @return è®¾ç½®å¥½çš„sheet.
     */
    public void setXSSFValidation(Sheet sheet, String[] textlist, int firstRow, int endRow, int firstCol, int endCol)
    {
        DataValidationHelper helper = sheet.getDataValidationHelper();
        // åŠ è½½ä¸‹æ‹‰åˆ—è¡¨å†…å®¹
        DataValidationConstraint constraint = helper.createExplicitListConstraint(textlist);
        // è®¾ç½®æ•°æ®æœ‰æ•ˆæ€§åŠ è½½åœ¨å“ªä¸ªå•å…ƒæ ¼ä¸Š,四个参数分别是:起始行、终止行、起始列、终止列
        CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol);
        // æ•°æ®æœ‰æ•ˆæ€§å¯¹è±¡
        DataValidation dataValidation = helper.createValidation(constraint, regions);
        // å¤„理Excel兼容性问题
        if (dataValidation instanceof XSSFDataValidation)
        {
            dataValidation.setSuppressDropDownArrow(true);
            dataValidation.setShowErrorBox(true);
        }
        else
        {
            dataValidation.setSuppressDropDownArrow(false);
        }
        sheet.addValidationData(dataValidation);
    }
    /**
     * è§£æžå¯¼å‡ºå€¼ 0=男,1=女,2=未知
     *
     * @param propertyValue å‚数值
     * @param converterExp ç¿»è¯‘注解
     * @return è§£æžåŽå€¼
     * @throws Exception
     */
    public static String convertByExp(String propertyValue, String converterExp) throws Exception
    {
        try
        {
            String[] convertSource = converterExp.split(",");
            for (String item : convertSource)
            {
                String[] itemArray = item.split("=");
                if (itemArray[0].equals(propertyValue))
                {
                    return itemArray[1];
                }
            }
        }
        catch (Exception e)
        {
            throw e;
        }
        return propertyValue;
    }
    /**
     * åå‘解析值 ç”·=0,女=1,未知=2
     *
     * @param propertyValue å‚数值
     * @param converterExp ç¿»è¯‘注解
     * @return è§£æžåŽå€¼
     * @throws Exception
     */
    public static String reverseByExp(String propertyValue, String converterExp) throws Exception
    {
        try
        {
            String[] convertSource = converterExp.split(",");
            for (String item : convertSource)
            {
                String[] itemArray = item.split("=");
                if (itemArray[1].equals(propertyValue))
                {
                    return itemArray[0];
                }
            }
        }
        catch (Exception e)
        {
            throw e;
        }
        return propertyValue;
    }
    /**
     * ç¼–码文件名
     */
    public String encodingFilename(String filename)
    {
        filename = UUID.randomUUID().toString() + "_" + filename + ".xlsx";
        return filename;
    }
    /**
     * èŽ·å–ä¸‹è½½è·¯å¾„
     *
     * @param filename æ–‡ä»¶åç§°
     */
    public String getAbsoluteFile(String filename)
    {
        String downloadPath = RuoYiConfig.getDownloadPath() + filename;
        File desc = new File(downloadPath);
        if (!desc.getParentFile().exists())
        {
            desc.getParentFile().mkdirs();
        }
        return downloadPath;
    }
    /**
     * èŽ·å–bean中的属性值
     *
     * @param vo å®žä½“对象
     * @param field å­—段
     * @param excel æ³¨è§£
     * @return æœ€ç»ˆçš„属性值
     * @throws Exception
     */
    private Object getTargetValue(T vo, Field field, Excel excel) throws Exception
    {
        Object o = field.get(vo);
        if (StringUtils.isNotEmpty(excel.targetAttr()))
        {
            String target = excel.targetAttr();
            if (target.indexOf(".") > -1)
            {
                String[] targets = target.split("[.]");
                for (String name : targets)
                {
                    o = getValue(o, name);
                }
            }
            else
            {
                o = getValue(o, target);
            }
        }
        return o;
    }
    /**
     * ä»¥ç±»çš„属性的get方法方法形式获取值
     *
     * @param o
     * @param name
     * @return value
     * @throws Exception
     */
    private Object getValue(Object o, String name) throws Exception
    {
        if (StringUtils.isNotEmpty(name))
        {
            Class<?> clazz = o.getClass();
            String methodName = "get" + name.substring(0, 1).toUpperCase() + name.substring(1);
            Method method = clazz.getMethod(methodName);
            o = method.invoke(o);
        }
        return o;
    }
    /**
     * å¾—到所有定义字段
     */
    private void createExcelField()
    {
        this.fields = new ArrayList<Object[]>();
        List<Field> tempFields = new ArrayList<>();
        tempFields.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredFields()));
        tempFields.addAll(Arrays.asList(clazz.getDeclaredFields()));
        for (Field field : tempFields)
        {
            // å•注解
            if (field.isAnnotationPresent(Excel.class))
            {
                putToField(field, field.getAnnotation(Excel.class));
            }
            // å¤šæ³¨è§£
            if (field.isAnnotationPresent(Excels.class))
            {
                Excels attrs = field.getAnnotation(Excels.class);
                Excel[] excels = attrs.value();
                for (Excel excel : excels)
                {
                    putToField(field, excel);
                }
            }
        }
        this.fields = this.fields.stream().sorted(Comparator.comparing(objects -> ((Excel) objects[1]).sort())).collect(Collectors.toList());
    }
    /**
     * æ”¾åˆ°å­—段集合中
     */
    private void putToField(Field field, Excel attr)
    {
        if (attr != null && (attr.type() == Type.ALL || attr.type() == type))
        {
            this.fields.add(new Object[] { field, attr });
        }
    }
    /**
     * åˆ›å»ºä¸€ä¸ªå·¥ä½œç°¿
     */
    public void createWorkbook()
    {
        this.wb = new SXSSFWorkbook(500);
    }
    /**
     * åˆ›å»ºå·¥ä½œè¡¨
     *
     * @param sheetNo sheet数量
     * @param index åºå·
     */
    public void createSheet(double sheetNo, int index)
    {
        this.sheet = wb.createSheet();
        this.styles = createStyles(wb);
        // è®¾ç½®å·¥ä½œè¡¨çš„名称.
        if (sheetNo == 0)
        {
            wb.setSheetName(index, sheetName);
        }
        else
        {
            wb.setSheetName(index, sheetName + index);
        }
    }
    /**
     * èŽ·å–å•å…ƒæ ¼å€¼
     *
     * @param row èŽ·å–çš„è¡Œ
     * @param column èŽ·å–å•å…ƒæ ¼åˆ—å·
     * @return å•元格值
     */
    public Object getCellValue(Row row, int column)
    {
        if (row == null)
        {
            return row;
        }
        Object val = "";
        try
        {
            Cell cell = row.getCell(column);
            if (StringUtils.isNotNull(cell))
            {
                if (cell.getCellTypeEnum() == CellType.NUMERIC || cell.getCellTypeEnum() == CellType.FORMULA)
                {
                    val = cell.getNumericCellValue();
                    if (HSSFDateUtil.isCellDateFormatted(cell))
                    {
                        val = DateUtil.getJavaDate((Double) val); // POI Excel æ—¥æœŸæ ¼å¼è½¬æ¢
                    }
                    else
                    {
                        if ((Double) val % 1 > 0)
                        {
                            val = new DecimalFormat("0.00").format(val);
                        }
                        else
                        {
                            val = new DecimalFormat("0").format(val);
                        }
                    }
                }
                else if (cell.getCellTypeEnum() == CellType.STRING)
                {
                    val = cell.getStringCellValue();
                }
                else if (cell.getCellTypeEnum() == CellType.BOOLEAN)
                {
                    val = cell.getBooleanCellValue();
                }
                else if (cell.getCellTypeEnum() == CellType.ERROR)
                {
                    val = cell.getErrorCellValue();
                }
            }
        }
        catch (Exception e)
        {
            return val;
        }
        return val;
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/utils/reflect/ReflectUtils.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,406 @@
package com.ruoyi.common.utils.reflect;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Date;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.apache.poi.ss.usermodel.DateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.utils.DateUtils;
/**
 * åå°„工具类. æä¾›è°ƒç”¨getter/setter方法, è®¿é—®ç§æœ‰å˜é‡, è°ƒç”¨ç§æœ‰æ–¹æ³•, èŽ·å–æ³›åž‹ç±»åž‹Class, è¢«AOP过的真实类等工具函数.
 *
 * @author ruoyi
 */
@SuppressWarnings("rawtypes")
public class ReflectUtils
{
    private static final String SETTER_PREFIX = "set";
    private static final String GETTER_PREFIX = "get";
    private static final String CGLIB_CLASS_SEPARATOR = "$$";
    private static Logger logger = LoggerFactory.getLogger(ReflectUtils.class);
    /**
     * è°ƒç”¨Getter方法.
     * æ”¯æŒå¤šçº§ï¼Œå¦‚:对象名.对象名.方法
     */
    @SuppressWarnings("unchecked")
    public static <E> E invokeGetter(Object obj, String propertyName)
    {
        Object object = obj;
        for (String name : StringUtils.split(propertyName, "."))
        {
            String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(name);
            object = invokeMethod(object, getterMethodName, new Class[] {}, new Object[] {});
        }
        return (E) object;
    }
    /**
     * è°ƒç”¨Setter方法, ä»…匹配方法名。
     * æ”¯æŒå¤šçº§ï¼Œå¦‚:对象名.对象名.方法
     */
    public static <E> void invokeSetter(Object obj, String propertyName, E value)
    {
        Object object = obj;
        String[] names = StringUtils.split(propertyName, ".");
        for (int i = 0; i < names.length; i++)
        {
            if (i < names.length - 1)
            {
                String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(names[i]);
                object = invokeMethod(object, getterMethodName, new Class[] {}, new Object[] {});
            }
            else
            {
                String setterMethodName = SETTER_PREFIX + StringUtils.capitalize(names[i]);
                invokeMethodByName(object, setterMethodName, new Object[] { value });
            }
        }
    }
    /**
     * ç›´æŽ¥è¯»å–对象属性值, æ— è§†private/protected修饰符, ä¸ç»è¿‡getter函数.
     */
    @SuppressWarnings("unchecked")
    public static <E> E getFieldValue(final Object obj, final String fieldName)
    {
        Field field = getAccessibleField(obj, fieldName);
        if (field == null)
        {
            logger.debug("在 [" + obj.getClass() + "] ä¸­ï¼Œæ²¡æœ‰æ‰¾åˆ° [" + fieldName + "] å­—段 ");
            return null;
        }
        E result = null;
        try
        {
            result = (E) field.get(obj);
        }
        catch (IllegalAccessException e)
        {
            logger.error("不可能抛出的异常{}", e.getMessage());
        }
        return result;
    }
    /**
     * ç›´æŽ¥è®¾ç½®å¯¹è±¡å±žæ€§å€¼, æ— è§†private/protected修饰符, ä¸ç»è¿‡setter函数.
     */
    public static <E> void setFieldValue(final Object obj, final String fieldName, final E value)
    {
        Field field = getAccessibleField(obj, fieldName);
        if (field == null)
        {
            // throw new IllegalArgumentException("在 [" + obj.getClass() + "] ä¸­ï¼Œæ²¡æœ‰æ‰¾åˆ° [" + fieldName + "] å­—段 ");
            logger.debug("在 [" + obj.getClass() + "] ä¸­ï¼Œæ²¡æœ‰æ‰¾åˆ° [" + fieldName + "] å­—段 ");
            return;
        }
        try
        {
            field.set(obj, value);
        }
        catch (IllegalAccessException e)
        {
            logger.error("不可能抛出的异常: {}", e.getMessage());
        }
    }
    /**
     * ç›´æŽ¥è°ƒç”¨å¯¹è±¡æ–¹æ³•, æ— è§†private/protected修饰符.
     * ç”¨äºŽä¸€æ¬¡æ€§è°ƒç”¨çš„æƒ…况,否则应使用getAccessibleMethod()函数获得Method后反复调用.
     * åŒæ—¶åŒ¹é…æ–¹æ³•名+参数类型,
     */
    @SuppressWarnings("unchecked")
    public static <E> E invokeMethod(final Object obj, final String methodName, final Class<?>[] parameterTypes,
            final Object[] args)
    {
        if (obj == null || methodName == null)
        {
            return null;
        }
        Method method = getAccessibleMethod(obj, methodName, parameterTypes);
        if (method == null)
        {
            logger.debug("在 [" + obj.getClass() + "] ä¸­ï¼Œæ²¡æœ‰æ‰¾åˆ° [" + methodName + "] æ–¹æ³• ");
            return null;
        }
        try
        {
            return (E) method.invoke(obj, args);
        }
        catch (Exception e)
        {
            String msg = "method: " + method + ", obj: " + obj + ", args: " + args + "";
            throw convertReflectionExceptionToUnchecked(msg, e);
        }
    }
    /**
     * ç›´æŽ¥è°ƒç”¨å¯¹è±¡æ–¹æ³•, æ— è§†private/protected修饰符,
     * ç”¨äºŽä¸€æ¬¡æ€§è°ƒç”¨çš„æƒ…况,否则应使用getAccessibleMethodByName()函数获得Method后反复调用.
     * åªåŒ¹é…å‡½æ•°åï¼Œå¦‚果有多个同名函数调用第一个。
     */
    @SuppressWarnings("unchecked")
    public static <E> E invokeMethodByName(final Object obj, final String methodName, final Object[] args)
    {
        Method method = getAccessibleMethodByName(obj, methodName, args.length);
        if (method == null)
        {
            // å¦‚果为空不报错,直接返回空。
            logger.debug("在 [" + obj.getClass() + "] ä¸­ï¼Œæ²¡æœ‰æ‰¾åˆ° [" + methodName + "] æ–¹æ³• ");
            return null;
        }
        try
        {
            // ç±»åž‹è½¬æ¢ï¼ˆå°†å‚数数据类型转换为目标方法参数类型)
            Class<?>[] cs = method.getParameterTypes();
            for (int i = 0; i < cs.length; i++)
            {
                if (args[i] != null && !args[i].getClass().equals(cs[i]))
                {
                    if (cs[i] == String.class)
                    {
                        args[i] = Convert.toStr(args[i]);
                        if (StringUtils.endsWith((String) args[i], ".0"))
                        {
                            args[i] = StringUtils.substringBefore((String) args[i], ".0");
                        }
                    }
                    else if (cs[i] == Integer.class)
                    {
                        args[i] = Convert.toInt(args[i]);
                    }
                    else if (cs[i] == Long.class)
                    {
                        args[i] = Convert.toLong(args[i]);
                    }
                    else if (cs[i] == Double.class)
                    {
                        args[i] = Convert.toDouble(args[i]);
                    }
                    else if (cs[i] == Float.class)
                    {
                        args[i] = Convert.toFloat(args[i]);
                    }
                    else if (cs[i] == Date.class)
                    {
                        if (args[i] instanceof String)
                        {
                            args[i] = DateUtils.parseDate(args[i]);
                        }
                        else
                        {
                            args[i] = DateUtil.getJavaDate((Double) args[i]);
                        }
                    }
                }
            }
            return (E) method.invoke(obj, args);
        }
        catch (Exception e)
        {
            String msg = "method: " + method + ", obj: " + obj + ", args: " + args + "";
            throw convertReflectionExceptionToUnchecked(msg, e);
        }
    }
    /**
     * å¾ªçŽ¯å‘ä¸Šè½¬åž‹, èŽ·å–å¯¹è±¡çš„DeclaredField, å¹¶å¼ºåˆ¶è®¾ç½®ä¸ºå¯è®¿é—®.
     * å¦‚向上转型到Object仍无法找到, è¿”回null.
     */
    public static Field getAccessibleField(final Object obj, final String fieldName)
    {
        // ä¸ºç©ºä¸æŠ¥é”™ã€‚直接返回 null
        if (obj == null)
        {
            return null;
        }
        Validate.notBlank(fieldName, "fieldName can't be blank");
        for (Class<?> superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass())
        {
            try
            {
                Field field = superClass.getDeclaredField(fieldName);
                makeAccessible(field);
                return field;
            }
            catch (NoSuchFieldException e)
            {
                continue;
            }
        }
        return null;
    }
    /**
     * å¾ªçŽ¯å‘ä¸Šè½¬åž‹, èŽ·å–å¯¹è±¡çš„DeclaredMethod,并强制设置为可访问.
     * å¦‚向上转型到Object仍无法找到, è¿”回null.
     * åŒ¹é…å‡½æ•°å+参数类型。
     * ç”¨äºŽæ–¹æ³•需要被多次调用的情况. å…ˆä½¿ç”¨æœ¬å‡½æ•°å…ˆå–å¾—Method,然后调用Method.invoke(Object obj, Object... args)
     */
    public static Method getAccessibleMethod(final Object obj, final String methodName,
            final Class<?>... parameterTypes)
    {
        // ä¸ºç©ºä¸æŠ¥é”™ã€‚直接返回 null
        if (obj == null)
        {
            return null;
        }
        Validate.notBlank(methodName, "methodName can't be blank");
        for (Class<?> searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass())
        {
            try
            {
                Method method = searchType.getDeclaredMethod(methodName, parameterTypes);
                makeAccessible(method);
                return method;
            }
            catch (NoSuchMethodException e)
            {
                continue;
            }
        }
        return null;
    }
    /**
     * å¾ªçŽ¯å‘ä¸Šè½¬åž‹, èŽ·å–å¯¹è±¡çš„DeclaredMethod,并强制设置为可访问.
     * å¦‚向上转型到Object仍无法找到, è¿”回null.
     * åªåŒ¹é…å‡½æ•°åã€‚
     * ç”¨äºŽæ–¹æ³•需要被多次调用的情况. å…ˆä½¿ç”¨æœ¬å‡½æ•°å…ˆå–å¾—Method,然后调用Method.invoke(Object obj, Object... args)
     */
    public static Method getAccessibleMethodByName(final Object obj, final String methodName, int argsNum)
    {
        // ä¸ºç©ºä¸æŠ¥é”™ã€‚直接返回 null
        if (obj == null)
        {
            return null;
        }
        Validate.notBlank(methodName, "methodName can't be blank");
        for (Class<?> searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass())
        {
            Method[] methods = searchType.getDeclaredMethods();
            for (Method method : methods)
            {
                if (method.getName().equals(methodName) && method.getParameterTypes().length == argsNum)
                {
                    makeAccessible(method);
                    return method;
                }
            }
        }
        return null;
    }
    /**
     * æ”¹å˜private/protected的方法为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。
     */
    public static void makeAccessible(Method method)
    {
        if ((!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers()))
                && !method.isAccessible())
        {
            method.setAccessible(true);
        }
    }
    /**
     * æ”¹å˜private/protected的成员变量为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。
     */
    public static void makeAccessible(Field field)
    {
        if ((!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers())
                || Modifier.isFinal(field.getModifiers())) && !field.isAccessible())
        {
            field.setAccessible(true);
        }
    }
    /**
     * é€šè¿‡åå°„, èŽ·å¾—Class定义中声明的泛型参数的类型, æ³¨æ„æ³›åž‹å¿…须定义在父类处
     * å¦‚无法找到, è¿”回Object.class.
     */
    @SuppressWarnings("unchecked")
    public static <T> Class<T> getClassGenricType(final Class clazz)
    {
        return getClassGenricType(clazz, 0);
    }
    /**
     * é€šè¿‡åå°„, èŽ·å¾—Class定义中声明的父类的泛型参数的类型.
     * å¦‚无法找到, è¿”回Object.class.
     */
    public static Class getClassGenricType(final Class clazz, final int index)
    {
        Type genType = clazz.getGenericSuperclass();
        if (!(genType instanceof ParameterizedType))
        {
            logger.debug(clazz.getSimpleName() + "'s superclass not ParameterizedType");
            return Object.class;
        }
        Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
        if (index >= params.length || index < 0)
        {
            logger.debug("Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: "
                    + params.length);
            return Object.class;
        }
        if (!(params[index] instanceof Class))
        {
            logger.debug(clazz.getSimpleName() + " not set the actual class on superclass generic parameter");
            return Object.class;
        }
        return (Class) params[index];
    }
    public static Class<?> getUserClass(Object instance)
    {
        if (instance == null)
        {
            throw new RuntimeException("Instance must not be null");
        }
        Class clazz = instance.getClass();
        if (clazz != null && clazz.getName().contains(CGLIB_CLASS_SEPARATOR))
        {
            Class<?> superClass = clazz.getSuperclass();
            if (superClass != null && !Object.class.equals(superClass))
            {
                return superClass;
            }
        }
        return clazz;
    }
    /**
     * å°†åå°„æ—¶çš„checked exception转换为unchecked exception.
     */
    public static RuntimeException convertReflectionExceptionToUnchecked(String msg, Exception e)
    {
        if (e instanceof IllegalAccessException || e instanceof IllegalArgumentException
                || e instanceof NoSuchMethodException)
        {
            return new IllegalArgumentException(msg, e);
        }
        else if (e instanceof InvocationTargetException)
        {
            return new RuntimeException(msg, ((InvocationTargetException) e).getTargetException());
        }
        return new RuntimeException(msg, e);
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/utils/sign/Base64.java
ruoyi-common/src/main/java/com/ruoyi/common/utils/sign/Md5Utils.java
ruoyi-common/src/main/java/com/ruoyi/common/utils/spring/SpringUtils.java
ruoyi-common/src/main/java/com/ruoyi/common/utils/sql/SqlUtil.java
ruoyi-common/src/main/java/com/ruoyi/common/utils/uuid/IdUtils.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,51 @@
package com.ruoyi.common.utils.uuid;
import com.ruoyi.common.utils.uuid.UUID;
/**
 * ID生成器工具类
 *
 * @author ruoyi
 */
public class IdUtils
{
    /**
     * èŽ·å–éšæœºUUID
     *
     * @return éšæœºUUID
     */
    public static String randomUUID()
    {
        return UUID.randomUUID().toString();
    }
    /**
     * ç®€åŒ–çš„UUID,去掉了横线
     *
     * @return ç®€åŒ–çš„UUID,去掉了横线
     */
    public static String simpleUUID()
    {
        return UUID.randomUUID().toString(true);
    }
    /**
     * èŽ·å–éšæœºUUID,使用性能更好的ThreadLocalRandom生成UUID
     *
     * @return éšæœºUUID
     */
    public static String fastUUID()
    {
        return UUID.fastUUID().toString();
    }
    /**
     * ç®€åŒ–çš„UUID,去掉了横线,使用性能更好的ThreadLocalRandom生成UUID
     *
     * @return ç®€åŒ–çš„UUID,去掉了横线
     */
    public static String fastSimpleUUID()
    {
        return UUID.fastUUID().toString(true);
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/utils/uuid/UUID.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,484 @@
package com.ruoyi.common.utils.uuid;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
import com.ruoyi.common.exception.UtilException;
/**
 * æä¾›é€šç”¨å”¯ä¸€è¯†åˆ«ç ï¼ˆuniversally unique identifier)(UUID)实现
 *
 * @author ruoyi
 */
public final class UUID implements java.io.Serializable, Comparable<UUID>
{
    private static final long serialVersionUID = -1185015143654744140L;
    /**
     * SecureRandom çš„单例
     *
     */
    private static class Holder
    {
        static final SecureRandom numberGenerator = getSecureRandom();
    }
    /** æ­¤UUID的最高64有效位 */
    private final long mostSigBits;
    /** æ­¤UUID的最低64有效位 */
    private final long leastSigBits;
    /**
     * ç§æœ‰æž„造
     *
     * @param data æ•°æ®
     */
    private UUID(byte[] data)
    {
        long msb = 0;
        long lsb = 0;
        assert data.length == 16 : "data must be 16 bytes in length";
        for (int i = 0; i < 8; i++)
        {
            msb = (msb << 8) | (data[i] & 0xff);
        }
        for (int i = 8; i < 16; i++)
        {
            lsb = (lsb << 8) | (data[i] & 0xff);
        }
        this.mostSigBits = msb;
        this.leastSigBits = lsb;
    }
    /**
     * ä½¿ç”¨æŒ‡å®šçš„æ•°æ®æž„造新的 UUID。
     *
     * @param mostSigBits ç”¨äºŽ {@code UUID} çš„æœ€é«˜æœ‰æ•ˆ 64 ä½
     * @param leastSigBits ç”¨äºŽ {@code UUID} çš„æœ€ä½Žæœ‰æ•ˆ 64 ä½
     */
    public UUID(long mostSigBits, long leastSigBits)
    {
        this.mostSigBits = mostSigBits;
        this.leastSigBits = leastSigBits;
    }
    /**
     * èŽ·å–ç±»åž‹ 4(伪随机生成的)UUID çš„静态工厂。 ä½¿ç”¨åŠ å¯†çš„æœ¬åœ°çº¿ç¨‹ä¼ªéšæœºæ•°ç”Ÿæˆå™¨ç”Ÿæˆè¯¥ UUID。
     *
     * @return éšæœºç”Ÿæˆçš„ {@code UUID}
     */
    public static UUID fastUUID()
    {
        return randomUUID(false);
    }
    /**
     * èŽ·å–ç±»åž‹ 4(伪随机生成的)UUID çš„静态工厂。 ä½¿ç”¨åŠ å¯†çš„å¼ºä¼ªéšæœºæ•°ç”Ÿæˆå™¨ç”Ÿæˆè¯¥ UUID。
     *
     * @return éšæœºç”Ÿæˆçš„ {@code UUID}
     */
    public static UUID randomUUID()
    {
        return randomUUID(true);
    }
    /**
     * èŽ·å–ç±»åž‹ 4(伪随机生成的)UUID çš„静态工厂。 ä½¿ç”¨åŠ å¯†çš„å¼ºä¼ªéšæœºæ•°ç”Ÿæˆå™¨ç”Ÿæˆè¯¥ UUID。
     *
     * @param isSecure æ˜¯å¦ä½¿ç”¨{@link SecureRandom}如果是可以获得更安全的随机码,否则可以得到更好的性能
     * @return éšæœºç”Ÿæˆçš„ {@code UUID}
     */
    public static UUID randomUUID(boolean isSecure)
    {
        final Random ng = isSecure ? Holder.numberGenerator : getRandom();
        byte[] randomBytes = new byte[16];
        ng.nextBytes(randomBytes);
        randomBytes[6] &= 0x0f; /* clear version */
        randomBytes[6] |= 0x40; /* set to version 4 */
        randomBytes[8] &= 0x3f; /* clear variant */
        randomBytes[8] |= 0x80; /* set to IETF variant */
        return new UUID(randomBytes);
    }
    /**
     * æ ¹æ®æŒ‡å®šçš„字节数组获取类型 3(基于名称的)UUID çš„静态工厂。
     *
     * @param name ç”¨äºŽæž„造 UUID çš„字节数组。
     *
     * @return æ ¹æ®æŒ‡å®šæ•°ç»„生成的 {@code UUID}
     */
    public static UUID nameUUIDFromBytes(byte[] name)
    {
        MessageDigest md;
        try
        {
            md = MessageDigest.getInstance("MD5");
        }
        catch (NoSuchAlgorithmException nsae)
        {
            throw new InternalError("MD5 not supported");
        }
        byte[] md5Bytes = md.digest(name);
        md5Bytes[6] &= 0x0f; /* clear version */
        md5Bytes[6] |= 0x30; /* set to version 3 */
        md5Bytes[8] &= 0x3f; /* clear variant */
        md5Bytes[8] |= 0x80; /* set to IETF variant */
        return new UUID(md5Bytes);
    }
    /**
     * æ ¹æ® {@link #toString()} æ–¹æ³•中描述的字符串标准表示形式创建{@code UUID}。
     *
     * @param name æŒ‡å®š {@code UUID} å­—符串
     * @return å…·æœ‰æŒ‡å®šå€¼çš„ {@code UUID}
     * @throws IllegalArgumentException å¦‚æžœ name ä¸Ž {@link #toString} ä¸­æè¿°çš„字符串表示形式不符抛出此异常
     *
     */
    public static UUID fromString(String name)
    {
        String[] components = name.split("-");
        if (components.length != 5)
        {
            throw new IllegalArgumentException("Invalid UUID string: " + name);
        }
        for (int i = 0; i < 5; i++)
        {
            components[i] = "0x" + components[i];
        }
        long mostSigBits = Long.decode(components[0]).longValue();
        mostSigBits <<= 16;
        mostSigBits |= Long.decode(components[1]).longValue();
        mostSigBits <<= 16;
        mostSigBits |= Long.decode(components[2]).longValue();
        long leastSigBits = Long.decode(components[3]).longValue();
        leastSigBits <<= 48;
        leastSigBits |= Long.decode(components[4]).longValue();
        return new UUID(mostSigBits, leastSigBits);
    }
    /**
     * è¿”回此 UUID çš„ 128 ä½å€¼ä¸­çš„æœ€ä½Žæœ‰æ•ˆ 64 ä½ã€‚
     *
     * @return æ­¤ UUID çš„ 128 ä½å€¼ä¸­çš„æœ€ä½Žæœ‰æ•ˆ 64 ä½ã€‚
     */
    public long getLeastSignificantBits()
    {
        return leastSigBits;
    }
    /**
     * è¿”回此 UUID çš„ 128 ä½å€¼ä¸­çš„æœ€é«˜æœ‰æ•ˆ 64 ä½ã€‚
     *
     * @return æ­¤ UUID çš„ 128 ä½å€¼ä¸­æœ€é«˜æœ‰æ•ˆ 64 ä½ã€‚
     */
    public long getMostSignificantBits()
    {
        return mostSigBits;
    }
    /**
     * ä¸Žæ­¤ {@code UUID} ç›¸å…³è”的版本号. ç‰ˆæœ¬å·æè¿°æ­¤ {@code UUID} æ˜¯å¦‚何生成的。
     * <p>
     * ç‰ˆæœ¬å·å…·æœ‰ä»¥ä¸‹å«æ„:
     * <ul>
     * <li>1 åŸºäºŽæ—¶é—´çš„ UUID
     * <li>2 DCE å®‰å…¨ UUID
     * <li>3 åŸºäºŽåç§°çš„ UUID
     * <li>4 éšæœºç”Ÿæˆçš„ UUID
     * </ul>
     *
     * @return æ­¤ {@code UUID} çš„版本号
     */
    public int version()
    {
        // Version is bits masked by 0x000000000000F000 in MS long
        return (int) ((mostSigBits >> 12) & 0x0f);
    }
    /**
     * ä¸Žæ­¤ {@code UUID} ç›¸å…³è”的变体号。变体号描述 {@code UUID} çš„布局。
     * <p>
     * å˜ä½“号具有以下含意:
     * <ul>
     * <li>0 ä¸º NCS å‘后兼容保留
     * <li>2 <a href="http://www.ietf.org/rfc/rfc4122.txt">IETF&nbsp;RFC&nbsp;4122</a>(Leach-Salz), ç”¨äºŽæ­¤ç±»
     * <li>6 ä¿ç•™ï¼Œå¾®è½¯å‘后兼容
     * <li>7 ä¿ç•™ä¾›ä»¥åŽå®šä¹‰ä½¿ç”¨
     * </ul>
     *
     * @return æ­¤ {@code UUID} ç›¸å…³è”的变体号
     */
    public int variant()
    {
        // This field is composed of a varying number of bits.
        // 0 - - Reserved for NCS backward compatibility
        // 1 0 - The IETF aka Leach-Salz variant (used by this class)
        // 1 1 0 Reserved, Microsoft backward compatibility
        // 1 1 1 Reserved for future definition.
        return (int) ((leastSigBits >>> (64 - (leastSigBits >>> 62))) & (leastSigBits >> 63));
    }
    /**
     * ä¸Žæ­¤ UUID ç›¸å…³è”的时间戳值。
     *
     * <p>
     * 60 ä½çš„æ—¶é—´æˆ³å€¼æ ¹æ®æ­¤ {@code UUID} çš„ time_low、time_mid å’Œ time_hi å­—段构造。<br>
     * æ‰€å¾—到的时间戳以 100 æ¯«å¾®ç§’为单位,从 UTC(通用协调时间) 1582 å¹´ 10 æœˆ 15 æ—¥é›¶æ—¶å¼€å§‹ã€‚
     *
     * <p>
     * æ—¶é—´æˆ³å€¼ä»…在在基于时间的 UUID(其 version ç±»åž‹ä¸º 1)中才有意义。<br>
     * å¦‚果此 {@code UUID} ä¸æ˜¯åŸºäºŽæ—¶é—´çš„ UUID,则此方法抛出 UnsupportedOperationException。
     *
     * @throws UnsupportedOperationException å¦‚果此 {@code UUID} ä¸æ˜¯ version ä¸º 1 çš„ UUID。
     */
    public long timestamp() throws UnsupportedOperationException
    {
        checkTimeBase();
        return (mostSigBits & 0x0FFFL) << 48//
                | ((mostSigBits >> 16) & 0x0FFFFL) << 32//
                | mostSigBits >>> 32;
    }
    /**
     * ä¸Žæ­¤ UUID ç›¸å…³è”的时钟序列值。
     *
     * <p>
     * 14 ä½çš„æ—¶é’Ÿåºåˆ—值根据此 UUID çš„ clock_seq å­—段构造。clock_seq å­—段用于保证在基于时间的 UUID ä¸­çš„æ—¶é—´å”¯ä¸€æ€§ã€‚
     * <p>
     * {@code clockSequence} å€¼ä»…在基于时间的 UUID(其 version ç±»åž‹ä¸º 1)中才有意义。 å¦‚果此 UUID ä¸æ˜¯åŸºäºŽæ—¶é—´çš„ UUID,则此方法抛出
     * UnsupportedOperationException。
     *
     * @return æ­¤ {@code UUID} çš„æ—¶é’Ÿåºåˆ—
     *
     * @throws UnsupportedOperationException å¦‚果此 UUID çš„ version ä¸ä¸º 1
     */
    public int clockSequence() throws UnsupportedOperationException
    {
        checkTimeBase();
        return (int) ((leastSigBits & 0x3FFF000000000000L) >>> 48);
    }
    /**
     * ä¸Žæ­¤ UUID ç›¸å…³çš„节点值。
     *
     * <p>
     * 48 ä½çš„节点值根据此 UUID çš„ node å­—段构造。此字段旨在用于保存机器的 IEEE 802 åœ°å€ï¼Œè¯¥åœ°å€ç”¨äºŽç”Ÿæˆæ­¤ UUID ä»¥ä¿è¯ç©ºé—´å”¯ä¸€æ€§ã€‚
     * <p>
     * èŠ‚ç‚¹å€¼ä»…åœ¨åŸºäºŽæ—¶é—´çš„ UUID(其 version ç±»åž‹ä¸º 1)中才有意义。<br>
     * å¦‚果此 UUID ä¸æ˜¯åŸºäºŽæ—¶é—´çš„ UUID,则此方法抛出 UnsupportedOperationException。
     *
     * @return æ­¤ {@code UUID} çš„节点值
     *
     * @throws UnsupportedOperationException å¦‚果此 UUID çš„ version ä¸ä¸º 1
     */
    public long node() throws UnsupportedOperationException
    {
        checkTimeBase();
        return leastSigBits & 0x0000FFFFFFFFFFFFL;
    }
    /**
     * è¿”回此{@code UUID} çš„字符串表现形式。
     *
     * <p>
     * UUID çš„字符串表示形式由此 BNF æè¿°ï¼š
     *
     * <pre>
     * {@code
     * UUID                   = <time_low>-<time_mid>-<time_high_and_version>-<variant_and_sequence>-<node>
     * time_low               = 4*<hexOctet>
     * time_mid               = 2*<hexOctet>
     * time_high_and_version  = 2*<hexOctet>
     * variant_and_sequence   = 2*<hexOctet>
     * node                   = 6*<hexOctet>
     * hexOctet               = <hexDigit><hexDigit>
     * hexDigit               = [0-9a-fA-F]
     * }
     * </pre>
     *
     * </blockquote>
     *
     * @return æ­¤{@code UUID} çš„字符串表现形式
     * @see #toString(boolean)
     */
    @Override
    public String toString()
    {
        return toString(false);
    }
    /**
     * è¿”回此{@code UUID} çš„字符串表现形式。
     *
     * <p>
     * UUID çš„字符串表示形式由此 BNF æè¿°ï¼š
     *
     * <pre>
     * {@code
     * UUID                   = <time_low>-<time_mid>-<time_high_and_version>-<variant_and_sequence>-<node>
     * time_low               = 4*<hexOctet>
     * time_mid               = 2*<hexOctet>
     * time_high_and_version  = 2*<hexOctet>
     * variant_and_sequence   = 2*<hexOctet>
     * node                   = 6*<hexOctet>
     * hexOctet               = <hexDigit><hexDigit>
     * hexDigit               = [0-9a-fA-F]
     * }
     * </pre>
     *
     * </blockquote>
     *
     * @param isSimple æ˜¯å¦ç®€å•模式,简单模式为不带'-'的UUID字符串
     * @return æ­¤{@code UUID} çš„字符串表现形式
     */
    public String toString(boolean isSimple)
    {
        final StringBuilder builder = new StringBuilder(isSimple ? 32 : 36);
        // time_low
        builder.append(digits(mostSigBits >> 32, 8));
        if (false == isSimple)
        {
            builder.append('-');
        }
        // time_mid
        builder.append(digits(mostSigBits >> 16, 4));
        if (false == isSimple)
        {
            builder.append('-');
        }
        // time_high_and_version
        builder.append(digits(mostSigBits, 4));
        if (false == isSimple)
        {
            builder.append('-');
        }
        // variant_and_sequence
        builder.append(digits(leastSigBits >> 48, 4));
        if (false == isSimple)
        {
            builder.append('-');
        }
        // node
        builder.append(digits(leastSigBits, 12));
        return builder.toString();
    }
    /**
     * è¿”回此 UUID çš„哈希码。
     *
     * @return UUID çš„哈希码值。
     */
    @Override
    public int hashCode()
    {
        long hilo = mostSigBits ^ leastSigBits;
        return ((int) (hilo >> 32)) ^ (int) hilo;
    }
    /**
     * å°†æ­¤å¯¹è±¡ä¸ŽæŒ‡å®šå¯¹è±¡æ¯”较。
     * <p>
     * å½“且仅当参数不为 {@code null}、而是一个 UUID å¯¹è±¡ã€å…·æœ‰ä¸Žæ­¤ UUID ç›¸åŒçš„ varriant、包含相同的值(每一位均相同)时,结果才为 {@code true}。
     *
     * @param obj è¦ä¸Žä¹‹æ¯”较的对象
     *
     * @return å¦‚果对象相同,则返回 {@code true};否则返回 {@code false}
     */
    @Override
    public boolean equals(Object obj)
    {
        if ((null == obj) || (obj.getClass() != UUID.class))
        {
            return false;
        }
        UUID id = (UUID) obj;
        return (mostSigBits == id.mostSigBits && leastSigBits == id.leastSigBits);
    }
    // Comparison Operations
    /**
     * å°†æ­¤ UUID ä¸ŽæŒ‡å®šçš„ UUID æ¯”较。
     *
     * <p>
     * å¦‚果两个 UUID ä¸åŒï¼Œä¸”第一个 UUID çš„æœ€é«˜æœ‰æ•ˆå­—段大于第二个 UUID çš„对应字段,则第一个 UUID å¤§äºŽç¬¬äºŒä¸ª UUID。
     *
     * @param val ä¸Žæ­¤ UUID æ¯”较的 UUID
     *
     * @return åœ¨æ­¤ UUID å°äºŽã€ç­‰äºŽæˆ–大于 val æ—¶ï¼Œåˆ†åˆ«è¿”回 -1、0 æˆ– 1。
     *
     */
    @Override
    public int compareTo(UUID val)
    {
        // The ordering is intentionally set up so that the UUIDs
        // can simply be numerically compared as two numbers
        return (this.mostSigBits < val.mostSigBits ? -1 : //
                (this.mostSigBits > val.mostSigBits ? 1 : //
                        (this.leastSigBits < val.leastSigBits ? -1 : //
                                (this.leastSigBits > val.leastSigBits ? 1 : //
                                        0))));
    }
    // -------------------------------------------------------------------------------------------------------------------
    // Private method start
    /**
     * è¿”回指定数字对应的hex值
     *
     * @param val å€¼
     * @param digits ä½
     * @return å€¼
     */
    private static String digits(long val, int digits)
    {
        long hi = 1L << (digits * 4);
        return Long.toHexString(hi | (val & (hi - 1))).substring(1);
    }
    /**
     * æ£€æŸ¥æ˜¯å¦ä¸ºtime-based版本UUID
     */
    private void checkTimeBase()
    {
        if (version() != 1)
        {
            throw new UnsupportedOperationException("Not a time-based UUID");
        }
    }
    /**
     * èŽ·å–{@link SecureRandom},类提供加密的强随机数生成器 (RNG)
     *
     * @return {@link SecureRandom}
     */
    public static SecureRandom getSecureRandom()
    {
        try
        {
            return SecureRandom.getInstance("SHA1PRNG");
        }
        catch (NoSuchAlgorithmException e)
        {
            throw new UtilException(e);
        }
    }
    /**
     * èŽ·å–éšæœºæ•°ç”Ÿæˆå™¨å¯¹è±¡<br>
     * ThreadLocalRandom是JDK 7之后提供并发产生随机数,能够解决多个线程发生的竞争争夺。
     *
     * @return {@link ThreadLocalRandom}
     */
    public static ThreadLocalRandom getRandom()
    {
        return ThreadLocalRandom.current();
    }
}
ruoyi-common/src/main/resources/application-dev.yml
copy from ruoyi/src/main/resources/application-dev.yml copy to ruoyi-common/src/main/resources/application-dev.yml
ruoyi-common/src/main/resources/application-prop.yml
ruoyi-common/src/main/resources/application-test.yml
ruoyi-framework/pom.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>ruoyi</artifactId>
        <groupId>com.ruoyi</groupId>
        <version>3.0.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>ruoyi-framework</artifactId>
    <description>
        framework框架核心
    </description>
    <dependencies>
        <!-- SpringBoot Web容器 -->
         <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
             <exclusions>
                 <exclusion>
                     <artifactId>spring-boot-starter-tomcat</artifactId>
                     <groupId>org.springframework.boot</groupId>
                 </exclusion>
             </exclusions>
        </dependency>
        <!-- web å®¹å™¨ä½¿ç”¨ undertow æ€§èƒ½æ›´å¼º -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-undertow</artifactId>
        </dependency>
        <!-- SpringBoot æ‹¦æˆªå™¨ -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <!-- é˜¿é‡Œæ•°æ®åº“连接池 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
        </dependency>
        <!-- èŽ·å–ç³»ç»Ÿä¿¡æ¯ -->
        <dependency>
            <groupId>com.github.oshi</groupId>
            <artifactId>oshi-core</artifactId>
        </dependency>
        <dependency>
            <groupId>net.java.dev.jna</groupId>
            <artifactId>jna</artifactId>
        </dependency>
        <dependency>
            <groupId>net.java.dev.jna</groupId>
            <artifactId>jna-platform</artifactId>
        </dependency>
        <!-- ç³»ç»Ÿæ¨¡å—-->
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>ruoyi-system</artifactId>
        </dependency>
    </dependencies>
</project>
ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/DataScopeAspect.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,165 @@
package com.ruoyi.framework.aspectj;
import java.lang.reflect.Method;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.common.core.domain.BaseEntity;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.framework.web.service.TokenService;
/**
 * æ•°æ®è¿‡æ»¤å¤„理
 *
 * @author ruoyi
 */
@Aspect
@Component
public class DataScopeAspect
{
    /**
     * å…¨éƒ¨æ•°æ®æƒé™
     */
    public static final String DATA_SCOPE_ALL = "1";
    /**
     * è‡ªå®šæ•°æ®æƒé™
     */
    public static final String DATA_SCOPE_CUSTOM = "2";
    /**
     * éƒ¨é—¨æ•°æ®æƒé™
     */
    public static final String DATA_SCOPE_DEPT = "3";
    /**
     * éƒ¨é—¨åŠä»¥ä¸‹æ•°æ®æƒé™
     */
    public static final String DATA_SCOPE_DEPT_AND_CHILD = "4";
    /**
     * ä»…本人数据权限
     */
    public static final String DATA_SCOPE_SELF = "5";
    /**
     * æ•°æ®æƒé™è¿‡æ»¤å…³é”®å­—
     */
    public static final String DATA_SCOPE = "dataScope";
    // é…ç½®ç»‡å…¥ç‚¹
    @Pointcut("@annotation(com.ruoyi.common.annotation.DataScope)")
    public void dataScopePointCut()
    {
    }
    @Before("dataScopePointCut()")
    public void doBefore(JoinPoint point) throws Throwable
    {
        handleDataScope(point);
    }
    protected void handleDataScope(final JoinPoint joinPoint)
    {
        // èŽ·å¾—æ³¨è§£
        DataScope controllerDataScope = getAnnotationLog(joinPoint);
        if (controllerDataScope == null)
        {
            return;
        }
        // èŽ·å–å½“å‰çš„ç”¨æˆ·
        LoginUser loginUser = SpringUtils.getBean(TokenService.class).getLoginUser(ServletUtils.getRequest());
        SysUser currentUser = loginUser.getUser();
        if (currentUser != null)
        {
            // å¦‚果是超级管理员,则不过滤数据
            if (!currentUser.isAdmin())
            {
                dataScopeFilter(joinPoint, currentUser, controllerDataScope.deptAlias(),
                        controllerDataScope.userAlias());
            }
        }
    }
    /**
     * æ•°æ®èŒƒå›´è¿‡æ»¤
     *
     * @param joinPoint åˆ‡ç‚¹
     * @param user ç”¨æˆ·
     * @param alias åˆ«å
     */
    public static void dataScopeFilter(JoinPoint joinPoint, SysUser user, String deptAlias, String userAlias)
    {
        StringBuilder sqlString = new StringBuilder();
        for (SysRole role : user.getRoles())
        {
            String dataScope = role.getDataScope();
            if (DATA_SCOPE_ALL.equals(dataScope))
            {
                sqlString = new StringBuilder();
                break;
            }
            else if (DATA_SCOPE_CUSTOM.equals(dataScope))
            {
                sqlString.append(StringUtils.format(
                        " OR {}.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id = {} ) ", deptAlias,
                        role.getRoleId()));
            }
            else if (DATA_SCOPE_DEPT.equals(dataScope))
            {
                sqlString.append(StringUtils.format(" OR {}.dept_id = {} ", deptAlias, user.getDeptId()));
            }
            else if (DATA_SCOPE_DEPT_AND_CHILD.equals(dataScope))
            {
                sqlString.append(StringUtils.format(
                        " OR {}.dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = {} or find_in_set( {} , ancestors ) )",
                        deptAlias, user.getDeptId(), user.getDeptId()));
            }
            else if (DATA_SCOPE_SELF.equals(dataScope))
            {
                if (StringUtils.isNotBlank(userAlias))
                {
                    sqlString.append(StringUtils.format(" OR {}.user_id = {} ", userAlias, user.getUserId()));
                }
                else
                {
                    // æ•°æ®æƒé™ä¸ºä»…本人且没有userAlias别名不查询任何数据
                    sqlString.append(" OR 1=0 ");
                }
            }
        }
        if (StringUtils.isNotBlank(sqlString.toString()))
        {
            BaseEntity baseEntity = (BaseEntity) joinPoint.getArgs()[0];
            baseEntity.getParams().put(DATA_SCOPE, " AND (" + sqlString.substring(4) + ")");
        }
    }
    /**
     * æ˜¯å¦å­˜åœ¨æ³¨è§£ï¼Œå¦‚果存在就获取
     */
    private DataScope getAnnotationLog(JoinPoint joinPoint)
    {
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();
        if (method != null)
        {
            return method.getAnnotation(DataScope.class);
        }
        return null;
    }
}
ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/DataSourceAspect.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,72 @@
package com.ruoyi.framework.aspectj;
import java.util.Objects;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import com.ruoyi.common.annotation.DataSource;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.datasource.DynamicDataSourceContextHolder;
/**
 * å¤šæ•°æ®æºå¤„理
 *
 * @author ruoyi
 */
@Aspect
@Order(1)
@Component
public class DataSourceAspect
{
    protected Logger logger = LoggerFactory.getLogger(getClass());
    @Pointcut("@annotation(com.ruoyi.common.annotation.DataSource)"
            + "|| @within(com.ruoyi.common.annotation.DataSource)")
    public void dsPointCut()
    {
    }
    @Around("dsPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable
    {
        DataSource dataSource = getDataSource(point);
        if (StringUtils.isNotNull(dataSource))
        {
            DynamicDataSourceContextHolder.setDataSourceType(dataSource.value().name());
        }
        try
        {
            return point.proceed();
        }
        finally
        {
            // é”€æ¯æ•°æ®æº åœ¨æ‰§è¡Œæ–¹æ³•之后
            DynamicDataSourceContextHolder.clearDataSourceType();
        }
    }
    /**
     * èŽ·å–éœ€è¦åˆ‡æ¢çš„æ•°æ®æº
     */
    public DataSource getDataSource(ProceedingJoinPoint point)
    {
        MethodSignature signature = (MethodSignature) point.getSignature();
        DataSource dataSource = AnnotationUtils.findAnnotation(signature.getMethod(), DataSource.class);
        if (Objects.nonNull(dataSource))
        {
            return dataSource;
        }
        return AnnotationUtils.findAnnotation(signature.getDeclaringType(), DataSource.class);
    }
}
ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,217 @@
package com.ruoyi.framework.aspectj;
import java.lang.reflect.Method;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.HandlerMapping;
import com.alibaba.fastjson.JSON;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.enums.BusinessStatus;
import com.ruoyi.common.enums.HttpMethod;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.ip.IpUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.framework.manager.factory.AsyncFactory;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.system.domain.SysOperLog;
/**
 * æ“ä½œæ—¥å¿—记录处理
 *
 * @author ruoyi
 */
@Aspect
@Component
public class LogAspect
{
    private static final Logger log = LoggerFactory.getLogger(LogAspect.class);
    // é…ç½®ç»‡å…¥ç‚¹
    @Pointcut("@annotation(com.ruoyi.common.annotation.Log)")
    public void logPointCut()
    {
    }
    /**
     * å¤„理完请求后执行
     *
     * @param joinPoint åˆ‡ç‚¹
     */
    @AfterReturning(pointcut = "logPointCut()", returning = "jsonResult")
    public void doAfterReturning(JoinPoint joinPoint, Object jsonResult)
    {
        handleLog(joinPoint, null, jsonResult);
    }
    /**
     * æ‹¦æˆªå¼‚常操作
     *
     * @param joinPoint åˆ‡ç‚¹
     * @param e å¼‚常
     */
    @AfterThrowing(value = "logPointCut()", throwing = "e")
    public void doAfterThrowing(JoinPoint joinPoint, Exception e)
    {
        handleLog(joinPoint, e, null);
    }
    protected void handleLog(final JoinPoint joinPoint, final Exception e, Object jsonResult)
    {
        try
        {
            // èŽ·å¾—æ³¨è§£
            Log controllerLog = getAnnotationLog(joinPoint);
            if (controllerLog == null)
            {
                return;
            }
            // èŽ·å–å½“å‰çš„ç”¨æˆ·
            LoginUser loginUser = SpringUtils.getBean(TokenService.class).getLoginUser(ServletUtils.getRequest());
            // *========数据库日志=========*//
            SysOperLog operLog = new SysOperLog();
            operLog.setStatus(BusinessStatus.SUCCESS.ordinal());
            // è¯·æ±‚的地址
            String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
            operLog.setOperIp(ip);
            // è¿”回参数
            operLog.setJsonResult(JSON.toJSONString(jsonResult));
            operLog.setOperUrl(ServletUtils.getRequest().getRequestURI());
            if (loginUser != null)
            {
                operLog.setOperName(loginUser.getUsername());
            }
            if (e != null)
            {
                operLog.setStatus(BusinessStatus.FAIL.ordinal());
                operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000));
            }
            // è®¾ç½®æ–¹æ³•名称
            String className = joinPoint.getTarget().getClass().getName();
            String methodName = joinPoint.getSignature().getName();
            operLog.setMethod(className + "." + methodName + "()");
            // è®¾ç½®è¯·æ±‚方式
            operLog.setRequestMethod(ServletUtils.getRequest().getMethod());
            // å¤„理设置注解上的参数
            getControllerMethodDescription(joinPoint, controllerLog, operLog);
            // ä¿å­˜æ•°æ®åº“
            AsyncManager.me().execute(AsyncFactory.recordOper(operLog));
        }
        catch (Exception exp)
        {
            // è®°å½•本地异常日志
            log.error("==前置通知异常==");
            log.error("异常信息:{}", exp.getMessage());
            exp.printStackTrace();
        }
    }
    /**
     * èŽ·å–æ³¨è§£ä¸­å¯¹æ–¹æ³•çš„æè¿°ä¿¡æ¯ ç”¨äºŽController层注解
     *
     * @param log æ—¥å¿—
     * @param operLog æ“ä½œæ—¥å¿—
     * @throws Exception
     */
    public void getControllerMethodDescription(JoinPoint joinPoint, Log log, SysOperLog operLog) throws Exception
    {
        // è®¾ç½®action动作
        operLog.setBusinessType(log.businessType().ordinal());
        // è®¾ç½®æ ‡é¢˜
        operLog.setTitle(log.title());
        // è®¾ç½®æ“ä½œäººç±»åˆ«
        operLog.setOperatorType(log.operatorType().ordinal());
        // æ˜¯å¦éœ€è¦ä¿å­˜request,参数和值
        if (log.isSaveRequestData())
        {
            // èŽ·å–å‚æ•°çš„ä¿¡æ¯ï¼Œä¼ å…¥åˆ°æ•°æ®åº“ä¸­ã€‚
            setRequestValue(joinPoint, operLog);
        }
    }
    /**
     * èŽ·å–è¯·æ±‚çš„å‚æ•°ï¼Œæ”¾åˆ°log中
     *
     * @param operLog æ“ä½œæ—¥å¿—
     * @throws Exception å¼‚常
     */
    private void setRequestValue(JoinPoint joinPoint, SysOperLog operLog) throws Exception
    {
        String requestMethod = operLog.getRequestMethod();
        if (HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod))
        {
            String params = argsArrayToString(joinPoint.getArgs());
            operLog.setOperParam(StringUtils.substring(params, 0, 2000));
        }
        else
        {
            Map<?, ?> paramsMap = (Map<?, ?>) ServletUtils.getRequest().getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
            operLog.setOperParam(StringUtils.substring(paramsMap.toString(), 0, 2000));
        }
    }
    /**
     * æ˜¯å¦å­˜åœ¨æ³¨è§£ï¼Œå¦‚果存在就获取
     */
    private Log getAnnotationLog(JoinPoint joinPoint) throws Exception
    {
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();
        if (method != null)
        {
            return method.getAnnotation(Log.class);
        }
        return null;
    }
    /**
     * å‚数拼装
     */
    private String argsArrayToString(Object[] paramsArray)
    {
        String params = "";
        if (paramsArray != null && paramsArray.length > 0)
        {
            for (int i = 0; i < paramsArray.length; i++)
            {
                if (!isFilterObject(paramsArray[i]))
                {
                    Object jsonObj = JSON.toJSON(paramsArray[i]);
                    params += jsonObj.toString() + " ";
                }
            }
        }
        return params.trim();
    }
    /**
     * åˆ¤æ–­æ˜¯å¦éœ€è¦è¿‡æ»¤çš„对象。
     *
     * @param o å¯¹è±¡ä¿¡æ¯ã€‚
     * @return å¦‚果是需要过滤的对象,则返回true;否则返回false。
     */
    public boolean isFilterObject(final Object o)
    {
        return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse;
    }
}
ruoyi-framework/src/main/java/com/ruoyi/framework/config/ApplicationConfig.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,30 @@
package com.ruoyi.framework.config;
import java.util.TimeZone;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
/**
 * ç¨‹åºæ³¨è§£é…ç½®
 *
 * @author ruoyi
 */
@Configuration
// è¡¨ç¤ºé€šè¿‡aop框架暴露该代理对象,AopContext能够访问
@EnableAspectJAutoProxy(exposeProxy = true)
// æŒ‡å®šè¦æ‰«æçš„Mapper类的包的路径
@MapperScan("com.ruoyi.**.mapper")
public class ApplicationConfig
{
    /**
     * æ—¶åŒºé…ç½®
     */
    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization()
    {
        return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder.timeZone(TimeZone.getDefault());
    }
}
ruoyi-framework/src/main/java/com/ruoyi/framework/config/DruidConfig.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,126 @@
package com.ruoyi.framework.config;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.sql.DataSource;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import com.alibaba.druid.spring.boot.autoconfigure.properties.DruidStatProperties;
import com.alibaba.druid.util.Utils;
import com.ruoyi.common.enums.DataSourceType;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.framework.config.properties.DruidProperties;
import com.ruoyi.framework.datasource.DynamicDataSource;
/**
 * druid é…ç½®å¤šæ•°æ®æº
 *
 * @author ruoyi
 */
@Configuration
public class DruidConfig
{
    @Bean
    @ConfigurationProperties("spring.datasource.druid.master")
    public DataSource masterDataSource(DruidProperties druidProperties)
    {
        DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
        return druidProperties.dataSource(dataSource);
    }
    @Bean
    @ConfigurationProperties("spring.datasource.druid.slave")
    @ConditionalOnProperty(prefix = "spring.datasource.druid.slave", name = "enabled", havingValue = "true")
    public DataSource slaveDataSource(DruidProperties druidProperties)
    {
        DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
        return druidProperties.dataSource(dataSource);
    }
    @Bean(name = "dynamicDataSource")
    @Primary
    public DynamicDataSource dataSource(DataSource masterDataSource)
    {
        Map<Object, Object> targetDataSources = new HashMap<>();
        targetDataSources.put(DataSourceType.MASTER.name(), masterDataSource);
        setDataSource(targetDataSources, DataSourceType.SLAVE.name(), "slaveDataSource");
        return new DynamicDataSource(masterDataSource, targetDataSources);
    }
    /**
     * è®¾ç½®æ•°æ®æº
     *
     * @param targetDataSources å¤‡é€‰æ•°æ®æºé›†åˆ
     * @param sourceName æ•°æ®æºåç§°
     * @param beanName bean名称
     */
    public void setDataSource(Map<Object, Object> targetDataSources, String sourceName, String beanName)
    {
        try
        {
            DataSource dataSource = SpringUtils.getBean(beanName);
            targetDataSources.put(sourceName, dataSource);
        }
        catch (Exception e)
        {
        }
    }
    /**
     * åŽ»é™¤ç›‘æŽ§é¡µé¢åº•éƒ¨çš„å¹¿å‘Š
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Bean
    @ConditionalOnProperty(name = "spring.datasource.druid.statViewServlet.enabled", havingValue = "true")
    public FilterRegistrationBean removeDruidFilterRegistrationBean(DruidStatProperties properties)
    {
        // èŽ·å–web监控页面的参数
        DruidStatProperties.StatViewServlet config = properties.getStatViewServlet();
        // æå–common.js的配置路径
        String pattern = config.getUrlPattern() != null ? config.getUrlPattern() : "/druid/*";
        String commonJsPattern = pattern.replaceAll("\\*", "js/common.js");
        final String filePath = "support/http/resources/js/common.js";
        // åˆ›å»ºfilter进行过滤
        Filter filter = new Filter()
        {
            @Override
            public void init(javax.servlet.FilterConfig filterConfig) throws ServletException
            {
            }
            @Override
            public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                    throws IOException, ServletException
            {
                chain.doFilter(request, response);
                // é‡ç½®ç¼“冲区,响应头不会被重置
                response.resetBuffer();
                // èŽ·å–common.js
                String text = Utils.readFromResource(filePath);
                // æ­£åˆ™æ›¿æ¢banner, é™¤åŽ»åº•éƒ¨çš„å¹¿å‘Šä¿¡æ¯
                text = text.replaceAll("<a.*?banner\"></a><br/>", "");
                text = text.replaceAll("powered.*?shrek.wang</a>", "");
                response.getWriter().write(text);
            }
            @Override
            public void destroy()
            {
            }
        };
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        registrationBean.setFilter(filter);
        registrationBean.addUrlPatterns(commonJsPattern);
        return registrationBean;
    }
}
ruoyi-framework/src/main/java/com/ruoyi/framework/config/FastJson2JsonRedisSerializer.java
ruoyi-framework/src/main/java/com/ruoyi/framework/config/FilterConfig.java
ruoyi-framework/src/main/java/com/ruoyi/framework/config/MyBatisConfig.java
ruoyi-framework/src/main/java/com/ruoyi/framework/config/RedisConfig.java
ruoyi-framework/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,42 @@
package com.ruoyi.framework.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.framework.interceptor.RepeatSubmitInterceptor;
/**
 * é€šç”¨é…ç½®
 *
 * @author ruoyi
 */
@Configuration
public class ResourcesConfig implements WebMvcConfigurer
{
    @Autowired
    private RepeatSubmitInterceptor repeatSubmitInterceptor;
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry)
    {
        /** æœ¬åœ°æ–‡ä»¶ä¸Šä¼ è·¯å¾„ */
        registry.addResourceHandler(Constants.RESOURCE_PREFIX + "/**").addResourceLocations("file:" + RuoYiConfig.getProfile() + "/");
        /** swagger配置 */
        registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
    }
    /**
     * è‡ªå®šä¹‰æ‹¦æˆªè§„则
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry)
    {
        registry.addInterceptor(repeatSubmitInterceptor).addPathPatterns("/**");
    }
}
ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java
ruoyi-framework/src/main/java/com/ruoyi/framework/config/ServerConfig.java
ruoyi-framework/src/main/java/com/ruoyi/framework/config/ThreadPoolConfig.java
ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/DruidProperties.java
ruoyi-framework/src/main/java/com/ruoyi/framework/datasource/DynamicDataSource.java
ruoyi-framework/src/main/java/com/ruoyi/framework/datasource/DynamicDataSourceContextHolder.java
ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/RepeatSubmitInterceptor.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,55 @@
package com.ruoyi.framework.interceptor;
import java.lang.reflect.Method;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.annotation.RepeatSubmit;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.ServletUtils;
/**
 * é˜²æ­¢é‡å¤æäº¤æ‹¦æˆªå™¨
 *
 * @author ruoyi
 */
@Component
public abstract class RepeatSubmitInterceptor extends HandlerInterceptorAdapter
{
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
    {
        if (handler instanceof HandlerMethod)
        {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Method method = handlerMethod.getMethod();
            RepeatSubmit annotation = method.getAnnotation(RepeatSubmit.class);
            if (annotation != null)
            {
                if (this.isRepeatSubmit(request))
                {
                    AjaxResult ajaxResult = AjaxResult.error("不允许重复提交,请稍后再试");
                    ServletUtils.renderString(response, JSONObject.toJSONString(ajaxResult));
                    return false;
                }
            }
            return true;
        }
        else
        {
            return super.preHandle(request, response, handler);
        }
    }
    /**
     * éªŒè¯æ˜¯å¦é‡å¤æäº¤ç”±å­ç±»å®žçŽ°å…·ä½“çš„é˜²é‡å¤æäº¤çš„è§„åˆ™
     *
     * @param httpServletRequest
     * @return
     * @throws Exception
     */
    public abstract boolean isRepeatSubmit(HttpServletRequest request);
}
ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/impl/SameUrlDataInterceptor.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,107 @@
package com.ruoyi.framework.interceptor.impl;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.filter.RepeatedlyRequestWrapper;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.http.HttpHelper;
import com.ruoyi.framework.interceptor.RepeatSubmitInterceptor;
/**
 * åˆ¤æ–­è¯·æ±‚url和数据是否和上一次相同,
 * å¦‚果和上次相同,则是重复提交表单。 æœ‰æ•ˆæ—¶é—´ä¸º10秒内。
 *
 * @author ruoyi
 */
@Component
public class SameUrlDataInterceptor extends RepeatSubmitInterceptor
{
    public final String REPEAT_PARAMS = "repeatParams";
    public final String REPEAT_TIME = "repeatTime";
    public final String CACHE_REPEAT_KEY = "repeatData";
    @Autowired
    private RedisCache redisCache;
    /**
     * é—´é𔿗¶é—´ï¼Œå•位:秒 é»˜è®¤10秒
     *
     * ä¸¤æ¬¡ç›¸åŒå‚数的请求,如果间隔时间大于该参数,系统不会认定为重复提交的数据
     */
    private int intervalTime = 10;
    public void setIntervalTime(int intervalTime)
    {
        this.intervalTime = intervalTime;
    }
    @SuppressWarnings("unchecked")
    @Override
    public boolean isRepeatSubmit(HttpServletRequest request)
    {
        RepeatedlyRequestWrapper repeatedlyRequest = (RepeatedlyRequestWrapper) request;
        String nowParams = HttpHelper.getBodyString(repeatedlyRequest);
        // body参数为空,获取Parameter的数据
        if (StringUtils.isEmpty(nowParams))
        {
            nowParams = JSONObject.toJSONString(request.getParameterMap());
        }
        Map<String, Object> nowDataMap = new HashMap<String, Object>();
        nowDataMap.put(REPEAT_PARAMS, nowParams);
        nowDataMap.put(REPEAT_TIME, System.currentTimeMillis());
        // è¯·æ±‚地址(作为存放cache的key值)
        String url = request.getRequestURI();
        Object sessionObj = redisCache.getCacheObject(CACHE_REPEAT_KEY);
        if (sessionObj != null)
        {
            Map<String, Object> sessionMap = (Map<String, Object>) sessionObj;
            if (sessionMap.containsKey(url))
            {
                Map<String, Object> preDataMap = (Map<String, Object>) sessionMap.get(url);
                if (compareParams(nowDataMap, preDataMap) && compareTime(nowDataMap, preDataMap))
                {
                    return true;
                }
            }
        }
        Map<String, Object> cacheMap = new HashMap<String, Object>();
        cacheMap.put(url, nowDataMap);
        redisCache.setCacheObject(CACHE_REPEAT_KEY, cacheMap, intervalTime, TimeUnit.SECONDS);
        return false;
    }
    /**
     * åˆ¤æ–­å‚数是否相同
     */
    private boolean compareParams(Map<String, Object> nowMap, Map<String, Object> preMap)
    {
        String nowParams = (String) nowMap.get(REPEAT_PARAMS);
        String preParams = (String) preMap.get(REPEAT_PARAMS);
        return nowParams.equals(preParams);
    }
    /**
     * åˆ¤æ–­ä¸¤æ¬¡é—´é𔿗¶é—´
     */
    private boolean compareTime(Map<String, Object> nowMap, Map<String, Object> preMap)
    {
        long time1 = (Long) nowMap.get(REPEAT_TIME);
        long time2 = (Long) preMap.get(REPEAT_TIME);
        if ((time1 - time2) < (this.intervalTime * 1000))
        {
            return true;
        }
        return false;
    }
}
ruoyi-framework/src/main/java/com/ruoyi/framework/manager/AsyncManager.java
ruoyi-framework/src/main/java/com/ruoyi/framework/manager/ShutdownManager.java
ruoyi-framework/src/main/java/com/ruoyi/framework/manager/factory/AsyncFactory.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,101 @@
package com.ruoyi.framework.manager.factory;
import java.util.TimerTask;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.utils.LogUtils;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.ip.AddressUtils;
import com.ruoyi.common.utils.ip.IpUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.system.domain.SysLogininfor;
import com.ruoyi.system.domain.SysOperLog;
import com.ruoyi.system.service.ISysLogininforService;
import com.ruoyi.system.service.ISysOperLogService;
import eu.bitwalker.useragentutils.UserAgent;
/**
 * å¼‚步工厂(产生任务用)
 *
 * @author ruoyi
 */
public class AsyncFactory
{
    private static final Logger sys_user_logger = LoggerFactory.getLogger("sys-user");
    /**
     * è®°å½•登陆信息
     *
     * @param username ç”¨æˆ·å
     * @param status çŠ¶æ€
     * @param message æ¶ˆæ¯
     * @param args åˆ—表
     * @return ä»»åŠ¡task
     */
    public static TimerTask recordLogininfor(final String username, final String status, final String message,
            final Object... args)
    {
        final UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent"));
        final String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
        return new TimerTask()
        {
            @Override
            public void run()
            {
                String address = AddressUtils.getRealAddressByIP(ip);
                StringBuilder s = new StringBuilder();
                s.append(LogUtils.getBlock(ip));
                s.append(address);
                s.append(LogUtils.getBlock(username));
                s.append(LogUtils.getBlock(status));
                s.append(LogUtils.getBlock(message));
                // æ‰“印信息到日志
                sys_user_logger.info(s.toString(), args);
                // èŽ·å–å®¢æˆ·ç«¯æ“ä½œç³»ç»Ÿ
                String os = userAgent.getOperatingSystem().getName();
                // èŽ·å–å®¢æˆ·ç«¯æµè§ˆå™¨
                String browser = userAgent.getBrowser().getName();
                // å°è£…对象
                SysLogininfor logininfor = new SysLogininfor();
                logininfor.setUserName(username);
                logininfor.setIpaddr(ip);
                logininfor.setLoginLocation(address);
                logininfor.setBrowser(browser);
                logininfor.setOs(os);
                logininfor.setMsg(message);
                // æ—¥å¿—状态
                if (Constants.LOGIN_SUCCESS.equals(status) || Constants.LOGOUT.equals(status))
                {
                    logininfor.setStatus(Constants.SUCCESS);
                }
                else if (Constants.LOGIN_FAIL.equals(status))
                {
                    logininfor.setStatus(Constants.FAIL);
                }
                // æ’入数据
                SpringUtils.getBean(ISysLogininforService.class).insertLogininfor(logininfor);
            }
        };
    }
    /**
     * æ“ä½œæ—¥å¿—记录
     *
     * @param operLog æ“ä½œæ—¥å¿—信息
     * @return ä»»åŠ¡task
     */
    public static TimerTask recordOper(final SysOperLog operLog)
    {
        return new TimerTask()
        {
            @Override
            public void run()
            {
                // è¿œç¨‹æŸ¥è¯¢æ“ä½œåœ°ç‚¹
                operLog.setOperLocation(AddressUtils.getRealAddressByIP(operLog.getOperIp()));
                SpringUtils.getBean(ISysOperLogService.class).insertOperlog(operLog);
            }
        };
    }
}
ruoyi-framework/src/main/java/com/ruoyi/framework/security/filter/JwtAuthenticationTokenFilter.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,44 @@
package com.ruoyi.framework.security.filter;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.web.service.TokenService;
/**
 * token过滤器 éªŒè¯token有效性
 *
 * @author ruoyi
 */
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter
{
    @Autowired
    private TokenService tokenService;
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException
    {
        LoginUser loginUser = tokenService.getLoginUser(request);
        if (StringUtils.isNotNull(loginUser) && StringUtils.isNull(SecurityUtils.getAuthentication()))
        {
            tokenService.verifyToken(loginUser);
            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
            authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
            SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        }
        chain.doFilter(request, response);
    }
}
ruoyi-framework/src/main/java/com/ruoyi/framework/security/handle/AuthenticationEntryPointImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,34 @@
package com.ruoyi.framework.security.handle;
import java.io.IOException;
import java.io.Serializable;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSON;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils;
/**
 * è®¤è¯å¤±è´¥å¤„理类 è¿”回未授权
 *
 * @author ruoyi
 */
@Component
public class AuthenticationEntryPointImpl implements AuthenticationEntryPoint, Serializable
{
    private static final long serialVersionUID = -8970718410437077606L;
    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e)
            throws IOException
    {
        int code = HttpStatus.UNAUTHORIZED;
        String msg = StringUtils.format("请求访问:{},认证失败,无法访问系统资源", request.getRequestURI());
        ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.error(code, msg)));
    }
}
ruoyi-framework/src/main/java/com/ruoyi/framework/security/handle/LogoutSuccessHandlerImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,53 @@
package com.ruoyi.framework.security.handle;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import com.alibaba.fastjson.JSON;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.framework.manager.factory.AsyncFactory;
import com.ruoyi.framework.web.service.TokenService;
/**
 * è‡ªå®šä¹‰é€€å‡ºå¤„理类 è¿”回成功
 *
 * @author ruoyi
 */
@Configuration
public class LogoutSuccessHandlerImpl implements LogoutSuccessHandler
{
    @Autowired
    private TokenService tokenService;
    /**
     * é€€å‡ºå¤„理
     *
     * @return
     */
    @Override
    public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
            throws IOException, ServletException
    {
        LoginUser loginUser = tokenService.getLoginUser(request);
        if (StringUtils.isNotNull(loginUser))
        {
            String userName = loginUser.getUsername();
            // åˆ é™¤ç”¨æˆ·ç¼“存记录
            tokenService.delLoginUser(loginUser.getToken());
            // è®°å½•用户退出日志
            AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName, Constants.LOGOUT, "退出成功"));
        }
        ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.error(HttpStatus.SUCCESS, "退出成功")));
    }
}
ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/Server.java
ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/Cpu.java
ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/Jvm.java
ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/Mem.java
ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/Sys.java
ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/SysFile.java
ruoyi-framework/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,117 @@
package com.ruoyi.framework.web.exception;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.AccountExpiredException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.exception.BaseException;
import com.ruoyi.common.exception.CustomException;
import com.ruoyi.common.exception.DemoModeException;
import com.ruoyi.common.utils.StringUtils;
/**
 * å…¨å±€å¼‚常处理器
 *
 * @author ruoyi
 */
@RestControllerAdvice
public class GlobalExceptionHandler
{
    private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
    /**
     * åŸºç¡€å¼‚常
     */
    @ExceptionHandler(BaseException.class)
    public AjaxResult baseException(BaseException e)
    {
        return AjaxResult.error(e.getMessage());
    }
    /**
     * ä¸šåС异叏
     */
    @ExceptionHandler(CustomException.class)
    public AjaxResult businessException(CustomException e)
    {
        if (StringUtils.isNull(e.getCode()))
        {
            return AjaxResult.error(e.getMessage());
        }
        return AjaxResult.error(e.getCode(), e.getMessage());
    }
    @ExceptionHandler(NoHandlerFoundException.class)
    public AjaxResult handlerNoFoundException(Exception e)
    {
        log.error(e.getMessage(), e);
        return AjaxResult.error(HttpStatus.NOT_FOUND, "路径不存在,请检查路径是否正确");
    }
    @ExceptionHandler(AccessDeniedException.class)
    public AjaxResult handleAuthorizationException(AccessDeniedException e)
    {
        log.error(e.getMessage());
        return AjaxResult.error(HttpStatus.FORBIDDEN, "没有权限,请联系管理员授权");
    }
    @ExceptionHandler(AccountExpiredException.class)
    public AjaxResult handleAccountExpiredException(AccountExpiredException e)
    {
        log.error(e.getMessage(), e);
        return AjaxResult.error(e.getMessage());
    }
    @ExceptionHandler(UsernameNotFoundException.class)
    public AjaxResult handleUsernameNotFoundException(UsernameNotFoundException e)
    {
        log.error(e.getMessage(), e);
        return AjaxResult.error(e.getMessage());
    }
    @ExceptionHandler(Exception.class)
    public AjaxResult handleException(Exception e)
    {
        log.error(e.getMessage(), e);
        return AjaxResult.error(e.getMessage());
    }
    /**
     * è‡ªå®šä¹‰éªŒè¯å¼‚常
     */
    @ExceptionHandler(BindException.class)
    public AjaxResult validatedBindException(BindException e)
    {
        log.error(e.getMessage(), e);
        String message = e.getAllErrors().get(0).getDefaultMessage();
        return AjaxResult.error(message);
    }
    /**
     * è‡ªå®šä¹‰éªŒè¯å¼‚常
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Object validExceptionHandler(MethodArgumentNotValidException e)
    {
        log.error(e.getMessage(), e);
        String message = e.getBindingResult().getFieldError().getDefaultMessage();
        return AjaxResult.error(message);
    }
    /**
     * æ¼”示模式异常
     */
    @ExceptionHandler(DemoModeException.class)
    public AjaxResult demoModeException(DemoModeException e)
    {
        return AjaxResult.error("演示模式,不允许操作");
    }
}
ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/PermissionService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,169 @@
package com.ruoyi.framework.web.service;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils;
/**
 * RuoYi首创 è‡ªå®šä¹‰æƒé™å®žçŽ°ï¼Œss取自SpringSecurity首字母
 *
 * @author ruoyi
 */
@Service("ss")
public class PermissionService
{
    /** æ‰€æœ‰æƒé™æ ‡è¯† */
    private static final String ALL_PERMISSION = "*:*:*";
    /** ç®¡ç†å‘˜è§’色权限标识 */
    private static final String SUPER_ADMIN = "admin";
    private static final String ROLE_DELIMETER = ",";
    private static final String PERMISSION_DELIMETER = ",";
    @Autowired
    private TokenService tokenService;
    /**
     * éªŒè¯ç”¨æˆ·æ˜¯å¦å…·å¤‡æŸæƒé™
     *
     * @param permission æƒé™å­—符串
     * @return ç”¨æˆ·æ˜¯å¦å…·å¤‡æŸæƒé™
     */
    public boolean hasPermi(String permission)
    {
        if (StringUtils.isEmpty(permission))
        {
            return false;
        }
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getPermissions()))
        {
            return false;
        }
        return hasPermissions(loginUser.getPermissions(), permission);
    }
    /**
     * éªŒè¯ç”¨æˆ·æ˜¯å¦ä¸å…·å¤‡æŸæƒé™ï¼Œä¸Ž hasPermi逻辑相反
     *
     * @param permission æƒé™å­—符串
     * @return ç”¨æˆ·æ˜¯å¦ä¸å…·å¤‡æŸæƒé™
     */
    public boolean lacksPermi(String permission)
    {
        return hasPermi(permission) != true;
    }
    /**
     * éªŒè¯ç”¨æˆ·æ˜¯å¦å…·æœ‰ä»¥ä¸‹ä»»æ„ä¸€ä¸ªæƒé™
     *
     * @param permissions ä»¥ PERMISSION_NAMES_DELIMETER ä¸ºåˆ†éš”符的权限列表
     * @return ç”¨æˆ·æ˜¯å¦å…·æœ‰ä»¥ä¸‹ä»»æ„ä¸€ä¸ªæƒé™
     */
    public boolean hasAnyPermi(String permissions)
    {
        if (StringUtils.isEmpty(permissions))
        {
            return false;
        }
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getPermissions()))
        {
            return false;
        }
        Set<String> authorities = loginUser.getPermissions();
        for (String permission : permissions.split(PERMISSION_DELIMETER))
        {
            if (permission != null && hasPermissions(authorities, permission))
            {
                return true;
            }
        }
        return false;
    }
    /**
     * åˆ¤æ–­ç”¨æˆ·æ˜¯å¦æ‹¥æœ‰æŸä¸ªè§’色
     *
     * @param role è§’色字符串
     * @return ç”¨æˆ·æ˜¯å¦å…·å¤‡æŸè§’色
     */
    public boolean hasRole(String role)
    {
        if (StringUtils.isEmpty(role))
        {
            return false;
        }
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getUser().getRoles()))
        {
            return false;
        }
        for (SysRole sysRole : loginUser.getUser().getRoles())
        {
            String roleKey = sysRole.getRoleKey();
            if (SUPER_ADMIN.contains(roleKey) || roleKey.contains(StringUtils.trim(role)))
            {
                return true;
            }
        }
        return false;
    }
    /**
     * éªŒè¯ç”¨æˆ·æ˜¯å¦ä¸å…·å¤‡æŸè§’色,与 isRole逻辑相反。
     *
     * @param role è§’色名称
     * @return ç”¨æˆ·æ˜¯å¦ä¸å…·å¤‡æŸè§’色
     */
    public boolean lacksRole(String role)
    {
        return hasRole(role) != true;
    }
    /**
     * éªŒè¯ç”¨æˆ·æ˜¯å¦å…·æœ‰ä»¥ä¸‹ä»»æ„ä¸€ä¸ªè§’色
     *
     * @param roles ä»¥ ROLE_NAMES_DELIMETER ä¸ºåˆ†éš”符的角色列表
     * @return ç”¨æˆ·æ˜¯å¦å…·æœ‰ä»¥ä¸‹ä»»æ„ä¸€ä¸ªè§’色
     */
    public boolean hasAnyRoles(String roles)
    {
        if (StringUtils.isEmpty(roles))
        {
            return false;
        }
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getUser().getRoles()))
        {
            return false;
        }
        for (String role : roles.split(ROLE_DELIMETER))
        {
            if (hasRole(role))
            {
                return true;
            }
        }
        return false;
    }
    /**
     * åˆ¤æ–­æ˜¯å¦åŒ…含权限
     *
     * @param permissions æƒé™åˆ—表
     * @param permission æƒé™å­—符串
     * @return ç”¨æˆ·æ˜¯å¦å…·å¤‡æŸæƒé™
     */
    private boolean hasPermissions(Set<String> permissions, String permission)
    {
        return permissions.contains(ALL_PERMISSION) || permissions.contains(StringUtils.trim(permission));
    }
}
ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,88 @@
package com.ruoyi.framework.web.service;
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.CustomException;
import com.ruoyi.common.exception.user.CaptchaException;
import com.ruoyi.common.exception.user.CaptchaExpireException;
import com.ruoyi.common.exception.user.UserPasswordNotMatchException;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.framework.manager.factory.AsyncFactory;
/**
 * ç™»å½•校验方法
 *
 * @author ruoyi
 */
@Component
public class SysLoginService
{
    @Autowired
    private TokenService tokenService;
    @Resource
    private AuthenticationManager authenticationManager;
    @Autowired
    private RedisCache redisCache;
    /**
     * ç™»å½•验证
     *
     * @param username ç”¨æˆ·å
     * @param password å¯†ç 
     * @param code éªŒè¯ç 
     * @param uuid å”¯ä¸€æ ‡è¯†
     * @return ç»“æžœ
     */
    public String login(String username, String password, String code, String uuid)
    {
        String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid;
        String captcha = redisCache.getCacheObject(verifyKey);
        redisCache.deleteObject(verifyKey);
        if (captcha == null)
        {
            AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire")));
            throw new CaptchaExpireException();
        }
        if (!code.equalsIgnoreCase(captcha))
        {
            AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")));
            throw new CaptchaException();
        }
        // ç”¨æˆ·éªŒè¯
        Authentication authentication = null;
        try
        {
            // è¯¥æ–¹æ³•会去调用UserDetailsServiceImpl.loadUserByUsername
            authentication = authenticationManager
                    .authenticate(new UsernamePasswordAuthenticationToken(username, password));
        }
        catch (Exception e)
        {
            if (e instanceof BadCredentialsException)
            {
                AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
                throw new UserPasswordNotMatchException();
            }
            else
            {
                AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage()));
                throw new CustomException(e.getMessage());
            }
        }
        AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        // ç”Ÿæˆtoken
        return tokenService.createToken(loginUser);
    }
}
ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysPermissionService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,66 @@
package com.ruoyi.framework.web.service;
import java.util.HashSet;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.system.service.ISysMenuService;
import com.ruoyi.system.service.ISysRoleService;
/**
 * ç”¨æˆ·æƒé™å¤„理
 *
 * @author ruoyi
 */
@Component
public class SysPermissionService
{
    @Autowired
    private ISysRoleService roleService;
    @Autowired
    private ISysMenuService menuService;
    /**
     * èŽ·å–è§’è‰²æ•°æ®æƒé™
     *
     * @param user ç”¨æˆ·ä¿¡æ¯
     * @return è§’色权限信息
     */
    public Set<String> getRolePermission(SysUser user)
    {
        Set<String> roles = new HashSet<String>();
        // ç®¡ç†å‘˜æ‹¥æœ‰æ‰€æœ‰æƒé™
        if (user.isAdmin())
        {
            roles.add("admin");
        }
        else
        {
            roles.addAll(roleService.selectRolePermissionByUserId(user.getUserId()));
        }
        return roles;
    }
    /**
     * èŽ·å–èœå•æ•°æ®æƒé™
     *
     * @param user ç”¨æˆ·ä¿¡æ¯
     * @return èœå•权限信息
     */
    public Set<String> getMenuPermission(SysUser user)
    {
        Set<String> perms = new HashSet<String>();
        // ç®¡ç†å‘˜æ‹¥æœ‰æ‰€æœ‰æƒé™
        if (user.isAdmin())
        {
            perms.add("*:*:*");
        }
        else
        {
            perms.addAll(menuService.selectMenuPermsByUserId(user.getUserId()));
        }
        return perms;
    }
}
ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,219 @@
package com.ruoyi.framework.web.service;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.ip.AddressUtils;
import com.ruoyi.common.utils.ip.IpUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import eu.bitwalker.useragentutils.UserAgent;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
/**
 * token验证处理
 *
 * @author ruoyi
 */
@Component
public class TokenService
{
    // ä»¤ç‰Œè‡ªå®šä¹‰æ ‡è¯†
    @Value("${token.header}")
    private String header;
    // ä»¤ç‰Œç§˜é’¥
    @Value("${token.secret}")
    private String secret;
    // ä»¤ç‰Œæœ‰æ•ˆæœŸï¼ˆé»˜è®¤30分钟)
    @Value("${token.expireTime}")
    private int expireTime;
    protected static final long MILLIS_SECOND = 1000;
    protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND;
    private static final Long MILLIS_MINUTE_TEN = 20 * 60 * 1000L;
    @Autowired
    private RedisCache redisCache;
    /**
     * èŽ·å–ç”¨æˆ·èº«ä»½ä¿¡æ¯
     *
     * @return ç”¨æˆ·ä¿¡æ¯
     */
    public LoginUser getLoginUser(HttpServletRequest request)
    {
        // èŽ·å–è¯·æ±‚æºå¸¦çš„ä»¤ç‰Œ
        String token = getToken(request);
        if (StringUtils.isNotEmpty(token))
        {
            Claims claims = parseToken(token);
            // è§£æžå¯¹åº”的权限以及用户信息
            String uuid = (String) claims.get(Constants.LOGIN_USER_KEY);
            String userKey = getTokenKey(uuid);
            LoginUser user = redisCache.getCacheObject(userKey);
            return user;
        }
        return null;
    }
    /**
     * è®¾ç½®ç”¨æˆ·èº«ä»½ä¿¡æ¯
     */
    public void setLoginUser(LoginUser loginUser)
    {
        if (StringUtils.isNotNull(loginUser) && StringUtils.isNotEmpty(loginUser.getToken()))
        {
            refreshToken(loginUser);
        }
    }
    /**
     * åˆ é™¤ç”¨æˆ·èº«ä»½ä¿¡æ¯
     */
    public void delLoginUser(String token)
    {
        if (StringUtils.isNotEmpty(token))
        {
            String userKey = getTokenKey(token);
            redisCache.deleteObject(userKey);
        }
    }
    /**
     * åˆ›å»ºä»¤ç‰Œ
     *
     * @param loginUser ç”¨æˆ·ä¿¡æ¯
     * @return ä»¤ç‰Œ
     */
    public String createToken(LoginUser loginUser)
    {
        String token = IdUtils.fastUUID();
        loginUser.setToken(token);
        setUserAgent(loginUser);
        refreshToken(loginUser);
        Map<String, Object> claims = new HashMap<>();
        claims.put(Constants.LOGIN_USER_KEY, token);
        return createToken(claims);
    }
    /**
     * éªŒè¯ä»¤ç‰Œæœ‰æ•ˆæœŸï¼Œç›¸å·®ä¸è¶³20分钟,自动刷新缓存
     *
     * @param token ä»¤ç‰Œ
     * @return ä»¤ç‰Œ
     */
    public void verifyToken(LoginUser loginUser)
    {
        long expireTime = loginUser.getExpireTime();
        long currentTime = System.currentTimeMillis();
        if (expireTime - currentTime <= MILLIS_MINUTE_TEN)
        {
            refreshToken(loginUser);
        }
    }
    /**
     * åˆ·æ–°ä»¤ç‰Œæœ‰æ•ˆæœŸ
     *
     * @param loginUser ç™»å½•信息
     */
    public void refreshToken(LoginUser loginUser)
    {
        loginUser.setLoginTime(System.currentTimeMillis());
        loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE);
        // æ ¹æ®uuid将loginUser缓存
        String userKey = getTokenKey(loginUser.getToken());
        redisCache.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES);
    }
    /**
     * è®¾ç½®ç”¨æˆ·ä»£ç†ä¿¡æ¯
     *
     * @param loginUser ç™»å½•信息
     */
    public void setUserAgent(LoginUser loginUser)
    {
        UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent"));
        String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
        loginUser.setIpaddr(ip);
        loginUser.setLoginLocation(AddressUtils.getRealAddressByIP(ip));
        loginUser.setBrowser(userAgent.getBrowser().getName());
        loginUser.setOs(userAgent.getOperatingSystem().getName());
    }
    /**
     * ä»Žæ•°æ®å£°æ˜Žç”Ÿæˆä»¤ç‰Œ
     *
     * @param claims æ•°æ®å£°æ˜Ž
     * @return ä»¤ç‰Œ
     */
    private String createToken(Map<String, Object> claims)
    {
        String token = Jwts.builder()
                .setClaims(claims)
                .signWith(SignatureAlgorithm.HS512, secret).compact();
        return token;
    }
    /**
     * ä»Žä»¤ç‰Œä¸­èŽ·å–æ•°æ®å£°æ˜Ž
     *
     * @param token ä»¤ç‰Œ
     * @return æ•°æ®å£°æ˜Ž
     */
    private Claims parseToken(String token)
    {
        return Jwts.parser()
                .setSigningKey(secret)
                .parseClaimsJws(token)
                .getBody();
    }
    /**
     * ä»Žä»¤ç‰Œä¸­èŽ·å–ç”¨æˆ·å
     *
     * @param token ä»¤ç‰Œ
     * @return ç”¨æˆ·å
     */
    public String getUsernameFromToken(String token)
    {
        Claims claims = parseToken(token);
        return claims.getSubject();
    }
    /**
     * èŽ·å–è¯·æ±‚token
     *
     * @param request
     * @return token
     */
    private String getToken(HttpServletRequest request)
    {
        String token = request.getHeader(header);
        if (StringUtils.isNotEmpty(token) && token.startsWith(Constants.TOKEN_PREFIX))
        {
            token = token.replace(Constants.TOKEN_PREFIX, "");
        }
        return token;
    }
    private String getTokenKey(String uuid)
    {
        return Constants.LOGIN_TOKEN_KEY + uuid;
    }
}
ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/UserDetailsServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,60 @@
package com.ruoyi.framework.web.service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.enums.UserStatus;
import com.ruoyi.common.exception.BaseException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.service.ISysUserService;
/**
 * ç”¨æˆ·éªŒè¯å¤„理
 *
 * @author ruoyi
 */
@Service
public class UserDetailsServiceImpl implements UserDetailsService
{
    private static final Logger log = LoggerFactory.getLogger(UserDetailsServiceImpl.class);
    @Autowired
    private ISysUserService userService;
    @Autowired
    private SysPermissionService permissionService;
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException
    {
        SysUser user = userService.selectUserByUserName(username);
        if (StringUtils.isNull(user))
        {
            log.info("登录用户:{} ä¸å­˜åœ¨.", username);
            throw new UsernameNotFoundException("登录用户:" + username + " ä¸å­˜åœ¨");
        }
        else if (UserStatus.DELETED.getCode().equals(user.getDelFlag()))
        {
            log.info("登录用户:{} å·²è¢«åˆ é™¤.", username);
            throw new BaseException("对不起,您的账号:" + username + " å·²è¢«åˆ é™¤");
        }
        else if (UserStatus.DISABLE.getCode().equals(user.getStatus()))
        {
            log.info("登录用户:{} å·²è¢«åœç”¨.", username);
            throw new BaseException("对不起,您的账号:" + username + " å·²åœç”¨");
        }
        return createLoginUser(user);
    }
    public UserDetails createLoginUser(SysUser user)
    {
        return new LoginUser(user, permissionService.getMenuPermission(user));
    }
}
ruoyi-generator/pom.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>ruoyi</artifactId>
        <groupId>com.ruoyi</groupId>
        <version>3.0.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>ruoyi-generator</artifactId>
    <description>
        generator代码生成
    </description>
    <dependencies>
        <!--velocity代码生成使用模板 -->
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity</artifactId>
        </dependency>
        <!-- é€šç”¨å·¥å…·-->
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>ruoyi-common</artifactId>
        </dependency>
    </dependencies>
</project>
ruoyi-generator/src/main/java/com/ruoyi/generator/config/GenConfig.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,73 @@
package com.ruoyi.generator.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
/**
 * è¯»å–代码生成相关配置
 *
 * @author ruoyi
 */
@Component
@ConfigurationProperties(prefix = "gen")
@PropertySource(value = { "classpath:generator.yml" })
public class GenConfig
{
    /** ä½œè€… */
    public static String author;
    /** ç”ŸæˆåŒ…路径 */
    public static String packageName;
    /** è‡ªåŠ¨åŽ»é™¤è¡¨å‰ç¼€ï¼Œé»˜è®¤æ˜¯false */
    public static boolean autoRemovePre;
    /** è¡¨å‰ç¼€(类名不会包含表前缀) */
    public static String tablePrefix;
    public static String getAuthor()
    {
        return author;
    }
    @Value("${author}")
    public void setAuthor(String author)
    {
        GenConfig.author = author;
    }
    public static String getPackageName()
    {
        return packageName;
    }
    @Value("${packageName}")
    public void setPackageName(String packageName)
    {
        GenConfig.packageName = packageName;
    }
    public static boolean getAutoRemovePre()
    {
        return autoRemovePre;
    }
    @Value("${autoRemovePre}")
    public void setAutoRemovePre(boolean autoRemovePre)
    {
        GenConfig.autoRemovePre = autoRemovePre;
    }
    public static String getTablePrefix()
    {
        return tablePrefix;
    }
    @Value("${tablePrefix}")
    public void setTablePrefix(String tablePrefix)
    {
        GenConfig.tablePrefix = tablePrefix;
    }
}
ruoyi-generator/src/main/java/com/ruoyi/generator/controller/GenController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,186 @@
package com.ruoyi.generator.controller;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
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.core.text.Convert;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.generator.domain.GenTable;
import com.ruoyi.generator.domain.GenTableColumn;
import com.ruoyi.generator.service.IGenTableColumnService;
import com.ruoyi.generator.service.IGenTableService;
/**
 * ä»£ç ç”Ÿæˆ æ“ä½œå¤„理
 *
 * @author ruoyi
 */
@RestController
@RequestMapping("/tool/gen")
public class GenController extends BaseController
{
    @Autowired
    private IGenTableService genTableService;
    @Autowired
    private IGenTableColumnService genTableColumnService;
    /**
     * æŸ¥è¯¢ä»£ç ç”Ÿæˆåˆ—表
     */
    @PreAuthorize("@ss.hasPermi('tool:gen:list')")
    @GetMapping("/list")
    public TableDataInfo genList(GenTable genTable)
    {
        startPage();
        List<GenTable> list = genTableService.selectGenTableList(genTable);
        return getDataTable(list);
    }
    /**
     * ä¿®æ”¹ä»£ç ç”Ÿæˆä¸šåŠ¡
     */
    @PreAuthorize("@ss.hasPermi('tool:gen:query')")
    @GetMapping(value = "/{talbleId}")
    public AjaxResult getInfo(@PathVariable Long talbleId)
    {
        GenTable table = genTableService.selectGenTableById(talbleId);
        List<GenTableColumn> list = genTableColumnService.selectGenTableColumnListByTableId(talbleId);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("info", table);
        map.put("rows", list);
        return AjaxResult.success(map);
    }
    /**
     * æŸ¥è¯¢æ•°æ®åº“列表
     */
    @PreAuthorize("@ss.hasPermi('tool:gen:list')")
    @GetMapping("/db/list")
    public TableDataInfo dataList(GenTable genTable)
    {
        startPage();
        List<GenTable> list = genTableService.selectDbTableList(genTable);
        return getDataTable(list);
    }
    /**
     * æŸ¥è¯¢æ•°æ®è¡¨å­—段列表
     */
    @PreAuthorize("@ss.hasPermi('tool:gen:list')")
    @GetMapping(value = "/column/{talbleId}")
    public TableDataInfo columnList(Long tableId)
    {
        TableDataInfo dataInfo = new TableDataInfo();
        List<GenTableColumn> list = genTableColumnService.selectGenTableColumnListByTableId(tableId);
        dataInfo.setRows(list);
        dataInfo.setTotal(list.size());
        return dataInfo;
    }
    /**
     * å¯¼å…¥è¡¨ç»“构(保存)
     */
    @PreAuthorize("@ss.hasPermi('tool:gen:list')")
    @Log(title = "代码生成", businessType = BusinessType.IMPORT)
    @PostMapping("/importTable")
    public AjaxResult importTableSave(String tables)
    {
        String[] tableNames = Convert.toStrArray(tables);
        // æŸ¥è¯¢è¡¨ä¿¡æ¯
        List<GenTable> tableList = genTableService.selectDbTableListByNames(tableNames);
        genTableService.importGenTable(tableList);
        return AjaxResult.success();
    }
    /**
     * ä¿®æ”¹ä¿å­˜ä»£ç ç”Ÿæˆä¸šåŠ¡
     */
    @PreAuthorize("@ss.hasPermi('tool:gen:edit')")
    @Log(title = "代码生成", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult editSave(@Validated @RequestBody GenTable genTable)
    {
        genTableService.validateEdit(genTable);
        genTableService.updateGenTable(genTable);
        return AjaxResult.success();
    }
    /**
     * åˆ é™¤ä»£ç ç”Ÿæˆ
     */
    @PreAuthorize("@ss.hasPermi('tool:gen:remove')")
    @Log(title = "代码生成", businessType = BusinessType.DELETE)
    @DeleteMapping("/{tableIds}")
    public AjaxResult remove(@PathVariable Long[] tableIds)
    {
        genTableService.deleteGenTableByIds(tableIds);
        return AjaxResult.success();
    }
    /**
     * é¢„览代码
     */
    @PreAuthorize("@ss.hasPermi('tool:gen:preview')")
    @GetMapping("/preview/{tableId}")
    public AjaxResult preview(@PathVariable("tableId") Long tableId) throws IOException
    {
        Map<String, String> dataMap = genTableService.previewCode(tableId);
        return AjaxResult.success(dataMap);
    }
    /**
     * ç”Ÿæˆä»£ç 
     */
    @PreAuthorize("@ss.hasPermi('tool:gen:code')")
    @Log(title = "代码生成", businessType = BusinessType.GENCODE)
    @GetMapping("/genCode/{tableName}")
    public void genCode(HttpServletResponse response, @PathVariable("tableName") String tableName) throws IOException
    {
        byte[] data = genTableService.generatorCode(tableName);
        genCode(response, data);
    }
    /**
     * æ‰¹é‡ç”Ÿæˆä»£ç 
     */
    @PreAuthorize("@ss.hasPermi('tool:gen:code')")
    @Log(title = "代码生成", businessType = BusinessType.GENCODE)
    @GetMapping("/batchGenCode")
    public void batchGenCode(HttpServletResponse response, String tables) throws IOException
    {
        String[] tableNames = Convert.toStrArray(tables);
        byte[] data = genTableService.generatorCode(tableNames);
        genCode(response, data);
    }
    /**
     * ç”Ÿæˆzip文件
     */
    private void genCode(HttpServletResponse response, byte[] data) throws IOException
    {
        response.reset();
        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());
    }
}
ruoyi-generator/src/main/java/com/ruoyi/generator/domain/GenTable.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,271 @@
package com.ruoyi.generator.domain;
import java.util.List;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import org.apache.commons.lang3.ArrayUtils;
import com.ruoyi.common.constant.GenConstants;
import com.ruoyi.common.core.domain.BaseEntity;
import com.ruoyi.common.utils.StringUtils;
/**
 * ä¸šåŠ¡è¡¨ gen_table
 *
 * @author ruoyi
 */
public class GenTable extends BaseEntity
{
    private static final long serialVersionUID = 1L;
    /** ç¼–号 */
    private Long tableId;
    /** è¡¨åç§° */
    @NotBlank(message = "表名称不能为空")
    private String tableName;
    /** è¡¨æè¿° */
    @NotBlank(message = "表描述不能为空")
    private String tableComment;
    /** å®žä½“类名称(首字母大写) */
    @NotBlank(message = "实体类名称不能为空")
    private String className;
    /** ä½¿ç”¨çš„æ¨¡æ¿ï¼ˆcrud单表操作 tree树表操作) */
    private String tplCategory;
    /** ç”ŸæˆåŒ…路径 */
    @NotBlank(message = "生成包路径不能为空")
    private String packageName;
    /** ç”Ÿæˆæ¨¡å—名 */
    @NotBlank(message = "生成模块名不能为空")
    private String moduleName;
    /** ç”Ÿæˆä¸šåŠ¡å */
    @NotBlank(message = "生成业务名不能为空")
    private String businessName;
    /** ç”ŸæˆåŠŸèƒ½å */
    @NotBlank(message = "生成功能名不能为空")
    private String functionName;
    /** ç”Ÿæˆä½œè€… */
    @NotBlank(message = "作者不能为空")
    private String functionAuthor;
    /** ä¸»é”®ä¿¡æ¯ */
    private GenTableColumn pkColumn;
    /** è¡¨åˆ—信息 */
    @Valid
    private List<GenTableColumn> columns;
    /** å…¶å®ƒç”Ÿæˆé€‰é¡¹ */
    private String options;
    /** æ ‘编码字段 */
    private String treeCode;
    /** æ ‘父编码字段 */
    private String treeParentCode;
    /** æ ‘名称字段 */
    private String treeName;
    public Long getTableId()
    {
        return tableId;
    }
    public void setTableId(Long tableId)
    {
        this.tableId = tableId;
    }
    public String getTableName()
    {
        return tableName;
    }
    public void setTableName(String tableName)
    {
        this.tableName = tableName;
    }
    public String getTableComment()
    {
        return tableComment;
    }
    public void setTableComment(String tableComment)
    {
        this.tableComment = tableComment;
    }
    public String getClassName()
    {
        return className;
    }
    public void setClassName(String className)
    {
        this.className = className;
    }
    public String getTplCategory()
    {
        return tplCategory;
    }
    public void setTplCategory(String tplCategory)
    {
        this.tplCategory = tplCategory;
    }
    public String getPackageName()
    {
        return packageName;
    }
    public void setPackageName(String packageName)
    {
        this.packageName = packageName;
    }
    public String getModuleName()
    {
        return moduleName;
    }
    public void setModuleName(String moduleName)
    {
        this.moduleName = moduleName;
    }
    public String getBusinessName()
    {
        return businessName;
    }
    public void setBusinessName(String businessName)
    {
        this.businessName = businessName;
    }
    public String getFunctionName()
    {
        return functionName;
    }
    public void setFunctionName(String functionName)
    {
        this.functionName = functionName;
    }
    public String getFunctionAuthor()
    {
        return functionAuthor;
    }
    public void setFunctionAuthor(String functionAuthor)
    {
        this.functionAuthor = functionAuthor;
    }
    public GenTableColumn getPkColumn()
    {
        return pkColumn;
    }
    public void setPkColumn(GenTableColumn pkColumn)
    {
        this.pkColumn = pkColumn;
    }
    public List<GenTableColumn> getColumns()
    {
        return columns;
    }
    public void setColumns(List<GenTableColumn> columns)
    {
        this.columns = columns;
    }
    public String getOptions()
    {
        return options;
    }
    public void setOptions(String options)
    {
        this.options = options;
    }
    public String getTreeCode()
    {
        return treeCode;
    }
    public void setTreeCode(String treeCode)
    {
        this.treeCode = treeCode;
    }
    public String getTreeParentCode()
    {
        return treeParentCode;
    }
    public void setTreeParentCode(String treeParentCode)
    {
        this.treeParentCode = treeParentCode;
    }
    public String getTreeName()
    {
        return treeName;
    }
    public void setTreeName(String treeName)
    {
        this.treeName = treeName;
    }
    public boolean isTree()
    {
        return isTree(this.tplCategory);
    }
    public static boolean isTree(String tplCategory)
    {
        return tplCategory != null && StringUtils.equals(GenConstants.TPL_TREE, tplCategory);
    }
    public boolean isCrud()
    {
        return isCrud(this.tplCategory);
    }
    public static boolean isCrud(String tplCategory)
    {
        return tplCategory != null && StringUtils.equals(GenConstants.TPL_CRUD, tplCategory);
    }
    public boolean isSuperColumn(String javaField)
    {
        return isSuperColumn(this.tplCategory, javaField);
    }
    public static boolean isSuperColumn(String tplCategory, String javaField)
    {
        if (isTree(tplCategory))
        {
            return StringUtils.equalsAnyIgnoreCase(javaField,
                    ArrayUtils.addAll(GenConstants.TREE_ENTITY, GenConstants.BASE_ENTITY));
        }
        return StringUtils.equalsAnyIgnoreCase(javaField, GenConstants.BASE_ENTITY);
    }
}
ruoyi-generator/src/main/java/com/ruoyi/generator/domain/GenTableColumn.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,368 @@
package com.ruoyi.generator.domain;
import javax.validation.constraints.NotBlank;
import com.ruoyi.common.core.domain.BaseEntity;
import com.ruoyi.common.utils.StringUtils;
/**
 * ä»£ç ç”Ÿæˆä¸šåŠ¡å­—æ®µè¡¨ gen_table_column
 *
 * @author ruoyi
 */
public class GenTableColumn extends BaseEntity
{
    private static final long serialVersionUID = 1L;
    /** ç¼–号 */
    private Long columnId;
    /** å½’属表编号 */
    private Long tableId;
    /** åˆ—名称 */
    private String columnName;
    /** åˆ—描述 */
    private String columnComment;
    /** åˆ—类型 */
    private String columnType;
    /** JAVA类型 */
    private String javaType;
    /** JAVA字段名 */
    @NotBlank(message = "Java属性不能为空")
    private String javaField;
    /** æ˜¯å¦ä¸»é”®ï¼ˆ1是) */
    private String isPk;
    /** æ˜¯å¦è‡ªå¢žï¼ˆ1是) */
    private String isIncrement;
    /** æ˜¯å¦å¿…填(1是) */
    private String isRequired;
    /** æ˜¯å¦ä¸ºæ’入字段(1是) */
    private String isInsert;
    /** æ˜¯å¦ç¼–辑字段(1是) */
    private String isEdit;
    /** æ˜¯å¦åˆ—表字段(1是) */
    private String isList;
    /** æ˜¯å¦æŸ¥è¯¢å­—段(1是) */
    private String isQuery;
    /** æŸ¥è¯¢æ–¹å¼ï¼ˆEQ等于、NE不等于、GT大于、LT小于、LIKE模糊、BETWEEN范围) */
    private String queryType;
    /** æ˜¾ç¤ºç±»åž‹ï¼ˆinput文本框、textarea文本域、select下拉框、checkbox复选框、radio单选框、datetime日期控件) */
    private String htmlType;
    /** å­—典类型 */
    private String dictType;
    /** æŽ’序 */
    private Integer sort;
    public void setColumnId(Long columnId)
    {
        this.columnId = columnId;
    }
    public Long getColumnId()
    {
        return columnId;
    }
    public void setTableId(Long tableId)
    {
        this.tableId = tableId;
    }
    public Long getTableId()
    {
        return tableId;
    }
    public void setColumnName(String columnName)
    {
        this.columnName = columnName;
    }
    public String getColumnName()
    {
        return columnName;
    }
    public void setColumnComment(String columnComment)
    {
        this.columnComment = columnComment;
    }
    public String getColumnComment()
    {
        return columnComment;
    }
    public void setColumnType(String columnType)
    {
        this.columnType = columnType;
    }
    public String getColumnType()
    {
        return columnType;
    }
    public void setJavaType(String javaType)
    {
        this.javaType = javaType;
    }
    public String getJavaType()
    {
        return javaType;
    }
    public void setJavaField(String javaField)
    {
        this.javaField = javaField;
    }
    public String getJavaField()
    {
        return javaField;
    }
    public void setIsPk(String isPk)
    {
        this.isPk = isPk;
    }
    public String getIsPk()
    {
        return isPk;
    }
    public boolean isPk()
    {
        return isPk(this.isPk);
    }
    public boolean isPk(String isPk)
    {
        return isPk != null && StringUtils.equals("1", isPk);
    }
    public String getIsIncrement()
    {
        return isIncrement;
    }
    public void setIsIncrement(String isIncrement)
    {
        this.isIncrement = isIncrement;
    }
    public boolean isIncrement()
    {
        return isIncrement(this.isIncrement);
    }
    public boolean isIncrement(String isIncrement)
    {
        return isIncrement != null && StringUtils.equals("1", isIncrement);
    }
    public void setIsRequired(String isRequired)
    {
        this.isRequired = isRequired;
    }
    public String getIsRequired()
    {
        return isRequired;
    }
    public boolean isRequired()
    {
        return isRequired(this.isRequired);
    }
    public boolean isRequired(String isRequired)
    {
        return isRequired != null && StringUtils.equals("1", isRequired);
    }
    public void setIsInsert(String isInsert)
    {
        this.isInsert = isInsert;
    }
    public String getIsInsert()
    {
        return isInsert;
    }
    public boolean isInsert()
    {
        return isInsert(this.isInsert);
    }
    public boolean isInsert(String isInsert)
    {
        return isInsert != null && StringUtils.equals("1", isInsert);
    }
    public void setIsEdit(String isEdit)
    {
        this.isEdit = isEdit;
    }
    public String getIsEdit()
    {
        return isEdit;
    }
    public boolean isEdit()
    {
        return isInsert(this.isEdit);
    }
    public boolean isEdit(String isEdit)
    {
        return isEdit != null && StringUtils.equals("1", isEdit);
    }
    public void setIsList(String isList)
    {
        this.isList = isList;
    }
    public String getIsList()
    {
        return isList;
    }
    public boolean isList()
    {
        return isList(this.isList);
    }
    public boolean isList(String isList)
    {
        return isList != null && StringUtils.equals("1", isList);
    }
    public void setIsQuery(String isQuery)
    {
        this.isQuery = isQuery;
    }
    public String getIsQuery()
    {
        return isQuery;
    }
    public boolean isQuery()
    {
        return isQuery(this.isQuery);
    }
    public boolean isQuery(String isQuery)
    {
        return isQuery != null && StringUtils.equals("1", isQuery);
    }
    public void setQueryType(String queryType)
    {
        this.queryType = queryType;
    }
    public String getQueryType()
    {
        return queryType;
    }
    public String getHtmlType()
    {
        return htmlType;
    }
    public void setHtmlType(String htmlType)
    {
        this.htmlType = htmlType;
    }
    public void setDictType(String dictType)
    {
        this.dictType = dictType;
    }
    public String getDictType()
    {
        return dictType;
    }
    public void setSort(Integer sort)
    {
        this.sort = sort;
    }
    public Integer getSort()
    {
        return sort;
    }
    public boolean isSuperColumn()
    {
        return isSuperColumn(this.javaField);
    }
    public static boolean isSuperColumn(String javaField)
    {
        return StringUtils.equalsAnyIgnoreCase(javaField,
                // BaseEntity
                "createBy", "createTime", "updateBy", "updateTime", "remark",
                // TreeEntity
                "parentName", "parentId", "orderNum", "ancestors");
    }
    public boolean isUsableColumn()
    {
        return isUsableColumn(javaField);
    }
    public static boolean isUsableColumn(String javaField)
    {
        // isSuperColumn()中的名单用于避免生成多余Domain属性,若某些属性在生成页面时需要用到不能忽略,则放在此处白名单
        return StringUtils.equalsAnyIgnoreCase(javaField, "parentId", "orderNum");
    }
    public String readConverterExp()
    {
        String remarks = StringUtils.substringBetween(this.columnComment, "(", ")");
        StringBuffer sb = new StringBuffer();
        if (StringUtils.isNotEmpty(remarks))
        {
            for (String value : remarks.split(" "))
            {
                if (StringUtils.isNotEmpty(value))
                {
                    Object startStr = value.subSequence(0, 1);
                    String endStr = value.substring(1);
                    sb.append("").append(startStr).append("=").append(endStr).append(",");
                }
            }
            return sb.deleteCharAt(sb.length() - 1).toString();
        }
        else
        {
            return this.columnComment;
        }
    }
}
ruoyi-generator/src/main/java/com/ruoyi/generator/mapper/GenTableColumnMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,52 @@
package com.ruoyi.generator.mapper;
import java.util.List;
import com.ruoyi.generator.domain.GenTableColumn;
/**
 * ä¸šåŠ¡å­—æ®µ æ•°æ®å±‚
 *
 * @author ruoyi
 */
public interface GenTableColumnMapper
{
    /**
     * æ ¹æ®è¡¨åç§°æŸ¥è¯¢åˆ—信息
     *
     * @param tableName è¡¨åç§°
     * @return åˆ—信息
     */
    public List<GenTableColumn> selectDbTableColumnsByName(String tableName);
    /**
     * æŸ¥è¯¢ä¸šåŠ¡å­—æ®µåˆ—è¡¨
     *
     * @param tableId ä¸šåŠ¡å­—æ®µç¼–å·
     * @return ä¸šåŠ¡å­—æ®µé›†åˆ
     */
    public List<GenTableColumn> selectGenTableColumnListByTableId(Long tableId);
    /**
     * æ–°å¢žä¸šåŠ¡å­—æ®µ
     *
     * @param genTableColumn ä¸šåŠ¡å­—æ®µä¿¡æ¯
     * @return ç»“æžœ
     */
    public int insertGenTableColumn(GenTableColumn genTableColumn);
    /**
     * ä¿®æ”¹ä¸šåŠ¡å­—æ®µ
     *
     * @param genTableColumn ä¸šåŠ¡å­—æ®µä¿¡æ¯
     * @return ç»“æžœ
     */
    public int updateGenTableColumn(GenTableColumn genTableColumn);
    /**
     * æ‰¹é‡åˆ é™¤ä¸šåŠ¡å­—æ®µ
     *
     * @param ids éœ€è¦åˆ é™¤çš„æ•°æ®ID
     * @return ç»“æžœ
     */
    public int deleteGenTableColumnByIds(Long[] ids);
}
ruoyi-generator/src/main/java/com/ruoyi/generator/mapper/GenTableMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,76 @@
package com.ruoyi.generator.mapper;
import java.util.List;
import com.ruoyi.generator.domain.GenTable;
/**
 * ä¸šåŠ¡ æ•°æ®å±‚
 *
 * @author ruoyi
 */
public interface GenTableMapper
{
    /**
     * æŸ¥è¯¢ä¸šåŠ¡åˆ—è¡¨
     *
     * @param genTable ä¸šåŠ¡ä¿¡æ¯
     * @return ä¸šåŠ¡é›†åˆ
     */
    public List<GenTable> selectGenTableList(GenTable genTable);
    /**
     * æŸ¥è¯¢æ®åº“列表
     *
     * @param genTable ä¸šåŠ¡ä¿¡æ¯
     * @return æ•°æ®åº“表集合
     */
    public List<GenTable> selectDbTableList(GenTable genTable);
    /**
     * æŸ¥è¯¢æ®åº“列表
     *
     * @param tableNames è¡¨åç§°ç»„
     * @return æ•°æ®åº“表集合
     */
    public List<GenTable> selectDbTableListByNames(String[] tableNames);
    /**
     * æŸ¥è¯¢è¡¨ID业务信息
     *
     * @param id ä¸šåŠ¡ID
     * @return ä¸šåŠ¡ä¿¡æ¯
     */
    public GenTable selectGenTableById(Long id);
    /**
     * æŸ¥è¯¢è¡¨åç§°ä¸šåŠ¡ä¿¡æ¯
     *
     * @param tableName è¡¨åç§°
     * @return ä¸šåŠ¡ä¿¡æ¯
     */
    public GenTable selectGenTableByName(String tableName);
    /**
     * æ–°å¢žä¸šåŠ¡
     *
     * @param genTable ä¸šåŠ¡ä¿¡æ¯
     * @return ç»“æžœ
     */
    public int insertGenTable(GenTable genTable);
    /**
     * ä¿®æ”¹ä¸šåŠ¡
     *
     * @param genTable ä¸šåŠ¡ä¿¡æ¯
     * @return ç»“æžœ
     */
    public int updateGenTable(GenTable genTable);
    /**
     * æ‰¹é‡åˆ é™¤ä¸šåŠ¡
     *
     * @param ids éœ€è¦åˆ é™¤çš„æ•°æ®ID
     * @return ç»“æžœ
     */
    public int deleteGenTableByIds(Long[] ids);
}
ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableColumnServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,68 @@
package com.ruoyi.generator.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.generator.domain.GenTableColumn;
import com.ruoyi.generator.mapper.GenTableColumnMapper;
/**
 * ä¸šåŠ¡å­—æ®µ æœåŠ¡å±‚å®žçŽ°
 *
 * @author ruoyi
 */
@Service
public class GenTableColumnServiceImpl implements IGenTableColumnService
{
    @Autowired
    private GenTableColumnMapper genTableColumnMapper;
    /**
     * æŸ¥è¯¢ä¸šåŠ¡å­—æ®µåˆ—è¡¨
     *
     * @param tableId ä¸šåŠ¡å­—æ®µç¼–å·
     * @return ä¸šåŠ¡å­—æ®µé›†åˆ
     */
    @Override
    public List<GenTableColumn> selectGenTableColumnListByTableId(Long tableId)
    {
        return genTableColumnMapper.selectGenTableColumnListByTableId(tableId);
    }
    /**
     * æ–°å¢žä¸šåŠ¡å­—æ®µ
     *
     * @param genTableColumn ä¸šåŠ¡å­—æ®µä¿¡æ¯
     * @return ç»“æžœ
     */
    @Override
    public int insertGenTableColumn(GenTableColumn genTableColumn)
    {
        return genTableColumnMapper.insertGenTableColumn(genTableColumn);
    }
    /**
     * ä¿®æ”¹ä¸šåŠ¡å­—æ®µ
     *
     * @param genTableColumn ä¸šåŠ¡å­—æ®µä¿¡æ¯
     * @return ç»“æžœ
     */
    @Override
    public int updateGenTableColumn(GenTableColumn genTableColumn)
    {
        return genTableColumnMapper.updateGenTableColumn(genTableColumn);
    }
    /**
     * åˆ é™¤ä¸šåŠ¡å­—æ®µå¯¹è±¡
     *
     * @param ids éœ€è¦åˆ é™¤çš„æ•°æ®ID
     * @return ç»“æžœ
     */
    @Override
    public int deleteGenTableColumnByIds(String ids)
    {
        return genTableColumnMapper.deleteGenTableColumnByIds(Convert.toLongArray(ids));
    }
}
ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,345 @@
package com.ruoyi.generator.service;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.apache.commons.io.IOUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.GenConstants;
import com.ruoyi.common.exception.CustomException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.generator.domain.GenTable;
import com.ruoyi.generator.domain.GenTableColumn;
import com.ruoyi.generator.mapper.GenTableColumnMapper;
import com.ruoyi.generator.mapper.GenTableMapper;
import com.ruoyi.generator.util.GenUtils;
import com.ruoyi.generator.util.VelocityInitializer;
import com.ruoyi.generator.util.VelocityUtils;
/**
 * ä¸šåŠ¡ æœåŠ¡å±‚å®žçŽ°
 *
 * @author ruoyi
 */
@Service
public class GenTableServiceImpl implements IGenTableService
{
    private static final Logger log = LoggerFactory.getLogger(GenTableServiceImpl.class);
    @Autowired
    private GenTableMapper genTableMapper;
    @Autowired
    private GenTableColumnMapper genTableColumnMapper;
    /**
     * æŸ¥è¯¢ä¸šåŠ¡ä¿¡æ¯
     *
     * @param id ä¸šåŠ¡ID
     * @return ä¸šåŠ¡ä¿¡æ¯
     */
    @Override
    public GenTable selectGenTableById(Long id)
    {
        GenTable genTable = genTableMapper.selectGenTableById(id);
        setTableFromOptions(genTable);
        return genTable;
    }
    /**
     * æŸ¥è¯¢ä¸šåŠ¡åˆ—è¡¨
     *
     * @param genTable ä¸šåŠ¡ä¿¡æ¯
     * @return ä¸šåŠ¡é›†åˆ
     */
    @Override
    public List<GenTable> selectGenTableList(GenTable genTable)
    {
        return genTableMapper.selectGenTableList(genTable);
    }
    /**
     * æŸ¥è¯¢æ®åº“列表
     *
     * @param genTable ä¸šåŠ¡ä¿¡æ¯
     * @return æ•°æ®åº“表集合
     */
    @Override
    public List<GenTable> selectDbTableList(GenTable genTable)
    {
        return genTableMapper.selectDbTableList(genTable);
    }
    /**
     * æŸ¥è¯¢æ®åº“列表
     *
     * @param tableNames è¡¨åç§°ç»„
     * @return æ•°æ®åº“表集合
     */
    @Override
    public List<GenTable> selectDbTableListByNames(String[] tableNames)
    {
        return genTableMapper.selectDbTableListByNames(tableNames);
    }
    /**
     * ä¿®æ”¹ä¸šåŠ¡
     *
     * @param genTable ä¸šåŠ¡ä¿¡æ¯
     * @return ç»“æžœ
     */
    @Override
    @Transactional
    public void updateGenTable(GenTable genTable)
    {
        String options = JSON.toJSONString(genTable.getParams());
        genTable.setOptions(options);
        int row = genTableMapper.updateGenTable(genTable);
        if (row > 0)
        {
            for (GenTableColumn cenTableColumn : genTable.getColumns())
            {
                genTableColumnMapper.updateGenTableColumn(cenTableColumn);
            }
        }
    }
    /**
     * åˆ é™¤ä¸šåŠ¡å¯¹è±¡
     *
     * @param tableIds éœ€è¦åˆ é™¤çš„æ•°æ®ID
     * @return ç»“æžœ
     */
    @Override
    @Transactional
    public void deleteGenTableByIds(Long[] tableIds)
    {
        genTableMapper.deleteGenTableByIds(tableIds);
        genTableColumnMapper.deleteGenTableColumnByIds(tableIds);
    }
    /**
     * å¯¼å…¥è¡¨ç»“æž„
     *
     * @param tableList å¯¼å…¥è¡¨åˆ—表
     */
    @Override
    @Transactional
    public void importGenTable(List<GenTable> tableList)
    {
        String operName = SecurityUtils.getUsername();
        try
        {
            for (GenTable table : tableList)
            {
                String tableName = table.getTableName();
                GenUtils.initTable(table, operName);
                int row = genTableMapper.insertGenTable(table);
                if (row > 0)
                {
                    // ä¿å­˜åˆ—信息
                    List<GenTableColumn> genTableColumns = genTableColumnMapper.selectDbTableColumnsByName(tableName);
                    for (GenTableColumn column : genTableColumns)
                    {
                        GenUtils.initColumnField(column, table);
                        genTableColumnMapper.insertGenTableColumn(column);
                    }
                }
            }
        }
        catch (Exception e)
        {
            throw new CustomException("导入失败:" + e.getMessage());
        }
    }
    /**
     * é¢„览代码
     *
     * @param tableId è¡¨ç¼–号
     * @return é¢„览数据列表
     */
    @Override
    public Map<String, String> previewCode(Long tableId)
    {
        Map<String, String> dataMap = new LinkedHashMap<>();
        // æŸ¥è¯¢è¡¨ä¿¡æ¯
        GenTable table = genTableMapper.selectGenTableById(tableId);
        // æŸ¥è¯¢åˆ—信息
        List<GenTableColumn> columns = table.getColumns();
        setPkColumn(table, columns);
        VelocityInitializer.initVelocity();
        VelocityContext context = VelocityUtils.prepareContext(table);
        // èŽ·å–æ¨¡æ¿åˆ—è¡¨
        List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory());
        for (String template : templates)
        {
            // æ¸²æŸ“模板
            StringWriter sw = new StringWriter();
            Template tpl = Velocity.getTemplate(template, Constants.UTF8);
            tpl.merge(context, sw);
            dataMap.put(template, sw.toString());
        }
        return dataMap;
    }
    /**
     * ç”Ÿæˆä»£ç 
     *
     * @param tableName è¡¨åç§°
     * @return æ•°æ®
     */
    @Override
    public byte[] generatorCode(String tableName)
    {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ZipOutputStream zip = new ZipOutputStream(outputStream);
        generatorCode(tableName, zip);
        IOUtils.closeQuietly(zip);
        return outputStream.toByteArray();
    }
    /**
     * æ‰¹é‡ç”Ÿæˆä»£ç 
     *
     * @param tableNames è¡¨æ•°ç»„
     * @return æ•°æ®
     */
    @Override
    public byte[] generatorCode(String[] tableNames)
    {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ZipOutputStream zip = new ZipOutputStream(outputStream);
        for (String tableName : tableNames)
        {
            generatorCode(tableName, zip);
        }
        IOUtils.closeQuietly(zip);
        return outputStream.toByteArray();
    }
    /**
     * æŸ¥è¯¢è¡¨ä¿¡æ¯å¹¶ç”Ÿæˆä»£ç 
     */
    private void generatorCode(String tableName, ZipOutputStream zip)
    {
        // æŸ¥è¯¢è¡¨ä¿¡æ¯
        GenTable table = genTableMapper.selectGenTableByName(tableName);
        // æŸ¥è¯¢åˆ—信息
        List<GenTableColumn> columns = table.getColumns();
        setPkColumn(table, columns);
        VelocityInitializer.initVelocity();
        VelocityContext context = VelocityUtils.prepareContext(table);
        // èŽ·å–æ¨¡æ¿åˆ—è¡¨
        List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory());
        for (String template : templates)
        {
            // æ¸²æŸ“模板
            StringWriter sw = new StringWriter();
            Template tpl = Velocity.getTemplate(template, Constants.UTF8);
            tpl.merge(context, sw);
            try
            {
                // æ·»åŠ åˆ°zip
                zip.putNextEntry(new ZipEntry(VelocityUtils.getFileName(template, table)));
                IOUtils.write(sw.toString(), zip, Constants.UTF8);
                IOUtils.closeQuietly(sw);
                zip.flush();
                zip.closeEntry();
            }
            catch (IOException e)
            {
                log.error("渲染模板失败,表名:" + table.getTableName(), e);
            }
        }
    }
    /**
     * ä¿®æ”¹ä¿å­˜å‚数校验
     *
     * @param genTable ä¸šåŠ¡ä¿¡æ¯
     */
    @Override
    public void validateEdit(GenTable genTable)
    {
        if (GenConstants.TPL_TREE.equals(genTable.getTplCategory()))
        {
            String options = JSON.toJSONString(genTable.getParams());
            JSONObject paramsObj = JSONObject.parseObject(options);
            if (StringUtils.isEmpty(paramsObj.getString(GenConstants.TREE_CODE)))
            {
                throw new CustomException("树编码字段不能为空");
            }
            else if (StringUtils.isEmpty(paramsObj.getString(GenConstants.TREE_PARENT_CODE)))
            {
                throw new CustomException("树父编码字段不能为空");
            }
            else if (StringUtils.isEmpty(paramsObj.getString(GenConstants.TREE_NAME)))
            {
                throw new CustomException("树名称字段不能为空");
            }
        }
    }
    /**
     * è®¾ç½®ä¸»é”®åˆ—信息
     *
     * @param table ä¸šåŠ¡è¡¨ä¿¡æ¯
     * @param columns ä¸šåŠ¡å­—æ®µåˆ—è¡¨
     */
    public void setPkColumn(GenTable table, List<GenTableColumn> columns)
    {
        for (GenTableColumn column : columns)
        {
            if (column.isPk())
            {
                table.setPkColumn(column);
                break;
            }
        }
        if (StringUtils.isNull(table.getPkColumn()))
        {
            table.setPkColumn(columns.get(0));
        }
    }
    /**
     * è®¾ç½®ä»£ç ç”Ÿæˆå…¶ä»–选项值
     *
     * @param genTable è®¾ç½®åŽçš„生成对象
     */
    public void setTableFromOptions(GenTable genTable)
    {
        JSONObject paramsObj = JSONObject.parseObject(genTable.getOptions());
        if (StringUtils.isNotNull(paramsObj))
        {
            String treeCode = paramsObj.getString(GenConstants.TREE_CODE);
            String treeParentCode = paramsObj.getString(GenConstants.TREE_PARENT_CODE);
            String treeName = paramsObj.getString(GenConstants.TREE_NAME);
            genTable.setTreeCode(treeCode);
            genTable.setTreeParentCode(treeParentCode);
            genTable.setTreeName(treeName);
        }
    }
}
ruoyi-generator/src/main/java/com/ruoyi/generator/service/IGenTableColumnService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,44 @@
package com.ruoyi.generator.service;
import java.util.List;
import com.ruoyi.generator.domain.GenTableColumn;
/**
 * ä¸šåŠ¡å­—æ®µ æœåС层
 *
 * @author ruoyi
 */
public interface IGenTableColumnService
{
    /**
     * æŸ¥è¯¢ä¸šåŠ¡å­—æ®µåˆ—è¡¨
     *
     * @param tableId ä¸šåŠ¡å­—æ®µç¼–å·
     * @return ä¸šåŠ¡å­—æ®µé›†åˆ
     */
    public List<GenTableColumn> selectGenTableColumnListByTableId(Long tableId);
    /**
     * æ–°å¢žä¸šåŠ¡å­—æ®µ
     *
     * @param genTableColumn ä¸šåŠ¡å­—æ®µä¿¡æ¯
     * @return ç»“æžœ
     */
    public int insertGenTableColumn(GenTableColumn genTableColumn);
    /**
     * ä¿®æ”¹ä¸šåŠ¡å­—æ®µ
     *
     * @param genTableColumn ä¸šåŠ¡å­—æ®µä¿¡æ¯
     * @return ç»“æžœ
     */
    public int updateGenTableColumn(GenTableColumn genTableColumn);
    /**
     * åˆ é™¤ä¸šåŠ¡å­—æ®µä¿¡æ¯
     *
     * @param ids éœ€è¦åˆ é™¤çš„æ•°æ®ID
     * @return ç»“æžœ
     */
    public int deleteGenTableColumnByIds(String ids);
}
ruoyi-generator/src/main/java/com/ruoyi/generator/service/IGenTableService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,99 @@
package com.ruoyi.generator.service;
import java.util.List;
import java.util.Map;
import com.ruoyi.generator.domain.GenTable;
/**
 * ä¸šåŠ¡ æœåС层
 *
 * @author ruoyi
 */
public interface IGenTableService
{
    /**
     * æŸ¥è¯¢ä¸šåŠ¡åˆ—è¡¨
     *
     * @param genTable ä¸šåŠ¡ä¿¡æ¯
     * @return ä¸šåŠ¡é›†åˆ
     */
    public List<GenTable> selectGenTableList(GenTable genTable);
    /**
     * æŸ¥è¯¢æ®åº“列表
     *
     * @param genTable ä¸šåŠ¡ä¿¡æ¯
     * @return æ•°æ®åº“表集合
     */
    public List<GenTable> selectDbTableList(GenTable genTable);
    /**
     * æŸ¥è¯¢æ®åº“列表
     *
     * @param tableNames è¡¨åç§°ç»„
     * @return æ•°æ®åº“表集合
     */
    public List<GenTable> selectDbTableListByNames(String[] tableNames);
    /**
     * æŸ¥è¯¢ä¸šåŠ¡ä¿¡æ¯
     *
     * @param id ä¸šåŠ¡ID
     * @return ä¸šåŠ¡ä¿¡æ¯
     */
    public GenTable selectGenTableById(Long id);
    /**
     * ä¿®æ”¹ä¸šåŠ¡
     *
     * @param genTable ä¸šåŠ¡ä¿¡æ¯
     * @return ç»“æžœ
     */
    public void updateGenTable(GenTable genTable);
    /**
     * åˆ é™¤ä¸šåŠ¡ä¿¡æ¯
     *
     * @param tableIds éœ€è¦åˆ é™¤çš„表数据ID
     * @return ç»“æžœ
     */
    public void deleteGenTableByIds(Long[] tableIds);
    /**
     * å¯¼å…¥è¡¨ç»“æž„
     *
     * @param tableList å¯¼å…¥è¡¨åˆ—表
     */
    public void importGenTable(List<GenTable> tableList);
    /**
     * é¢„览代码
     *
     * @param tableId è¡¨ç¼–号
     * @return é¢„览数据列表
     */
    public Map<String, String> previewCode(Long tableId);
    /**
     * ç”Ÿæˆä»£ç 
     *
     * @param tableName è¡¨åç§°
     * @return æ•°æ®
     */
    public byte[] generatorCode(String tableName);
    /**
     * æ‰¹é‡ç”Ÿæˆä»£ç 
     *
     * @param tableNames è¡¨æ•°ç»„
     * @return æ•°æ®
     */
    public byte[] generatorCode(String[] tableNames);
    /**
     * ä¿®æ”¹ä¿å­˜å‚数校验
     *
     * @param genTable ä¸šåŠ¡ä¿¡æ¯
     */
    public void validateEdit(GenTable genTable);
}
ruoyi-generator/src/main/java/com/ruoyi/generator/util/GenUtils.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,242 @@
package com.ruoyi.generator.util;
import java.util.Arrays;
import org.apache.commons.lang3.RegExUtils;
import com.ruoyi.common.constant.GenConstants;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.generator.config.GenConfig;
import com.ruoyi.generator.domain.GenTable;
import com.ruoyi.generator.domain.GenTableColumn;
/**
 * ä»£ç ç”Ÿæˆå™¨ å·¥å…·ç±»
 *
 * @author ruoyi
 */
public class GenUtils
{
    /**
     * åˆå§‹åŒ–表信息
     */
    public static void initTable(GenTable genTable, String operName)
    {
        genTable.setClassName(convertClassName(genTable.getTableName()));
        genTable.setPackageName(GenConfig.getPackageName());
        genTable.setModuleName(getModuleName(GenConfig.getPackageName()));
        genTable.setBusinessName(getBusinessName(genTable.getTableName()));
        genTable.setFunctionName(replaceText(genTable.getTableComment()));
        genTable.setFunctionAuthor(GenConfig.getAuthor());
        genTable.setCreateBy(operName);
    }
    /**
     * åˆå§‹åŒ–列属性字段
     */
    public static void initColumnField(GenTableColumn column, GenTable table)
    {
        String dataType = getDbType(column.getColumnType());
        String columnName = column.getColumnName();
        column.setTableId(table.getTableId());
        column.setCreateBy(table.getCreateBy());
        // è®¾ç½®java字段名
        column.setJavaField(StringUtils.toCamelCase(columnName));
        if (arraysContains(GenConstants.COLUMNTYPE_STR, dataType))
        {
            column.setJavaType(GenConstants.TYPE_STRING);
            // å­—符串长度超过500设置为文本域
            Integer columnLength = getColumnLength(column.getColumnType());
            String htmlType = columnLength >= 500 ? GenConstants.HTML_TEXTAREA : GenConstants.HTML_INPUT;
            column.setHtmlType(htmlType);
        }
        else if (arraysContains(GenConstants.COLUMNTYPE_TIME, dataType))
        {
            column.setJavaType(GenConstants.TYPE_DATE);
            column.setHtmlType(GenConstants.HTML_DATETIME);
        }
        else if (arraysContains(GenConstants.COLUMNTYPE_NUMBER, dataType))
        {
            column.setHtmlType(GenConstants.HTML_INPUT);
            // å¦‚果是浮点型 ç»Ÿä¸€ç”¨BigDecimal
            String[] str = StringUtils.split(StringUtils.substringBetween(column.getColumnType(), "(", ")"), ",");
            if (str != null && str.length == 2 && Integer.parseInt(str[1]) > 0)
            {
                column.setJavaType(GenConstants.TYPE_BIGDECIMAL);
            }
            // å¦‚果是整形
            else if (str != null && str.length == 1 && Integer.parseInt(str[0]) <= 10)
            {
                column.setJavaType(GenConstants.TYPE_INTEGER);
            }
            // é•¿æ•´å½¢
            else
            {
                column.setJavaType(GenConstants.TYPE_LONG);
            }
        }
        // æ’入字段(默认所有字段都需要插入)
        column.setIsInsert(GenConstants.REQUIRE);
        // ç¼–辑字段
        if (!arraysContains(GenConstants.COLUMNNAME_NOT_EDIT, columnName) && !column.isPk())
        {
            column.setIsEdit(GenConstants.REQUIRE);
        }
        // åˆ—表字段
        if (!arraysContains(GenConstants.COLUMNNAME_NOT_LIST, columnName) && !column.isPk())
        {
            column.setIsList(GenConstants.REQUIRE);
        }
        // æŸ¥è¯¢å­—段
        if (!arraysContains(GenConstants.COLUMNNAME_NOT_QUERY, columnName) && !column.isPk())
        {
            column.setIsQuery(GenConstants.REQUIRE);
        }
        // æŸ¥è¯¢å­—段类型
        if (StringUtils.endsWithIgnoreCase(columnName, "name"))
        {
            column.setQueryType(GenConstants.QUERY_LIKE);
        }
        // çŠ¶æ€å­—æ®µè®¾ç½®å•é€‰æ¡†
        if (StringUtils.endsWithIgnoreCase(columnName, "status"))
        {
            column.setHtmlType(GenConstants.HTML_RADIO);
        }
        // ç±»åž‹&性别字段设置下拉框
        else if (StringUtils.endsWithIgnoreCase(columnName, "type")
                || StringUtils.endsWithIgnoreCase(columnName, "sex"))
        {
            column.setHtmlType(GenConstants.HTML_SELECT);
        }
    }
    /**
     * æ ¡éªŒæ•°ç»„是否包含指定值
     *
     * @param arr æ•°ç»„
     * @param targetValue å€¼
     * @return æ˜¯å¦åŒ…含
     */
    public static boolean arraysContains(String[] arr, String targetValue)
    {
        return Arrays.asList(arr).contains(targetValue);
    }
    /**
     * èŽ·å–æ¨¡å—å
     *
     * @param packageName åŒ…名
     * @return æ¨¡å—名
     */
    public static String getModuleName(String packageName)
    {
        int lastIndex = packageName.lastIndexOf(".");
        int nameLength = packageName.length();
        String moduleName = StringUtils.substring(packageName, lastIndex + 1, nameLength);
        return moduleName;
    }
    /**
     * èŽ·å–ä¸šåŠ¡å
     *
     * @param tableName è¡¨å
     * @return ä¸šåŠ¡å
     */
    public static String getBusinessName(String tableName)
    {
        int lastIndex = tableName.indexOf("_");
        int nameLength = tableName.length();
        String businessName = StringUtils.substring(tableName, lastIndex + 1, nameLength);
        return StringUtils.toCamelCase(businessName);
    }
    /**
     * è¡¨åè½¬æ¢æˆJava类名
     *
     * @param tableName è¡¨åç§°
     * @return ç±»å
     */
    public static String convertClassName(String tableName)
    {
        boolean autoRemovePre = GenConfig.getAutoRemovePre();
        String tablePrefix = GenConfig.getTablePrefix();
        if (autoRemovePre && StringUtils.isNotEmpty(tablePrefix))
        {
            String[] searchList = StringUtils.split(tablePrefix, ",");
            tableName = replaceFirst(tableName, searchList);
        }
        return StringUtils.convertToCamelCase(tableName);
    }
    /**
     * æ‰¹é‡æ›¿æ¢å‰ç¼€
     *
     * @param replacementm æ›¿æ¢å€¼
     * @param searchList æ›¿æ¢åˆ—表
     * @return
     */
    public static String replaceFirst(String replacementm, String[] searchList)
    {
        String text = replacementm;
        for (String searchString : searchList)
        {
            if (replacementm.startsWith(searchString))
            {
                text = replacementm.replaceFirst(searchString, "");
                break;
            }
        }
        return text;
    }
    /**
     * å…³é”®å­—替换
     *
     * @param name éœ€è¦è¢«æ›¿æ¢çš„名字
     * @return æ›¿æ¢åŽçš„名字
     */
    public static String replaceText(String text)
    {
        return RegExUtils.replaceAll(text, "(?:表|若依)", "");
    }
    /**
     * èŽ·å–æ•°æ®åº“ç±»åž‹å­—æ®µ
     *
     * @param columnType åˆ—类型
     * @return æˆªå–后的列类型
     */
    public static String getDbType(String columnType)
    {
        if (StringUtils.indexOf(columnType, "(") > 0)
        {
            return StringUtils.substringBefore(columnType, "(");
        }
        else
        {
            return columnType;
        }
    }
    /**
     * èŽ·å–å­—æ®µé•¿åº¦
     *
     * @param columnType åˆ—类型
     * @return æˆªå–后的列类型
     */
    public static Integer getColumnLength(String columnType)
    {
        if (StringUtils.indexOf(columnType, "(") > 0)
        {
            String length = StringUtils.substringBetween(columnType, "(", ")");
            return Integer.valueOf(length);
        }
        else
        {
            return 0;
        }
    }
}
ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityInitializer.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,35 @@
package com.ruoyi.generator.util;
import java.util.Properties;
import org.apache.velocity.app.Velocity;
import com.ruoyi.common.constant.Constants;
/**
 * VelocityEngine工厂
 *
 * @author RuoYi
 */
public class VelocityInitializer
{
    /**
     * åˆå§‹åŒ–vm方法
     */
    public static void initVelocity()
    {
        Properties p = new Properties();
        try
        {
            // åŠ è½½classpath目录下的vm文件
            p.setProperty("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
            // å®šä¹‰å­—符集
            p.setProperty(Velocity.ENCODING_DEFAULT, Constants.UTF8);
            p.setProperty(Velocity.OUTPUT_ENCODING, Constants.UTF8);
            // åˆå§‹åŒ–Velocity引擎,指定配置Properties
            Velocity.init(p);
        }
        catch (Exception e)
        {
            throw new RuntimeException(e);
        }
    }
}
ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityUtils.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,298 @@
package com.ruoyi.generator.util;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import org.apache.velocity.VelocityContext;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.constant.GenConstants;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.generator.domain.GenTable;
import com.ruoyi.generator.domain.GenTableColumn;
/**
 * ä»£ç ç”Ÿæˆæ¨¡æ¿å¤„理
 *
 * @author ruoyi
 */
public class VelocityUtils
{
    /** é¡¹ç›®ç©ºé—´è·¯å¾„ */
    private static final String PROJECT_PATH = "main/java";
    /** mybatis空间路径 */
    private static final String MYBATIS_PATH = "main/resources/mapper";
    /**
     * è®¾ç½®æ¨¡æ¿å˜é‡ä¿¡æ¯
     *
     * @return æ¨¡æ¿åˆ—表
     */
    public static VelocityContext prepareContext(GenTable genTable)
    {
        String moduleName = genTable.getModuleName();
        String businessName = genTable.getBusinessName();
        String packageName = genTable.getPackageName();
        String tplCategory = genTable.getTplCategory();
        String functionName = genTable.getFunctionName();
        VelocityContext velocityContext = new VelocityContext();
        velocityContext.put("tplCategory", genTable.getTplCategory());
        velocityContext.put("tableName", genTable.getTableName());
        velocityContext.put("functionName", StringUtils.isNotEmpty(functionName) ? functionName : "【请填写功能名称】");
        velocityContext.put("ClassName", genTable.getClassName());
        velocityContext.put("className", StringUtils.uncapitalize(genTable.getClassName()));
        velocityContext.put("moduleName", genTable.getModuleName());
        velocityContext.put("BusinessName", StringUtils.capitalize(genTable.getBusinessName()));
        velocityContext.put("businessName", genTable.getBusinessName());
        velocityContext.put("basePackage", getPackagePrefix(packageName));
        velocityContext.put("packageName", packageName);
        velocityContext.put("author", genTable.getFunctionAuthor());
        velocityContext.put("datetime", DateUtils.getDate());
        velocityContext.put("pkColumn", genTable.getPkColumn());
        velocityContext.put("importList", getImportList(genTable.getColumns()));
        velocityContext.put("permissionPrefix", getPermissionPrefix(moduleName, businessName));
        velocityContext.put("columns", genTable.getColumns());
        velocityContext.put("table", genTable);
        if (GenConstants.TPL_TREE.equals(tplCategory))
        {
            setTreeVelocityContext(velocityContext, genTable);
        }
        return velocityContext;
    }
    public static void setTreeVelocityContext(VelocityContext context, GenTable genTable)
    {
        String options = genTable.getOptions();
        JSONObject paramsObj = JSONObject.parseObject(options);
        String treeCode = getTreecode(paramsObj);
        String treeParentCode = getTreeParentCode(paramsObj);
        String treeName = getTreeName(paramsObj);
        context.put("treeCode", treeCode);
        context.put("treeParentCode", treeParentCode);
        context.put("treeName", treeName);
        context.put("expandColumn", getExpandColumn(genTable));
        if (paramsObj.containsKey(GenConstants.TREE_PARENT_CODE))
        {
            context.put("tree_parent_code", paramsObj.getString(GenConstants.TREE_PARENT_CODE));
        }
        if (paramsObj.containsKey(GenConstants.TREE_NAME))
        {
            context.put("tree_name", paramsObj.getString(GenConstants.TREE_NAME));
        }
    }
    /**
     * èŽ·å–æ¨¡æ¿ä¿¡æ¯
     *
     * @return æ¨¡æ¿åˆ—表
     */
    public static List<String> getTemplateList(String tplCategory)
    {
        List<String> templates = new ArrayList<String>();
        templates.add("vm/java/domain.java.vm");
        templates.add("vm/java/mapper.java.vm");
        templates.add("vm/java/service.java.vm");
        templates.add("vm/java/serviceImpl.java.vm");
        templates.add("vm/java/controller.java.vm");
        templates.add("vm/xml/mapper.xml.vm");
        templates.add("vm/sql/sql.vm");
        templates.add("vm/js/api.js.vm");
        if (GenConstants.TPL_CRUD.equals(tplCategory))
        {
            templates.add("vm/vue/index.vue.vm");
        }
        else if (GenConstants.TPL_TREE.equals(tplCategory))
        {
            templates.add("vm/vue/index-tree.vue.vm");
        }
        return templates;
    }
    /**
     * èŽ·å–æ–‡ä»¶å
     */
    public static String getFileName(String template, GenTable genTable)
    {
        // æ–‡ä»¶åç§°
        String fileName = "";
        // åŒ…路径
        String packageName = genTable.getPackageName();
        // æ¨¡å—名
        String moduleName = genTable.getModuleName();
        // å¤§å†™ç±»å
        String className = genTable.getClassName();
        // ä¸šåŠ¡åç§°
        String businessName = genTable.getBusinessName();
        String javaPath = PROJECT_PATH + "/" + StringUtils.replace(packageName, ".", "/");
        String mybatisPath = MYBATIS_PATH + "/" + moduleName;
        String vuePath = "vue";
        if (template.contains("domain.java.vm"))
        {
            fileName = StringUtils.format("{}/domain/{}.java", javaPath, className);
        }
        else if (template.contains("mapper.java.vm"))
        {
            fileName = StringUtils.format("{}/mapper/{}Mapper.java", javaPath, className);
        }
        else if (template.contains("service.java.vm"))
        {
            fileName = StringUtils.format("{}/service/I{}Service.java", javaPath, className);
        }
        else if (template.contains("serviceImpl.java.vm"))
        {
            fileName = StringUtils.format("{}/service/impl/{}ServiceImpl.java", javaPath, className);
        }
        else if (template.contains("controller.java.vm"))
        {
            fileName = StringUtils.format("{}/controller/{}Controller.java", javaPath, className);
        }
        else if (template.contains("mapper.xml.vm"))
        {
            fileName = StringUtils.format("{}/{}Mapper.xml", mybatisPath, className);
        }
        else if (template.contains("sql.vm"))
        {
            fileName = businessName + "Menu.sql";
        }
        else if (template.contains("api.js.vm"))
        {
            fileName = StringUtils.format("{}/api/{}/{}.js", vuePath, moduleName, businessName);
        }
        else if (template.contains("index.vue.vm"))
        {
            fileName = StringUtils.format("{}/views/{}/{}/index.vue", vuePath, moduleName, businessName);
        }
        else if (template.contains("index-tree.vue.vm"))
        {
            fileName = StringUtils.format("{}/views/{}/{}/index.vue", vuePath, moduleName, businessName);
        }
        return fileName;
    }
    /**
     * èŽ·å–åŒ…å‰ç¼€
     *
     * @param packageName åŒ…名称
     * @return åŒ…前缀名称
     */
    public static String getPackagePrefix(String packageName)
    {
        int lastIndex = packageName.lastIndexOf(".");
        String basePackage = StringUtils.substring(packageName, 0, lastIndex);
        return basePackage;
    }
    /**
     * æ ¹æ®åˆ—类型获取导入包
     *
     * @param column åˆ—集合
     * @return è¿”回需要导入的包列表
     */
    public static HashSet<String> getImportList(List<GenTableColumn> columns)
    {
        HashSet<String> importList = new HashSet<String>();
        for (GenTableColumn column : columns)
        {
            if (!column.isSuperColumn() && GenConstants.TYPE_DATE.equals(column.getJavaType()))
            {
                importList.add("java.util.Date");
                importList.add("com.fasterxml.jackson.annotation.JsonFormat");
            }
            else if (!column.isSuperColumn() && GenConstants.TYPE_BIGDECIMAL.equals(column.getJavaType()))
            {
                importList.add("java.math.BigDecimal");
            }
        }
        return importList;
    }
    /**
     * èŽ·å–æƒé™å‰ç¼€
     *
     * @param moduleName æ¨¡å—名称
     * @param businessName ä¸šåŠ¡åç§°
     * @return è¿”回权限前缀
     */
    public static String getPermissionPrefix(String moduleName, String businessName)
    {
        return StringUtils.format("{}:{}", moduleName, businessName);
    }
    /**
     * èŽ·å–æ ‘ç¼–ç 
     *
     * @param options ç”Ÿæˆå…¶ä»–选项
     * @return æ ‘编码
     */
    public static String getTreecode(JSONObject paramsObj)
    {
        if (paramsObj.containsKey(GenConstants.TREE_CODE))
        {
            return StringUtils.toCamelCase(paramsObj.getString(GenConstants.TREE_CODE));
        }
        return "";
    }
    /**
     * èŽ·å–æ ‘çˆ¶ç¼–ç 
     *
     * @param options ç”Ÿæˆå…¶ä»–选项
     * @return æ ‘父编码
     */
    public static String getTreeParentCode(JSONObject paramsObj)
    {
        if (paramsObj.containsKey(GenConstants.TREE_PARENT_CODE))
        {
            return StringUtils.toCamelCase(paramsObj.getString(GenConstants.TREE_PARENT_CODE));
        }
        return "";
    }
    /**
     * èŽ·å–æ ‘åç§°
     *
     * @param options ç”Ÿæˆå…¶ä»–选项
     * @return æ ‘名称
     */
    public static String getTreeName(JSONObject paramsObj)
    {
        if (paramsObj.containsKey(GenConstants.TREE_NAME))
        {
            return StringUtils.toCamelCase(paramsObj.getString(GenConstants.TREE_NAME));
        }
        return "";
    }
    /**
     * èŽ·å–éœ€è¦åœ¨å“ªä¸€åˆ—ä¸Šé¢æ˜¾ç¤ºå±•å¼€æŒ‰é’®
     *
     * @param genTable ä¸šåŠ¡è¡¨å¯¹è±¡
     * @return å±•开按钮列序号
     */
    public static int getExpandColumn(GenTable genTable)
    {
        String options = genTable.getOptions();
        JSONObject paramsObj = JSONObject.parseObject(options);
        String treeName = paramsObj.getString(GenConstants.TREE_NAME);
        int num = 0;
        for (GenTableColumn column : genTable.getColumns())
        {
            if (column.isList())
            {
                num++;
                String columnName = column.getColumnName();
                if (columnName.equals(treeName))
                {
                    break;
                }
            }
        }
        return num;
    }
}
ruoyi-generator/src/main/resources/generator.yml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,10 @@
# ä»£ç ç”Ÿæˆ
gen:
  # ä½œè€…
  author: ruoyi
  # é»˜è®¤ç”ŸæˆåŒ…路径 system éœ€æ”¹æˆè‡ªå·±çš„æ¨¡å—名称 å¦‚ system monitor tool
  packageName: com.ruoyi.system
  # è‡ªåŠ¨åŽ»é™¤è¡¨å‰ç¼€ï¼Œé»˜è®¤æ˜¯false
  autoRemovePre: false
  # è¡¨å‰ç¼€ï¼ˆç”Ÿæˆç±»åä¸ä¼šåŒ…含表前缀,多个用逗号分隔)
  tablePrefix: sys_
ruoyi-generator/src/main/resources/mapper/generator/GenTableColumnMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.generator.mapper.GenTableColumnMapper">
    <resultMap type="GenTableColumn" id="GenTableColumnResult">
        <id     property="columnId"       column="column_id"      />
        <result property="tableId"        column="table_id"       />
        <result property="columnName"     column="column_name"    />
        <result property="columnComment"  column="column_comment" />
        <result property="columnType"     column="column_type"    />
        <result property="javaType"       column="java_type"      />
        <result property="javaField"      column="java_field"     />
        <result property="isPk"           column="is_pk"          />
        <result property="isIncrement"    column="is_increment"   />
        <result property="isRequired"     column="is_required"    />
        <result property="isInsert"       column="is_insert"      />
        <result property="isEdit"         column="is_edit"        />
        <result property="isList"         column="is_list"        />
        <result property="isQuery"        column="is_query"       />
        <result property="queryType"      column="query_type"     />
        <result property="htmlType"       column="html_type"      />
        <result property="dictType"       column="dict_type"      />
        <result property="sort"           column="sort"           />
        <result property="createBy"       column="create_by"      />
        <result property="createTime"     column="create_time"    />
        <result property="updateBy"       column="update_by"      />
        <result property="updateTime"     column="update_time"    />
    </resultMap>
    <sql id="selectGenTableColumnVo">
        select column_id, table_id, column_name, column_comment, column_type, java_type, java_field, is_pk, is_increment, is_required, is_insert, is_edit, is_list, is_query, query_type, html_type, dict_type, sort, create_by, create_time, update_by, update_time from gen_table_column
    </sql>
    <select id="selectGenTableColumnListByTableId" parameterType="Long" resultMap="GenTableColumnResult">
        <include refid="selectGenTableColumnVo"/>
        where table_id = #{tableId}
        order by sort
    </select>
    <select id="selectDbTableColumnsByName" parameterType="String" resultMap="GenTableColumnResult">
        select column_name, (case when (is_nullable = 'no' <![CDATA[ && ]]> column_key != 'PRI') then '1' else null end) as is_required, (case when column_key = 'PRI' then '1' else '0' end) as is_pk, ordinal_position as sort, column_comment, (case when extra = 'auto_increment' then '1' else '0' end) as is_increment, column_type
        from information_schema.columns where table_schema = (select database()) and table_name = (#{tableName})
        order by ordinal_position
    </select>
    <insert id="insertGenTableColumn" parameterType="GenTableColumn" useGeneratedKeys="true" keyProperty="columnId">
        insert into gen_table_column (
            <if test="tableId != null and tableId != ''">table_id,</if>
            <if test="columnName != null and columnName != ''">column_name,</if>
            <if test="columnComment != null and columnComment != ''">column_comment,</if>
            <if test="columnType != null and columnType != ''">column_type,</if>
            <if test="javaType != null and javaType != ''">java_type,</if>
            <if test="javaField != null  and javaField != ''">java_field,</if>
            <if test="isPk != null and isPk != ''">is_pk,</if>
            <if test="isIncrement != null and isIncrement != ''">is_increment,</if>
            <if test="isRequired != null and isRequired != ''">is_required,</if>
            <if test="isInsert != null and isInsert != ''">is_insert,</if>
            <if test="isEdit != null and isEdit != ''">is_edit,</if>
            <if test="isList != null and isList != ''">is_list,</if>
            <if test="isQuery != null and isQuery != ''">is_query,</if>
            <if test="queryType != null and queryType != ''">query_type,</if>
            <if test="htmlType != null and htmlType != ''">html_type,</if>
            <if test="dictType != null and dictType != ''">dict_type,</if>
            <if test="sort != null">sort,</if>
            <if test="createBy != null and createBy != ''">create_by,</if>
            create_time
         )values(
            <if test="tableId != null and tableId != ''">#{tableId},</if>
            <if test="columnName != null and columnName != ''">#{columnName},</if>
            <if test="columnComment != null and columnComment != ''">#{columnComment},</if>
            <if test="columnType != null and columnType != ''">#{columnType},</if>
            <if test="javaType != null and javaType != ''">#{javaType},</if>
            <if test="javaField != null and javaField != ''">#{javaField},</if>
            <if test="isPk != null and isPk != ''">#{isPk},</if>
            <if test="isIncrement != null and isIncrement != ''">#{isIncrement},</if>
            <if test="isRequired != null and isRequired != ''">#{isRequired},</if>
            <if test="isInsert != null and isInsert != ''">#{isInsert},</if>
            <if test="isEdit != null and isEdit != ''">#{isEdit},</if>
            <if test="isList != null and isList != ''">#{isList},</if>
            <if test="isQuery != null and isQuery != ''">#{isQuery},</if>
            <if test="queryType != null and queryType != ''">#{queryType},</if>
            <if test="htmlType != null and htmlType != ''">#{htmlType},</if>
            <if test="dictType != null and dictType != ''">#{dictType},</if>
            <if test="sort != null">#{sort},</if>
            <if test="createBy != null and createBy != ''">#{createBy},</if>
            sysdate()
         )
    </insert>
    <update id="updateGenTableColumn" parameterType="GenTableColumn">
        update gen_table_column
        <set>
            column_comment = #{columnComment},
            java_type = #{javaType},
            java_field = #{javaField},
            is_insert = #{isInsert},
            is_edit = #{isEdit},
            is_list = #{isList},
            is_query = #{isQuery},
            is_required = #{isRequired},
            query_type = #{queryType},
            html_type = #{htmlType},
            dict_type = #{dictType},
            sort = #{sort},
            update_by = #{updateBy},
            update_time = sysdate()
        </set>
        where column_id = #{columnId}
    </update>
    <delete id="deleteGenTableColumnByIds" parameterType="Long">
        delete from gen_table_column where table_id in
        <foreach collection="array" item="tableId" open="(" separator="," close=")">
            #{tableId}
        </foreach>
    </delete>
</mapper>
ruoyi-generator/src/main/resources/mapper/generator/GenTableMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,181 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.generator.mapper.GenTableMapper">
    <resultMap type="GenTable" id="GenTableResult">
        <id     property="tableId"        column="table_id"        />
        <result property="tableName"      column="table_name"      />
        <result property="tableComment"   column="table_comment"   />
        <result property="className"      column="class_name"      />
        <result property="tplCategory"    column="tpl_category"    />
        <result property="packageName"    column="package_name"    />
        <result property="moduleName"     column="module_name"     />
        <result property="businessName"   column="business_name"   />
        <result property="functionName"   column="function_name"   />
        <result property="functionAuthor" column="function_author" />
        <result property="options"        column="options"         />
        <result property="createBy"       column="create_by"       />
        <result property="createTime"     column="create_time"     />
        <result property="updateBy"       column="update_by"       />
        <result property="updateTime"     column="update_time"     />
        <result property="remark"         column="remark"          />
        <collection  property="columns"  javaType="java.util.List"  resultMap="GenTableColumnResult" />
    </resultMap>
    <resultMap type="GenTableColumn" id="GenTableColumnResult">
        <id     property="columnId"       column="column_id"      />
        <result property="tableId"        column="table_id"       />
        <result property="columnName"     column="column_name"    />
        <result property="columnComment"  column="column_comment" />
        <result property="columnType"     column="column_type"    />
        <result property="javaType"       column="java_type"      />
        <result property="javaField"      column="java_field"     />
        <result property="isPk"           column="is_pk"          />
        <result property="isIncrement"    column="is_increment"   />
        <result property="isRequired"     column="is_required"    />
        <result property="isInsert"       column="is_insert"      />
        <result property="isEdit"         column="is_edit"        />
        <result property="isList"         column="is_list"        />
        <result property="isQuery"        column="is_query"       />
        <result property="queryType"      column="query_type"     />
        <result property="htmlType"       column="html_type"      />
        <result property="dictType"       column="dict_type"      />
        <result property="sort"           column="sort"           />
        <result property="createBy"       column="create_by"      />
        <result property="createTime"     column="create_time"    />
        <result property="updateBy"       column="update_by"      />
        <result property="updateTime"     column="update_time"    />
    </resultMap>
    <sql id="selectGenTableVo">
        select table_id, table_name, table_comment, class_name, tpl_category, package_name, module_name, business_name, function_name, function_author, options, create_by, create_time, update_by, update_time, remark from gen_table
    </sql>
    <select id="selectGenTableList" parameterType="GenTable" resultMap="GenTableResult">
        <include refid="selectGenTableVo"/>
        <where>
            <if test="tableName != null and tableName != ''">
                AND lower(table_name) like lower(concat('%', #{tableName}, '%'))
            </if>
            <if test="tableComment != null and tableComment != ''">
                AND lower(table_comment) like lower(concat('%', #{tableComment}, '%'))
            </if>
            <if test="beginTime != null and beginTime != ''"><!-- å¼€å§‹æ—¶é—´æ£€ç´¢ -->
                AND date_format(create_time,'%y%m%d') &gt;= date_format(#{beginTime},'%y%m%d')
            </if>
            <if test="endTime != null and endTime != ''"><!-- ç»“束时间检索 -->
                AND date_format(create_time,'%y%m%d') &lt;= date_format(#{endTime},'%y%m%d')
            </if>
        </where>
    </select>
    <select id="selectDbTableList" parameterType="GenTable" resultMap="GenTableResult">
        select table_name, table_comment, create_time, update_time from information_schema.tables
        where table_schema = (select database())
        AND table_name NOT LIKE 'qrtz_%' AND table_name NOT LIKE 'gen_%'
        AND table_name NOT IN (select table_name from gen_table)
        <if test="tableName != null and tableName != ''">
            AND lower(table_name) like lower(concat('%', #{tableName}, '%'))
        </if>
        <if test="tableComment != null and tableComment != ''">
            AND lower(table_comment) like lower(concat('%', #{tableComment}, '%'))
        </if>
        <if test="beginTime != null and beginTime != ''"><!-- å¼€å§‹æ—¶é—´æ£€ç´¢ -->
            AND date_format(create_time,'%y%m%d') &gt;= date_format(#{beginTime},'%y%m%d')
        </if>
        <if test="endTime != null and endTime != ''"><!-- ç»“束时间检索 -->
            AND date_format(create_time,'%y%m%d') &lt;= date_format(#{endTime},'%y%m%d')
        </if>
    </select>
    <select id="selectDbTableListByNames" resultMap="GenTableResult">
        select table_name, table_comment, create_time, update_time from information_schema.tables
        where table_name NOT LIKE 'qrtz_%' and table_name NOT LIKE 'gen_%' and table_schema = (select database())
        and table_name in
        <foreach collection="array" item="name" open="(" separator="," close=")">
             #{name}
        </foreach>
    </select>
    <select id="selectTableByName" parameterType="String" resultMap="GenTableResult">
        select table_name, table_comment, create_time, update_time from information_schema.tables
        where table_comment <![CDATA[ <> ]]> '' and table_schema = (select database())
        and table_name = #{tableName}
    </select>
    <select id="selectGenTableById" parameterType="Long" resultMap="GenTableResult">
        SELECT t.table_id, t.table_name, t.table_comment, t.class_name, t.tpl_category, t.package_name, t.module_name, t.business_name, t.function_name, t.function_author, t.options, t.remark,
               c.column_id, c.column_name, c.column_comment, c.column_type, c.java_type, c.java_field, c.is_pk, c.is_increment, c.is_required, c.is_insert, c.is_edit, c.is_list, c.is_query, c.query_type, c.html_type, c.dict_type, c.sort
        FROM gen_table t
             LEFT JOIN gen_table_column c ON t.table_id = c.table_id
        where t.table_id = #{tableId} order by c.sort
    </select>
    <select id="selectGenTableByName" parameterType="String" resultMap="GenTableResult">
        SELECT t.table_id, t.table_name, t.table_comment, t.class_name, t.tpl_category, t.package_name, t.module_name, t.business_name, t.function_name, t.function_author, t.options, t.remark,
               c.column_id, c.column_name, c.column_comment, c.column_type, c.java_type, c.java_field, c.is_pk, c.is_increment, c.is_required, c.is_insert, c.is_edit, c.is_list, c.is_query, c.query_type, c.html_type, c.dict_type, c.sort
        FROM gen_table t
             LEFT JOIN gen_table_column c ON t.table_id = c.table_id
        where t.table_name = #{tableName} order by c.sort
    </select>
    <insert id="insertGenTable" parameterType="GenTable" useGeneratedKeys="true" keyProperty="tableId">
        insert into gen_table (
            <if test="tableName != null">table_name,</if>
            <if test="tableComment != null and tableComment != ''">table_comment,</if>
            <if test="className != null and className != ''">class_name,</if>
            <if test="tplCategory != null and tplCategory != ''">tpl_category,</if>
            <if test="packageName != null and packageName != ''">package_name,</if>
            <if test="moduleName != null and moduleName != ''">module_name,</if>
            <if test="businessName != null and businessName != ''">business_name,</if>
            <if test="functionName != null and functionName != ''">function_name,</if>
            <if test="functionAuthor != null and functionAuthor != ''">function_author,</if>
            <if test="remark != null and remark != ''">remark,</if>
             <if test="createBy != null and createBy != ''">create_by,</if>
            create_time
         )values(
            <if test="tableName != null">#{tableName},</if>
            <if test="tableComment != null and tableComment != ''">#{tableComment},</if>
            <if test="className != null and className != ''">#{className},</if>
            <if test="tplCategory != null and tplCategory != ''">#{tplCategory},</if>
            <if test="packageName != null and packageName != ''">#{packageName},</if>
            <if test="moduleName != null and moduleName != ''">#{moduleName},</if>
            <if test="businessName != null and businessName != ''">#{businessName},</if>
            <if test="functionName != null and functionName != ''">#{functionName},</if>
            <if test="functionAuthor != null and functionAuthor != ''">#{functionAuthor},</if>
            <if test="remark != null and remark != ''">#{remark},</if>
             <if test="createBy != null and createBy != ''">#{createBy},</if>
            sysdate()
         )
    </insert>
    <update id="updateGenTable" parameterType="GenTable">
        update gen_table
        <set>
            <if test="tableName != null">table_name = #{tableName},</if>
            <if test="tableComment != null and tableComment != ''">table_comment = #{tableComment},</if>
            <if test="className != null and className != ''">class_name = #{className},</if>
            <if test="functionAuthor != null and functionAuthor != ''">function_author = #{functionAuthor},</if>
            <if test="tplCategory != null and tplCategory != ''">tpl_category = #{tplCategory},</if>
            <if test="packageName != null and packageName != ''">package_name = #{packageName},</if>
            <if test="moduleName != null and moduleName != ''">module_name = #{moduleName},</if>
            <if test="businessName != null and businessName != ''">business_name = #{businessName},</if>
            <if test="functionName != null and functionName != ''">function_name = #{functionName},</if>
            <if test="options != null and options != ''">options = #{options},</if>
            <if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
            <if test="remark != null">remark = #{remark},</if>
            update_time = sysdate()
        </set>
        where table_id = #{tableId}
    </update>
    <delete id="deleteGenTableByIds" parameterType="Long">
        delete from gen_table where table_id in
        <foreach collection="array" item="tableId" open="(" separator="," close=")">
            #{tableId}
        </foreach>
    </delete>
</mapper>
ruoyi-generator/src/main/resources/vm/java/controller.java.vm
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,197 @@
package ${packageName}.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import java.util.List;
import java.util.Arrays;
import com.ruoyi.common.utils.StringUtils;
import lombok.AllArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import ${packageName}.domain.${ClassName};
import ${packageName}.service.I${ClassName}Service;
import com.ruoyi.common.utils.poi.ExcelUtil;
#if($table.crud)
import com.ruoyi.common.core.page.TableDataInfo;
#elseif($table.tree)
#end
/**
 * ${functionName}Controller
 *
 * @author ${author}
 * @date ${datetime}
 */
@AllArgsConstructor
@RestController
@RequestMapping("/${moduleName}/${businessName}" )
public class ${ClassName}Controller extends BaseController {
    private final I${ClassName}Service i${ClassName}Service;
    /**
     * æŸ¥è¯¢${functionName}列表
     */
    @PreAuthorize("@ss.hasPermi('${permissionPrefix}:list')")
    @GetMapping("/list")
#if($table.crud)
    public TableDataInfo list(${ClassName} ${className})
    {
        startPage();
        LambdaQueryWrapper<${ClassName}> lqw = new LambdaQueryWrapper<${ClassName}>();
#foreach($column in $columns)
#set($queryType=$column.queryType)
#set($javaField=$column.javaField)
#set($javaType=$column.javaType)
#set($columnName=$column.columnName)
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
#if($column.query)
#if($column.queryType == "EQ")
#if($javaType == 'String')
        if (StringUtils.isNotBlank(${className}.get$AttrName())){
            lqw.eq(${ClassName}::get$AttrName ,${className}.get$AttrName());
        }
#else
        if (${className}.get$AttrName() != null){
            lqw.eq(${ClassName}::get$AttrName ,${className}.get$AttrName());
        }
#end
#elseif($queryType == "NE")
#if($javaType == 'String')
        if (StringUtils.isNotBlank(${className}.get$AttrName())){
            lqw.ne(${ClassName}::get$AttrName ,${className}.get$AttrName());
        }
#else
        if (${className}.get$AttrName() != null){
            lqw.ne(${ClassName}::get$AttrName ,${className}.get$AttrName());
        }
#end
#elseif($queryType == "GT")
#if($javaType == 'String')
        if (StringUtils.isNotBlank(${className}.get$AttrName())){
            lqw.gt(${ClassName}::get$AttrName ,${className}.get$AttrName());
        }
#else
        if (${className}.get$AttrName() != null){
            lqw.gt(${ClassName}::get$AttrName ,${className}.get$AttrName());
        }
#end
#elseif($queryType == "GTE")
#if($javaType == 'String')
        if (StringUtils.isNotBlank(${className}.get$AttrName())){
            lqw.ge(${ClassName}::get$AttrName ,${className}.get$AttrName());
        }
#else
        if (${className}.get$AttrName() != null){
            lqw.ge(${ClassName}::get$AttrName ,${className}.get$AttrName());
        }
#end
#elseif($queryType == "LT")
#if($javaType == 'String')
        if (StringUtils.isNotBlank(${className}.get$AttrName())){
            lqw.lt(${ClassName}::get$AttrName ,${className}.get$AttrName());
        }
#else
        if (${className}.get$AttrName() != null){
            lqw.lt(${ClassName}::get$AttrName ,${className}.get$AttrName());
        }
#end
#elseif($queryType == "LTE")
#if($javaType == 'String')
        if (StringUtils.isNotBlank(${className}.get$AttrName())){
            lqw.le(${ClassName}::get$AttrName ,${className}.get$AttrName());
        }
#else
        if (${className}.get$AttrName() != null){
            lqw.le(${ClassName}::get$AttrName ,${className}.get$AttrName());
        }
#end
#elseif($queryType == "LIKE")
#if($javaType == 'String')
        if (StringUtils.isNotBlank(${className}.get$AttrName())){
            lqw.like(${ClassName}::get$AttrName ,${className}.get$AttrName());
        }
#else
        if (${className}.get$AttrName() != null){
            lqw.like(${ClassName}::get$AttrName ,${className}.get$AttrName());
        }
#end
#elseif($queryType == "BETWEEN")
#end
#end
#end
        List<${ClassName}> list = i${ClassName}Service.list(lqw);
        return getDataTable(list);
    }
#elseif($table.tree)
    public AjaxResult list(${ClassName} ${className}) {
        List<${ClassName}> list = i${ClassName}Service.list(lqw);
        return AjaxResult.success(list);
    }
#end
    /**
     * å¯¼å‡º${functionName}列表
     */
    @PreAuthorize("@ss.hasPermi('${permissionPrefix}:export')" )
    @Log(title = "${functionName}" , businessType = BusinessType.EXPORT)
    @GetMapping("/export" )
    public AjaxResult export(${ClassName} ${className}) {
        LambdaQueryWrapper<${ClassName}> lqw = new LambdaQueryWrapper<${ClassName}>(${className});
        List<${ClassName}> list = i${ClassName}Service.list(lqw);
        ExcelUtil<${ClassName}> util = new ExcelUtil<${ClassName}>(${ClassName}. class);
        return util.exportExcel(list, "${businessName}" );
    }
    /**
     * èŽ·å–${functionName}详细信息
     */
    @PreAuthorize("@ss.hasPermi('${permissionPrefix}:query')" )
    @GetMapping(value = "/{${pkColumn.javaField}}" )
    public AjaxResult getInfo(@PathVariable("${pkColumn.javaField}" ) ${pkColumn.javaType} ${pkColumn.javaField}) {
        return AjaxResult.success(i${ClassName}Service.getById(${pkColumn.javaField}));
    }
    /**
     * æ–°å¢ž${functionName}
     */
    @PreAuthorize("@ss.hasPermi('${permissionPrefix}:add')" )
    @Log(title = "${functionName}" , businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody ${ClassName} ${className}) {
        return toAjax(i${ClassName}Service.save(${className}) ? 1 : 0);
    }
    /**
     * ä¿®æ”¹${functionName}
     */
    @PreAuthorize("@ss.hasPermi('${permissionPrefix}:edit')" )
    @Log(title = "${functionName}" , businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody ${ClassName} ${className}) {
        return toAjax(i${ClassName}Service.updateById(${className}) ? 1 : 0);
    }
    /**
     * åˆ é™¤${functionName}
     */
    @PreAuthorize("@ss.hasPermi('${permissionPrefix}:remove')" )
    @Log(title = "${functionName}" , businessType = BusinessType.DELETE)
    @DeleteMapping("/{${pkColumn.javaField}s}" )
    public AjaxResult remove(@PathVariable ${pkColumn.javaType}[] ${pkColumn.javaField}s) {
        return toAjax(i${ClassName}Service.removeByIds(Arrays.asList(${pkColumn.javaField}s)) ? 1 : 0);
    }
}
ruoyi-generator/src/main/resources/vm/java/domain.java.vm
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,69 @@
package ${packageName}.domain;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.ToString;
import lombok.experimental.Accessors;
import com.ruoyi.common.annotation.Excel;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import java.io.Serializable;
import java.util.Date;
import java.math.BigDecimal;
#if($table.crud)
import com.ruoyi.common.core.domain.BaseEntity;
#elseif($table.tree)
import com.ruoyi.common.core.domain.TreeEntity;
#end
/**
 * ${functionName}对象 ${tableName}
 *
 * @author ${author}
 * @date ${datetime}
 */
#if($table.crud)
#set($Entity="BaseEntity")
#elseif($table.tree)
#set($Entity="TreeEntity")
#end
@Data
@ToString
@EqualsAndHashCode
@NoArgsConstructor
@Accessors(chain = true)
@TableName("${tableName}")
public class ${ClassName} implements Serializable {
private static final long serialVersionUID=1L;
#foreach ($column in $columns)
    /** $column.columnComment */
#if($column.list)
#set($parentheseIndex=$column.columnComment.indexOf("("))
#if($parentheseIndex != -1)
#set($comment=$column.columnComment.substring(0, $parentheseIndex))
#else
#set($comment=$column.columnComment)
#end
#if($parentheseIndex != -1)
    @Excel(name = "${comment}" , readConverterExp = "$column.readConverterExp()")
#elseif($column.javaType == 'Date')
    @Excel(name = "${comment}" , width = 30, dateFormat = "yyyy-MM-dd")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
#else
    @Excel(name = "${comment}")
#end
#end
#if($column.isPk==1)
    @TableId(value = "$column.columnName", type = IdType.AUTO)
    private $column.javaType $column.javaField;
#else
    private $column.javaType $column.javaField;
#end
#end
}
ruoyi-generator/src/main/resources/vm/java/mapper.java.vm
ruoyi-generator/src/main/resources/vm/java/service.java.vm
ruoyi-generator/src/main/resources/vm/java/serviceImpl.java.vm
ruoyi-generator/src/main/resources/vm/js/api.js.vm
ruoyi-generator/src/main/resources/vm/sql/sql.vm
ruoyi-generator/src/main/resources/vm/vue/index-tree.vue.vm
ruoyi-generator/src/main/resources/vm/vue/index.vue.vm
ruoyi-generator/src/main/resources/vm/xml/mapper.xml.vm
ruoyi-quartz/pom.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>ruoyi</artifactId>
        <groupId>com.ruoyi</groupId>
        <version>3.0.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>ruoyi-quartz</artifactId>
    <description>
        quartz定时任务
    </description>
    <dependencies>
        <!-- å®šæ—¶ä»»åŠ¡ -->
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>com.mchange</groupId>
                    <artifactId>c3p0</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!-- é€šç”¨å·¥å…·-->
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>ruoyi-common</artifactId>
        </dependency>
    </dependencies>
</project>
ruoyi-quartz/src/main/java/com/ruoyi/quartz/config/MybatisPlusConfig.java
ruoyi-quartz/src/main/java/com/ruoyi/quartz/config/ScheduleConfig.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,57 @@
package com.ruoyi.quartz.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import javax.sql.DataSource;
import java.util.Properties;
/**
 * å®šæ—¶ä»»åŠ¡é…ç½®
 *
 * @author ruoyi
 */
@Configuration
public class ScheduleConfig
{
    @Bean
    public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource)
    {
        SchedulerFactoryBean factory = new SchedulerFactoryBean();
        factory.setDataSource(dataSource);
        // quartz参数
        Properties prop = new Properties();
        prop.put("org.quartz.scheduler.instanceName", "RuoyiScheduler");
        prop.put("org.quartz.scheduler.instanceId", "AUTO");
        // çº¿ç¨‹æ± é…ç½®
        prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");
        prop.put("org.quartz.threadPool.threadCount", "20");
        prop.put("org.quartz.threadPool.threadPriority", "5");
        // JobStore配置
        prop.put("org.quartz.jobStore.class", "org.quartz.impl.jdbcjobstore.JobStoreTX");
        // é›†ç¾¤é…ç½®
        prop.put("org.quartz.jobStore.isClustered", "true");
        prop.put("org.quartz.jobStore.clusterCheckinInterval", "15000");
        prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "1");
        prop.put("org.quartz.jobStore.txIsolationLevelSerializable", "true");
        // sqlserver å¯ç”¨
        // prop.put("org.quartz.jobStore.selectWithLockSQL", "SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ?");
        prop.put("org.quartz.jobStore.misfireThreshold", "12000");
        prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_");
        factory.setQuartzProperties(prop);
        factory.setSchedulerName("RuoyiScheduler");
        // å»¶æ—¶å¯åЍ
        factory.setStartupDelay(1);
        factory.setApplicationContextSchedulerContextKey("applicationContextKey");
        // å¯é€‰ï¼ŒQuartzScheduler
        // å¯åŠ¨æ—¶æ›´æ–°å·±å­˜åœ¨çš„Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了
        factory.setOverwriteExistingJobs(true);
        // è®¾ç½®è‡ªåŠ¨å¯åŠ¨ï¼Œé»˜è®¤ä¸ºtrue
        factory.setAutoStartup(true);
        return factory;
    }
}
ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,142 @@
package com.ruoyi.quartz.controller;
import java.util.List;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
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.exception.job.TaskException;
import com.ruoyi.common.utils.SecurityUtils;
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;
/**
 * è°ƒåº¦ä»»åŠ¡ä¿¡æ¯æ“ä½œå¤„ç†
 *
 * @author ruoyi
 */
@RestController
@RequestMapping("/monitor/job")
public class SysJobController extends BaseController
{
    @Autowired
    private ISysJobService jobService;
    /**
     * æŸ¥è¯¢å®šæ—¶ä»»åŠ¡åˆ—è¡¨
     */
    @PreAuthorize("@ss.hasPermi('monitor:job:list')")
    @GetMapping("/list")
    public TableDataInfo list(SysJob sysJob)
    {
        startPage();
        List<SysJob> list = jobService.selectJobList(sysJob);
        return getDataTable(list);
    }
    /**
     * å¯¼å‡ºå®šæ—¶ä»»åŠ¡åˆ—è¡¨
     */
    @PreAuthorize("@ss.hasPermi('monitor:job:export')")
    @Log(title = "定时任务", businessType = BusinessType.EXPORT)
    @GetMapping("/export")
    public AjaxResult export(SysJob sysJob)
    {
        List<SysJob> list = jobService.selectJobList(sysJob);
        ExcelUtil<SysJob> util = new ExcelUtil<SysJob>(SysJob.class);
        return util.exportExcel(list, "定时任务");
    }
    /**
     * èŽ·å–å®šæ—¶ä»»åŠ¡è¯¦ç»†ä¿¡æ¯
     */
    @PreAuthorize("@ss.hasPermi('monitor:job:query')")
    @GetMapping(value = "/{jobId}")
    public AjaxResult getInfo(@PathVariable("jobId") Long jobId)
    {
        return AjaxResult.success(jobService.selectJobById(jobId));
    }
    /**
     * æ–°å¢žå®šæ—¶ä»»åŠ¡
     */
    @PreAuthorize("@ss.hasPermi('monitor:job:add')")
    @Log(title = "定时任务", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody SysJob sysJob) throws SchedulerException, TaskException
    {
        if (!CronUtils.isValid(sysJob.getCronExpression()))
        {
            return AjaxResult.error("cron表达式不正确");
        }
        sysJob.setCreateBy(SecurityUtils.getUsername());
        return toAjax(jobService.insertJob(sysJob));
    }
    /**
     * ä¿®æ”¹å®šæ—¶ä»»åŠ¡
     */
    @PreAuthorize("@ss.hasPermi('monitor:job:edit')")
    @Log(title = "定时任务", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody SysJob sysJob) throws SchedulerException, TaskException
    {
        if (!CronUtils.isValid(sysJob.getCronExpression()))
        {
            return AjaxResult.error("cron表达式不正确");
        }
        sysJob.setUpdateBy(SecurityUtils.getUsername());
        return toAjax(jobService.updateJob(sysJob));
    }
    /**
     * å®šæ—¶ä»»åŠ¡çŠ¶æ€ä¿®æ”¹
     */
    @PreAuthorize("@ss.hasPermi('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));
    }
    /**
     * å®šæ—¶ä»»åŠ¡ç«‹å³æ‰§è¡Œä¸€æ¬¡
     */
    @PreAuthorize("@ss.hasPermi('monitor:job:changeStatus')")
    @Log(title = "定时任务", businessType = BusinessType.UPDATE)
    @PutMapping("/run")
    public AjaxResult run(@RequestBody SysJob job) throws SchedulerException
    {
        jobService.run(job);
        return AjaxResult.success();
    }
    /**
     * åˆ é™¤å®šæ—¶ä»»åŠ¡
     */
    @PreAuthorize("@ss.hasPermi('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();
    }
}
ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobLogController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,90 @@
package com.ruoyi.quartz.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
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;
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;
/**
 * è°ƒåº¦æ—¥å¿—操作处理
 *
 * @author ruoyi
 */
@RestController
@RequestMapping("/monitor/jobLog")
public class SysJobLogController extends BaseController
{
    @Autowired
    private ISysJobLogService jobLogService;
    /**
     * æŸ¥è¯¢å®šæ—¶ä»»åŠ¡è°ƒåº¦æ—¥å¿—åˆ—è¡¨
     */
    @PreAuthorize("@ss.hasPermi('monitor:job:list')")
    @GetMapping("/list")
    public TableDataInfo list(SysJobLog sysJobLog)
    {
        startPage();
        List<SysJobLog> list = jobLogService.selectJobLogList(sysJobLog);
        return getDataTable(list);
    }
    /**
     * å¯¼å‡ºå®šæ—¶ä»»åŠ¡è°ƒåº¦æ—¥å¿—åˆ—è¡¨
     */
    @PreAuthorize("@ss.hasPermi('monitor:job:export')")
    @Log(title = "任务调度日志", businessType = BusinessType.EXPORT)
    @GetMapping("/export")
    public AjaxResult export(SysJobLog sysJobLog)
    {
        List<SysJobLog> list = jobLogService.selectJobLogList(sysJobLog);
        ExcelUtil<SysJobLog> util = new ExcelUtil<SysJobLog>(SysJobLog.class);
        return util.exportExcel(list, "调度日志");
    }
    /**
     * æ ¹æ®è°ƒåº¦ç¼–号获取详细信息
     */
    @PreAuthorize("@ss.hasPermi('monitor:job:query')")
    @GetMapping(value = "/{configId}")
    public AjaxResult getInfo(@PathVariable Long jobLogId)
    {
        return AjaxResult.success(jobLogService.selectJobLogById(jobLogId));
    }
    /**
     * åˆ é™¤å®šæ—¶ä»»åŠ¡è°ƒåº¦æ—¥å¿—
     */
    @PreAuthorize("@ss.hasPermi('monitor:job:remove')")
    @Log(title = "定时任务调度日志", businessType = BusinessType.DELETE)
    @DeleteMapping("/{jobLogIds}")
    public AjaxResult remove(@PathVariable Long[] jobLogIds)
    {
        return toAjax(jobLogService.deleteJobLogByIds(jobLogIds));
    }
    /**
     * æ¸…空定时任务调度日志
     */
    @PreAuthorize("@ss.hasPermi('monitor:job:remove')")
    @Log(title = "调度日志", businessType = BusinessType.CLEAN)
    @DeleteMapping("/clean")
    public AjaxResult clean()
    {
        jobLogService.cleanJobLog();
        return AjaxResult.success();
    }
}
ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/SysJob.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,172 @@
package com.ruoyi.quartz.domain;
import java.io.Serializable;
import java.util.Date;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.annotation.Excel.ColumnType;
import com.ruoyi.common.constant.ScheduleConstants;
import com.ruoyi.common.core.domain.BaseEntity;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.quartz.util.CronUtils;
/**
 * å®šæ—¶ä»»åŠ¡è°ƒåº¦è¡¨ sys_job
 *
 * @author ruoyi
 */
public class SysJob extends BaseEntity implements Serializable
{
    private static final long serialVersionUID = 1L;
    /** ä»»åŠ¡ID */
    @Excel(name = "任务序号", cellType = ColumnType.NUMERIC)
    private Long jobId;
    /** ä»»åŠ¡åç§° */
    @Excel(name = "任务名称")
    private String jobName;
    /** ä»»åŠ¡ç»„å */
    @Excel(name = "任务组名")
    private String jobGroup;
    /** è°ƒç”¨ç›®æ ‡å­—符串 */
    @Excel(name = "调用目标字符串")
    private String invokeTarget;
    /** cron执行表达式 */
    @Excel(name = "执行表达式 ")
    private String cronExpression;
    /** cron计划策略 */
    @Excel(name = "计划策略 ", readConverterExp = "0=默认,1=立即触发执行,2=触发一次执行,3=不触发立即执行")
    private String misfirePolicy = ScheduleConstants.MISFIRE_DEFAULT;
    /** æ˜¯å¦å¹¶å‘执行(0允许 1禁止) */
    @Excel(name = "并发执行", readConverterExp = "0=允许,1=禁止")
    private String concurrent;
    /** ä»»åŠ¡çŠ¶æ€ï¼ˆ0正常 1暂停) */
    @Excel(name = "任务状态", readConverterExp = "0=正常,1=暂停")
    private String status;
    public Long getJobId()
    {
        return jobId;
    }
    public void setJobId(Long jobId)
    {
        this.jobId = jobId;
    }
    @NotBlank(message = "任务名称不能为空")
    @Size(min = 0, max = 64, message = "任务名称不能超过64个字符")
    public String getJobName()
    {
        return jobName;
    }
    public void setJobName(String jobName)
    {
        this.jobName = jobName;
    }
    public String getJobGroup()
    {
        return jobGroup;
    }
    public void setJobGroup(String jobGroup)
    {
        this.jobGroup = jobGroup;
    }
    @NotBlank(message = "调用目标字符串不能为空")
    @Size(min = 0, max = 1000, message = "调用目标字符串长度不能超过500个字符")
    public String getInvokeTarget()
    {
        return invokeTarget;
    }
    public void setInvokeTarget(String invokeTarget)
    {
        this.invokeTarget = invokeTarget;
    }
    @NotBlank(message = "Cron执行表达式不能为空")
    @Size(min = 0, max = 255, message = "Cron执行表达式不能超过255个字符")
    public String getCronExpression()
    {
        return cronExpression;
    }
    public void setCronExpression(String cronExpression)
    {
        this.cronExpression = cronExpression;
    }
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    public Date getNextValidTime()
    {
        if (StringUtils.isNotEmpty(cronExpression))
        {
            return CronUtils.getNextExecution(cronExpression);
        }
        return null;
    }
    public String getMisfirePolicy()
    {
        return misfirePolicy;
    }
    public void setMisfirePolicy(String misfirePolicy)
    {
        this.misfirePolicy = misfirePolicy;
    }
    public String getConcurrent()
    {
        return concurrent;
    }
    public void setConcurrent(String concurrent)
    {
        this.concurrent = concurrent;
    }
    public String getStatus()
    {
        return status;
    }
    public void setStatus(String status)
    {
        this.status = status;
    }
    @Override
    public String toString() {
        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
            .append("jobId", getJobId())
            .append("jobName", getJobName())
            .append("jobGroup", getJobGroup())
            .append("cronExpression", getCronExpression())
            .append("nextValidTime", getNextValidTime())
            .append("misfirePolicy", getMisfirePolicy())
            .append("concurrent", getConcurrent())
            .append("status", getStatus())
            .append("createBy", getCreateBy())
            .append("createTime", getCreateTime())
            .append("updateBy", getUpdateBy())
            .append("updateTime", getUpdateTime())
            .append("remark", getRemark())
            .toString();
    }
}
ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/SysJobLog.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,155 @@
package com.ruoyi.quartz.domain;
import java.util.Date;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
/**
 * å®šæ—¶ä»»åŠ¡è°ƒåº¦æ—¥å¿—è¡¨ sys_job_log
 *
 * @author ruoyi
 */
public class SysJobLog extends BaseEntity
{
    private static final long serialVersionUID = 1L;
    /** ID */
    @Excel(name = "日志序号")
    private Long jobLogId;
    /** ä»»åŠ¡åç§° */
    @Excel(name = "任务名称")
    private String jobName;
    /** ä»»åŠ¡ç»„å */
    @Excel(name = "任务组名")
    private String jobGroup;
    /** è°ƒç”¨ç›®æ ‡å­—符串 */
    @Excel(name = "调用目标字符串")
    private String invokeTarget;
    /** æ—¥å¿—信息 */
    @Excel(name = "日志信息")
    private String jobMessage;
    /** æ‰§è¡ŒçŠ¶æ€ï¼ˆ0正常 1失败) */
    @Excel(name = "执行状态", readConverterExp = "0=正常,1=失败")
    private String status;
    /** å¼‚常信息 */
    @Excel(name = "异常信息")
    private String exceptionInfo;
    /** å¼€å§‹æ—¶é—´ */
    private Date startTime;
    /** åœæ­¢æ—¶é—´ */
    private Date stopTime;
    public Long getJobLogId()
    {
        return jobLogId;
    }
    public void setJobLogId(Long jobLogId)
    {
        this.jobLogId = jobLogId;
    }
    public String getJobName()
    {
        return jobName;
    }
    public void setJobName(String jobName)
    {
        this.jobName = jobName;
    }
    public String getJobGroup()
    {
        return jobGroup;
    }
    public void setJobGroup(String jobGroup)
    {
        this.jobGroup = jobGroup;
    }
    public String getInvokeTarget()
    {
        return invokeTarget;
    }
    public void setInvokeTarget(String invokeTarget)
    {
        this.invokeTarget = invokeTarget;
    }
    public String getJobMessage()
    {
        return jobMessage;
    }
    public void setJobMessage(String jobMessage)
    {
        this.jobMessage = jobMessage;
    }
    public String getStatus()
    {
        return status;
    }
    public void setStatus(String status)
    {
        this.status = status;
    }
    public String getExceptionInfo()
    {
        return exceptionInfo;
    }
    public void setExceptionInfo(String exceptionInfo)
    {
        this.exceptionInfo = exceptionInfo;
    }
    public Date getStartTime()
    {
        return startTime;
    }
    public void setStartTime(Date startTime)
    {
        this.startTime = startTime;
    }
    public Date getStopTime()
    {
        return stopTime;
    }
    public void setStopTime(Date stopTime)
    {
        this.stopTime = stopTime;
    }
    @Override
    public String toString() {
        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
            .append("jobLogId", getJobLogId())
            .append("jobName", getJobName())
            .append("jobGroup", getJobGroup())
            .append("jobMessage", getJobMessage())
            .append("status", getStatus())
            .append("exceptionInfo", getExceptionInfo())
            .append("startTime", getStartTime())
            .append("stopTime", getStopTime())
            .toString();
    }
}
ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/SysJobLogMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,64 @@
package com.ruoyi.quartz.mapper;
import java.util.List;
import com.ruoyi.quartz.domain.SysJobLog;
/**
 * è°ƒåº¦ä»»åŠ¡æ—¥å¿—ä¿¡æ¯ æ•°æ®å±‚
 *
 * @author ruoyi
 */
public interface SysJobLogMapper
{
    /**
     * èŽ·å–quartz调度器日志的计划任务
     *
     * @param jobLog è°ƒåº¦æ—¥å¿—信息
     * @return è°ƒåº¦ä»»åŠ¡æ—¥å¿—é›†åˆ
     */
    public List<SysJobLog> selectJobLogList(SysJobLog jobLog);
    /**
     * æŸ¥è¯¢æ‰€æœ‰è°ƒåº¦ä»»åŠ¡æ—¥å¿—
     *
     * @return è°ƒåº¦ä»»åŠ¡æ—¥å¿—åˆ—è¡¨
     */
    public List<SysJobLog> selectJobLogAll();
    /**
     * é€šè¿‡è°ƒåº¦ä»»åŠ¡æ—¥å¿—ID查询调度信息
     *
     * @param jobLogId è°ƒåº¦ä»»åŠ¡æ—¥å¿—ID
     * @return è°ƒåº¦ä»»åŠ¡æ—¥å¿—å¯¹è±¡ä¿¡æ¯
     */
    public SysJobLog selectJobLogById(Long jobLogId);
    /**
     * æ–°å¢žä»»åŠ¡æ—¥å¿—
     *
     * @param jobLog è°ƒåº¦æ—¥å¿—信息
     * @return ç»“æžœ
     */
    public int insertJobLog(SysJobLog jobLog);
    /**
     * æ‰¹é‡åˆ é™¤è°ƒåº¦æ—¥å¿—信息
     *
     * @param logIds éœ€è¦åˆ é™¤çš„æ•°æ®ID
     * @return ç»“æžœ
     */
    public int deleteJobLogByIds(Long[] logIds);
    /**
     * åˆ é™¤ä»»åŠ¡æ—¥å¿—
     *
     * @param jobId è°ƒåº¦æ—¥å¿—ID
     * @return ç»“æžœ
     */
    public int deleteJobLogById(Long jobId);
    /**
     * æ¸…空任务日志
     */
    public void cleanJobLog();
}
ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/SysJobMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,67 @@
package com.ruoyi.quartz.mapper;
import java.util.List;
import com.ruoyi.quartz.domain.SysJob;
/**
 * è°ƒåº¦ä»»åŠ¡ä¿¡æ¯ æ•°æ®å±‚
 *
 * @author ruoyi
 */
public interface SysJobMapper
{
    /**
     * æŸ¥è¯¢è°ƒåº¦ä»»åŠ¡æ—¥å¿—é›†åˆ
     *
     * @param job è°ƒåº¦ä¿¡æ¯
     * @return æ“ä½œæ—¥å¿—集合
     */
    public List<SysJob> selectJobList(SysJob job);
    /**
     * æŸ¥è¯¢æ‰€æœ‰è°ƒåº¦ä»»åŠ¡
     *
     * @return è°ƒåº¦ä»»åŠ¡åˆ—è¡¨
     */
    public List<SysJob> selectJobAll();
    /**
     * é€šè¿‡è°ƒåº¦ID查询调度任务信息
     *
     * @param jobId è°ƒåº¦ID
     * @return è§’色对象信息
     */
    public SysJob selectJobById(Long jobId);
    /**
     * é€šè¿‡è°ƒåº¦ID删除调度任务信息
     *
     * @param jobId è°ƒåº¦ID
     * @return ç»“æžœ
     */
    public int deleteJobById(Long jobId);
    /**
     * æ‰¹é‡åˆ é™¤è°ƒåº¦ä»»åŠ¡ä¿¡æ¯
     *
     * @param ids éœ€è¦åˆ é™¤çš„æ•°æ®ID
     * @return ç»“æžœ
     */
    public int deleteJobByIds(Long[] ids);
    /**
     * ä¿®æ”¹è°ƒåº¦ä»»åŠ¡ä¿¡æ¯
     *
     * @param job è°ƒåº¦ä»»åŠ¡ä¿¡æ¯
     * @return ç»“æžœ
     */
    public int updateJob(SysJob job);
    /**
     * æ–°å¢žè°ƒåº¦ä»»åŠ¡ä¿¡æ¯
     *
     * @param job è°ƒåº¦ä»»åŠ¡ä¿¡æ¯
     * @return ç»“æžœ
     */
    public int insertJob(SysJob job);
}
ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/ISysJobLogService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,56 @@
package com.ruoyi.quartz.service;
import java.util.List;
import com.ruoyi.quartz.domain.SysJobLog;
/**
 * å®šæ—¶ä»»åŠ¡è°ƒåº¦æ—¥å¿—ä¿¡æ¯ä¿¡æ¯ æœåС层
 *
 * @author ruoyi
 */
public interface ISysJobLogService
{
    /**
     * èŽ·å–quartz调度器日志的计划任务
     *
     * @param jobLog è°ƒåº¦æ—¥å¿—信息
     * @return è°ƒåº¦ä»»åŠ¡æ—¥å¿—é›†åˆ
     */
    public List<SysJobLog> 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();
}
ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/ISysJobService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,102 @@
package com.ruoyi.quartz.service;
import java.util.List;
import org.quartz.SchedulerException;
import com.ruoyi.common.exception.job.TaskException;
import com.ruoyi.quartz.domain.SysJob;
/**
 * å®šæ—¶ä»»åŠ¡è°ƒåº¦ä¿¡æ¯ä¿¡æ¯ æœåС层
 *
 * @author ruoyi
 */
public interface ISysJobService
{
    /**
     * èŽ·å–quartz调度器的计划任务
     *
     * @param job è°ƒåº¦ä¿¡æ¯
     * @return è°ƒåº¦ä»»åŠ¡é›†åˆ
     */
    public List<SysJob> 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);
}
ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/impl/SysJobLogServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,87 @@
package com.ruoyi.quartz.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.quartz.domain.SysJobLog;
import com.ruoyi.quartz.mapper.SysJobLogMapper;
import com.ruoyi.quartz.service.ISysJobLogService;
/**
 * å®šæ—¶ä»»åŠ¡è°ƒåº¦æ—¥å¿—ä¿¡æ¯ æœåС层
 *
 * @author ruoyi
 */
@Service
public class SysJobLogServiceImpl implements ISysJobLogService
{
    @Autowired
    private SysJobLogMapper jobLogMapper;
    /**
     * èŽ·å–quartz调度器日志的计划任务
     *
     * @param jobLog è°ƒåº¦æ—¥å¿—信息
     * @return è°ƒåº¦ä»»åŠ¡æ—¥å¿—é›†åˆ
     */
    @Override
    public List<SysJobLog> selectJobLogList(SysJobLog jobLog)
    {
        return jobLogMapper.selectJobLogList(jobLog);
    }
    /**
     * é€šè¿‡è°ƒåº¦ä»»åŠ¡æ—¥å¿—ID查询调度信息
     *
     * @param jobLogId è°ƒåº¦ä»»åŠ¡æ—¥å¿—ID
     * @return è°ƒåº¦ä»»åŠ¡æ—¥å¿—å¯¹è±¡ä¿¡æ¯
     */
    @Override
    public SysJobLog selectJobLogById(Long jobLogId)
    {
        return jobLogMapper.selectJobLogById(jobLogId);
    }
    /**
     * æ–°å¢žä»»åŠ¡æ—¥å¿—
     *
     * @param jobLog è°ƒåº¦æ—¥å¿—信息
     */
    @Override
    public void addJobLog(SysJobLog jobLog)
    {
        jobLogMapper.insertJobLog(jobLog);
    }
    /**
     * æ‰¹é‡åˆ é™¤è°ƒåº¦æ—¥å¿—信息
     *
     * @param logIds éœ€è¦åˆ é™¤çš„æ•°æ®ID
     * @return ç»“æžœ
     */
    @Override
    public int deleteJobLogByIds(Long[] logIds)
    {
        return jobLogMapper.deleteJobLogByIds(logIds);
    }
    /**
     * åˆ é™¤ä»»åŠ¡æ—¥å¿—
     *
     * @param jobId è°ƒåº¦æ—¥å¿—ID
     */
    @Override
    public int deleteJobLogById(Long jobId)
    {
        return jobLogMapper.deleteJobLogById(jobId);
    }
    /**
     * æ¸…空任务日志
     */
    @Override
    public void cleanJobLog()
    {
        jobLogMapper.cleanJobLog();
    }
}
ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/impl/SysJobServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,254 @@
package com.ruoyi.quartz.service.impl;
import java.util.List;
import javax.annotation.PostConstruct;
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 com.ruoyi.common.constant.ScheduleConstants;
import com.ruoyi.common.exception.job.TaskException;
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;
/**
 * å®šæ—¶ä»»åŠ¡è°ƒåº¦ä¿¡æ¯ æœåС层
 *
 * @author ruoyi
 */
@Service
public class SysJobServiceImpl implements ISysJobService
{
    @Autowired
    private Scheduler scheduler;
    @Autowired
    private SysJobMapper jobMapper;
    /**
     * é¡¹ç›®å¯åŠ¨æ—¶ï¼Œåˆå§‹åŒ–å®šæ—¶å™¨ ä¸»è¦æ˜¯é˜²æ­¢æ‰‹åŠ¨ä¿®æ”¹æ•°æ®åº“å¯¼è‡´æœªåŒæ­¥åˆ°å®šæ—¶ä»»åŠ¡å¤„ç†ï¼ˆæ³¨ï¼šä¸èƒ½æ‰‹åŠ¨ä¿®æ”¹æ•°æ®åº“ID和任务组名,否则会导致脏数据)
     */
    @PostConstruct
    public void init() throws SchedulerException, TaskException
    {
        scheduler.clear();
        List<SysJob> jobList = jobMapper.selectJobAll();
        for (SysJob job : jobList)
        {
            ScheduleUtils.createScheduleJob(scheduler, job);
        }
    }
    /**
     * èŽ·å–quartz调度器的计划任务列表
     *
     * @param job è°ƒåº¦ä¿¡æ¯
     * @return
     */
    @Override
    public List<SysJob> selectJobList(SysJob job)
    {
        return jobMapper.selectJobList(job);
    }
    /**
     * é€šè¿‡è°ƒåº¦ä»»åŠ¡ID查询调度信息
     *
     * @param jobId è°ƒåº¦ä»»åŠ¡ID
     * @return è°ƒåº¦ä»»åŠ¡å¯¹è±¡ä¿¡æ¯
     */
    @Override
    public SysJob selectJobById(Long jobId)
    {
        return jobMapper.selectJobById(jobId);
    }
    /**
     * æš‚停任务
     *
     * @param job è°ƒåº¦ä¿¡æ¯
     */
    @Override
    @Transactional
    public int pauseJob(SysJob job) throws SchedulerException
    {
        Long jobId = job.getJobId();
        String jobGroup = job.getJobGroup();
        job.setStatus(ScheduleConstants.Status.PAUSE.getValue());
        int rows = jobMapper.updateJob(job);
        if (rows > 0)
        {
            scheduler.pauseJob(ScheduleUtils.getJobKey(jobId, jobGroup));
        }
        return rows;
    }
    /**
     * æ¢å¤ä»»åŠ¡
     *
     * @param job è°ƒåº¦ä¿¡æ¯
     */
    @Override
    @Transactional
    public int resumeJob(SysJob job) throws SchedulerException
    {
        Long jobId = job.getJobId();
        String jobGroup = job.getJobGroup();
        job.setStatus(ScheduleConstants.Status.NORMAL.getValue());
        int rows = jobMapper.updateJob(job);
        if (rows > 0)
        {
            scheduler.resumeJob(ScheduleUtils.getJobKey(jobId, jobGroup));
        }
        return rows;
    }
    /**
     * åˆ é™¤ä»»åŠ¡åŽï¼Œæ‰€å¯¹åº”çš„trigger也将被删除
     *
     * @param job è°ƒåº¦ä¿¡æ¯
     */
    @Override
    @Transactional
    public int deleteJob(SysJob job) throws SchedulerException
    {
        Long jobId = job.getJobId();
        String jobGroup = job.getJobGroup();
        int rows = jobMapper.deleteJobById(jobId);
        if (rows > 0)
        {
            scheduler.deleteJob(ScheduleUtils.getJobKey(jobId, jobGroup));
        }
        return rows;
    }
    /**
     * æ‰¹é‡åˆ é™¤è°ƒåº¦ä¿¡æ¯
     *
     * @param jobIds éœ€è¦åˆ é™¤çš„任务ID
     * @return ç»“æžœ
     */
    @Override
    @Transactional
    public void deleteJobByIds(Long[] jobIds) throws SchedulerException
    {
        for (Long jobId : jobIds)
        {
            SysJob job = jobMapper.selectJobById(jobId);
            deleteJob(job);
        }
    }
    /**
     * ä»»åŠ¡è°ƒåº¦çŠ¶æ€ä¿®æ”¹
     *
     * @param job è°ƒåº¦ä¿¡æ¯
     */
    @Override
    @Transactional
    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
    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
    public int insertJob(SysJob job) throws SchedulerException, TaskException
    {
        job.setStatus(ScheduleConstants.Status.PAUSE.getValue());
        int rows = jobMapper.insertJob(job);
        if (rows > 0)
        {
            ScheduleUtils.createScheduleJob(scheduler, job);
        }
        return rows;
    }
    /**
     * æ›´æ–°ä»»åŠ¡çš„æ—¶é—´è¡¨è¾¾å¼
     *
     * @param job è°ƒåº¦ä¿¡æ¯
     */
    @Override
    @Transactional
    public int updateJob(SysJob job) throws SchedulerException, TaskException
    {
        SysJob properties = selectJobById(job.getJobId());
        int rows = jobMapper.updateJob(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);
    }
}
ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,28 @@
package com.ruoyi.quartz.task;
import org.springframework.stereotype.Component;
import com.ruoyi.common.utils.StringUtils;
/**
 * å®šæ—¶ä»»åŠ¡è°ƒåº¦æµ‹è¯•
 *
 * @author ruoyi
 */
@Component("ryTask")
public class RyTask
{
    public void ryMultipleParams(String s, Boolean b, Long l, Double d, Integer i)
    {
        System.out.println(StringUtils.format("执行多参方法: å­—符串类型{},布尔类型{},长整型{},浮点型{},整形{}", s, b, l, d, i));
    }
    public void ryParams(String params)
    {
        System.out.println("执行有参方法:" + params);
    }
    public void ryNoParams()
    {
        System.out.println("执行无参方法");
    }
}
ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/AbstractQuartzJob.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,107 @@
package com.ruoyi.quartz.util;
import java.util.Date;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.ScheduleConstants;
import com.ruoyi.common.utils.ExceptionUtil;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
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;
/**
 * æŠ½è±¡quartz调用
 *
 * @author ruoyi
 */
public abstract class AbstractQuartzJob implements Job
{
    private static final Logger log = LoggerFactory.getLogger(AbstractQuartzJob.class);
    /**
     * çº¿ç¨‹æœ¬åœ°å˜é‡
     */
    private static ThreadLocal<Date> threadLocal = new ThreadLocal<>();
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException
    {
        SysJob sysJob = new SysJob();
        BeanUtils.copyBeanProp(sysJob, context.getMergedJobDataMap().get(ScheduleConstants.TASK_PROPERTIES));
        try
        {
            before(context, sysJob);
            if (sysJob != null)
            {
                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 sysScheduleJob ç³»ç»Ÿè®¡åˆ’任务
     */
    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.getExceptionMessage(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;
}
ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/CronUtils.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,63 @@
package com.ruoyi.quartz.util;
import java.text.ParseException;
import java.util.Date;
import org.quartz.CronExpression;
/**
 * cron表达式工具类
 *
 * @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());
        }
    }
}
ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/JobInvokeUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,182 @@
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;
/**
 * ä»»åŠ¡æ‰§è¡Œå·¥å…·
 *
 * @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<Object[]> 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<Object[]> 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<Object[]> getMethodParams(String invokeTarget)
    {
        String methodStr = StringUtils.substringBetween(invokeTarget, "(", ")");
        if (StringUtils.isEmpty(methodStr))
        {
            return null;
        }
        String[] methodParams = methodStr.split(",");
        List<Object[]> 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<Object[]> 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<Object[]> methodParams)
    {
        Object[] classs = new Object[methodParams.size()];
        int index = 0;
        for (Object[] os : methodParams)
        {
            classs[index] = (Object) os[0];
            index++;
        }
        return classs;
    }
}
ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/QuartzDisallowConcurrentExecution.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,21 @@
package com.ruoyi.quartz.util;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionContext;
import com.ruoyi.quartz.domain.SysJob;
/**
 * å®šæ—¶ä»»åŠ¡å¤„ç†ï¼ˆç¦æ­¢å¹¶å‘æ‰§è¡Œï¼‰
 *
 * @author ruoyi
 *
 */
@DisallowConcurrentExecution
public class QuartzDisallowConcurrentExecution extends AbstractQuartzJob
{
    @Override
    protected void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception
    {
        JobInvokeUtil.invokeMethod(sysJob);
    }
}
ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/QuartzJobExecution.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,19 @@
package com.ruoyi.quartz.util;
import org.quartz.JobExecutionContext;
import com.ruoyi.quartz.domain.SysJob;
/**
 * å®šæ—¶ä»»åŠ¡å¤„ç†ï¼ˆå…è®¸å¹¶å‘æ‰§è¡Œï¼‰
 *
 * @author ruoyi
 *
 */
public class QuartzJobExecution extends AbstractQuartzJob
{
    @Override
    protected void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception
    {
        JobInvokeUtil.invokeMethod(sysJob);
    }
}
ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/ScheduleUtils.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,113 @@
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;
/**
 * å®šæ—¶ä»»åŠ¡å·¥å…·ç±»
 *
 * @author ruoyi
 *
 */
public class ScheduleUtils
{
    /**
     * å¾—到quartz任务类
     *
     * @param sysJob æ‰§è¡Œè®¡åˆ’
     * @return å…·ä½“执行任务类
     */
    private static Class<? extends Job> 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<? extends Job> 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);
        }
    }
}
ruoyi-quartz/src/main/resources/mapper/quartz/SysJobLogMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,93 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.quartz.mapper.SysJobLogMapper">
    <resultMap type="SysJobLog" id="SysJobLogResult">
        <id     property="jobLogId"       column="job_log_id"      />
        <result property="jobName"        column="job_name"        />
        <result property="jobGroup"       column="job_group"       />
        <result property="invokeTarget"   column="invoke_target"   />
        <result property="jobMessage"     column="job_message"     />
        <result property="status"         column="status"          />
        <result property="exceptionInfo"  column="exception_info"  />
        <result property="createTime"     column="create_time"     />
    </resultMap>
    <sql id="selectJobLogVo">
        select job_log_id, job_name, job_group, invoke_target, job_message, status, exception_info, create_time
        from sys_job_log
    </sql>
    <select id="selectJobLogList" parameterType="SysJobLog" resultMap="SysJobLogResult">
        <include refid="selectJobLogVo"/>
        <where>
            <if test="jobName != null and jobName != ''">
                AND job_name like concat('%', #{jobName}, '%')
            </if>
            <if test="jobGroup != null and jobGroup != ''">
                AND job_group = #{jobGroup}
            </if>
            <if test="status != null and status != ''">
                AND status = #{status}
            </if>
            <if test="invokeTarget != null and invokeTarget != ''">
                AND invoke_target like concat('%', #{invokeTarget}, '%')
            </if>
            <if test="beginTime != null and beginTime != ''"><!-- å¼€å§‹æ—¶é—´æ£€ç´¢ -->
                and date_format(create_time,'%y%m%d') &gt;= date_format(#{beginTime},'%y%m%d')
            </if>
            <if test="endTime != null and endTime != ''"><!-- ç»“束时间检索 -->
                and date_format(create_time,'%y%m%d') &lt;= date_format(#{endTime},'%y%m%d')
            </if>
        </where>
    </select>
    <select id="selectJobLogAll" resultMap="SysJobLogResult">
        <include refid="selectJobLogVo"/>
    </select>
    <select id="selectJobLogById" parameterType="Long" resultMap="SysJobLogResult">
        <include refid="selectJobLogVo"/>
        where job_log_id = #{jobLogId}
    </select>
    <delete id="deleteJobLogById" parameterType="Long">
         delete from sys_job_log where job_log_id = #{jobLogId}
     </delete>
     <delete id="deleteJobLogByIds" parameterType="Long">
         delete from sys_job_log where job_log_id in
         <foreach collection="array" item="jobLogId" open="(" separator="," close=")">
             #{jobLogId}
        </foreach>
     </delete>
     <update id="cleanJobLog">
        truncate table sys_job_log
    </update>
     <insert id="insertJobLog" parameterType="SysJobLog">
         insert into sys_job_log(
             <if test="jobLogId != null and jobLogId != 0">job_log_id,</if>
             <if test="jobName != null and jobName != ''">job_name,</if>
             <if test="jobGroup != null and jobGroup != ''">job_group,</if>
             <if test="invokeTarget != null and invokeTarget != ''">invoke_target,</if>
             <if test="jobMessage != null and jobMessage != ''">job_message,</if>
             <if test="status != null and status != ''">status,</if>
             <if test="exceptionInfo != null and exceptionInfo != ''">exception_info,</if>
             create_time
         )values(
             <if test="jobLogId != null and jobLogId != 0">#{jobLogId},</if>
             <if test="jobName != null and jobName != ''">#{jobName},</if>
             <if test="jobGroup != null and jobGroup != ''">#{jobGroup},</if>
             <if test="invokeTarget != null and invokeTarget != ''">#{invokeTarget},</if>
             <if test="jobMessage != null and jobMessage != ''">#{jobMessage},</if>
             <if test="status != null and status != ''">#{status},</if>
             <if test="exceptionInfo != null and exceptionInfo != ''">#{exceptionInfo},</if>
             sysdate()
         )
    </insert>
</mapper>
ruoyi-quartz/src/main/resources/mapper/quartz/SysJobMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,111 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.quartz.mapper.SysJobMapper">
    <resultMap type="SysJob" id="SysJobResult">
        <id     property="jobId"          column="job_id"          />
        <result property="jobName"        column="job_name"        />
        <result property="jobGroup"       column="job_group"       />
        <result property="invokeTarget"   column="invoke_target"   />
        <result property="cronExpression" column="cron_expression" />
        <result property="misfirePolicy"  column="misfire_policy"  />
        <result property="concurrent"     column="concurrent"      />
        <result property="status"         column="status"          />
        <result property="createBy"       column="create_by"       />
        <result property="createTime"     column="create_time"     />
        <result property="updateBy"       column="update_by"       />
        <result property="updateTime"     column="update_time"     />
        <result property="remark"         column="remark"          />
    </resultMap>
    <sql id="selectJobVo">
        select job_id, job_name, job_group, invoke_target, cron_expression, misfire_policy, concurrent, status, create_by, create_time, remark
        from sys_job
    </sql>
    <select id="selectJobList" parameterType="SysJob" resultMap="SysJobResult">
        <include refid="selectJobVo"/>
        <where>
            <if test="jobName != null and jobName != ''">
                AND job_name like concat('%', #{jobName}, '%')
            </if>
            <if test="jobGroup != null and jobGroup != ''">
                AND job_group = #{jobGroup}
            </if>
            <if test="status != null and status != ''">
                AND status = #{status}
            </if>
            <if test="invokeTarget != null and invokeTarget != ''">
                AND invoke_target like concat('%', #{invokeTarget}, '%')
            </if>
        </where>
    </select>
    <select id="selectJobAll" resultMap="SysJobResult">
        <include refid="selectJobVo"/>
    </select>
    <select id="selectJobById" parameterType="Long" resultMap="SysJobResult">
        <include refid="selectJobVo"/>
        where job_id = #{jobId}
    </select>
    <delete id="deleteJobById" parameterType="Long">
         delete from sys_job where job_id = #{jobId}
     </delete>
     <delete id="deleteJobByIds" parameterType="Long">
         delete from sys_job where job_id in
         <foreach collection="array" item="jobId" open="(" separator="," close=")">
             #{jobId}
        </foreach>
     </delete>
     <update id="updateJob" parameterType="SysJob">
         update sys_job
         <set>
             <if test="jobName != null and jobName != ''">job_name = #{jobName},</if>
             <if test="jobGroup != null and jobGroup != ''">job_group = #{jobGroup},</if>
             <if test="invokeTarget != null and invokeTarget != ''">invoke_target = #{invokeTarget},</if>
             <if test="cronExpression != null and cronExpression != ''">cron_expression = #{cronExpression},</if>
             <if test="misfirePolicy != null and misfirePolicy != ''">misfire_policy = #{misfirePolicy},</if>
             <if test="concurrent != null and concurrent != ''">concurrent = #{concurrent},</if>
             <if test="status !=null">status = #{status},</if>
             <if test="remark != null and remark != ''">remark = #{remark},</if>
             <if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
             update_time = sysdate()
         </set>
         where job_id = #{jobId}
    </update>
     <insert id="insertJob" parameterType="SysJob" useGeneratedKeys="true" keyProperty="jobId">
         insert into sys_job(
             <if test="jobId != null and jobId != 0">job_id,</if>
             <if test="jobName != null and jobName != ''">job_name,</if>
             <if test="jobGroup != null and jobGroup != ''">job_group,</if>
             <if test="invokeTarget != null and invokeTarget != ''">invoke_target,</if>
             <if test="cronExpression != null and cronExpression != ''">cron_expression,</if>
             <if test="misfirePolicy != null and misfirePolicy != ''">misfire_policy,</if>
             <if test="concurrent != null and concurrent != ''">concurrent,</if>
             <if test="status != null and status != ''">status,</if>
             <if test="remark != null and remark != ''">remark,</if>
             <if test="createBy != null and createBy != ''">create_by,</if>
             create_time
         )values(
             <if test="jobId != null and jobId != 0">#{jobId},</if>
             <if test="jobName != null and jobName != ''">#{jobName},</if>
             <if test="jobGroup != null and jobGroup != ''">#{jobGroup},</if>
             <if test="invokeTarget != null and invokeTarget != ''">#{invokeTarget},</if>
             <if test="cronExpression != null and cronExpression != ''">#{cronExpression},</if>
             <if test="misfirePolicy != null and misfirePolicy != ''">#{misfirePolicy},</if>
             <if test="concurrent != null and concurrent != ''">#{concurrent},</if>
             <if test="status != null and status != ''">#{status},</if>
             <if test="remark != null and remark != ''">#{remark},</if>
             <if test="createBy != null and createBy != ''">#{createBy},</if>
             sysdate()
         )
    </insert>
</mapper>
ruoyi-system/pom.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>ruoyi</artifactId>
        <groupId>com.ruoyi</groupId>
        <version>3.0.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>ruoyi-system</artifactId>
    <description>
        system系统模块
    </description>
    <dependencies>
        <!-- é€šç”¨å·¥å…·-->
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>ruoyi-common</artifactId>
        </dependency>
    </dependencies>
</project>
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysConfig.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,111 @@
package com.ruoyi.system.domain;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.annotation.Excel.ColumnType;
import com.ruoyi.common.core.domain.BaseEntity;
/**
 * å‚数配置表 sys_config
 *
 * @author ruoyi
 */
public class SysConfig extends BaseEntity
{
    private static final long serialVersionUID = 1L;
    /** å‚数主键 */
    @Excel(name = "参数主键", cellType = ColumnType.NUMERIC)
    private Long configId;
    /** å‚数名称 */
    @Excel(name = "参数名称")
    private String configName;
    /** å‚数键名 */
    @Excel(name = "参数键名")
    private String configKey;
    /** å‚数键值 */
    @Excel(name = "参数键值")
    private String configValue;
    /** ç³»ç»Ÿå†…置(Y是 N否) */
    @Excel(name = "系统内置", readConverterExp = "Y=是,N=否")
    private String configType;
    public Long getConfigId()
    {
        return configId;
    }
    public void setConfigId(Long configId)
    {
        this.configId = configId;
    }
    @NotBlank(message = "参数名称不能为空")
    @Size(min = 0, max = 100, message = "参数名称不能超过100个字符")
    public String getConfigName()
    {
        return configName;
    }
    public void setConfigName(String configName)
    {
        this.configName = configName;
    }
    @NotBlank(message = "参数键名长度不能为空")
    @Size(min = 0, max = 100, message = "参数键名长度不能超过100个字符")
    public String getConfigKey()
    {
        return configKey;
    }
    public void setConfigKey(String configKey)
    {
        this.configKey = configKey;
    }
    @NotBlank(message = "参数键值不能为空")
    @Size(min = 0, max = 500, message = "参数键值长度不能超过500个字符")
    public String getConfigValue()
    {
        return configValue;
    }
    public void setConfigValue(String configValue)
    {
        this.configValue = configValue;
    }
    public String getConfigType()
    {
        return configType;
    }
    public void setConfigType(String configType)
    {
        this.configType = configType;
    }
    @Override
    public String toString() {
        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
            .append("configId", getConfigId())
            .append("configName", getConfigName())
            .append("configKey", getConfigKey())
            .append("configValue", getConfigValue())
            .append("configType", getConfigType())
            .append("createBy", getCreateBy())
            .append("createTime", getCreateTime())
            .append("updateBy", getUpdateBy())
            .append("updateTime", getUpdateTime())
            .append("remark", getRemark())
            .toString();
    }
}
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysLogininfor.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,144 @@
package com.ruoyi.system.domain;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.annotation.Excel.ColumnType;
import com.ruoyi.common.core.domain.BaseEntity;
/**
 * ç³»ç»Ÿè®¿é—®è®°å½•表 sys_logininfor
 *
 * @author ruoyi
 */
public class SysLogininfor extends BaseEntity
{
    private static final long serialVersionUID = 1L;
    /** ID */
    @Excel(name = "序号", cellType = ColumnType.NUMERIC)
    private Long infoId;
    /** ç”¨æˆ·è´¦å· */
    @Excel(name = "用户账号")
    private String userName;
    /** ç™»å½•状态 0成功 1失败 */
    @Excel(name = "登录状态", readConverterExp = "0=成功,1=失败")
    private String status;
    /** ç™»å½•IP地址 */
    @Excel(name = "登录地址")
    private String ipaddr;
    /** ç™»å½•地点 */
    @Excel(name = "登录地点")
    private String loginLocation;
    /** æµè§ˆå™¨ç±»åž‹ */
    @Excel(name = "浏览器")
    private String browser;
    /** æ“ä½œç³»ç»Ÿ */
    @Excel(name = "操作系统")
    private String os;
    /** æç¤ºæ¶ˆæ¯ */
    @Excel(name = "提示消息")
    private String msg;
    /** è®¿é—®æ—¶é—´ */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @Excel(name = "访问时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
    private Date loginTime;
    public Long getInfoId()
    {
        return infoId;
    }
    public void setInfoId(Long infoId)
    {
        this.infoId = infoId;
    }
    public String getUserName()
    {
        return userName;
    }
    public void setUserName(String userName)
    {
        this.userName = userName;
    }
    public String getStatus()
    {
        return status;
    }
    public void setStatus(String status)
    {
        this.status = status;
    }
    public String getIpaddr()
    {
        return ipaddr;
    }
    public void setIpaddr(String ipaddr)
    {
        this.ipaddr = ipaddr;
    }
    public String getLoginLocation()
    {
        return loginLocation;
    }
    public void setLoginLocation(String loginLocation)
    {
        this.loginLocation = loginLocation;
    }
    public String getBrowser()
    {
        return browser;
    }
    public void setBrowser(String browser)
    {
        this.browser = browser;
    }
    public String getOs()
    {
        return os;
    }
    public void setOs(String os)
    {
        this.os = os;
    }
    public String getMsg()
    {
        return msg;
    }
    public void setMsg(String msg)
    {
        this.msg = msg;
    }
    public Date getLoginTime()
    {
        return loginTime;
    }
    public void setLoginTime(Date loginTime)
    {
        this.loginTime = loginTime;
    }
}
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysNotice.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,100 @@
package com.ruoyi.system.domain;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.core.domain.BaseEntity;
/**
 * é€šçŸ¥å…¬å‘Šè¡¨ sys_notice
 *
 * @author ruoyi
 */
public class SysNotice extends BaseEntity
{
    private static final long serialVersionUID = 1L;
    /** å…¬å‘ŠID */
    private Long noticeId;
    /** å…¬å‘Šæ ‡é¢˜ */
    private String noticeTitle;
    /** å…¬å‘Šç±»åž‹ï¼ˆ1通知 2公告) */
    private String noticeType;
    /** å…¬å‘Šå†…容 */
    private String noticeContent;
    /** å…¬å‘ŠçŠ¶æ€ï¼ˆ0正常 1关闭) */
    private String status;
    public Long getNoticeId()
    {
        return noticeId;
    }
    public void setNoticeId(Long noticeId)
    {
        this.noticeId = noticeId;
    }
    public void setNoticeTitle(String noticeTitle)
    {
        this.noticeTitle = noticeTitle;
    }
    @NotBlank(message = "公告标题不能为空")
    @Size(min = 0, max = 50, message = "公告标题不能超过50个字符")
    public String getNoticeTitle()
    {
        return noticeTitle;
    }
    public void setNoticeType(String noticeType)
    {
        this.noticeType = noticeType;
    }
    public String getNoticeType()
    {
        return noticeType;
    }
    public void setNoticeContent(String noticeContent)
    {
        this.noticeContent = noticeContent;
    }
    public String getNoticeContent()
    {
        return noticeContent;
    }
    public void setStatus(String status)
    {
        this.status = status;
    }
    public String getStatus()
    {
        return status;
    }
    @Override
    public String toString() {
        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
            .append("noticeId", getNoticeId())
            .append("noticeTitle", getNoticeTitle())
            .append("noticeType", getNoticeType())
            .append("noticeContent", getNoticeContent())
            .append("status", getStatus())
            .append("createBy", getCreateBy())
            .append("createTime", getCreateTime())
            .append("updateBy", getUpdateBy())
            .append("updateTime", getUpdateTime())
            .append("remark", getRemark())
            .toString();
    }
}
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysOperLog.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,255 @@
package com.ruoyi.system.domain;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.annotation.Excel.ColumnType;
import com.ruoyi.common.core.domain.BaseEntity;
/**
 * æ“ä½œæ—¥å¿—记录表 oper_log
 *
 * @author ruoyi
 */
public class SysOperLog extends BaseEntity
{
    private static final long serialVersionUID = 1L;
    /** æ—¥å¿—主键 */
    @Excel(name = "操作序号", cellType = ColumnType.NUMERIC)
    private Long operId;
    /** æ“ä½œæ¨¡å— */
    @Excel(name = "操作模块")
    private String title;
    /** ä¸šåŠ¡ç±»åž‹ï¼ˆ0其它 1新增 2修改 3删除) */
    @Excel(name = "业务类型", readConverterExp = "0=其它,1=新增,2=修改,3=删除,4=授权,5=导出,6=导入,7=强退,8=生成代码,9=清空数据")
    private Integer businessType;
    /** ä¸šåŠ¡ç±»åž‹æ•°ç»„ */
    private Integer[] businessTypes;
    /** è¯·æ±‚方法 */
    @Excel(name = "请求方法")
    private String method;
    /** è¯·æ±‚方式 */
    @Excel(name = "请求方式")
    private String requestMethod;
    /** æ“ä½œç±»åˆ«ï¼ˆ0其它 1后台用户 2手机端用户) */
    @Excel(name = "操作类别", readConverterExp = "0=其它,1=后台用户,2=手机端用户")
    private Integer operatorType;
    /** æ“ä½œäººå‘˜ */
    @Excel(name = "操作人员")
    private String operName;
    /** éƒ¨é—¨åç§° */
    @Excel(name = "部门名称")
    private String deptName;
    /** è¯·æ±‚url */
    @Excel(name = "请求地址")
    private String operUrl;
    /** æ“ä½œåœ°å€ */
    @Excel(name = "操作地址")
    private String operIp;
    /** æ“ä½œåœ°ç‚¹ */
    @Excel(name = "操作地点")
    private String operLocation;
    /** è¯·æ±‚参数 */
    @Excel(name = "请求参数")
    private String operParam;
    /** è¿”回参数 */
    @Excel(name = "返回参数")
    private String jsonResult;
    /** æ“ä½œçŠ¶æ€ï¼ˆ0正常 1异常) */
    @Excel(name = "状态", readConverterExp = "0=正常,1=异常")
    private Integer status;
    /** é”™è¯¯æ¶ˆæ¯ */
    @Excel(name = "错误消息")
    private String errorMsg;
    /** æ“ä½œæ—¶é—´ */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @Excel(name = "操作时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
    private Date operTime;
    public Long getOperId()
    {
        return operId;
    }
    public void setOperId(Long operId)
    {
        this.operId = operId;
    }
    public String getTitle()
    {
        return title;
    }
    public void setTitle(String title)
    {
        this.title = title;
    }
    public Integer getBusinessType()
    {
        return businessType;
    }
    public void setBusinessType(Integer businessType)
    {
        this.businessType = businessType;
    }
    public Integer[] getBusinessTypes()
    {
        return businessTypes;
    }
    public void setBusinessTypes(Integer[] businessTypes)
    {
        this.businessTypes = businessTypes;
    }
    public String getMethod()
    {
        return method;
    }
    public void setMethod(String method)
    {
        this.method = method;
    }
    public String getRequestMethod()
    {
        return requestMethod;
    }
    public void setRequestMethod(String requestMethod)
    {
        this.requestMethod = requestMethod;
    }
    public Integer getOperatorType()
    {
        return operatorType;
    }
    public void setOperatorType(Integer operatorType)
    {
        this.operatorType = operatorType;
    }
    public String getOperName()
    {
        return operName;
    }
    public void setOperName(String operName)
    {
        this.operName = operName;
    }
    public String getDeptName()
    {
        return deptName;
    }
    public void setDeptName(String deptName)
    {
        this.deptName = deptName;
    }
    public String getOperUrl()
    {
        return operUrl;
    }
    public void setOperUrl(String operUrl)
    {
        this.operUrl = operUrl;
    }
    public String getOperIp()
    {
        return operIp;
    }
    public void setOperIp(String operIp)
    {
        this.operIp = operIp;
    }
    public String getOperLocation()
    {
        return operLocation;
    }
    public void setOperLocation(String operLocation)
    {
        this.operLocation = operLocation;
    }
    public String getOperParam()
    {
        return operParam;
    }
    public void setOperParam(String operParam)
    {
        this.operParam = operParam;
    }
    public String getJsonResult()
    {
        return jsonResult;
    }
    public void setJsonResult(String jsonResult)
    {
        this.jsonResult = jsonResult;
    }
    public Integer getStatus()
    {
        return status;
    }
    public void setStatus(Integer status)
    {
        this.status = status;
    }
    public String getErrorMsg()
    {
        return errorMsg;
    }
    public void setErrorMsg(String errorMsg)
    {
        this.errorMsg = errorMsg;
    }
    public Date getOperTime()
    {
        return operTime;
    }
    public void setOperTime(Date operTime)
    {
        this.operTime = operTime;
    }
}
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysPost.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,123 @@
package com.ruoyi.system.domain;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.annotation.Excel.ColumnType;
import com.ruoyi.common.core.domain.BaseEntity;
/**
 * å²—位表 sys_post
 *
 * @author ruoyi
 */
public class SysPost extends BaseEntity
{
    private static final long serialVersionUID = 1L;
    /** å²—位序号 */
    @Excel(name = "岗位序号", cellType = ColumnType.NUMERIC)
    private Long postId;
    /** å²—位编码 */
    @Excel(name = "岗位编码")
    private String postCode;
    /** å²—位名称 */
    @Excel(name = "岗位名称")
    private String postName;
    /** å²—位排序 */
    @Excel(name = "岗位排序")
    private String postSort;
    /** çŠ¶æ€ï¼ˆ0正常 1停用) */
    @Excel(name = "状态", readConverterExp = "0=正常,1=停用")
    private String status;
    /** ç”¨æˆ·æ˜¯å¦å­˜åœ¨æ­¤å²—位标识 é»˜è®¤ä¸å­˜åœ¨ */
    private boolean flag = false;
    public Long getPostId()
    {
        return postId;
    }
    public void setPostId(Long postId)
    {
        this.postId = postId;
    }
    @NotBlank(message = "岗位编码不能为空")
    @Size(min = 0, max = 64, message = "岗位编码长度不能超过64个字符")
    public String getPostCode()
    {
        return postCode;
    }
    public void setPostCode(String postCode)
    {
        this.postCode = postCode;
    }
    @NotBlank(message = "岗位名称不能为空")
    @Size(min = 0, max = 50, message = "岗位名称长度不能超过50个字符")
    public String getPostName()
    {
        return postName;
    }
    public void setPostName(String postName)
    {
        this.postName = postName;
    }
    @NotBlank(message = "显示顺序不能为空")
    public String getPostSort()
    {
        return postSort;
    }
    public void setPostSort(String postSort)
    {
        this.postSort = postSort;
    }
    public String getStatus()
    {
        return status;
    }
    public void setStatus(String status)
    {
        this.status = status;
    }
    public boolean isFlag()
    {
        return flag;
    }
    public void setFlag(boolean flag)
    {
        this.flag = flag;
    }
    @Override
    public String toString() {
        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
            .append("postId", getPostId())
            .append("postCode", getPostCode())
            .append("postName", getPostName())
            .append("postSort", getPostSort())
            .append("status", getStatus())
            .append("createBy", getCreateBy())
            .append("createTime", getCreateTime())
            .append("updateBy", getUpdateBy())
            .append("updateTime", getUpdateTime())
            .append("remark", getRemark())
            .toString();
    }
}
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysRoleDept.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,46 @@
package com.ruoyi.system.domain;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
/**
 * è§’色和部门关联 sys_role_dept
 *
 * @author ruoyi
 */
public class SysRoleDept
{
    /** è§’色ID */
    private Long roleId;
    /** éƒ¨é—¨ID */
    private Long deptId;
    public Long getRoleId()
    {
        return roleId;
    }
    public void setRoleId(Long roleId)
    {
        this.roleId = roleId;
    }
    public Long getDeptId()
    {
        return deptId;
    }
    public void setDeptId(Long deptId)
    {
        this.deptId = deptId;
    }
    @Override
    public String toString() {
        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
            .append("roleId", getRoleId())
            .append("deptId", getDeptId())
            .toString();
    }
}
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysRoleMenu.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,46 @@
package com.ruoyi.system.domain;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
/**
 * è§’色和菜单关联 sys_role_menu
 *
 * @author ruoyi
 */
public class SysRoleMenu
{
    /** è§’色ID */
    private Long roleId;
    /** èœå•ID */
    private Long menuId;
    public Long getRoleId()
    {
        return roleId;
    }
    public void setRoleId(Long roleId)
    {
        this.roleId = roleId;
    }
    public Long getMenuId()
    {
        return menuId;
    }
    public void setMenuId(Long menuId)
    {
        this.menuId = menuId;
    }
    @Override
    public String toString() {
        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
            .append("roleId", getRoleId())
            .append("menuId", getMenuId())
            .toString();
    }
}
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUserOnline.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,113 @@
package com.ruoyi.system.domain;
/**
 * å½“前在线会话
 *
 * @author ruoyi
 */
public class SysUserOnline
{
    /** ä¼šè¯ç¼–号 */
    private String tokenId;
    /** éƒ¨é—¨åç§° */
    private String deptName;
    /** ç”¨æˆ·åç§° */
    private String userName;
    /** ç™»å½•IP地址 */
    private String ipaddr;
    /** ç™»å½•地址 */
    private String loginLocation;
    /** æµè§ˆå™¨ç±»åž‹ */
    private String browser;
    /** æ“ä½œç³»ç»Ÿ */
    private String os;
    /** ç™»å½•æ—¶é—´ */
    private Long loginTime;
    public String getTokenId()
    {
        return tokenId;
    }
    public void setTokenId(String tokenId)
    {
        this.tokenId = tokenId;
    }
    public String getDeptName()
    {
        return deptName;
    }
    public void setDeptName(String deptName)
    {
        this.deptName = deptName;
    }
    public String getUserName()
    {
        return userName;
    }
    public void setUserName(String userName)
    {
        this.userName = userName;
    }
    public String getIpaddr()
    {
        return ipaddr;
    }
    public void setIpaddr(String ipaddr)
    {
        this.ipaddr = ipaddr;
    }
    public String getLoginLocation()
    {
        return loginLocation;
    }
    public void setLoginLocation(String loginLocation)
    {
        this.loginLocation = loginLocation;
    }
    public String getBrowser()
    {
        return browser;
    }
    public void setBrowser(String browser)
    {
        this.browser = browser;
    }
    public String getOs()
    {
        return os;
    }
    public void setOs(String os)
    {
        this.os = os;
    }
    public Long getLoginTime()
    {
        return loginTime;
    }
    public void setLoginTime(Long loginTime)
    {
        this.loginTime = loginTime;
    }
}
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUserPost.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,46 @@
package com.ruoyi.system.domain;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
/**
 * ç”¨æˆ·å’Œå²—位关联 sys_user_post
 *
 * @author ruoyi
 */
public class SysUserPost
{
    /** ç”¨æˆ·ID */
    private Long userId;
    /** å²—位ID */
    private Long postId;
    public Long getUserId()
    {
        return userId;
    }
    public void setUserId(Long userId)
    {
        this.userId = userId;
    }
    public Long getPostId()
    {
        return postId;
    }
    public void setPostId(Long postId)
    {
        this.postId = postId;
    }
    @Override
    public String toString() {
        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
            .append("userId", getUserId())
            .append("postId", getPostId())
            .toString();
    }
}
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUserRole.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,46 @@
package com.ruoyi.system.domain;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
/**
 * ç”¨æˆ·å’Œè§’色关联 sys_user_role
 *
 * @author ruoyi
 */
public class SysUserRole
{
    /** ç”¨æˆ·ID */
    private Long userId;
    /** è§’色ID */
    private Long roleId;
    public Long getUserId()
    {
        return userId;
    }
    public void setUserId(Long userId)
    {
        this.userId = userId;
    }
    public Long getRoleId()
    {
        return roleId;
    }
    public void setRoleId(Long roleId)
    {
        this.roleId = roleId;
    }
    @Override
    public String toString() {
        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
            .append("userId", getUserId())
            .append("roleId", getRoleId())
            .toString();
    }
}
ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/MetaVo.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,49 @@
package com.ruoyi.system.domain.vo;
/**
 * è·¯ç”±æ˜¾ç¤ºä¿¡æ¯
 *
 * @author ruoyi
 */
public class MetaVo
{
    /**
     * è®¾ç½®è¯¥è·¯ç”±åœ¨ä¾§è¾¹æ å’Œé¢åŒ…屑中展示的名字
     */
    private String title;
    /**
     * è®¾ç½®è¯¥è·¯ç”±çš„图标,对应路径src/icons/svg
     */
    private String icon;
    public MetaVo()
    {
    }
    public MetaVo(String title, String icon)
    {
        this.title = title;
        this.icon = icon;
    }
    public String getTitle()
    {
        return title;
    }
    public void setTitle(String title)
    {
        this.title = title;
    }
    public String getIcon()
    {
        return icon;
    }
    public void setIcon(String icon)
    {
        this.icon = icon;
    }
}
ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/RouterVo.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,133 @@
package com.ruoyi.system.domain.vo;
import com.fasterxml.jackson.annotation.JsonInclude;
import java.util.List;
/**
 * è·¯ç”±é…ç½®ä¿¡æ¯
 *
 * @author ruoyi
 */
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class RouterVo
{
    /**
     * è·¯ç”±åå­—
     */
    private String name;
    /**
     * è·¯ç”±åœ°å€
     */
    private String path;
    /**
     * æ˜¯å¦éšè—è·¯ç”±ï¼Œå½“设置 true çš„æ—¶å€™è¯¥è·¯ç”±ä¸ä¼šå†ä¾§è¾¹æ å‡ºçް
     */
    private boolean hidden;
    /**
     * é‡å®šå‘地址,当设置 noRedirect çš„æ—¶å€™è¯¥è·¯ç”±åœ¨é¢åŒ…屑导航中不可被点击
     */
    private String redirect;
    /**
     * ç»„件地址
     */
    private String component;
    /**
     * å½“你一个路由下面的 children å£°æ˜Žçš„路由大于1个时,自动会变成嵌套的模式--如组件页面
     */
    private Boolean alwaysShow;
    /**
     * å…¶ä»–元素
     */
    private MetaVo meta;
    /**
     * å­è·¯ç”±
     */
    private List<RouterVo> children;
    public String getName()
    {
        return name;
    }
    public void setName(String name)
    {
        this.name = name;
    }
    public String getPath()
    {
        return path;
    }
    public void setPath(String path)
    {
        this.path = path;
    }
    public boolean getHidden()
    {
        return hidden;
    }
    public void setHidden(boolean hidden)
    {
        this.hidden = hidden;
    }
    public String getRedirect()
    {
        return redirect;
    }
    public void setRedirect(String redirect)
    {
        this.redirect = redirect;
    }
    public String getComponent()
    {
        return component;
    }
    public void setComponent(String component)
    {
        this.component = component;
    }
    public Boolean getAlwaysShow()
    {
        return alwaysShow;
    }
    public void setAlwaysShow(Boolean alwaysShow)
    {
        this.alwaysShow = alwaysShow;
    }
    public MetaVo getMeta()
    {
        return meta;
    }
    public void setMeta(MetaVo meta)
    {
        this.meta = meta;
    }
    public List<RouterVo> getChildren()
    {
        return children;
    }
    public void setChildren(List<RouterVo> children)
    {
        this.children = children;
    }
}
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysConfigMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,68 @@
package com.ruoyi.system.mapper;
import java.util.List;
import com.ruoyi.system.domain.SysConfig;
/**
 * å‚数配置 æ•°æ®å±‚
 *
 * @author ruoyi
 */
public interface SysConfigMapper
{
    /**
     * æŸ¥è¯¢å‚数配置信息
     *
     * @param config å‚数配置信息
     * @return å‚数配置信息
     */
    public SysConfig selectConfig(SysConfig config);
    /**
     * æŸ¥è¯¢å‚数配置列表
     *
     * @param config å‚数配置信息
     * @return å‚数配置集合
     */
    public List<SysConfig> selectConfigList(SysConfig config);
    /**
     * æ ¹æ®é”®åæŸ¥è¯¢å‚数配置信息
     *
     * @param configKey å‚数键名
     * @return å‚数配置信息
     */
    public SysConfig checkConfigKeyUnique(String configKey);
    /**
     * æ–°å¢žå‚数配置
     *
     * @param config å‚数配置信息
     * @return ç»“æžœ
     */
    public int insertConfig(SysConfig config);
    /**
     * ä¿®æ”¹å‚数配置
     *
     * @param config å‚数配置信息
     * @return ç»“æžœ
     */
    public int updateConfig(SysConfig config);
    /**
     * åˆ é™¤å‚数配置
     *
     * @param configId å‚æ•°ID
     * @return ç»“æžœ
     */
    public int deleteConfigById(Long configId);
    /**
     * æ‰¹é‡åˆ é™¤å‚数信息
     *
     * @param configIds éœ€è¦åˆ é™¤çš„参数ID
     * @return ç»“æžœ
     */
    public int deleteConfigByIds(Long[] configIds);
}
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDeptMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,117 @@
package com.ruoyi.system.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import com.ruoyi.common.core.domain.entity.SysDept;
/**
 * éƒ¨é—¨ç®¡ç† æ•°æ®å±‚
 *
 * @author ruoyi
 */
public interface SysDeptMapper
{
    /**
     * æŸ¥è¯¢éƒ¨é—¨ç®¡ç†æ•°æ®
     *
     * @param dept éƒ¨é—¨ä¿¡æ¯
     * @return éƒ¨é—¨ä¿¡æ¯é›†åˆ
     */
    public List<SysDept> selectDeptList(SysDept dept);
    /**
     * æ ¹æ®è§’色ID查询部门树信息
     *
     * @param roleId è§’色ID
     * @return é€‰ä¸­éƒ¨é—¨åˆ—表
     */
    public List<Integer> selectDeptListByRoleId(Long roleId);
    /**
     * æ ¹æ®éƒ¨é—¨ID查询信息
     *
     * @param deptId éƒ¨é—¨ID
     * @return éƒ¨é—¨ä¿¡æ¯
     */
    public SysDept selectDeptById(Long deptId);
    /**
     * æ ¹æ®ID查询所有子部门
     *
     * @param deptId éƒ¨é—¨ID
     * @return éƒ¨é—¨åˆ—表
     */
    public List<SysDept> selectChildrenDeptById(Long deptId);
    /**
     * æ ¹æ®ID查询所有子部门(正常状态)
     *
     * @param deptId éƒ¨é—¨ID
     * @return å­éƒ¨é—¨æ•°
     */
    public int selectNormalChildrenDeptById(Long deptId);
    /**
     * æ˜¯å¦å­˜åœ¨å­èŠ‚ç‚¹
     *
     * @param deptId éƒ¨é—¨ID
     * @return ç»“æžœ
     */
    public int hasChildByDeptId(Long deptId);
    /**
     * æŸ¥è¯¢éƒ¨é—¨æ˜¯å¦å­˜åœ¨ç”¨æˆ·
     *
     * @param deptId éƒ¨é—¨ID
     * @return ç»“æžœ
     */
    public int checkDeptExistUser(Long deptId);
    /**
     * æ ¡éªŒéƒ¨é—¨åç§°æ˜¯å¦å”¯ä¸€
     *
     * @param deptName éƒ¨é—¨åç§°
     * @param parentId çˆ¶éƒ¨é—¨ID
     * @return ç»“æžœ
     */
    public SysDept checkDeptNameUnique(@Param("deptName") String deptName, @Param("parentId") Long parentId);
    /**
     * æ–°å¢žéƒ¨é—¨ä¿¡æ¯
     *
     * @param dept éƒ¨é—¨ä¿¡æ¯
     * @return ç»“æžœ
     */
    public int insertDept(SysDept dept);
    /**
     * ä¿®æ”¹éƒ¨é—¨ä¿¡æ¯
     *
     * @param dept éƒ¨é—¨ä¿¡æ¯
     * @return ç»“æžœ
     */
    public int updateDept(SysDept dept);
    /**
     * ä¿®æ”¹æ‰€åœ¨éƒ¨é—¨çš„父级部门状态
     *
     * @param dept éƒ¨é—¨
     */
    public void updateDeptStatus(SysDept dept);
    /**
     * ä¿®æ”¹å­å…ƒç´ å…³ç³»
     *
     * @param depts å­å…ƒç´ 
     * @return ç»“æžœ
     */
    public int updateDeptChildren(@Param("depts") List<SysDept> depts);
    /**
     * åˆ é™¤éƒ¨é—¨ç®¡ç†ä¿¡æ¯
     *
     * @param deptId éƒ¨é—¨ID
     * @return ç»“æžœ
     */
    public int deleteDeptById(Long deptId);
}
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDictDataMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,95 @@
package com.ruoyi.system.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import com.ruoyi.common.core.domain.entity.SysDictData;
/**
 * å­—典表 æ•°æ®å±‚
 *
 * @author ruoyi
 */
public interface SysDictDataMapper
{
    /**
     * æ ¹æ®æ¡ä»¶åˆ†é¡µæŸ¥è¯¢å­—典数据
     *
     * @param dictData å­—典数据信息
     * @return å­—典数据集合信息
     */
    public List<SysDictData> selectDictDataList(SysDictData dictData);
    /**
     * æ ¹æ®å­—典类型查询字典数据
     *
     * @param dictType å­—典类型
     * @return å­—典数据集合信息
     */
    public List<SysDictData> selectDictDataByType(String dictType);
    /**
     * æ ¹æ®å­—典类型和字典键值查询字典数据信息
     *
     * @param dictType å­—典类型
     * @param dictValue å­—典键值
     * @return å­—典标签
     */
    public String selectDictLabel(@Param("dictType") String dictType, @Param("dictValue") String dictValue);
    /**
     * æ ¹æ®å­—典数据ID查询信息
     *
     * @param dictCode å­—典数据ID
     * @return å­—典数据
     */
    public SysDictData selectDictDataById(Long dictCode);
    /**
     * æŸ¥è¯¢å­—典数据
     *
     * @param dictType å­—典类型
     * @return å­—典数据
     */
    public int countDictDataByType(String dictType);
    /**
     * é€šè¿‡å­—å…¸ID删除字典数据信息
     *
     * @param dictCode å­—典数据ID
     * @return ç»“æžœ
     */
    public int deleteDictDataById(Long dictCode);
    /**
     * æ‰¹é‡åˆ é™¤å­—典数据信息
     *
     * @param dictCodes éœ€è¦åˆ é™¤çš„字典数据ID
     * @return ç»“æžœ
     */
    public int deleteDictDataByIds(Long[] dictCodes);
    /**
     * æ–°å¢žå­—典数据信息
     *
     * @param dictData å­—典数据信息
     * @return ç»“æžœ
     */
    public int insertDictData(SysDictData dictData);
    /**
     * ä¿®æ”¹å­—典数据信息
     *
     * @param dictData å­—典数据信息
     * @return ç»“æžœ
     */
    public int updateDictData(SysDictData dictData);
    /**
     * åŒæ­¥ä¿®æ”¹å­—典类型
     *
     * @param oldDictType æ—§å­—典类型
     * @param newDictType æ–°æ—§å­—典类型
     * @return ç»“æžœ
     */
    public int updateDictDataType(@Param("oldDictType") String oldDictType, @Param("newDictType") String newDictType);
}
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDictTypeMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,85 @@
package com.ruoyi.system.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import com.ruoyi.common.core.domain.entity.SysDictType;
/**
 * å­—典表 æ•°æ®å±‚
 *
 * @author ruoyi
 */
@Mapper
public interface SysDictTypeMapper
{
    /**
     * æ ¹æ®æ¡ä»¶åˆ†é¡µæŸ¥è¯¢å­—典类型
     *
     * @param dictType å­—典类型信息
     * @return å­—典类型集合信息
     */
    public List<SysDictType> selectDictTypeList(SysDictType dictType);
    /**
     * æ ¹æ®æ‰€æœ‰å­—典类型
     *
     * @return å­—典类型集合信息
     */
    public List<SysDictType> selectDictTypeAll();
    /**
     * æ ¹æ®å­—典类型ID查询信息
     *
     * @param dictId å­—典类型ID
     * @return å­—典类型
     */
    public SysDictType selectDictTypeById(Long dictId);
    /**
     * æ ¹æ®å­—典类型查询信息
     *
     * @param dictType å­—典类型
     * @return å­—典类型
     */
    public SysDictType selectDictTypeByType(String dictType);
    /**
     * é€šè¿‡å­—å…¸ID删除字典信息
     *
     * @param dictId å­—å…¸ID
     * @return ç»“æžœ
     */
    public int deleteDictTypeById(Long dictId);
    /**
     * æ‰¹é‡åˆ é™¤å­—典类型信息
     *
     * @param dictIds éœ€è¦åˆ é™¤çš„å­—å…¸ID
     * @return ç»“æžœ
     */
    public int deleteDictTypeByIds(Long[] dictIds);
    /**
     * æ–°å¢žå­—典类型信息
     *
     * @param dictType å­—典类型信息
     * @return ç»“æžœ
     */
    public int insertDictType(SysDictType dictType);
    /**
     * ä¿®æ”¹å­—典类型信息
     *
     * @param dictType å­—典类型信息
     * @return ç»“æžœ
     */
    public int updateDictType(SysDictType dictType);
    /**
     * æ ¡éªŒå­—典类型称是否唯一
     *
     * @param dictType å­—典类型
     * @return ç»“æžœ
     */
    public SysDictType checkDictTypeUnique(String dictType);
}
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysLogininforMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,42 @@
package com.ruoyi.system.mapper;
import java.util.List;
import com.ruoyi.system.domain.SysLogininfor;
/**
 * ç³»ç»Ÿè®¿é—®æ—¥å¿—情况信息 æ•°æ®å±‚
 *
 * @author ruoyi
 */
public interface SysLogininforMapper
{
    /**
     * æ–°å¢žç³»ç»Ÿç™»å½•日志
     *
     * @param logininfor è®¿é—®æ—¥å¿—对象
     */
    public void insertLogininfor(SysLogininfor logininfor);
    /**
     * æŸ¥è¯¢ç³»ç»Ÿç™»å½•日志集合
     *
     * @param logininfor è®¿é—®æ—¥å¿—对象
     * @return ç™»å½•记录集合
     */
    public List<SysLogininfor> selectLogininforList(SysLogininfor logininfor);
    /**
     * æ‰¹é‡åˆ é™¤ç³»ç»Ÿç™»å½•日志
     *
     * @param infoIds éœ€è¦åˆ é™¤çš„登录日志ID
     * @return ç»“æžœ
     */
    public int deleteLogininforByIds(Long[] infoIds);
    /**
     * æ¸…空系统登录日志
     *
     * @return ç»“æžœ
     */
    public int cleanLogininfor();
}
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysMenuMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,116 @@
package com.ruoyi.system.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import com.ruoyi.common.core.domain.entity.SysMenu;
/**
 * èœå•表 æ•°æ®å±‚
 *
 * @author ruoyi
 */
public interface SysMenuMapper
{
    /**
     * æŸ¥è¯¢ç³»ç»Ÿèœå•列表
     *
     * @param menu èœå•信息
     * @return èœå•列表
     */
    public List<SysMenu> selectMenuList(SysMenu menu);
    /**
     * æ ¹æ®ç”¨æˆ·æ‰€æœ‰æƒé™
     *
     * @return æƒé™åˆ—表
     */
    public List<String> selectMenuPerms();
    /**
     * æ ¹æ®ç”¨æˆ·æŸ¥è¯¢ç³»ç»Ÿèœå•列表
     *
     * @param menu èœå•信息
     * @return èœå•列表
     */
    public List<SysMenu> selectMenuListByUserId(SysMenu menu);
    /**
     * æ ¹æ®ç”¨æˆ·ID查询权限
     *
     * @param userId ç”¨æˆ·ID
     * @return æƒé™åˆ—表
     */
    public List<String> selectMenuPermsByUserId(Long userId);
    /**
     * æ ¹æ®ç”¨æˆ·ID查询菜单
     *
     * @return èœå•列表
     */
    public List<SysMenu> selectMenuTreeAll();
    /**
     * æ ¹æ®ç”¨æˆ·ID查询菜单
     *
     * @param username ç”¨æˆ·ID
     * @return èœå•列表
     */
    public List<SysMenu> selectMenuTreeByUserId(Long userId);
    /**
     * æ ¹æ®è§’色ID查询菜单树信息
     *
     * @param roleId è§’色ID
     * @return é€‰ä¸­èœå•列表
     */
    public List<Integer> selectMenuListByRoleId(Long roleId);
    /**
     * æ ¹æ®èœå•ID查询信息
     *
     * @param menuId èœå•ID
     * @return èœå•信息
     */
    public SysMenu selectMenuById(Long menuId);
    /**
     * æ˜¯å¦å­˜åœ¨èœå•子节点
     *
     * @param menuId èœå•ID
     * @return ç»“æžœ
     */
    public int hasChildByMenuId(Long menuId);
    /**
     * æ–°å¢žèœå•信息
     *
     * @param menu èœå•信息
     * @return ç»“æžœ
     */
    public int insertMenu(SysMenu menu);
    /**
     * ä¿®æ”¹èœå•信息
     *
     * @param menu èœå•信息
     * @return ç»“æžœ
     */
    public int updateMenu(SysMenu menu);
    /**
     * åˆ é™¤èœå•管理信息
     *
     * @param menuId èœå•ID
     * @return ç»“æžœ
     */
    public int deleteMenuById(Long menuId);
    /**
     * æ ¡éªŒèœå•名称是否唯一
     *
     * @param menuName èœå•名称
     * @param parentId çˆ¶èœå•ID
     * @return ç»“æžœ
     */
    public SysMenu checkMenuNameUnique(@Param("menuName") String menuName, @Param("parentId") Long parentId);
}
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysNoticeMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,60 @@
package com.ruoyi.system.mapper;
import java.util.List;
import com.ruoyi.system.domain.SysNotice;
/**
 * é€šçŸ¥å…¬å‘Šè¡¨ æ•°æ®å±‚
 *
 * @author ruoyi
 */
public interface SysNoticeMapper
{
    /**
     * æŸ¥è¯¢å…¬å‘Šä¿¡æ¯
     *
     * @param noticeId å…¬å‘ŠID
     * @return å…¬å‘Šä¿¡æ¯
     */
    public SysNotice selectNoticeById(Long noticeId);
    /**
     * æŸ¥è¯¢å…¬å‘Šåˆ—表
     *
     * @param notice å…¬å‘Šä¿¡æ¯
     * @return å…¬å‘Šé›†åˆ
     */
    public List<SysNotice> selectNoticeList(SysNotice notice);
    /**
     * æ–°å¢žå…¬å‘Š
     *
     * @param notice å…¬å‘Šä¿¡æ¯
     * @return ç»“æžœ
     */
    public int insertNotice(SysNotice notice);
    /**
     * ä¿®æ”¹å…¬å‘Š
     *
     * @param notice å…¬å‘Šä¿¡æ¯
     * @return ç»“æžœ
     */
    public int updateNotice(SysNotice notice);
    /**
     * æ‰¹é‡åˆ é™¤å…¬å‘Š
     *
     * @param noticeId å…¬å‘ŠID
     * @return ç»“æžœ
     */
    public int deleteNoticeById(Long noticeId);
    /**
     * æ‰¹é‡åˆ é™¤å…¬å‘Šä¿¡æ¯
     *
     * @param noticeIds éœ€è¦åˆ é™¤çš„公告ID
     * @return ç»“æžœ
     */
    public int deleteNoticeByIds(Long[] noticeIds);
}
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysOperLogMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,48 @@
package com.ruoyi.system.mapper;
import java.util.List;
import com.ruoyi.system.domain.SysOperLog;
/**
 * æ“ä½œæ—¥å¿— æ•°æ®å±‚
 *
 * @author ruoyi
 */
public interface SysOperLogMapper
{
    /**
     * æ–°å¢žæ“ä½œæ—¥å¿—
     *
     * @param operLog æ“ä½œæ—¥å¿—对象
     */
    public void insertOperlog(SysOperLog operLog);
    /**
     * æŸ¥è¯¢ç³»ç»Ÿæ“ä½œæ—¥å¿—集合
     *
     * @param operLog æ“ä½œæ—¥å¿—对象
     * @return æ“ä½œæ—¥å¿—集合
     */
    public List<SysOperLog> selectOperLogList(SysOperLog operLog);
    /**
     * æ‰¹é‡åˆ é™¤ç³»ç»Ÿæ“ä½œæ—¥å¿—
     *
     * @param operIds éœ€è¦åˆ é™¤çš„æ“ä½œæ—¥å¿—ID
     * @return ç»“æžœ
     */
    public int deleteOperLogByIds(Long[] operIds);
    /**
     * æŸ¥è¯¢æ“ä½œæ—¥å¿—详细
     *
     * @param operId æ“ä½œID
     * @return æ“ä½œæ—¥å¿—对象
     */
    public SysOperLog selectOperLogById(Long operId);
    /**
     * æ¸…空操作日志
     */
    public void cleanOperLog();
}
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysPostMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,99 @@
package com.ruoyi.system.mapper;
import java.util.List;
import com.ruoyi.system.domain.SysPost;
/**
 * å²—位信息 æ•°æ®å±‚
 *
 * @author ruoyi
 */
public interface SysPostMapper
{
    /**
     * æŸ¥è¯¢å²—位数据集合
     *
     * @param post å²—位信息
     * @return å²—位数据集合
     */
    public List<SysPost> selectPostList(SysPost post);
    /**
     * æŸ¥è¯¢æ‰€æœ‰å²—位
     *
     * @return å²—位列表
     */
    public List<SysPost> selectPostAll();
    /**
     * é€šè¿‡å²—位ID查询岗位信息
     *
     * @param postId å²—位ID
     * @return è§’色对象信息
     */
    public SysPost selectPostById(Long postId);
    /**
     * æ ¹æ®ç”¨æˆ·ID获取岗位选择框列表
     *
     * @param userId ç”¨æˆ·ID
     * @return é€‰ä¸­å²—位ID列表
     */
    public List<Integer> selectPostListByUserId(Long userId);
    /**
     * æŸ¥è¯¢ç”¨æˆ·æ‰€å±žå²—位组
     *
     * @param userName ç”¨æˆ·å
     * @return ç»“æžœ
     */
    public List<SysPost> selectPostsByUserName(String userName);
    /**
     * åˆ é™¤å²—位信息
     *
     * @param postId å²—位ID
     * @return ç»“æžœ
     */
    public int deletePostById(Long postId);
    /**
     * æ‰¹é‡åˆ é™¤å²—位信息
     *
     * @param postIds éœ€è¦åˆ é™¤çš„岗位ID
     * @return ç»“æžœ
     */
    public int deletePostByIds(Long[] postIds);
    /**
     * ä¿®æ”¹å²—位信息
     *
     * @param post å²—位信息
     * @return ç»“æžœ
     */
    public int updatePost(SysPost post);
    /**
     * æ–°å¢žå²—位信息
     *
     * @param post å²—位信息
     * @return ç»“æžœ
     */
    public int insertPost(SysPost post);
    /**
     * æ ¡éªŒå²—位名称
     *
     * @param postName å²—位名称
     * @return ç»“æžœ
     */
    public SysPost checkPostNameUnique(String postName);
    /**
     * æ ¡éªŒå²—位编码
     *
     * @param postCode å²—位编码
     * @return ç»“æžœ
     */
    public SysPost checkPostCodeUnique(String postCode);
}
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleDeptMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,44 @@
package com.ruoyi.system.mapper;
import java.util.List;
import com.ruoyi.system.domain.SysRoleDept;
/**
 * è§’色与部门关联表 æ•°æ®å±‚
 *
 * @author ruoyi
 */
public interface SysRoleDeptMapper
{
    /**
     * é€šè¿‡è§’色ID删除角色和部门关联
     *
     * @param roleId è§’色ID
     * @return ç»“æžœ
     */
    public int deleteRoleDeptByRoleId(Long roleId);
    /**
     * æ‰¹é‡åˆ é™¤è§’色部门关联信息
     *
     * @param ids éœ€è¦åˆ é™¤çš„æ•°æ®ID
     * @return ç»“æžœ
     */
    public int deleteRoleDept(Long[] ids);
    /**
     * æŸ¥è¯¢éƒ¨é—¨ä½¿ç”¨æ•°é‡
     *
     * @param deptId éƒ¨é—¨ID
     * @return ç»“æžœ
     */
    public int selectCountRoleDeptByDeptId(Long deptId);
    /**
     * æ‰¹é‡æ–°å¢žè§’色部门信息
     *
     * @param roleDeptList è§’色部门列表
     * @return ç»“æžœ
     */
    public int batchRoleDept(List<SysRoleDept> roleDeptList);
}
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,107 @@
package com.ruoyi.system.mapper;
import java.util.List;
import com.ruoyi.common.core.domain.entity.SysRole;
/**
 * è§’色表 æ•°æ®å±‚
 *
 * @author ruoyi
 */
public interface SysRoleMapper
{
    /**
     * æ ¹æ®æ¡ä»¶åˆ†é¡µæŸ¥è¯¢è§’色数据
     *
     * @param role è§’色信息
     * @return è§’色数据集合信息
     */
    public List<SysRole> selectRoleList(SysRole role);
    /**
     * æ ¹æ®ç”¨æˆ·ID查询角色
     *
     * @param userId ç”¨æˆ·ID
     * @return è§’色列表
     */
    public List<SysRole> selectRolePermissionByUserId(Long userId);
    /**
     * æŸ¥è¯¢æ‰€æœ‰è§’色
     *
     * @return è§’色列表
     */
    public List<SysRole> selectRoleAll();
    /**
     * æ ¹æ®ç”¨æˆ·ID获取角色选择框列表
     *
     * @param userId ç”¨æˆ·ID
     * @return é€‰ä¸­è§’色ID列表
     */
    public List<Integer> selectRoleListByUserId(Long userId);
    /**
     * é€šè¿‡è§’色ID查询角色
     *
     * @param roleId è§’色ID
     * @return è§’色对象信息
     */
    public SysRole selectRoleById(Long roleId);
    /**
     * æ ¹æ®ç”¨æˆ·ID查询角色
     *
     * @param userName ç”¨æˆ·å
     * @return è§’色列表
     */
    public List<SysRole> selectRolesByUserName(String userName);
    /**
     * æ ¡éªŒè§’色名称是否唯一
     *
     * @param roleName è§’色名称
     * @return è§’色信息
     */
    public SysRole checkRoleNameUnique(String roleName);
    /**
     * æ ¡éªŒè§’色权限是否唯一
     *
     * @param roleKey è§’色权限
     * @return è§’色信息
     */
    public SysRole checkRoleKeyUnique(String roleKey);
    /**
     * ä¿®æ”¹è§’色信息
     *
     * @param role è§’色信息
     * @return ç»“æžœ
     */
    public int updateRole(SysRole role);
    /**
     * æ–°å¢žè§’色信息
     *
     * @param role è§’色信息
     * @return ç»“æžœ
     */
    public int insertRole(SysRole role);
    /**
     * é€šè¿‡è§’色ID删除角色
     *
     * @param roleId è§’色ID
     * @return ç»“æžœ
     */
    public int deleteRoleById(Long roleId);
    /**
     * æ‰¹é‡åˆ é™¤è§’色信息
     *
     * @param roleIds éœ€è¦åˆ é™¤çš„角色ID
     * @return ç»“æžœ
     */
    public int deleteRoleByIds(Long[] roleIds);
}
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMenuMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,36 @@
package com.ruoyi.system.mapper;
import java.util.List;
import com.ruoyi.system.domain.SysRoleMenu;
/**
 * è§’色与菜单关联表 æ•°æ®å±‚
 *
 * @author ruoyi
 */
public interface SysRoleMenuMapper
{
    /**
     * æŸ¥è¯¢èœå•使用数量
     *
     * @param menuId èœå•ID
     * @return ç»“æžœ
     */
    public int checkMenuExistRole(Long menuId);
    /**
     * é€šè¿‡è§’色ID删除角色和菜单关联
     *
     * @param roleId è§’色ID
     * @return ç»“æžœ
     */
    public int deleteRoleMenuByRoleId(Long roleId);
    /**
     * æ‰¹é‡æ–°å¢žè§’色菜单信息
     *
     * @param roleMenuList è§’色菜单列表
     * @return ç»“æžœ
     */
    public int batchRoleMenu(List<SysRoleMenu> roleMenuList);
}
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,111 @@
package com.ruoyi.system.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import com.ruoyi.common.core.domain.entity.SysUser;
/**
 * ç”¨æˆ·è¡¨ æ•°æ®å±‚
 *
 * @author ruoyi
 */
public interface SysUserMapper
{
    /**
     * æ ¹æ®æ¡ä»¶åˆ†é¡µæŸ¥è¯¢ç”¨æˆ·åˆ—表
     *
     * @param sysUser ç”¨æˆ·ä¿¡æ¯
     * @return ç”¨æˆ·ä¿¡æ¯é›†åˆä¿¡æ¯
     */
    public List<SysUser> selectUserList(SysUser sysUser);
    /**
     * é€šè¿‡ç”¨æˆ·åæŸ¥è¯¢ç”¨æˆ·
     *
     * @param userName ç”¨æˆ·å
     * @return ç”¨æˆ·å¯¹è±¡ä¿¡æ¯
     */
    public SysUser selectUserByUserName(String userName);
    /**
     * é€šè¿‡ç”¨æˆ·ID查询用户
     *
     * @param userId ç”¨æˆ·ID
     * @return ç”¨æˆ·å¯¹è±¡ä¿¡æ¯
     */
    public SysUser selectUserById(Long userId);
    /**
     * æ–°å¢žç”¨æˆ·ä¿¡æ¯
     *
     * @param user ç”¨æˆ·ä¿¡æ¯
     * @return ç»“æžœ
     */
    public int insertUser(SysUser user);
    /**
     * ä¿®æ”¹ç”¨æˆ·ä¿¡æ¯
     *
     * @param user ç”¨æˆ·ä¿¡æ¯
     * @return ç»“æžœ
     */
    public int updateUser(SysUser user);
    /**
     * ä¿®æ”¹ç”¨æˆ·å¤´åƒ
     *
     * @param userName ç”¨æˆ·å
     * @param avatar å¤´åƒåœ°å€
     * @return ç»“æžœ
     */
    public int updateUserAvatar(@Param("userName") String userName, @Param("avatar") String avatar);
    /**
     * é‡ç½®ç”¨æˆ·å¯†ç 
     *
     * @param userName ç”¨æˆ·å
     * @param password å¯†ç 
     * @return ç»“æžœ
     */
    public int resetUserPwd(@Param("userName") String userName, @Param("password") String password);
    /**
     * é€šè¿‡ç”¨æˆ·ID删除用户
     *
     * @param userId ç”¨æˆ·ID
     * @return ç»“æžœ
     */
    public int deleteUserById(Long userId);
    /**
     * æ‰¹é‡åˆ é™¤ç”¨æˆ·ä¿¡æ¯
     *
     * @param userIds éœ€è¦åˆ é™¤çš„用户ID
     * @return ç»“æžœ
     */
    public int deleteUserByIds(Long[] userIds);
    /**
     * æ ¡éªŒç”¨æˆ·åç§°æ˜¯å¦å”¯ä¸€
     *
     * @param userName ç”¨æˆ·åç§°
     * @return ç»“æžœ
     */
    public int checkUserNameUnique(String userName);
    /**
     * æ ¡éªŒæ‰‹æœºå·ç æ˜¯å¦å”¯ä¸€
     *
     * @param phonenumber æ‰‹æœºå·ç 
     * @return ç»“æžœ
     */
    public SysUser checkPhoneUnique(String phonenumber);
    /**
     * æ ¡éªŒemail是否唯一
     *
     * @param email ç”¨æˆ·é‚®ç®±
     * @return ç»“æžœ
     */
    public SysUser checkEmailUnique(String email);
}
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserPostMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,44 @@
package com.ruoyi.system.mapper;
import java.util.List;
import com.ruoyi.system.domain.SysUserPost;
/**
 * ç”¨æˆ·ä¸Žå²—位关联表 æ•°æ®å±‚
 *
 * @author ruoyi
 */
public interface SysUserPostMapper
{
    /**
     * é€šè¿‡ç”¨æˆ·ID删除用户和岗位关联
     *
     * @param userId ç”¨æˆ·ID
     * @return ç»“æžœ
     */
    public int deleteUserPostByUserId(Long userId);
    /**
     * é€šè¿‡å²—位ID查询岗位使用数量
     *
     * @param postId å²—位ID
     * @return ç»“æžœ
     */
    public int countUserPostById(Long postId);
    /**
     * æ‰¹é‡åˆ é™¤ç”¨æˆ·å’Œå²—位关联
     *
     * @param ids éœ€è¦åˆ é™¤çš„æ•°æ®ID
     * @return ç»“æžœ
     */
    public int deleteUserPost(Long[] ids);
    /**
     * æ‰¹é‡æ–°å¢žç”¨æˆ·å²—位信息
     *
     * @param userPostList ç”¨æˆ·è§’色列表
     * @return ç»“æžœ
     */
    public int batchUserPost(List<SysUserPost> userPostList);
}
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserRoleMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,62 @@
package com.ruoyi.system.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import com.ruoyi.system.domain.SysUserRole;
/**
 * ç”¨æˆ·ä¸Žè§’色关联表 æ•°æ®å±‚
 *
 * @author ruoyi
 */
public interface SysUserRoleMapper
{
    /**
     * é€šè¿‡ç”¨æˆ·ID删除用户和角色关联
     *
     * @param userId ç”¨æˆ·ID
     * @return ç»“æžœ
     */
    public int deleteUserRoleByUserId(Long userId);
    /**
     * æ‰¹é‡åˆ é™¤ç”¨æˆ·å’Œè§’色关联
     *
     * @param ids éœ€è¦åˆ é™¤çš„æ•°æ®ID
     * @return ç»“æžœ
     */
    public int deleteUserRole(Long[] ids);
    /**
     * é€šè¿‡è§’色ID查询角色使用数量
     *
     * @param roleId è§’色ID
     * @return ç»“æžœ
     */
    public int countUserRoleByRoleId(Long roleId);
    /**
     * æ‰¹é‡æ–°å¢žç”¨æˆ·è§’色信息
     *
     * @param userRoleList ç”¨æˆ·è§’色列表
     * @return ç»“æžœ
     */
    public int batchUserRole(List<SysUserRole> userRoleList);
    /**
     * åˆ é™¤ç”¨æˆ·å’Œè§’色关联信息
     *
     * @param userRole ç”¨æˆ·å’Œè§’色关联信息
     * @return ç»“æžœ
     */
    public int deleteUserRoleInfo(SysUserRole userRole);
    /**
     * æ‰¹é‡å–消授权用户角色
     *
     * @param roleId è§’色ID
     * @param userIds éœ€è¦åˆ é™¤çš„用户数据ID
     * @return ç»“æžœ
     */
    public int deleteUserRoleInfos(@Param("roleId") Long roleId, @Param("userIds") Long[] userIds);
}
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysConfigService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,73 @@
package com.ruoyi.system.service;
import java.util.List;
import com.ruoyi.system.domain.SysConfig;
/**
 * å‚数配置 æœåС层
 *
 * @author ruoyi
 */
public interface ISysConfigService
{
    /**
     * æŸ¥è¯¢å‚数配置信息
     *
     * @param configId å‚数配置ID
     * @return å‚数配置信息
     */
    public SysConfig selectConfigById(Long configId);
    /**
     * æ ¹æ®é”®åæŸ¥è¯¢å‚数配置信息
     *
     * @param configKey å‚数键名
     * @return å‚数键值
     */
    public String selectConfigByKey(String configKey);
    /**
     * æŸ¥è¯¢å‚数配置列表
     *
     * @param config å‚数配置信息
     * @return å‚数配置集合
     */
    public List<SysConfig> selectConfigList(SysConfig config);
    /**
     * æ–°å¢žå‚数配置
     *
     * @param config å‚数配置信息
     * @return ç»“æžœ
     */
    public int insertConfig(SysConfig config);
    /**
     * ä¿®æ”¹å‚数配置
     *
     * @param config å‚数配置信息
     * @return ç»“æžœ
     */
    public int updateConfig(SysConfig config);
    /**
     * æ‰¹é‡åˆ é™¤å‚数信息
     *
     * @param configIds éœ€è¦åˆ é™¤çš„参数ID
     * @return ç»“æžœ
     */
    public int deleteConfigByIds(Long[] configIds);
    /**
     * æ¸…空缓存数据
     */
    public void clearCache();
    /**
     * æ ¡éªŒå‚数键名是否唯一
     *
     * @param config å‚数信息
     * @return ç»“æžœ
     */
    public String checkConfigKeyUnique(SysConfig config);
}
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDeptService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,109 @@
package com.ruoyi.system.service;
import java.util.List;
import com.ruoyi.common.core.domain.TreeSelect;
import com.ruoyi.common.core.domain.entity.SysDept;
/**
 * éƒ¨é—¨ç®¡ç† æœåС层
 *
 * @author ruoyi
 */
public interface ISysDeptService
{
    /**
     * æŸ¥è¯¢éƒ¨é—¨ç®¡ç†æ•°æ®
     *
     * @param dept éƒ¨é—¨ä¿¡æ¯
     * @return éƒ¨é—¨ä¿¡æ¯é›†åˆ
     */
    public List<SysDept> selectDeptList(SysDept dept);
    /**
     * æž„建前端所需要树结构
     *
     * @param depts éƒ¨é—¨åˆ—表
     * @return æ ‘结构列表
     */
    public List<SysDept> buildDeptTree(List<SysDept> depts);
    /**
     * æž„建前端所需要下拉树结构
     *
     * @param depts éƒ¨é—¨åˆ—表
     * @return ä¸‹æ‹‰æ ‘结构列表
     */
    public List<TreeSelect> buildDeptTreeSelect(List<SysDept> depts);
    /**
     * æ ¹æ®è§’色ID查询部门树信息
     *
     * @param roleId è§’色ID
     * @return é€‰ä¸­éƒ¨é—¨åˆ—表
     */
    public List<Integer> selectDeptListByRoleId(Long roleId);
    /**
     * æ ¹æ®éƒ¨é—¨ID查询信息
     *
     * @param deptId éƒ¨é—¨ID
     * @return éƒ¨é—¨ä¿¡æ¯
     */
    public SysDept selectDeptById(Long deptId);
    /**
     * æ ¹æ®ID查询所有子部门(正常状态)
     *
     * @param deptId éƒ¨é—¨ID
     * @return å­éƒ¨é—¨æ•°
     */
    public int selectNormalChildrenDeptById(Long deptId);
    /**
     * æ˜¯å¦å­˜åœ¨éƒ¨é—¨å­èŠ‚ç‚¹
     *
     * @param deptId éƒ¨é—¨ID
     * @return ç»“æžœ
     */
    public boolean hasChildByDeptId(Long deptId);
    /**
     * æŸ¥è¯¢éƒ¨é—¨æ˜¯å¦å­˜åœ¨ç”¨æˆ·
     *
     * @param deptId éƒ¨é—¨ID
     * @return ç»“æžœ true å­˜åœ¨ false ä¸å­˜åœ¨
     */
    public boolean checkDeptExistUser(Long deptId);
    /**
     * æ ¡éªŒéƒ¨é—¨åç§°æ˜¯å¦å”¯ä¸€
     *
     * @param dept éƒ¨é—¨ä¿¡æ¯
     * @return ç»“æžœ
     */
    public String checkDeptNameUnique(SysDept dept);
    /**
     * æ–°å¢žä¿å­˜éƒ¨é—¨ä¿¡æ¯
     *
     * @param dept éƒ¨é—¨ä¿¡æ¯
     * @return ç»“æžœ
     */
    public int insertDept(SysDept dept);
    /**
     * ä¿®æ”¹ä¿å­˜éƒ¨é—¨ä¿¡æ¯
     *
     * @param dept éƒ¨é—¨ä¿¡æ¯
     * @return ç»“æžœ
     */
    public int updateDept(SysDept dept);
    /**
     * åˆ é™¤éƒ¨é—¨ç®¡ç†ä¿¡æ¯
     *
     * @param deptId éƒ¨é—¨ID
     * @return ç»“æžœ
     */
    public int deleteDeptById(Long deptId);
}
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictDataService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,61 @@
package com.ruoyi.system.service;
import java.util.List;
import com.ruoyi.common.core.domain.entity.SysDictData;
/**
 * å­—å…¸ ä¸šåС层
 *
 * @author ruoyi
 */
public interface ISysDictDataService
{
    /**
     * æ ¹æ®æ¡ä»¶åˆ†é¡µæŸ¥è¯¢å­—典数据
     *
     * @param dictData å­—典数据信息
     * @return å­—典数据集合信息
     */
    public List<SysDictData> selectDictDataList(SysDictData dictData);
    /**
     * æ ¹æ®å­—典类型和字典键值查询字典数据信息
     *
     * @param dictType å­—典类型
     * @param dictValue å­—典键值
     * @return å­—典标签
     */
    public String selectDictLabel(String dictType, String dictValue);
    /**
     * æ ¹æ®å­—典数据ID查询信息
     *
     * @param dictCode å­—典数据ID
     * @return å­—典数据
     */
    public SysDictData selectDictDataById(Long dictCode);
    /**
     * æ‰¹é‡åˆ é™¤å­—典数据信息
     *
     * @param dictCodes éœ€è¦åˆ é™¤çš„字典数据ID
     * @return ç»“æžœ
     */
    public int deleteDictDataByIds(Long[] dictCodes);
    /**
     * æ–°å¢žä¿å­˜å­—典数据信息
     *
     * @param dictData å­—典数据信息
     * @return ç»“æžœ
     */
    public int insertDictData(SysDictData dictData);
    /**
     * ä¿®æ”¹ä¿å­˜å­—典数据信息
     *
     * @param dictData å­—典数据信息
     * @return ç»“æžœ
     */
    public int updateDictData(SysDictData dictData);
}
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictTypeService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,89 @@
package com.ruoyi.system.service;
import java.util.List;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.domain.entity.SysDictType;
/**
 * å­—å…¸ ä¸šåС层
 *
 * @author ruoyi
 */
public interface ISysDictTypeService
{
    /**
     * æ ¹æ®æ¡ä»¶åˆ†é¡µæŸ¥è¯¢å­—典类型
     *
     * @param dictType å­—典类型信息
     * @return å­—典类型集合信息
     */
    public List<SysDictType> selectDictTypeList(SysDictType dictType);
    /**
     * æ ¹æ®æ‰€æœ‰å­—典类型
     *
     * @return å­—典类型集合信息
     */
    public List<SysDictType> selectDictTypeAll();
    /**
     * æ ¹æ®å­—典类型查询字典数据
     *
     * @param dictType å­—典类型
     * @return å­—典数据集合信息
     */
    public List<SysDictData> selectDictDataByType(String dictType);
    /**
     * æ ¹æ®å­—典类型ID查询信息
     *
     * @param dictId å­—典类型ID
     * @return å­—典类型
     */
    public SysDictType selectDictTypeById(Long dictId);
    /**
     * æ ¹æ®å­—典类型查询信息
     *
     * @param dictType å­—典类型
     * @return å­—典类型
     */
    public SysDictType selectDictTypeByType(String dictType);
    /**
     * æ‰¹é‡åˆ é™¤å­—典信息
     *
     * @param dictIds éœ€è¦åˆ é™¤çš„å­—å…¸ID
     * @return ç»“æžœ
     */
    public int deleteDictTypeByIds(Long[] dictIds);
    /**
     * æ¸…空缓存数据
     */
    public void clearCache();
    /**
     * æ–°å¢žä¿å­˜å­—典类型信息
     *
     * @param dictType å­—典类型信息
     * @return ç»“æžœ
     */
    public int insertDictType(SysDictType dictType);
    /**
     * ä¿®æ”¹ä¿å­˜å­—典类型信息
     *
     * @param dictType å­—典类型信息
     * @return ç»“æžœ
     */
    public int updateDictType(SysDictType dictType);
    /**
     * æ ¡éªŒå­—典类型称是否唯一
     *
     * @param dictType å­—典类型
     * @return ç»“æžœ
     */
    public String checkDictTypeUnique(SysDictType dictType);
}
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysLogininforService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,40 @@
package com.ruoyi.system.service;
import java.util.List;
import com.ruoyi.system.domain.SysLogininfor;
/**
 * ç³»ç»Ÿè®¿é—®æ—¥å¿—情况信息 æœåС层
 *
 * @author ruoyi
 */
public interface ISysLogininforService
{
    /**
     * æ–°å¢žç³»ç»Ÿç™»å½•日志
     *
     * @param logininfor è®¿é—®æ—¥å¿—对象
     */
    public void insertLogininfor(SysLogininfor logininfor);
    /**
     * æŸ¥è¯¢ç³»ç»Ÿç™»å½•日志集合
     *
     * @param logininfor è®¿é—®æ—¥å¿—对象
     * @return ç™»å½•记录集合
     */
    public List<SysLogininfor> selectLogininforList(SysLogininfor logininfor);
    /**
     * æ‰¹é‡åˆ é™¤ç³»ç»Ÿç™»å½•日志
     *
     * @param infoIds éœ€è¦åˆ é™¤çš„登录日志ID
     * @return
     */
    public int deleteLogininforByIds(Long[] infoIds);
    /**
     * æ¸…空系统登录日志
     */
    public void cleanLogininfor();
}
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysMenuService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,136 @@
package com.ruoyi.system.service;
import java.util.List;
import java.util.Set;
import com.ruoyi.common.core.domain.TreeSelect;
import com.ruoyi.common.core.domain.entity.SysMenu;
import com.ruoyi.system.domain.vo.RouterVo;
/**
 * èœå• ä¸šåС层
 *
 * @author ruoyi
 */
public interface ISysMenuService
{
    /**
     * æ ¹æ®ç”¨æˆ·æŸ¥è¯¢ç³»ç»Ÿèœå•列表
     *
     * @param userId ç”¨æˆ·ID
     * @return èœå•列表
     */
    public List<SysMenu> selectMenuList(Long userId);
    /**
     * æ ¹æ®ç”¨æˆ·æŸ¥è¯¢ç³»ç»Ÿèœå•列表
     *
     * @param menu èœå•信息
     * @param userId ç”¨æˆ·ID
     * @return èœå•列表
     */
    public List<SysMenu> selectMenuList(SysMenu menu, Long userId);
    /**
     * æ ¹æ®ç”¨æˆ·ID查询权限
     *
     * @param userId ç”¨æˆ·ID
     * @return æƒé™åˆ—表
     */
    public Set<String> selectMenuPermsByUserId(Long userId);
    /**
     * æ ¹æ®ç”¨æˆ·ID查询菜单树信息
     *
     * @param userId ç”¨æˆ·ID
     * @return èœå•列表
     */
    public List<SysMenu> selectMenuTreeByUserId(Long userId);
    /**
     * æ ¹æ®è§’色ID查询菜单树信息
     *
     * @param roleId è§’色ID
     * @return é€‰ä¸­èœå•列表
     */
    public List<Integer> selectMenuListByRoleId(Long roleId);
    /**
     * æž„建前端路由所需要的菜单
     *
     * @param menus èœå•列表
     * @return è·¯ç”±åˆ—表
     */
    public List<RouterVo> buildMenus(List<SysMenu> menus);
    /**
     * æž„建前端所需要树结构
     *
     * @param menus èœå•列表
     * @return æ ‘结构列表
     */
    public List<SysMenu> buildMenuTree(List<SysMenu> menus);
    /**
     * æž„建前端所需要下拉树结构
     *
     * @param menus èœå•列表
     * @return ä¸‹æ‹‰æ ‘结构列表
     */
    public List<TreeSelect> buildMenuTreeSelect(List<SysMenu> menus);
    /**
     * æ ¹æ®èœå•ID查询信息
     *
     * @param menuId èœå•ID
     * @return èœå•信息
     */
    public SysMenu selectMenuById(Long menuId);
    /**
     * æ˜¯å¦å­˜åœ¨èœå•子节点
     *
     * @param menuId èœå•ID
     * @return ç»“æžœ true å­˜åœ¨ false ä¸å­˜åœ¨
     */
    public boolean hasChildByMenuId(Long menuId);
    /**
     * æŸ¥è¯¢èœå•是否存在角色
     *
     * @param menuId èœå•ID
     * @return ç»“æžœ true å­˜åœ¨ false ä¸å­˜åœ¨
     */
    public boolean checkMenuExistRole(Long menuId);
    /**
     * æ–°å¢žä¿å­˜èœå•信息
     *
     * @param menu èœå•信息
     * @return ç»“æžœ
     */
    public int insertMenu(SysMenu menu);
    /**
     * ä¿®æ”¹ä¿å­˜èœå•信息
     *
     * @param menu èœå•信息
     * @return ç»“æžœ
     */
    public int updateMenu(SysMenu menu);
    /**
     * åˆ é™¤èœå•管理信息
     *
     * @param menuId èœå•ID
     * @return ç»“æžœ
     */
    public int deleteMenuById(Long menuId);
    /**
     * æ ¡éªŒèœå•名称是否唯一
     *
     * @param menu èœå•信息
     * @return ç»“æžœ
     */
    public String checkMenuNameUnique(SysMenu menu);
}
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysNoticeService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,60 @@
package com.ruoyi.system.service;
import java.util.List;
import com.ruoyi.system.domain.SysNotice;
/**
 * å…¬å‘Š æœåŠ¡å±‚
 *
 * @author ruoyi
 */
public interface ISysNoticeService
{
    /**
     * æŸ¥è¯¢å…¬å‘Šä¿¡æ¯
     *
     * @param noticeId å…¬å‘ŠID
     * @return å…¬å‘Šä¿¡æ¯
     */
    public SysNotice selectNoticeById(Long noticeId);
    /**
     * æŸ¥è¯¢å…¬å‘Šåˆ—表
     *
     * @param notice å…¬å‘Šä¿¡æ¯
     * @return å…¬å‘Šé›†åˆ
     */
    public List<SysNotice> selectNoticeList(SysNotice notice);
    /**
     * æ–°å¢žå…¬å‘Š
     *
     * @param notice å…¬å‘Šä¿¡æ¯
     * @return ç»“æžœ
     */
    public int insertNotice(SysNotice notice);
    /**
     * ä¿®æ”¹å…¬å‘Š
     *
     * @param notice å…¬å‘Šä¿¡æ¯
     * @return ç»“æžœ
     */
    public int updateNotice(SysNotice notice);
    /**
     * åˆ é™¤å…¬å‘Šä¿¡æ¯
     *
     * @param noticeId å…¬å‘ŠID
     * @return ç»“æžœ
     */
    public int deleteNoticeById(Long noticeId);
    /**
     * æ‰¹é‡åˆ é™¤å…¬å‘Šä¿¡æ¯
     *
     * @param noticeIds éœ€è¦åˆ é™¤çš„公告ID
     * @return ç»“æžœ
     */
    public int deleteNoticeByIds(Long[] noticeIds);
}
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysOperLogService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,48 @@
package com.ruoyi.system.service;
import java.util.List;
import com.ruoyi.system.domain.SysOperLog;
/**
 * æ“ä½œæ—¥å¿— æœåС层
 *
 * @author ruoyi
 */
public interface ISysOperLogService
{
    /**
     * æ–°å¢žæ“ä½œæ—¥å¿—
     *
     * @param operLog æ“ä½œæ—¥å¿—对象
     */
    public void insertOperlog(SysOperLog operLog);
    /**
     * æŸ¥è¯¢ç³»ç»Ÿæ“ä½œæ—¥å¿—集合
     *
     * @param operLog æ“ä½œæ—¥å¿—对象
     * @return æ“ä½œæ—¥å¿—集合
     */
    public List<SysOperLog> selectOperLogList(SysOperLog operLog);
    /**
     * æ‰¹é‡åˆ é™¤ç³»ç»Ÿæ“ä½œæ—¥å¿—
     *
     * @param operIds éœ€è¦åˆ é™¤çš„æ“ä½œæ—¥å¿—ID
     * @return ç»“æžœ
     */
    public int deleteOperLogByIds(Long[] operIds);
    /**
     * æŸ¥è¯¢æ“ä½œæ—¥å¿—详细
     *
     * @param operId æ“ä½œID
     * @return æ“ä½œæ—¥å¿—对象
     */
    public SysOperLog selectOperLogById(Long operId);
    /**
     * æ¸…空操作日志
     */
    public void cleanOperLog();
}
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysPostService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,100 @@
package com.ruoyi.system.service;
import java.util.List;
import com.ruoyi.system.domain.SysPost;
/**
 * å²—位信息 æœåС层
 *
 * @author ruoyi
 */
public interface ISysPostService
{
    /**
     * æŸ¥è¯¢å²—位信息集合
     *
     * @param post å²—位信息
     * @return å²—位列表
     */
    public List<SysPost> selectPostList(SysPost post);
    /**
     * æŸ¥è¯¢æ‰€æœ‰å²—位
     *
     * @return å²—位列表
     */
    public List<SysPost> selectPostAll();
    /**
     * é€šè¿‡å²—位ID查询岗位信息
     *
     * @param postId å²—位ID
     * @return è§’色对象信息
     */
    public SysPost selectPostById(Long postId);
    /**
     * æ ¹æ®ç”¨æˆ·ID获取岗位选择框列表
     *
     * @param userId ç”¨æˆ·ID
     * @return é€‰ä¸­å²—位ID列表
     */
    public List<Integer> selectPostListByUserId(Long userId);
    /**
     * æ ¡éªŒå²—位名称
     *
     * @param post å²—位信息
     * @return ç»“æžœ
     */
    public String checkPostNameUnique(SysPost post);
    /**
     * æ ¡éªŒå²—位编码
     *
     * @param post å²—位信息
     * @return ç»“æžœ
     */
    public String checkPostCodeUnique(SysPost post);
    /**
     * é€šè¿‡å²—位ID查询岗位使用数量
     *
     * @param postId å²—位ID
     * @return ç»“æžœ
     */
    public int countUserPostById(Long postId);
    /**
     * åˆ é™¤å²—位信息
     *
     * @param postId å²—位ID
     * @return ç»“æžœ
     */
    public int deletePostById(Long postId);
    /**
     * æ‰¹é‡åˆ é™¤å²—位信息
     *
     * @param postIds éœ€è¦åˆ é™¤çš„岗位ID
     * @return ç»“æžœ
     * @throws Exception å¼‚常
     */
    public int deletePostByIds(Long[] postIds);
    /**
     * æ–°å¢žä¿å­˜å²—位信息
     *
     * @param post å²—位信息
     * @return ç»“æžœ
     */
    public int insertPost(SysPost post);
    /**
     * ä¿®æ”¹ä¿å­˜å²—位信息
     *
     * @param post å²—位信息
     * @return ç»“æžœ
     */
    public int updatePost(SysPost post);
}
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysRoleService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,131 @@
package com.ruoyi.system.service;
import java.util.List;
import java.util.Set;
import com.ruoyi.common.core.domain.entity.SysRole;
/**
 * è§’色业务层
 *
 * @author ruoyi
 */
public interface ISysRoleService
{
    /**
     * æ ¹æ®æ¡ä»¶åˆ†é¡µæŸ¥è¯¢è§’色数据
     *
     * @param role è§’色信息
     * @return è§’色数据集合信息
     */
    public List<SysRole> selectRoleList(SysRole role);
    /**
     * æ ¹æ®ç”¨æˆ·ID查询角色
     *
     * @param userId ç”¨æˆ·ID
     * @return æƒé™åˆ—表
     */
    public Set<String> selectRolePermissionByUserId(Long userId);
    /**
     * æŸ¥è¯¢æ‰€æœ‰è§’色
     *
     * @return è§’色列表
     */
    public List<SysRole> selectRoleAll();
    /**
     * æ ¹æ®ç”¨æˆ·ID获取角色选择框列表
     *
     * @param userId ç”¨æˆ·ID
     * @return é€‰ä¸­è§’色ID列表
     */
    public List<Integer> selectRoleListByUserId(Long userId);
    /**
     * é€šè¿‡è§’色ID查询角色
     *
     * @param roleId è§’色ID
     * @return è§’色对象信息
     */
    public SysRole selectRoleById(Long roleId);
    /**
     * æ ¡éªŒè§’色名称是否唯一
     *
     * @param role è§’色信息
     * @return ç»“æžœ
     */
    public String checkRoleNameUnique(SysRole role);
    /**
     * æ ¡éªŒè§’色权限是否唯一
     *
     * @param role è§’色信息
     * @return ç»“æžœ
     */
    public String checkRoleKeyUnique(SysRole role);
    /**
     * æ ¡éªŒè§’色是否允许操作
     *
     * @param role è§’色信息
     */
    public void checkRoleAllowed(SysRole role);
    /**
     * é€šè¿‡è§’色ID查询角色使用数量
     *
     * @param roleId è§’色ID
     * @return ç»“æžœ
     */
    public int countUserRoleByRoleId(Long roleId);
    /**
     * æ–°å¢žä¿å­˜è§’色信息
     *
     * @param role è§’色信息
     * @return ç»“æžœ
     */
    public int insertRole(SysRole role);
    /**
     * ä¿®æ”¹ä¿å­˜è§’色信息
     *
     * @param role è§’色信息
     * @return ç»“æžœ
     */
    public int updateRole(SysRole role);
    /**
     * ä¿®æ”¹è§’色状态
     *
     * @param role è§’色信息
     * @return ç»“æžœ
     */
    public int updateRoleStatus(SysRole role);
    /**
     * ä¿®æ”¹æ•°æ®æƒé™ä¿¡æ¯
     *
     * @param role è§’色信息
     * @return ç»“æžœ
     */
    public int authDataScope(SysRole role);
    /**
     * é€šè¿‡è§’色ID删除角色
     *
     * @param roleId è§’色ID
     * @return ç»“æžœ
     */
    public int deleteRoleById(Long roleId);
    /**
     * æ‰¹é‡åˆ é™¤è§’色信息
     *
     * @param roleIds éœ€è¦åˆ é™¤çš„角色ID
     * @return ç»“æžœ
     */
    public int deleteRoleByIds(Long[] roleIds);
}
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserOnlineService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,48 @@
package com.ruoyi.system.service;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.system.domain.SysUserOnline;
/**
 * åœ¨çº¿ç”¨æˆ· æœåС层
 *
 * @author ruoyi
 */
public interface ISysUserOnlineService
{
    /**
     * é€šè¿‡ç™»å½•地址查询信息
     *
     * @param ipaddr ç™»å½•地址
     * @param user ç”¨æˆ·ä¿¡æ¯
     * @return åœ¨çº¿ç”¨æˆ·ä¿¡æ¯
     */
    public SysUserOnline selectOnlineByIpaddr(String ipaddr, LoginUser user);
    /**
     * é€šè¿‡ç”¨æˆ·åç§°æŸ¥è¯¢ä¿¡æ¯
     *
     * @param userName ç”¨æˆ·åç§°
     * @param user ç”¨æˆ·ä¿¡æ¯
     * @return åœ¨çº¿ç”¨æˆ·ä¿¡æ¯
     */
    public SysUserOnline selectOnlineByUserName(String userName, LoginUser user);
    /**
     * é€šè¿‡ç™»å½•地址/用户名称查询信息
     *
     * @param ipaddr ç™»å½•地址
     * @param userName ç”¨æˆ·åç§°
     * @param user ç”¨æˆ·ä¿¡æ¯
     * @return åœ¨çº¿ç”¨æˆ·ä¿¡æ¯
     */
    public SysUserOnline selectOnlineByInfo(String ipaddr, String userName, LoginUser user);
    /**
     * è®¾ç½®åœ¨çº¿ç”¨æˆ·ä¿¡æ¯
     *
     * @param user ç”¨æˆ·ä¿¡æ¯
     * @return åœ¨çº¿ç”¨æˆ·
     */
    public SysUserOnline loginUserToUserOnline(LoginUser user);
}
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,167 @@
package com.ruoyi.system.service;
import java.util.List;
import com.ruoyi.common.core.domain.entity.SysUser;
/**
 * ç”¨æˆ· ä¸šåС层
 *
 * @author ruoyi
 */
public interface ISysUserService
{
    /**
     * æ ¹æ®æ¡ä»¶åˆ†é¡µæŸ¥è¯¢ç”¨æˆ·åˆ—表
     *
     * @param user ç”¨æˆ·ä¿¡æ¯
     * @return ç”¨æˆ·ä¿¡æ¯é›†åˆä¿¡æ¯
     */
    public List<SysUser> selectUserList(SysUser user);
    /**
     * é€šè¿‡ç”¨æˆ·åæŸ¥è¯¢ç”¨æˆ·
     *
     * @param userName ç”¨æˆ·å
     * @return ç”¨æˆ·å¯¹è±¡ä¿¡æ¯
     */
    public SysUser selectUserByUserName(String userName);
    /**
     * é€šè¿‡ç”¨æˆ·ID查询用户
     *
     * @param userId ç”¨æˆ·ID
     * @return ç”¨æˆ·å¯¹è±¡ä¿¡æ¯
     */
    public SysUser selectUserById(Long userId);
    /**
     * æ ¹æ®ç”¨æˆ·ID查询用户所属角色组
     *
     * @param userName ç”¨æˆ·å
     * @return ç»“æžœ
     */
    public String selectUserRoleGroup(String userName);
    /**
     * æ ¹æ®ç”¨æˆ·ID查询用户所属岗位组
     *
     * @param userName ç”¨æˆ·å
     * @return ç»“æžœ
     */
    public String selectUserPostGroup(String userName);
    /**
     * æ ¡éªŒç”¨æˆ·åç§°æ˜¯å¦å”¯ä¸€
     *
     * @param userName ç”¨æˆ·åç§°
     * @return ç»“æžœ
     */
    public String checkUserNameUnique(String userName);
    /**
     * æ ¡éªŒæ‰‹æœºå·ç æ˜¯å¦å”¯ä¸€
     *
     * @param user ç”¨æˆ·ä¿¡æ¯
     * @return ç»“æžœ
     */
    public String checkPhoneUnique(SysUser user);
    /**
     * æ ¡éªŒemail是否唯一
     *
     * @param user ç”¨æˆ·ä¿¡æ¯
     * @return ç»“æžœ
     */
    public String checkEmailUnique(SysUser user);
    /**
     * æ ¡éªŒç”¨æˆ·æ˜¯å¦å…è®¸æ“ä½œ
     *
     * @param user ç”¨æˆ·ä¿¡æ¯
     */
    public void checkUserAllowed(SysUser user);
    /**
     * æ–°å¢žç”¨æˆ·ä¿¡æ¯
     *
     * @param user ç”¨æˆ·ä¿¡æ¯
     * @return ç»“æžœ
     */
    public int insertUser(SysUser user);
    /**
     * ä¿®æ”¹ç”¨æˆ·ä¿¡æ¯
     *
     * @param user ç”¨æˆ·ä¿¡æ¯
     * @return ç»“æžœ
     */
    public int updateUser(SysUser user);
    /**
     * ä¿®æ”¹ç”¨æˆ·çŠ¶æ€
     *
     * @param user ç”¨æˆ·ä¿¡æ¯
     * @return ç»“æžœ
     */
    public int updateUserStatus(SysUser user);
    /**
     * ä¿®æ”¹ç”¨æˆ·åŸºæœ¬ä¿¡æ¯
     *
     * @param user ç”¨æˆ·ä¿¡æ¯
     * @return ç»“æžœ
     */
    public int updateUserProfile(SysUser user);
    /**
     * ä¿®æ”¹ç”¨æˆ·å¤´åƒ
     *
     * @param userName ç”¨æˆ·å
     * @param avatar å¤´åƒåœ°å€
     * @return ç»“æžœ
     */
    public boolean updateUserAvatar(String userName, String avatar);
    /**
     * é‡ç½®ç”¨æˆ·å¯†ç 
     *
     * @param user ç”¨æˆ·ä¿¡æ¯
     * @return ç»“æžœ
     */
    public int resetPwd(SysUser user);
    /**
     * é‡ç½®ç”¨æˆ·å¯†ç 
     *
     * @param userName ç”¨æˆ·å
     * @param password å¯†ç 
     * @return ç»“æžœ
     */
    public int resetUserPwd(String userName, String password);
    /**
     * é€šè¿‡ç”¨æˆ·ID删除用户
     *
     * @param userId ç”¨æˆ·ID
     * @return ç»“æžœ
     */
    public int deleteUserById(Long userId);
    /**
     * æ‰¹é‡åˆ é™¤ç”¨æˆ·ä¿¡æ¯
     *
     * @param userIds éœ€è¦åˆ é™¤çš„用户ID
     * @return ç»“æžœ
     */
    public int deleteUserByIds(Long[] userIds);
    /**
     * å¯¼å…¥ç”¨æˆ·æ•°æ®
     *
     * @param userList ç”¨æˆ·æ•°æ®åˆ—表
     * @param isUpdateSupport æ˜¯å¦æ›´æ–°æ”¯æŒï¼Œå¦‚果已存在,则进行更新数据
     * @param operName æ“ä½œç”¨æˆ·
     * @return ç»“æžœ
     */
    public String importUser(List<SysUser> userList, Boolean isUpdateSupport, String operName);
}
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,188 @@
package com.ruoyi.system.service.impl;
import java.util.Collection;
import java.util.List;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.common.annotation.DataSource;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.enums.DataSourceType;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.SysConfig;
import com.ruoyi.system.mapper.SysConfigMapper;
import com.ruoyi.system.service.ISysConfigService;
/**
 * å‚数配置 æœåŠ¡å±‚å®žçŽ°
 *
 * @author ruoyi
 */
@Service
public class SysConfigServiceImpl implements ISysConfigService
{
    @Autowired
    private SysConfigMapper configMapper;
    @Autowired
    private RedisCache redisCache;
    /**
     * é¡¹ç›®å¯åŠ¨æ—¶ï¼Œåˆå§‹åŒ–å‚æ•°åˆ°ç¼“å­˜
     */
    @PostConstruct
    public void init()
    {
        List<SysConfig> configsList = configMapper.selectConfigList(new SysConfig());
        for (SysConfig config : configsList)
        {
            redisCache.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue());
        }
    }
    /**
     * æŸ¥è¯¢å‚数配置信息
     *
     * @param configId å‚数配置ID
     * @return å‚数配置信息
     */
    @Override
    @DataSource(DataSourceType.MASTER)
    public SysConfig selectConfigById(Long configId)
    {
        SysConfig config = new SysConfig();
        config.setConfigId(configId);
        return configMapper.selectConfig(config);
    }
    /**
     * æ ¹æ®é”®åæŸ¥è¯¢å‚数配置信息
     *
     * @param configKey å‚æ•°key
     * @return å‚数键值
     */
    @Override
    public String selectConfigByKey(String configKey)
    {
        String configValue = Convert.toStr(redisCache.getCacheObject(getCacheKey(configKey)));
        if (StringUtils.isNotEmpty(configValue))
        {
            return configValue;
        }
        SysConfig config = new SysConfig();
        config.setConfigKey(configKey);
        SysConfig retConfig = configMapper.selectConfig(config);
        if (StringUtils.isNotNull(retConfig))
        {
            redisCache.setCacheObject(getCacheKey(configKey), retConfig.getConfigValue());
            return retConfig.getConfigValue();
        }
        return StringUtils.EMPTY;
    }
    /**
     * æŸ¥è¯¢å‚数配置列表
     *
     * @param config å‚数配置信息
     * @return å‚数配置集合
     */
    @Override
    public List<SysConfig> selectConfigList(SysConfig config)
    {
        return configMapper.selectConfigList(config);
    }
    /**
     * æ–°å¢žå‚数配置
     *
     * @param config å‚数配置信息
     * @return ç»“æžœ
     */
    @Override
    public int insertConfig(SysConfig config)
    {
        int row = configMapper.insertConfig(config);
        if (row > 0)
        {
            redisCache.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue());
        }
        return row;
    }
    /**
     * ä¿®æ”¹å‚数配置
     *
     * @param config å‚数配置信息
     * @return ç»“æžœ
     */
    @Override
    public int updateConfig(SysConfig config)
    {
        int row = configMapper.updateConfig(config);
        if (row > 0)
        {
            redisCache.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue());
        }
        return row;
    }
    /**
     * æ‰¹é‡åˆ é™¤å‚数信息
     *
     * @param configIds éœ€è¦åˆ é™¤çš„参数ID
     * @return ç»“æžœ
     */
    @Override
    public int deleteConfigByIds(Long[] configIds)
    {
        int count = configMapper.deleteConfigByIds(configIds);
        if (count > 0)
        {
            Collection<String> keys = redisCache.keys(Constants.SYS_CONFIG_KEY + "*");
            redisCache.deleteObject(keys);
        }
        return count;
    }
    /**
     * æ¸…空缓存数据
     */
    @Override
    public void clearCache()
    {
        Collection<String> keys = redisCache.keys(Constants.SYS_CONFIG_KEY + "*");
        redisCache.deleteObject(keys);
    }
    /**
     * æ ¡éªŒå‚数键名是否唯一
     *
     * @param config å‚数配置信息
     * @return ç»“æžœ
     */
    @Override
    public String checkConfigKeyUnique(SysConfig config)
    {
        Long configId = StringUtils.isNull(config.getConfigId()) ? -1L : config.getConfigId();
        SysConfig info = configMapper.checkConfigKeyUnique(config.getConfigKey());
        if (StringUtils.isNotNull(info) && info.getConfigId().longValue() != configId.longValue())
        {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }
    /**
     * è®¾ç½®cache key
     *
     * @param configKey å‚æ•°é”®
     * @return ç¼“存键key
     */
    private String getCacheKey(String configKey)
    {
        return Constants.SYS_CONFIG_KEY + configKey;
    }
}
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,306 @@
package com.ruoyi.system.service.impl;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.TreeSelect;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.exception.CustomException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.mapper.SysDeptMapper;
import com.ruoyi.system.service.ISysDeptService;
/**
 * éƒ¨é—¨ç®¡ç† æœåŠ¡å®žçŽ°
 *
 * @author ruoyi
 */
@Service
public class SysDeptServiceImpl implements ISysDeptService
{
    @Autowired
    private SysDeptMapper deptMapper;
    /**
     * æŸ¥è¯¢éƒ¨é—¨ç®¡ç†æ•°æ®
     *
     * @param dept éƒ¨é—¨ä¿¡æ¯
     * @return éƒ¨é—¨ä¿¡æ¯é›†åˆ
     */
    @Override
    @DataScope(deptAlias = "d")
    public List<SysDept> selectDeptList(SysDept dept)
    {
        return deptMapper.selectDeptList(dept);
    }
    /**
     * æž„建前端所需要树结构
     *
     * @param depts éƒ¨é—¨åˆ—表
     * @return æ ‘结构列表
     */
    @Override
    public List<SysDept> buildDeptTree(List<SysDept> depts)
    {
        List<SysDept> returnList = new ArrayList<SysDept>();
        List<Long> tempList = new ArrayList<Long>();
        for (SysDept dept : depts)
        {
            tempList.add(dept.getDeptId());
        }
        for (Iterator<SysDept> iterator = depts.iterator(); iterator.hasNext();)
        {
            SysDept dept = (SysDept) iterator.next();
            // å¦‚果是顶级节点, éåŽ†è¯¥çˆ¶èŠ‚ç‚¹çš„æ‰€æœ‰å­èŠ‚ç‚¹
            if (!tempList.contains(dept.getParentId()))
            {
                recursionFn(depts, dept);
                returnList.add(dept);
            }
        }
        if (returnList.isEmpty())
        {
            returnList = depts;
        }
        return returnList;
    }
    /**
     * æž„建前端所需要下拉树结构
     *
     * @param depts éƒ¨é—¨åˆ—表
     * @return ä¸‹æ‹‰æ ‘结构列表
     */
    @Override
    public List<TreeSelect> buildDeptTreeSelect(List<SysDept> depts)
    {
        List<SysDept> deptTrees = buildDeptTree(depts);
        return deptTrees.stream().map(TreeSelect::new).collect(Collectors.toList());
    }
    /**
     * æ ¹æ®è§’色ID查询部门树信息
     *
     * @param roleId è§’色ID
     * @return é€‰ä¸­éƒ¨é—¨åˆ—表
     */
    @Override
    public List<Integer> selectDeptListByRoleId(Long roleId)
    {
        return deptMapper.selectDeptListByRoleId(roleId);
    }
    /**
     * æ ¹æ®éƒ¨é—¨ID查询信息
     *
     * @param deptId éƒ¨é—¨ID
     * @return éƒ¨é—¨ä¿¡æ¯
     */
    @Override
    public SysDept selectDeptById(Long deptId)
    {
        return deptMapper.selectDeptById(deptId);
    }
    /**
     * æ ¹æ®ID查询所有子部门(正常状态)
     *
     * @param deptId éƒ¨é—¨ID
     * @return å­éƒ¨é—¨æ•°
     */
    @Override
    public int selectNormalChildrenDeptById(Long deptId)
    {
        return deptMapper.selectNormalChildrenDeptById(deptId);
    }
    /**
     * æ˜¯å¦å­˜åœ¨å­èŠ‚ç‚¹
     *
     * @param deptId éƒ¨é—¨ID
     * @return ç»“æžœ
     */
    @Override
    public boolean hasChildByDeptId(Long deptId)
    {
        int result = deptMapper.hasChildByDeptId(deptId);
        return result > 0 ? true : false;
    }
    /**
     * æŸ¥è¯¢éƒ¨é—¨æ˜¯å¦å­˜åœ¨ç”¨æˆ·
     *
     * @param deptId éƒ¨é—¨ID
     * @return ç»“æžœ true å­˜åœ¨ false ä¸å­˜åœ¨
     */
    @Override
    public boolean checkDeptExistUser(Long deptId)
    {
        int result = deptMapper.checkDeptExistUser(deptId);
        return result > 0 ? true : false;
    }
    /**
     * æ ¡éªŒéƒ¨é—¨åç§°æ˜¯å¦å”¯ä¸€
     *
     * @param dept éƒ¨é—¨ä¿¡æ¯
     * @return ç»“æžœ
     */
    @Override
    public String checkDeptNameUnique(SysDept dept)
    {
        Long deptId = StringUtils.isNull(dept.getDeptId()) ? -1L : dept.getDeptId();
        SysDept info = deptMapper.checkDeptNameUnique(dept.getDeptName(), dept.getParentId());
        if (StringUtils.isNotNull(info) && info.getDeptId().longValue() != deptId.longValue())
        {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }
    /**
     * æ–°å¢žä¿å­˜éƒ¨é—¨ä¿¡æ¯
     *
     * @param dept éƒ¨é—¨ä¿¡æ¯
     * @return ç»“æžœ
     */
    @Override
    public int insertDept(SysDept dept)
    {
        SysDept info = deptMapper.selectDeptById(dept.getParentId());
        // å¦‚果父节点不为正常状态,则不允许新增子节点
        if (!UserConstants.DEPT_NORMAL.equals(info.getStatus()))
        {
            throw new CustomException("部门停用,不允许新增");
        }
        dept.setAncestors(info.getAncestors() + "," + dept.getParentId());
        return deptMapper.insertDept(dept);
    }
    /**
     * ä¿®æ”¹ä¿å­˜éƒ¨é—¨ä¿¡æ¯
     *
     * @param dept éƒ¨é—¨ä¿¡æ¯
     * @return ç»“æžœ
     */
    @Override
    public int updateDept(SysDept dept)
    {
        SysDept newParentDept = deptMapper.selectDeptById(dept.getParentId());
        SysDept oldDept = deptMapper.selectDeptById(dept.getDeptId());
        if (StringUtils.isNotNull(newParentDept) && StringUtils.isNotNull(oldDept))
        {
            String newAncestors = newParentDept.getAncestors() + "," + newParentDept.getDeptId();
            String oldAncestors = oldDept.getAncestors();
            dept.setAncestors(newAncestors);
            updateDeptChildren(dept.getDeptId(), newAncestors, oldAncestors);
        }
        int result = deptMapper.updateDept(dept);
        if (UserConstants.DEPT_NORMAL.equals(dept.getStatus()))
        {
            // å¦‚果该部门是启用状态,则启用该部门的所有上级部门
            updateParentDeptStatus(dept);
        }
        return result;
    }
    /**
     * ä¿®æ”¹è¯¥éƒ¨é—¨çš„父级部门状态
     *
     * @param dept å½“前部门
     */
    private void updateParentDeptStatus(SysDept dept)
    {
        String updateBy = dept.getUpdateBy();
        dept = deptMapper.selectDeptById(dept.getDeptId());
        dept.setUpdateBy(updateBy);
        deptMapper.updateDeptStatus(dept);
    }
    /**
     * ä¿®æ”¹å­å…ƒç´ å…³ç³»
     *
     * @param deptId è¢«ä¿®æ”¹çš„部门ID
     * @param newAncestors æ–°çš„父ID集合
     * @param oldAncestors æ—§çš„父ID集合
     */
    public void updateDeptChildren(Long deptId, String newAncestors, String oldAncestors)
    {
        List<SysDept> children = deptMapper.selectChildrenDeptById(deptId);
        for (SysDept child : children)
        {
            child.setAncestors(child.getAncestors().replace(oldAncestors, newAncestors));
        }
        if (children.size() > 0)
        {
            deptMapper.updateDeptChildren(children);
        }
    }
    /**
     * åˆ é™¤éƒ¨é—¨ç®¡ç†ä¿¡æ¯
     *
     * @param deptId éƒ¨é—¨ID
     * @return ç»“æžœ
     */
    @Override
    public int deleteDeptById(Long deptId)
    {
        return deptMapper.deleteDeptById(deptId);
    }
    /**
     * é€’归列表
     */
    private void recursionFn(List<SysDept> list, SysDept t)
    {
        // å¾—到子节点列表
        List<SysDept> childList = getChildList(list, t);
        t.setChildren(childList);
        for (SysDept tChild : childList)
        {
            if (hasChild(list, tChild))
            {
                // åˆ¤æ–­æ˜¯å¦æœ‰å­èŠ‚ç‚¹
                Iterator<SysDept> it = childList.iterator();
                while (it.hasNext())
                {
                    SysDept n = (SysDept) it.next();
                    recursionFn(list, n);
                }
            }
        }
    }
    /**
     * å¾—到子节点列表
     */
    private List<SysDept> getChildList(List<SysDept> list, SysDept t)
    {
        List<SysDept> tlist = new ArrayList<SysDept>();
        Iterator<SysDept> it = list.iterator();
        while (it.hasNext())
        {
            SysDept n = (SysDept) it.next();
            if (StringUtils.isNotNull(n.getParentId()) && n.getParentId().longValue() == t.getDeptId().longValue())
            {
                tlist.add(n);
            }
        }
        return tlist;
    }
    /**
     * åˆ¤æ–­æ˜¯å¦æœ‰å­èŠ‚ç‚¹
     */
    private boolean hasChild(List<SysDept> list, SysDept t)
    {
        return getChildList(list, t).size() > 0 ? true : false;
    }
}
在上述文件截断后对比
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictDataServiceImpl.java ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictTypeServiceImpl.java ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysLogininforServiceImpl.java ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysNoticeServiceImpl.java ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOperLogServiceImpl.java ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysPostServiceImpl.java ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserOnlineServiceImpl.java ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java ruoyi-system/src/main/resources/mapper/system/SysConfigMapper.xml ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml ruoyi-system/src/main/resources/mapper/system/SysDictDataMapper.xml ruoyi-system/src/main/resources/mapper/system/SysDictTypeMapper.xml ruoyi-system/src/main/resources/mapper/system/SysLogininforMapper.xml ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml ruoyi-system/src/main/resources/mapper/system/SysNoticeMapper.xml ruoyi-system/src/main/resources/mapper/system/SysOperLogMapper.xml ruoyi-system/src/main/resources/mapper/system/SysPostMapper.xml ruoyi-system/src/main/resources/mapper/system/SysRoleDeptMapper.xml ruoyi-system/src/main/resources/mapper/system/SysRoleMapper.xml ruoyi-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml ruoyi-system/src/main/resources/mapper/system/SysUserPostMapper.xml ruoyi-system/src/main/resources/mapper/system/SysUserRoleMapper.xml ruoyi-ui/package.json ruoyi-ui/src/utils/index.js ruoyi-ui/vue.config.js ruoyi/bin/run-tomcat.bat (已删除) ruoyi/pom.xml (已删除) ruoyi/ry.sh (已删除) ruoyi/sql/quartz.sql (已删除) ruoyi/src/main/java/com/ruoyi/common/constant/Constants.java (已删除) ruoyi/src/main/java/com/ruoyi/common/constant/ScheduleConstants.java (已删除) ruoyi/src/main/java/com/ruoyi/common/core/lang/UUID.java (已删除) ruoyi/src/main/java/com/ruoyi/common/exception/job/TaskException.java (已删除) ruoyi/src/main/java/com/ruoyi/common/filter/RepeatableFilter.java (已删除) ruoyi/src/main/java/com/ruoyi/common/filter/RepeatedlyRequestWrapper.java (已删除) ruoyi/src/main/java/com/ruoyi/common/utils/DictUtils.java (已删除) ruoyi/src/main/java/com/ruoyi/common/utils/ExceptionUtil.java (已删除) ruoyi/src/main/java/com/ruoyi/common/utils/IdUtils.java (已删除) ruoyi/src/main/java/com/ruoyi/common/utils/SecurityUtils.java (已删除) ruoyi/src/main/java/com/ruoyi/common/utils/bean/BeanUtils.java (已删除) ruoyi/src/main/java/com/ruoyi/common/utils/file/FileUploadUtils.java (已删除) ruoyi/src/main/java/com/ruoyi/common/utils/html/HTMLFilter.java (已删除) ruoyi/src/main/java/com/ruoyi/common/utils/http/HttpHelper.java (已删除) ruoyi/src/main/java/com/ruoyi/common/utils/ip/AddressUtils.java (已删除) ruoyi/src/main/java/com/ruoyi/common/utils/job/AbstractQuartzJob.java (已删除) ruoyi/src/main/java/com/ruoyi/common/utils/job/CronUtils.java (已删除) ruoyi/src/main/java/com/ruoyi/common/utils/job/JobInvokeUtil.java (已删除) ruoyi/src/main/java/com/ruoyi/common/utils/job/QuartzDisallowConcurrentExecution.java (已删除) ruoyi/src/main/java/com/ruoyi/common/utils/job/QuartzJobExecution.java (已删除) ruoyi/src/main/java/com/ruoyi/common/utils/job/ScheduleUtils.java (已删除) ruoyi/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java (已删除) ruoyi/src/main/java/com/ruoyi/common/utils/reflect/ReflectUtils.java (已删除) ruoyi/src/main/java/com/ruoyi/framework/aspectj/DataScopeAspect.java (已删除) ruoyi/src/main/java/com/ruoyi/framework/aspectj/DataSourceAspect.java (已删除) ruoyi/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java (已删除) ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/DataScope.java (已删除) ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/DataSource.java (已删除) ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/Excel.java (已删除) ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/Excels.java (已删除) ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/Log.java (已删除) ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/enums/BusinessStatus.java (已删除) ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/enums/BusinessType.java (已删除) ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/enums/DataSourceType.java (已删除) ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/enums/OperatorType.java (已删除) ruoyi/src/main/java/com/ruoyi/framework/config/ApplicationConfig.java (已删除) ruoyi/src/main/java/com/ruoyi/framework/config/DruidConfig.java (已删除) ruoyi/src/main/java/com/ruoyi/framework/config/GenConfig.java (已删除) ruoyi/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java (已删除) ruoyi/src/main/java/com/ruoyi/framework/config/RuoYiConfig.java (已删除) ruoyi/src/main/java/com/ruoyi/framework/config/ScheduleConfig.java (已删除) ruoyi/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java (已删除) ruoyi/src/main/java/com/ruoyi/framework/interceptor/RepeatSubmitInterceptor.java (已删除) ruoyi/src/main/java/com/ruoyi/framework/interceptor/annotation/RepeatSubmit.java (已删除) ruoyi/src/main/java/com/ruoyi/framework/interceptor/impl/SameUrlDataInterceptor.java (已删除) ruoyi/src/main/java/com/ruoyi/framework/manager/factory/AsyncFactory.java (已删除) ruoyi/src/main/java/com/ruoyi/framework/redis/RedisCache.java (已删除) ruoyi/src/main/java/com/ruoyi/framework/security/LoginBody.java (已删除) ruoyi/src/main/java/com/ruoyi/framework/security/LoginUser.java (已删除) ruoyi/src/main/java/com/ruoyi/framework/security/filter/JwtAuthenticationTokenFilter.java (已删除) ruoyi/src/main/java/com/ruoyi/framework/security/handle/AuthenticationEntryPointImpl.java (已删除) ruoyi/src/main/java/com/ruoyi/framework/security/handle/LogoutSuccessHandlerImpl.java (已删除) ruoyi/src/main/java/com/ruoyi/framework/security/service/PermissionService.java (已删除) ruoyi/src/main/java/com/ruoyi/framework/security/service/SysLoginService.java (已删除) ruoyi/src/main/java/com/ruoyi/framework/security/service/SysPermissionService.java (已删除) ruoyi/src/main/java/com/ruoyi/framework/security/service/TokenService.java (已删除) ruoyi/src/main/java/com/ruoyi/framework/security/service/UserDetailsServiceImpl.java (已删除) ruoyi/src/main/java/com/ruoyi/framework/task/RyTask.java (已删除) ruoyi/src/main/java/com/ruoyi/framework/web/controller/BaseController.java (已删除) ruoyi/src/main/java/com/ruoyi/framework/web/domain/AjaxResult.java (已删除) ruoyi/src/main/java/com/ruoyi/framework/web/domain/BaseEntity.java (已删除) ruoyi/src/main/java/com/ruoyi/framework/web/domain/TreeEntity.java (已删除) ruoyi/src/main/java/com/ruoyi/framework/web/domain/TreeSelect.java (已删除) ruoyi/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java (已删除) ruoyi/src/main/java/com/ruoyi/framework/web/page/PageDomain.java (已删除) ruoyi/src/main/java/com/ruoyi/framework/web/page/TableDataInfo.java (已删除) ruoyi/src/main/java/com/ruoyi/framework/web/page/TableSupport.java (已删除) ruoyi/src/main/java/com/ruoyi/project/common/CaptchaController.java (已删除) ruoyi/src/main/java/com/ruoyi/project/common/CommonController.java (已删除) ruoyi/src/main/java/com/ruoyi/project/monitor/controller/ServerController.java (已删除) ruoyi/src/main/java/com/ruoyi/project/monitor/controller/SysJobController.java (已删除) ruoyi/src/main/java/com/ruoyi/project/monitor/controller/SysJobLogController.java (已删除) ruoyi/src/main/java/com/ruoyi/project/monitor/controller/SysLogininforController.java (已删除) ruoyi/src/main/java/com/ruoyi/project/monitor/controller/SysOperlogController.java (已删除) ruoyi/src/main/java/com/ruoyi/project/monitor/controller/SysUserOnlineController.java (已删除) ruoyi/src/main/java/com/ruoyi/project/monitor/domain/SysJob.java (已删除) ruoyi/src/main/java/com/ruoyi/project/monitor/domain/SysJobLog.java (已删除) ruoyi/src/main/java/com/ruoyi/project/monitor/domain/SysLogininfor.java (已删除) ruoyi/src/main/java/com/ruoyi/project/monitor/domain/SysOperLog.java (已删除) ruoyi/src/main/java/com/ruoyi/project/monitor/domain/SysUserOnline.java (已删除) ruoyi/src/main/java/com/ruoyi/project/monitor/mapper/SysJobLogMapper.java (已删除) ruoyi/src/main/java/com/ruoyi/project/monitor/mapper/SysJobMapper.java (已删除) ruoyi/src/main/java/com/ruoyi/project/monitor/mapper/SysLogininforMapper.java (已删除) ruoyi/src/main/java/com/ruoyi/project/monitor/mapper/SysOperLogMapper.java (已删除) ruoyi/src/main/java/com/ruoyi/project/monitor/service/ISysJobLogService.java (已删除) ruoyi/src/main/java/com/ruoyi/project/monitor/service/ISysJobService.java (已删除) ruoyi/src/main/java/com/ruoyi/project/monitor/service/ISysLogininforService.java (已删除) ruoyi/src/main/java/com/ruoyi/project/monitor/service/ISysOperLogService.java (已删除) ruoyi/src/main/java/com/ruoyi/project/monitor/service/impl/SysJobLogServiceImpl.java (已删除) ruoyi/src/main/java/com/ruoyi/project/monitor/service/impl/SysJobServiceImpl.java (已删除) ruoyi/src/main/java/com/ruoyi/project/monitor/service/impl/SysLogininforServiceImpl.java (已删除) ruoyi/src/main/java/com/ruoyi/project/monitor/service/impl/SysOperLogServiceImpl.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/controller/SysConfigController.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/controller/SysDeptController.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/controller/SysDictDataController.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/controller/SysDictTypeController.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/controller/SysLoginController.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/controller/SysMenuController.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/controller/SysNoticeController.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/controller/SysPostController.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/controller/SysProfileController.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/controller/SysRoleController.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/controller/SysUserController.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/domain/SysConfig.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/domain/SysDept.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/domain/SysDictData.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/domain/SysDictType.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/domain/SysMenu.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/domain/SysNotice.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/domain/SysPost.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/domain/SysRole.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/domain/SysRoleDept.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/domain/SysRoleMenu.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/domain/SysUser.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/domain/SysUserPost.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/domain/SysUserRole.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/domain/vo/MetaVo.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/domain/vo/RouterVo.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysConfigMapper.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysDeptMapper.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysDictDataMapper.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysDictTypeMapper.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysMenuMapper.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysNoticeMapper.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysPostMapper.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysRoleDeptMapper.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysRoleMapper.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysRoleMenuMapper.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysUserMapper.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysUserPostMapper.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysUserRoleMapper.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/service/ISysConfigService.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/service/ISysDeptService.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/service/ISysDictDataService.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/service/ISysDictTypeService.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/service/ISysMenuService.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/service/ISysNoticeService.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/service/ISysPostService.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/service/ISysRoleService.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/service/ISysUserOnlineService.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/service/ISysUserService.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysConfigServiceImpl.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysDeptServiceImpl.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysDictDataServiceImpl.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysDictTypeServiceImpl.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysMenuServiceImpl.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysNoticeServiceImpl.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysPostServiceImpl.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysRoleServiceImpl.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysUserOnlineServiceImpl.java (已删除) ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysUserServiceImpl.java (已删除) ruoyi/src/main/java/com/ruoyi/project/tool/gen/controller/GenController.java (已删除) ruoyi/src/main/java/com/ruoyi/project/tool/gen/domain/GenTable.java (已删除) ruoyi/src/main/java/com/ruoyi/project/tool/gen/domain/GenTableColumn.java (已删除) ruoyi/src/main/java/com/ruoyi/project/tool/gen/mapper/GenTableColumnMapper.java (已删除) ruoyi/src/main/java/com/ruoyi/project/tool/gen/mapper/GenTableMapper.java (已删除) ruoyi/src/main/java/com/ruoyi/project/tool/gen/service/GenTableColumnServiceImpl.java (已删除) ruoyi/src/main/java/com/ruoyi/project/tool/gen/service/GenTableServiceImpl.java (已删除) ruoyi/src/main/java/com/ruoyi/project/tool/gen/service/IGenTableColumnService.java (已删除) ruoyi/src/main/java/com/ruoyi/project/tool/gen/service/IGenTableService.java (已删除) ruoyi/src/main/java/com/ruoyi/project/tool/gen/util/GenUtils.java (已删除) ruoyi/src/main/java/com/ruoyi/project/tool/gen/util/VelocityInitializer.java (已删除) ruoyi/src/main/java/com/ruoyi/project/tool/gen/util/VelocityUtils.java (已删除) ruoyi/src/main/java/com/ruoyi/project/tool/swagger/TestController.java (已删除) ruoyi/src/main/resources/application.yml (已删除) ruoyi/src/main/resources/mybatis/monitor/SysLogininforMapper.xml (已删除) ruoyi/src/main/resources/mybatis/monitor/SysOperLogMapper.xml (已删除) ruoyi/src/main/resources/mybatis/system/SysConfigMapper.xml (已删除) ruoyi/src/main/resources/mybatis/system/SysDeptMapper.xml (已删除) ruoyi/src/main/resources/mybatis/system/SysDictDataMapper.xml (已删除) ruoyi/src/main/resources/mybatis/system/SysDictTypeMapper.xml (已删除) ruoyi/src/main/resources/mybatis/system/SysJobLogMapper.xml (已删除) ruoyi/src/main/resources/mybatis/system/SysJobMapper.xml (已删除) ruoyi/src/main/resources/mybatis/system/SysMenuMapper.xml (已删除) ruoyi/src/main/resources/mybatis/system/SysNoticeMapper.xml (已删除) ruoyi/src/main/resources/mybatis/system/SysPostMapper.xml (已删除) ruoyi/src/main/resources/mybatis/system/SysRoleDeptMapper.xml (已删除) ruoyi/src/main/resources/mybatis/system/SysRoleMapper.xml (已删除) ruoyi/src/main/resources/mybatis/system/SysRoleMenuMapper.xml (已删除) ruoyi/src/main/resources/mybatis/system/SysUserMapper.xml (已删除) ruoyi/src/main/resources/mybatis/system/SysUserPostMapper.xml (已删除) ruoyi/src/main/resources/mybatis/system/SysUserRoleMapper.xml (已删除) ruoyi/src/main/resources/mybatis/tool/GenTableColumnMapper.xml (已删除) ruoyi/src/main/resources/mybatis/tool/GenTableMapper.xml (已删除) ruoyi/src/main/resources/vm/java/controller.java.vm (已删除) ruoyi/src/main/resources/vm/java/domain.java.vm (已删除) ry.sh sql/quartz.sql sql/ry_20200629.sql