From c5f4dec55966032585ceee60c3ff27337347e0d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90Li?= <15040126243@163.com> Date: Tue, 28 Jun 2022 22:51:57 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8F=91=E5=B8=83=20v4.2.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitee/PULL_REQUEST_TEMPLATE.zh-CN.md | 2 +- README.md | 3 +- pom.xml | 89 +-- ruoyi-extend/pom.xml | 2 +- ruoyi-extend/ruoyi-monitor-admin/pom.xml | 2 +- ruoyi-extend/ruoyi-xxl-job-admin/pom.xml | 2 +- .../job/admin/controller/IndexController.java | 6 +- .../admin/controller/JobApiController.java | 12 +- .../admin/controller/JobCodeController.java | 6 +- .../admin/controller/JobGroupController.java | 6 +- .../admin/controller/JobInfoController.java | 14 +- .../admin/controller/JobLogController.java | 22 +- .../job/admin/controller/UserController.java | 8 +- .../interceptor/CookieInterceptor.java | 5 +- .../interceptor/PermissionInterceptor.java | 6 +- .../resolver/WebExceptionResolver.java | 8 +- .../xxl/job/admin/core/alarm/JobAlarmer.java | 4 +- .../admin/core/alarm/impl/EmailJobAlarm.java | 59 +- .../admin/core/complete/XxlJobCompleter.java | 32 +- .../admin/core/conf/XxlJobAdminConfig.java | 1 + .../job/admin/core/cron/CronExpression.java | 419 +++++------ .../admin/core/exception/XxlJobException.java | 1 + .../xxl/job/admin/core/model/XxlJobGroup.java | 3 +- .../xxl/job/admin/core/model/XxlJobInfo.java | 2 +- .../job/admin/core/old/RemoteHttpJobBean.java | 4 +- .../core/old/XxlJobDynamicScheduler.java | 4 +- .../job/admin/core/old/XxlJobThreadPool.java | 2 +- .../core/route/ExecutorRouteStrategyEnum.java | 5 +- .../job/admin/core/route/ExecutorRouter.java | 2 +- .../route/strategy/ExecutorRouteBusyover.java | 12 +- .../strategy/ExecutorRouteConsistentHash.java | 13 +- .../route/strategy/ExecutorRouteFailover.java | 12 +- .../route/strategy/ExecutorRouteFirst.java | 2 +- .../core/route/strategy/ExecutorRouteLFU.java | 16 +- .../core/route/strategy/ExecutorRouteLRU.java | 14 +- .../route/strategy/ExecutorRouteLast.java | 2 +- .../route/strategy/ExecutorRouteRound.java | 4 +- .../core/scheduler/MisfireStrategyEnum.java | 4 +- .../core/scheduler/ScheduleTypeEnum.java | 4 +- .../admin/core/scheduler/XxlJobScheduler.java | 11 +- .../admin/core/thread/JobCompleteHelper.java | 4 +- .../core/thread/JobFailMonitorHelper.java | 4 +- .../admin/core/thread/JobLogReportHelper.java | 24 +- .../admin/core/thread/JobRegistryHelper.java | 4 +- .../admin/core/thread/JobScheduleHelper.java | 51 +- .../admin/core/trigger/TriggerTypeEnum.java | 4 +- .../job/admin/core/trigger/XxlJobTrigger.java | 54 +- .../xxl/job/admin/core/util/CookieUtil.java | 2 +- .../com/xxl/job/admin/core/util/I18nUtil.java | 11 +- .../job/admin/core/util/LocalCacheUtil.java | 23 +- .../xxl/job/admin/dao/XxlJobRegistryDao.java | 4 +- .../xxl/job/admin/service/LoginService.java | 16 +- .../admin/service/impl/XxlJobServiceImpl.java | 30 +- .../main/resources/i18n/message_en.properties | 12 +- .../resources/i18n/message_zh_CN.properties | 4 +- .../resources/i18n/message_zh_TC.properties | 4 +- .../main/resources/static/js/user.index.1.js | 358 ++++----- ruoyi-ui/package.json | 2 +- ruoyi-ui/src/api/login.js | 12 + ruoyi-ui/src/api/system/oss.js | 8 + .../src/assets/styles/element-variables.scss | 2 +- ruoyi-ui/src/components/FileUpload/index.vue | 29 +- .../src/components/ImagePreview/index.vue | 11 +- ruoyi-ui/src/components/ImageUpload/index.vue | 26 +- ruoyi-ui/src/main.js | 3 + ruoyi-ui/src/utils/dict/DictMeta.js | 2 +- .../src/utils/generator/drawingDefalut.js | 29 - ruoyi-ui/src/utils/ruoyi.js | 8 +- ruoyi-ui/src/views/index.vue | 2 +- ruoyi-ui/src/views/system/dict/data.vue | 6 +- ruoyi-ui/src/views/system/oss/config.vue | 38 +- ruoyi-ui/src/views/system/user/index.vue | 1 + ruoyi-ui/src/views/tool/build/RightPanel.vue | 2 +- ruoyi-ui/src/views/tool/gen/index.vue | 2 +- ruoyi/pom.xml | 54 +- .../ruoyi/common/annotation/Anonymous.java | 18 + .../ruoyi/common/annotation/CellMerge.java | 24 + .../common/core/domain/entity/SysUser.java | 6 - .../ruoyi/common/excel/CellMergeStrategy.java | 114 +++ .../common/helper/DataPermissionHelper.java | 12 +- .../com/ruoyi/common/helper/LoginHelper.java | 22 +- .../jackson/SensitiveJsonSerializer.java | 4 +- .../ruoyi/common/utils/email/MailUtils.java | 468 ++++++++++++ .../common/utils/file/MimeTypeUtils.java | 40 + .../com/ruoyi/common/utils/poi/ExcelUtil.java | 127 +++- .../ruoyi/common/utils/redis/RedisUtils.java | 66 +- .../ruoyi/demo/controller/MailController.java | 48 ++ .../demo/controller/RedisCacheController.java | 4 +- .../ruoyi/demo/controller/SmsController.java | 72 ++ .../demo/controller/TestDemoController.java | 3 +- .../demo/controller/TestExcelController.java | 102 +++ .../com/ruoyi/demo/domain/bo/TestDemoBo.java | 2 +- .../com/ruoyi/demo/domain/vo/TestDemoVo.java | 2 +- .../com/ruoyi/demo/mapper/TestDemoMapper.java | 2 +- .../framework/aspectj/RepeatSubmitAspect.java | 4 +- .../ruoyi/framework/config/JacksonConfig.java | 38 +- .../ruoyi/framework/config/MailConfig.java | 35 + .../ruoyi/framework/config/RedisConfig.java | 108 ++- .../ruoyi/framework/config/SaTokenConfig.java | 22 +- .../ruoyi/framework/config/SwaggerConfig.java | 2 +- .../framework/config/ThreadPoolConfig.java | 4 +- .../framework/config/UndertowConfig.java | 30 + .../properties/ExcludeUrlProperties.java | 61 ++ .../config/properties/MailProperties.java | 71 ++ .../listener/UserActionListener.java | 8 +- .../framework/satoken/dao/PlusSaTokenDao.java | 16 +- .../service/GenTableServiceImpl.java | 5 + .../com/ruoyi/oss/constant/OssConstant.java | 5 + .../java/com/ruoyi/oss/core/OssClient.java | 188 +++++ .../java/com/ruoyi/oss/enumd/OssEnumd.java | 52 -- .../java/com/ruoyi/oss/enumd/PolicyType.java | 16 - .../com/ruoyi/oss/factory/OssFactory.java | 56 +- .../ruoyi/oss/properties/OssProperties.java | 7 +- .../com/ruoyi/oss/service/IOssStrategy.java | 73 -- .../abstractd/AbstractOssStrategy.java | 69 -- .../oss/service/impl/AliyunOssStrategy.java | 120 --- .../oss/service/impl/MinioOssStrategy.java | 194 ----- .../oss/service/impl/QcloudOssStrategy.java | 125 ---- .../oss/service/impl/QiniuOssStrategy.java | 127 ---- .../java/com/ruoyi/sms/config/SmsConfig.java | 46 ++ .../sms/config/properties/SmsProperties.java | 47 ++ .../com/ruoyi/sms/core/AliyunSmsTemplate.java | 66 ++ .../java/com/ruoyi/sms/core/SmsTemplate.java | 26 + .../ruoyi/sms/core/TencentSmsTemplate.java | 81 +++ .../java/com/ruoyi/sms/entity/SmsResult.java | 29 + .../com/ruoyi/sms/exception/SmsException.java | 16 + .../com/ruoyi/system/domain/SysOssConfig.java | 6 +- .../system/domain/bo/SysOssConfigBo.java | 26 +- .../system/domain/vo/SysOssConfigVo.java | 6 + .../ruoyi/system/service/ISysOssService.java | 3 + .../ruoyi/system/service/SysLoginService.java | 18 +- .../service/impl/SysMenuServiceImpl.java | 2 +- .../service/impl/SysOssConfigServiceImpl.java | 7 +- .../service/impl/SysOssServiceImpl.java | 28 +- .../service/impl/SysSensitiveServiceImpl.java | 2 +- .../service/impl/SysUserServiceImpl.java | 36 +- .../controller/common/CaptchaController.java | 44 +- .../controller/system/SysLoginController.java | 8 +- .../controller/system/SysOssController.java | 14 + .../system/SysProfileController.java | 7 + .../system/SysRegisterController.java | 2 + .../controller/system/SysRoleController.java | 2 +- ruoyi/src/main/resources/application-dev.yml | 38 +- ruoyi/src/main/resources/application-prod.yml | 38 +- ruoyi/src/main/resources/application.yml | 6 - ruoyi/src/main/resources/excel/单列表.xlsx | Bin 0 -> 10787 bytes ruoyi/src/main/resources/excel/多列表.xlsx | Bin 0 -> 10761 bytes ruoyi/src/main/resources/logback.xml | 10 +- .../resources/mapper/system/SysMenuMapper.xml | 18 +- .../resources/mapper/system/SysRoleMapper.xml | 10 +- .../resources/mapper/system/SysUserMapper.xml | 16 +- .../mapper/system/SysUserRoleMapper.xml | 4 +- .../main/resources/vm/java/controller.java.vm | 10 +- .../src/main/resources/vm/java/domain.java.vm | 3 +- .../main/resources/vm/java/service.java.vm | 19 - .../resources/vm/java/serviceImpl.java.vm | 20 - .../resources/vm/vue/v3/index-tree.vue.vm | 18 +- script/docker/docker-compose.yml | 16 +- script/docker/nginx/nginx.conf | 13 +- script/sql/oracle/oracle_ry_vue_4.X.sql | 14 +- script/sql/postgres/postgres_ry_vue_4.X.sql | 184 ++--- script/sql/ry_vue_4.0.sql | 686 ------------------ script/sql/ry_vue_4.X.sql | 17 +- script/sql/sqlserver/sqlserver_ry_vue_4.X.sql | 19 +- script/sql/update/oracle/update-4.1-4.2.sql | 12 + script/sql/update/postgres/update-4.1-4.2.sql | 11 + .../sql/update/sqlserver/update-4.1-4.2.sql | 27 + script/sql/update/update-4.1-4.2.sql | 14 + 168 files changed, 3232 insertions(+), 2756 deletions(-) delete mode 100644 ruoyi-ui/src/utils/generator/drawingDefalut.js create mode 100644 ruoyi/src/main/java/com/ruoyi/common/annotation/Anonymous.java create mode 100644 ruoyi/src/main/java/com/ruoyi/common/annotation/CellMerge.java create mode 100644 ruoyi/src/main/java/com/ruoyi/common/excel/CellMergeStrategy.java create mode 100644 ruoyi/src/main/java/com/ruoyi/common/utils/email/MailUtils.java create mode 100644 ruoyi/src/main/java/com/ruoyi/common/utils/file/MimeTypeUtils.java create mode 100644 ruoyi/src/main/java/com/ruoyi/demo/controller/MailController.java create mode 100644 ruoyi/src/main/java/com/ruoyi/demo/controller/SmsController.java create mode 100644 ruoyi/src/main/java/com/ruoyi/demo/controller/TestExcelController.java create mode 100644 ruoyi/src/main/java/com/ruoyi/framework/config/MailConfig.java create mode 100644 ruoyi/src/main/java/com/ruoyi/framework/config/UndertowConfig.java create mode 100644 ruoyi/src/main/java/com/ruoyi/framework/config/properties/ExcludeUrlProperties.java create mode 100644 ruoyi/src/main/java/com/ruoyi/framework/config/properties/MailProperties.java create mode 100644 ruoyi/src/main/java/com/ruoyi/oss/core/OssClient.java delete mode 100644 ruoyi/src/main/java/com/ruoyi/oss/enumd/OssEnumd.java delete mode 100644 ruoyi/src/main/java/com/ruoyi/oss/service/IOssStrategy.java delete mode 100644 ruoyi/src/main/java/com/ruoyi/oss/service/abstractd/AbstractOssStrategy.java delete mode 100644 ruoyi/src/main/java/com/ruoyi/oss/service/impl/AliyunOssStrategy.java delete mode 100644 ruoyi/src/main/java/com/ruoyi/oss/service/impl/MinioOssStrategy.java delete mode 100644 ruoyi/src/main/java/com/ruoyi/oss/service/impl/QcloudOssStrategy.java delete mode 100644 ruoyi/src/main/java/com/ruoyi/oss/service/impl/QiniuOssStrategy.java create mode 100644 ruoyi/src/main/java/com/ruoyi/sms/config/SmsConfig.java create mode 100644 ruoyi/src/main/java/com/ruoyi/sms/config/properties/SmsProperties.java create mode 100644 ruoyi/src/main/java/com/ruoyi/sms/core/AliyunSmsTemplate.java create mode 100644 ruoyi/src/main/java/com/ruoyi/sms/core/SmsTemplate.java create mode 100644 ruoyi/src/main/java/com/ruoyi/sms/core/TencentSmsTemplate.java create mode 100644 ruoyi/src/main/java/com/ruoyi/sms/entity/SmsResult.java create mode 100644 ruoyi/src/main/java/com/ruoyi/sms/exception/SmsException.java create mode 100644 ruoyi/src/main/resources/excel/单列表.xlsx create mode 100644 ruoyi/src/main/resources/excel/多列表.xlsx delete mode 100644 script/sql/ry_vue_4.0.sql create mode 100644 script/sql/update/oracle/update-4.1-4.2.sql create mode 100644 script/sql/update/postgres/update-4.1-4.2.sql create mode 100644 script/sql/update/sqlserver/update-4.1-4.2.sql create mode 100644 script/sql/update/update-4.1-4.2.sql diff --git a/.gitee/PULL_REQUEST_TEMPLATE.zh-CN.md b/.gitee/PULL_REQUEST_TEMPLATE.zh-CN.md index 9429a8e86..f5ef7c154 100644 --- a/.gitee/PULL_REQUEST_TEMPLATE.zh-CN.md +++ b/.gitee/PULL_REQUEST_TEMPLATE.zh-CN.md @@ -1,4 +1,4 @@ -### 更改目的 解决了什么问题 +### 更改目的 解决了什么问题(请提交到dev分支) ### 描述 做了哪些改动 diff --git a/README.md b/README.md index 203a03dbc..d2e514751 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [![License](https://img.shields.io/badge/License-MIT-blue.svg)](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/blob/master/LICENSE) [![使用IntelliJ IDEA开发维护](https://img.shields.io/badge/IntelliJ%20IDEA-提供支持-blue.svg)](https://www.jetbrains.com/?from=RuoYi-Vue-Plus)
-[![RuoYi-Vue-Plus](https://img.shields.io/badge/RuoYi_Vue_Plus-4.1.0-success.svg)](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus) +[![RuoYi-Vue-Plus](https://img.shields.io/badge/RuoYi_Vue_Plus-4.2.0-success.svg)](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus) [![Spring Boot](https://img.shields.io/badge/Spring%20Boot-2.6-blue.svg)]() [![JDK-8+](https://img.shields.io/badge/JDK-8-green.svg)]() [![JDK-11](https://img.shields.io/badge/JDK-11-green.svg)]() @@ -42,6 +42,7 @@ | 分布式任务调度 | Xxl-Job | [Xxl-Job官网](https://www.xuxueli.com/xxl-job/) | 高性能 高可靠 易扩展 | | 文件存储 | Minio | [Minio文档](https://docs.min.io/) | 本地存储 | | 文件存储 | 七牛、阿里、腾讯 | [OSS使用文档](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/pages?sort_id=4359146&doc_id=1469725) | 云存储 | +| 短信模块 | 阿里、腾讯 | [短信使用文档](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/pages?sort_id=5578491&doc_id=1469725) | 短信发送 | | 监控框架 | SpringBoot-Admin | [SpringBoot-Admin文档](https://codecentric.github.io/spring-boot-admin/current/) | 全方位服务监控 | | 校验框架 | Validation | [Validation文档](https://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/) | 增强接口安全性、严谨性 支持国际化 | | Excel框架 | Alibaba EasyExcel | [EasyExcel文档](https://www.yuque.com/easyexcel/doc/easyexcel) | 性能优异 扩展性强 | diff --git a/pom.xml b/pom.xml index 0ea4c098d..fe199e04e 100644 --- a/pom.xml +++ b/pom.xml @@ -6,49 +6,46 @@ com.ruoyi ruoyi-vue-plus - 4.1.0 + 4.2.0 RuoYi-Vue-Plus https://gitee.com/JavaLionLi/RuoYi-Vue-Plus RuoYi-Vue-Plus后台管理系统 - 4.1.0 - 2.6.7 + 4.2.0 + 2.6.9 UTF-8 UTF-8 1.8 3.2.2 - 2.2.0 - 1.2.8 + 2.2.2 + 1.2.11 3.0.3 1.5.22 - 4.1.2 - 1.21 - 3.0.5 + 5.2.2 + 3.1.1 2.3 - 1.29.0 - 3.5.1 + 1.30.0 + 3.5.2 3.9.1 - 5.7.22 + 5.8.3 4.9.3 - 2.6.6 - 3.17.0 + 2.6.7 + 3.17.4 2.2.1 3.5.1 - 1.3.6 - 2.3.0 + 1.4.3 + 2.3.1 - - 3.0.1 30.0-jre - 7.9.5 - 3.14.0 - 5.6.72 - 8.3.8 + 1.12.248 + + 2.0.9 + 3.1.537 localhost @@ -105,29 +102,21 @@ ${swagger-annotations.version} - + + org.apache.poi + poi + ${poi.version} + org.apache.poi poi-ooxml ${poi.version} - - - - org.apache.commons - commons-compress - ${commons-compress.version} - - com.alibaba easyexcel ${easyexcel.version} - - org.apache.poi - poi - org.apache.poi poi-ooxml-schemas @@ -155,13 +144,6 @@ ${satoken.version} - - - com.sun.xml.bind - jaxb-impl - ${jaxb.version} - - com.baomidou @@ -192,6 +174,24 @@ ${okhttp.version} + + com.amazonaws + aws-java-sdk-s3 + ${aws-java-sdk-s3.version} + + + + com.aliyun + dysmsapi20170525 + ${aliyun.sms.version} + + + + com.tencentcloudapi + tencentcloud-sdk-java + ${tencent.sms.version} + + de.codecentric spring-boot-admin-starter-server @@ -248,6 +248,13 @@ ${tlog.version} + + + com.google.guava + guava + ${guava.version} + + diff --git a/ruoyi-extend/pom.xml b/ruoyi-extend/pom.xml index 5e3725e57..2be8693e4 100644 --- a/ruoyi-extend/pom.xml +++ b/ruoyi-extend/pom.xml @@ -5,7 +5,7 @@ ruoyi-vue-plus com.ruoyi - 4.1.0 + 4.2.0 4.0.0 ruoyi-extend diff --git a/ruoyi-extend/ruoyi-monitor-admin/pom.xml b/ruoyi-extend/ruoyi-monitor-admin/pom.xml index 8fed38aad..e42e8e0f4 100644 --- a/ruoyi-extend/ruoyi-monitor-admin/pom.xml +++ b/ruoyi-extend/ruoyi-monitor-admin/pom.xml @@ -5,7 +5,7 @@ ruoyi-extend com.ruoyi - 4.1.0 + 4.2.0 4.0.0 jar diff --git a/ruoyi-extend/ruoyi-xxl-job-admin/pom.xml b/ruoyi-extend/ruoyi-xxl-job-admin/pom.xml index d61f79dc5..b9954beac 100644 --- a/ruoyi-extend/ruoyi-xxl-job-admin/pom.xml +++ b/ruoyi-extend/ruoyi-xxl-job-admin/pom.xml @@ -4,7 +4,7 @@ ruoyi-extend com.ruoyi - 4.1.0 + 4.2.0 ruoyi-xxl-job-admin jar diff --git a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/controller/IndexController.java b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/controller/IndexController.java index 8d5495c53..bbb25077d 100644 --- a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/controller/IndexController.java +++ b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/controller/IndexController.java @@ -56,13 +56,13 @@ public class IndexController { @PermissionLimit(limit = false) public ModelAndView toLogin(HttpServletRequest request, HttpServletResponse response, ModelAndView modelAndView) { if (loginService.ifLogin(request, response) != null) { - modelAndView.setView(new RedirectView("/" , true, false)); + modelAndView.setView(new RedirectView("/", true, false)); return modelAndView; } return new ModelAndView("login"); } - @RequestMapping(value = "login" , method = RequestMethod.POST) + @RequestMapping(value = "login", method = RequestMethod.POST) @ResponseBody @PermissionLimit(limit = false) public ReturnT loginDo(HttpServletRequest request, HttpServletResponse response, String userName, String password, String ifRemember) { @@ -70,7 +70,7 @@ public class IndexController { return loginService.login(request, response, userName, password, ifRem); } - @RequestMapping(value = "logout" , method = RequestMethod.POST) + @RequestMapping(value = "logout", method = RequestMethod.POST) @ResponseBody @PermissionLimit(limit = false) public ReturnT logout(HttpServletRequest request, HttpServletResponse response) { diff --git a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobApiController.java b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobApiController.java index aa51e7390..f4a37a71d 100644 --- a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobApiController.java +++ b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobApiController.java @@ -37,19 +37,19 @@ public class JobApiController { */ @RequestMapping("/{uri}") @ResponseBody - @PermissionLimit(limit=false) + @PermissionLimit(limit = false) public ReturnT api(HttpServletRequest request, @PathVariable("uri") String uri, @RequestBody(required = false) String data) { // valid if (!"POST".equalsIgnoreCase(request.getMethod())) { return new ReturnT(ReturnT.FAIL_CODE, "invalid request, HttpMethod not support."); } - if (uri==null || uri.trim().length()==0) { + if (uri == null || uri.trim().length() == 0) { return new ReturnT(ReturnT.FAIL_CODE, "invalid request, uri-mapping empty."); } - if (XxlJobAdminConfig.getAdminConfig().getAccessToken()!=null - && XxlJobAdminConfig.getAdminConfig().getAccessToken().trim().length()>0 - && !XxlJobAdminConfig.getAdminConfig().getAccessToken().equals(request.getHeader(XxlJobRemotingUtil.XXL_JOB_ACCESS_TOKEN))) { + if (XxlJobAdminConfig.getAdminConfig().getAccessToken() != null + && XxlJobAdminConfig.getAdminConfig().getAccessToken().trim().length() > 0 + && !XxlJobAdminConfig.getAdminConfig().getAccessToken().equals(request.getHeader(XxlJobRemotingUtil.XXL_JOB_ACCESS_TOKEN))) { return new ReturnT(ReturnT.FAIL_CODE, "The access token is wrong."); } @@ -64,7 +64,7 @@ public class JobApiController { RegistryParam registryParam = GsonTool.fromJson(data, RegistryParam.class); return adminBiz.registryRemove(registryParam); } else { - return new ReturnT(ReturnT.FAIL_CODE, "invalid request, uri-mapping("+ uri +") not found."); + return new ReturnT(ReturnT.FAIL_CODE, "invalid request, uri-mapping(" + uri + ") not found."); } } diff --git a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobCodeController.java b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobCodeController.java index 0c8384f0f..9185f86b4 100644 --- a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobCodeController.java +++ b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobCodeController.java @@ -47,10 +47,10 @@ public class JobCodeController { JobInfoController.validPermission(request, jobInfo.getJobGroup()); // Glue类型-字典 - model.addAttribute("GlueTypeEnum" , GlueTypeEnum.values()); + model.addAttribute("GlueTypeEnum", GlueTypeEnum.values()); - model.addAttribute("jobInfo" , jobInfo); - model.addAttribute("jobLogGlues" , jobLogGlues); + model.addAttribute("jobInfo", jobInfo); + model.addAttribute("jobLogGlues", jobLogGlues); return "jobcode/jobcode.index"; } diff --git a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobGroupController.java b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobGroupController.java index 4a4620092..82ec2dee4 100644 --- a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobGroupController.java +++ b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobGroupController.java @@ -52,9 +52,9 @@ public class JobGroupController { // package result Map maps = new HashMap(); - maps.put("recordsTotal" , list_count); // 总记录数 - maps.put("recordsFiltered" , list_count); // 过滤后的总记录数 - maps.put("data" , list); // 分页列表 + maps.put("recordsTotal", list_count); // 总记录数 + maps.put("recordsFiltered", list_count); // 过滤后的总记录数 + maps.put("data", list); // 分页列表 return maps; } diff --git a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobInfoController.java b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobInfoController.java index 0f52bef73..157c60ba7 100644 --- a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobInfoController.java +++ b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobInfoController.java @@ -49,11 +49,11 @@ public class JobInfoController { public String index(HttpServletRequest request, Model model, @RequestParam(required = false, defaultValue = "-1") int jobGroup) { // 枚举-字典 - model.addAttribute("ExecutorRouteStrategyEnum" , ExecutorRouteStrategyEnum.values()); // 路由策略-列表 - model.addAttribute("GlueTypeEnum" , GlueTypeEnum.values()); // Glue类型-字典 - model.addAttribute("ExecutorBlockStrategyEnum" , ExecutorBlockStrategyEnum.values()); // 阻塞处理策略-字典 - model.addAttribute("ScheduleTypeEnum" , ScheduleTypeEnum.values()); // 调度类型 - model.addAttribute("MisfireStrategyEnum" , MisfireStrategyEnum.values()); // 调度过期策略 + model.addAttribute("ExecutorRouteStrategyEnum", ExecutorRouteStrategyEnum.values()); // 路由策略-列表 + model.addAttribute("GlueTypeEnum", GlueTypeEnum.values()); // Glue类型-字典 + model.addAttribute("ExecutorBlockStrategyEnum", ExecutorBlockStrategyEnum.values()); // 阻塞处理策略-字典 + model.addAttribute("ScheduleTypeEnum", ScheduleTypeEnum.values()); // 调度类型 + model.addAttribute("MisfireStrategyEnum", MisfireStrategyEnum.values()); // 调度过期策略 // 执行器列表 List jobGroupList_all = xxlJobGroupDao.findAll(); @@ -64,8 +64,8 @@ public class JobInfoController { throw new XxlJobException(I18nUtil.getString("jobgroup_empty")); } - model.addAttribute("JobGroupList" , jobGroupList); - model.addAttribute("jobGroup" , jobGroup); + model.addAttribute("JobGroupList", jobGroupList); + model.addAttribute("jobGroup", jobGroup); return "jobinfo/jobinfo.index"; } diff --git a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobLogController.java b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobLogController.java index 141b539c1..3369edb8f 100644 --- a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobLogController.java +++ b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobLogController.java @@ -1,7 +1,7 @@ package com.xxl.job.admin.controller; -import com.xxl.job.admin.core.complete.XxlJobCompleter; import com.xxl.job.admin.core.exception.XxlJobException; +import com.xxl.job.admin.core.complete.XxlJobCompleter; import com.xxl.job.admin.core.model.XxlJobGroup; import com.xxl.job.admin.core.model.XxlJobInfo; import com.xxl.job.admin.core.model.XxlJobLog; @@ -60,7 +60,7 @@ public class JobLogController { throw new XxlJobException(I18nUtil.getString("jobgroup_empty")); } - model.addAttribute("JobGroupList" , jobGroupList); + model.addAttribute("JobGroupList", jobGroupList); // 任务 if (jobId > 0) { @@ -69,7 +69,7 @@ public class JobLogController { throw new RuntimeException(I18nUtil.getString("jobinfo_field_id") + I18nUtil.getString("system_unvalid")); } - model.addAttribute("jobInfo" , jobInfo); + model.addAttribute("jobInfo", jobInfo); // valid permission JobInfoController.validPermission(request, jobInfo.getJobGroup()); @@ -112,9 +112,9 @@ public class JobLogController { // package result Map maps = new HashMap(); - maps.put("recordsTotal" , list_count); // 总记录数 - maps.put("recordsFiltered" , list_count); // 过滤后的总记录数 - maps.put("data" , list); // 分页列表 + maps.put("recordsTotal", list_count); // 总记录数 + maps.put("recordsFiltered", list_count); // 过滤后的总记录数 + maps.put("data", list); // 分页列表 return maps; } @@ -128,11 +128,11 @@ public class JobLogController { throw new RuntimeException(I18nUtil.getString("joblog_logid_unvalid")); } - model.addAttribute("triggerCode" , jobLog.getTriggerCode()); - model.addAttribute("handleCode" , jobLog.getHandleCode()); - model.addAttribute("executorAddress" , jobLog.getExecutorAddress()); - model.addAttribute("triggerTime" , jobLog.getTriggerTime().getTime()); - model.addAttribute("logId" , jobLog.getId()); + model.addAttribute("triggerCode", jobLog.getTriggerCode()); + model.addAttribute("handleCode", jobLog.getHandleCode()); + model.addAttribute("executorAddress", jobLog.getExecutorAddress()); + model.addAttribute("triggerTime", jobLog.getTriggerTime().getTime()); + model.addAttribute("logId", jobLog.getId()); return "joblog/joblog.detail"; } diff --git a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/controller/UserController.java b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/controller/UserController.java index b38e1b1b8..878998d39 100644 --- a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/controller/UserController.java +++ b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/controller/UserController.java @@ -40,7 +40,7 @@ public class UserController { // 执行器列表 List groupList = xxlJobGroupDao.findAll(); - model.addAttribute("groupList" , groupList); + model.addAttribute("groupList", groupList); return "user/user.index"; } @@ -65,9 +65,9 @@ public class UserController { // package result Map maps = new HashMap(); - maps.put("recordsTotal" , list_count); // 总记录数 - maps.put("recordsFiltered" , list_count); // 过滤后的总记录数 - maps.put("data" , list); // 分页列表 + maps.put("recordsTotal", list_count); // 总记录数 + maps.put("recordsFiltered", list_count); // 过滤后的总记录数 + maps.put("data", list); // 分页列表 return maps; } diff --git a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/controller/interceptor/CookieInterceptor.java b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/controller/interceptor/CookieInterceptor.java index 6714d1eca..228384996 100644 --- a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/controller/interceptor/CookieInterceptor.java +++ b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/controller/interceptor/CookieInterceptor.java @@ -29,15 +29,14 @@ public class CookieInterceptor implements AsyncHandlerInterceptor { for (Cookie ck : request.getCookies()) { cookieMap.put(ck.getName(), ck); } - modelAndView.addObject("cookieMap" , cookieMap); + modelAndView.addObject("cookieMap", cookieMap); } // static method if (modelAndView != null) { - modelAndView.addObject("I18nUtil" , FtlUtil.generateStaticModel(I18nUtil.class.getName())); + modelAndView.addObject("I18nUtil", FtlUtil.generateStaticModel(I18nUtil.class.getName())); } - AsyncHandlerInterceptor.super.postHandle(request, response, handler, modelAndView); } } diff --git a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/controller/interceptor/PermissionInterceptor.java b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/controller/interceptor/PermissionInterceptor.java index ecaeca0ff..13e53b2f1 100644 --- a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/controller/interceptor/PermissionInterceptor.java +++ b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/controller/interceptor/PermissionInterceptor.java @@ -27,7 +27,7 @@ public class PermissionInterceptor implements AsyncHandlerInterceptor { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (!(handler instanceof HandlerMethod)) { - return AsyncHandlerInterceptor.super.preHandle(request, response, handler); + return true; // proceed with the next interceptor } // if need login @@ -44,7 +44,7 @@ public class PermissionInterceptor implements AsyncHandlerInterceptor { XxlJobUser loginUser = loginService.ifLogin(request, response); if (loginUser == null) { response.setStatus(302); - response.setHeader("location" , request.getContextPath() + "/toLogin"); + response.setHeader("location", request.getContextPath() + "/toLogin"); return false; } if (needAdminuser && loginUser.getRole() != 1) { @@ -53,7 +53,7 @@ public class PermissionInterceptor implements AsyncHandlerInterceptor { request.setAttribute(LoginService.LOGIN_IDENTITY_KEY, loginUser); } - return AsyncHandlerInterceptor.super.preHandle(request, response, handler); + return true; // proceed with the next interceptor } } diff --git a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/controller/resolver/WebExceptionResolver.java b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/controller/resolver/WebExceptionResolver.java index 4cd7f193d..d7cc0db5e 100644 --- a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/controller/resolver/WebExceptionResolver.java +++ b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/controller/resolver/WebExceptionResolver.java @@ -1,8 +1,8 @@ package com.xxl.job.admin.controller.resolver; import com.xxl.job.admin.core.exception.XxlJobException; -import com.xxl.job.admin.core.util.JacksonUtil; import com.xxl.job.core.biz.model.ReturnT; +import com.xxl.job.admin.core.util.JacksonUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; @@ -29,7 +29,7 @@ public class WebExceptionResolver implements HandlerExceptionResolver { HttpServletResponse response, Object handler, Exception ex) { if (!(ex instanceof XxlJobException)) { - logger.error("WebExceptionResolver:{}" , ex); + logger.error("WebExceptionResolver:{}", ex); } // if json @@ -43,7 +43,7 @@ public class WebExceptionResolver implements HandlerExceptionResolver { } // error result - ReturnT errorResult = new ReturnT(ReturnT.FAIL_CODE, ex.toString().replaceAll("\n" , "
")); + ReturnT errorResult = new ReturnT(ReturnT.FAIL_CODE, ex.toString().replaceAll("\n", "
")); // response ModelAndView mv = new ModelAndView(); @@ -57,7 +57,7 @@ public class WebExceptionResolver implements HandlerExceptionResolver { return mv; } else { - mv.addObject("exceptionMsg" , errorResult.getMsg()); + mv.addObject("exceptionMsg", errorResult.getMsg()); mv.setViewName("/common/common.exception"); return mv; } diff --git a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/core/alarm/JobAlarmer.java b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/core/alarm/JobAlarmer.java index 797dc900c..62dac9d27 100644 --- a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/core/alarm/JobAlarmer.java +++ b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/core/alarm/JobAlarmer.java @@ -44,9 +44,9 @@ public class JobAlarmer implements ApplicationContextAware, InitializingBean { public boolean alarm(XxlJobInfo info, XxlJobLog jobLog) { boolean result = false; - if (jobAlarmList!=null && jobAlarmList.size()>0) { + if (jobAlarmList != null && jobAlarmList.size() > 0) { result = true; // success means all-success - for (JobAlarm alarm: jobAlarmList) { + for (JobAlarm alarm : jobAlarmList) { boolean resultItem = false; try { resultItem = alarm.doAlarm(info, jobLog); diff --git a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/core/alarm/impl/EmailJobAlarm.java b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/core/alarm/impl/EmailJobAlarm.java index e7290d76f..6ad1c0b1c 100644 --- a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/core/alarm/impl/EmailJobAlarm.java +++ b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/core/alarm/impl/EmailJobAlarm.java @@ -32,18 +32,19 @@ public class EmailJobAlarm implements JobAlarm { * * @param jobLog */ - public boolean doAlarm(XxlJobInfo info, XxlJobLog jobLog){ + @Override + public boolean doAlarm(XxlJobInfo info, XxlJobLog jobLog) { boolean alarmResult = true; // send monitor email - if (info!=null && info.getAlarmEmail()!=null && info.getAlarmEmail().trim().length()>0) { + if (info != null && info.getAlarmEmail() != null && info.getAlarmEmail().trim().length() > 0) { // alarmContent String alarmContent = "Alarm Job LogId=" + jobLog.getId(); if (jobLog.getTriggerCode() != ReturnT.SUCCESS_CODE) { alarmContent += "
TriggerMsg=
" + jobLog.getTriggerMsg(); } - if (jobLog.getHandleCode()>0 && jobLog.getHandleCode() != ReturnT.SUCCESS_CODE) { + if (jobLog.getHandleCode() > 0 && jobLog.getHandleCode() != ReturnT.SUCCESS_CODE) { alarmContent += "
HandleCode=" + jobLog.getHandleMsg(); } @@ -52,13 +53,13 @@ public class EmailJobAlarm implements JobAlarm { String personal = I18nUtil.getString("admin_name_full"); String title = I18nUtil.getString("jobconf_monitor"); String content = MessageFormat.format(loadEmailJobAlarmTemplate(), - group!=null?group.getTitle():"null", - info.getId(), - info.getJobDesc(), - alarmContent); + group != null ? group.getTitle() : "null", + info.getId(), + info.getJobDesc(), + alarmContent); Set emailSet = new HashSet(Arrays.asList(info.getAlarmEmail().split(","))); - for (String email: emailSet) { + for (String email : emailSet) { // make mail try { @@ -88,28 +89,28 @@ public class EmailJobAlarm implements JobAlarm { * * @return */ - private static final String loadEmailJobAlarmTemplate(){ + private static final String loadEmailJobAlarmTemplate() { String mailBodyTemplate = "
" + I18nUtil.getString("jobconf_monitor_detail") + ":" + - "\n" + - " " + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
"+ I18nUtil.getString("jobinfo_field_jobgroup") +""+ I18nUtil.getString("jobinfo_field_id") +""+ I18nUtil.getString("jobinfo_field_jobdesc") +""+ I18nUtil.getString("jobconf_monitor_alarm_title") +""+ I18nUtil.getString("jobconf_monitor_alarm_content") +"
{0}{1}{2}"+ I18nUtil.getString("jobconf_monitor_alarm_type") +"{3}
"; + "\n" + + " " + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + "
" + I18nUtil.getString("jobinfo_field_jobgroup") + "" + I18nUtil.getString("jobinfo_field_id") + "" + I18nUtil.getString("jobinfo_field_jobdesc") + "" + I18nUtil.getString("jobconf_monitor_alarm_title") + "" + I18nUtil.getString("jobconf_monitor_alarm_content") + "
{0}{1}{2}" + I18nUtil.getString("jobconf_monitor_alarm_type") + "{3}
"; return mailBodyTemplate; } diff --git a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/core/complete/XxlJobCompleter.java b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/core/complete/XxlJobCompleter.java index b9ac59a38..83399336b 100644 --- a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/core/complete/XxlJobCompleter.java +++ b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/core/complete/XxlJobCompleter.java @@ -32,7 +32,7 @@ public class XxlJobCompleter { // text最大64kb 避免长度过长 if (xxlJobLog.getHandleMsg().length() > 15000) { - xxlJobLog.setHandleMsg( xxlJobLog.getHandleMsg().substring(0, 15000) ); + xxlJobLog.setHandleMsg(xxlJobLog.getHandleMsg().substring(0, 15000)); } // fresh handle @@ -43,18 +43,18 @@ public class XxlJobCompleter { /** * do somethind to finish job */ - private static void finishJob(XxlJobLog xxlJobLog){ + private static void finishJob(XxlJobLog xxlJobLog) { // 1、handle success, to trigger child job String triggerChildMsg = null; - if (XxlJobContext.HANDLE_COCE_SUCCESS == xxlJobLog.getHandleCode()) { + if (XxlJobContext.HANDLE_CODE_SUCCESS == xxlJobLog.getHandleCode()) { XxlJobInfo xxlJobInfo = XxlJobAdminConfig.getAdminConfig().getXxlJobInfoDao().loadById(xxlJobLog.getJobId()); - if (xxlJobInfo!=null && xxlJobInfo.getChildJobId()!=null && xxlJobInfo.getChildJobId().trim().length()>0) { - triggerChildMsg = "

>>>>>>>>>>>"+ I18nUtil.getString("jobconf_trigger_child_run") +"<<<<<<<<<<<
"; + if (xxlJobInfo != null && xxlJobInfo.getChildJobId() != null && xxlJobInfo.getChildJobId().trim().length() > 0) { + triggerChildMsg = "

>>>>>>>>>>>" + I18nUtil.getString("jobconf_trigger_child_run") + "<<<<<<<<<<<
"; String[] childJobIds = xxlJobInfo.getChildJobId().split(","); for (int i = 0; i < childJobIds.length; i++) { - int childJobId = (childJobIds[i]!=null && childJobIds[i].trim().length()>0 && isNumeric(childJobIds[i]))?Integer.valueOf(childJobIds[i]):-1; + int childJobId = (childJobIds[i] != null && childJobIds[i].trim().length() > 0 && isNumeric(childJobIds[i])) ? Integer.valueOf(childJobIds[i]) : -1; if (childJobId > 0) { JobTriggerPoolHelper.trigger(childJobId, TriggerTypeEnum.PARENT, -1, null, null, null); @@ -62,16 +62,16 @@ public class XxlJobCompleter { // add msg triggerChildMsg += MessageFormat.format(I18nUtil.getString("jobconf_callback_child_msg1"), - (i+1), - childJobIds.length, - childJobIds[i], - (triggerChildResult.getCode()==ReturnT.SUCCESS_CODE?I18nUtil.getString("system_success"):I18nUtil.getString("system_fail")), - triggerChildResult.getMsg()); + (i + 1), + childJobIds.length, + childJobIds[i], + (triggerChildResult.getCode() == ReturnT.SUCCESS_CODE ? I18nUtil.getString("system_success") : I18nUtil.getString("system_fail")), + triggerChildResult.getMsg()); } else { triggerChildMsg += MessageFormat.format(I18nUtil.getString("jobconf_callback_child_msg2"), - (i+1), - childJobIds.length, - childJobIds[i]); + (i + 1), + childJobIds.length, + childJobIds[i]); } } @@ -79,7 +79,7 @@ public class XxlJobCompleter { } if (triggerChildMsg != null) { - xxlJobLog.setHandleMsg( xxlJobLog.getHandleMsg() + triggerChildMsg ); + xxlJobLog.setHandleMsg(xxlJobLog.getHandleMsg() + triggerChildMsg); } // 2、fix_delay trigger next @@ -87,7 +87,7 @@ public class XxlJobCompleter { } - private static boolean isNumeric(String str){ + private static boolean isNumeric(String str) { try { int result = Integer.valueOf(str); return true; diff --git a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/core/conf/XxlJobAdminConfig.java b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/core/conf/XxlJobAdminConfig.java index 380b8a596..6e40cb760 100644 --- a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/core/conf/XxlJobAdminConfig.java +++ b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/core/conf/XxlJobAdminConfig.java @@ -23,6 +23,7 @@ import java.util.Arrays; public class XxlJobAdminConfig implements InitializingBean, DisposableBean { private static XxlJobAdminConfig adminConfig = null; + public static XxlJobAdminConfig getAdminConfig() { return adminConfig; } diff --git a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/core/cron/CronExpression.java b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/core/cron/CronExpression.java index fce23524d..2ce373eeb 100644 --- a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/core/cron/CronExpression.java +++ b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/core/cron/CronExpression.java @@ -1,18 +1,18 @@ /* * All content copyright Terracotta, Inc., unless otherwise indicated. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy - * of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations * under the License. - * + * */ package com.xxl.job.admin.core.cron; @@ -31,14 +31,14 @@ import java.util.TimeZone; import java.util.TreeSet; /** - * Provides a parser and evaluator for unix-like cron expressions. Cron + * Provides a parser and evaluator for unix-like cron expressions. Cron * expressions provide the ability to specify complex time combinations such as - * "At 8:00am every Monday through Friday" or "At 1:30am every - * last Friday of the month". + * "At 8:00am every Monday through Friday" or "At 1:30am every + * last Friday of the month". *

* Cron expressions are comprised of 6 required fields and one optional field * separated by white space. The fields respectively are described as follows: - * + * * * * @@ -98,7 +98,7 @@ import java.util.TreeSet; * *
Field Name
*

- * The '*' character is used to specify all values. For example, "*" + * The '*' character is used to specify all values. For example, "*" * in the minute field means "every minute". *

* The '?' character is allowed for the day-of-month and day-of-week fields. It @@ -113,55 +113,55 @@ import java.util.TreeSet; * Wednesday, and Friday". *

* The '/' character is used to specify increments. For example "0/15" - * in the seconds field means "the seconds 0, 15, 30, and 45". And + * in the seconds field means "the seconds 0, 15, 30, and 45". And * "5/15" in the seconds field means "the seconds 5, 20, 35, and * 50". Specifying '*' before the '/' is equivalent to specifying 0 is * the value to start with. Essentially, for each field in the expression, there - * is a set of numbers that can be turned on or off. For seconds and minutes, + * is a set of numbers that can be turned on or off. For seconds and minutes, * the numbers range from 0 to 59. For hours 0 to 23, for days of the month 0 to * 31, and for months 0 to 11 (JAN to DEC). The "/" character simply helps you turn * on every "nth" value in the given set. Thus "7/6" in the - * month field only turns on month "7", it does NOT mean every 6th - * month, please note that subtlety. + * month field only turns on month "7", it does NOT mean every 6th + * month, please note that subtlety. *

* The 'L' character is allowed for the day-of-month and day-of-week fields. - * This character is short-hand for "last", but it has different - * meaning in each of the two fields. For example, the value "L" in - * the day-of-month field means "the last day of the month" - day 31 - * for January, day 28 for February on non-leap years. If used in the - * day-of-week field by itself, it simply means "7" or + * This character is short-hand for "last", but it has different + * meaning in each of the two fields. For example, the value "L" in + * the day-of-month field means "the last day of the month" - day 31 + * for January, day 28 for February on non-leap years. If used in the + * day-of-week field by itself, it simply means "7" or * "SAT". But if used in the day-of-week field after another value, it * means "the last xxx day of the month" - for example "6L" - * means "the last friday of the month". You can also specify an offset - * from the last day of the month, such as "L-3" which would mean the third-to-last - * day of the calendar month. When using the 'L' option, it is important not to + * means "the last friday of the month". You can also specify an offset + * from the last day of the month, such as "L-3" which would mean the third-to-last + * day of the calendar month. When using the 'L' option, it is important not to * specify lists, or ranges of values, as you'll get confusing/unexpected results. *

- * The 'W' character is allowed for the day-of-month field. This character - * is used to specify the weekday (Monday-Friday) nearest the given day. As an - * example, if you were to specify "15W" as the value for the + * The 'W' character is allowed for the day-of-month field. This character + * is used to specify the weekday (Monday-Friday) nearest the given day. As an + * example, if you were to specify "15W" as the value for the * day-of-month field, the meaning is: "the nearest weekday to the 15th of - * the month". So if the 15th is a Saturday, the trigger will fire on + * the month". So if the 15th is a Saturday, the trigger will fire on * Friday the 14th. If the 15th is a Sunday, the trigger will fire on Monday the - * 16th. If the 15th is a Tuesday, then it will fire on Tuesday the 15th. + * 16th. If the 15th is a Tuesday, then it will fire on Tuesday the 15th. * However if you specify "1W" as the value for day-of-month, and the - * 1st is a Saturday, the trigger will fire on Monday the 3rd, as it will not - * 'jump' over the boundary of a month's days. The 'W' character can only be + * 1st is a Saturday, the trigger will fire on Monday the 3rd, as it will not + * 'jump' over the boundary of a month's days. The 'W' character can only be * specified when the day-of-month is a single day, not a range or list of days. *

- * The 'L' and 'W' characters can also be combined for the day-of-month - * expression to yield 'LW', which translates to "last weekday of the + * The 'L' and 'W' characters can also be combined for the day-of-month + * expression to yield 'LW', which translates to "last weekday of the * month". *

* The '#' character is allowed for the day-of-week field. This character is - * used to specify "the nth" XXX day of the month. For example, the - * value of "6#3" in the day-of-week field means the third Friday of - * the month (day 6 = Friday and "#3" = the 3rd one in the month). - * Other examples: "2#1" = the first Monday of the month and + * used to specify "the nth" XXX day of the month. For example, the + * value of "6#3" in the day-of-week field means the third Friday of + * the month (day 6 = Friday and "#3" = the 3rd one in the month). + * Other examples: "2#1" = the first Monday of the month and * "4#5" = the fifth Wednesday of the month. Note that if you specify * "#5" and there is not 5 of the given day-of-week in the month, then * no firing will occur that month. If the '#' character is used, there can - * only be one expression in the day-of-week field ("3#1,6#3" is + * only be one expression in the day-of-week field ("3#1,6#3" is * not valid, since there are two expressions). *

* - - org.apache.poi - poi-ooxml - - com.alibaba easyexcel - + - com.sun.xml.bind - jaxb-impl + org.yaml + snakeyaml @@ -179,6 +173,11 @@ hutool-extra + + com.sun.mail + jakarta.mail + + org.projectlombok lombok @@ -225,36 +224,27 @@ tlog-xxljob-spring-boot-starter - - com.qiniu - qiniu-java-sdk - ${qiniu.version} - - com.aliyun.oss - aliyun-sdk-oss - ${aliyun.oss.version} + com.amazonaws + aws-java-sdk-s3 + + - com.qcloud - cos_api - ${qcloud.cos.version} + com.aliyun + dysmsapi20170525 + + + + com.tencentcloudapi + tencentcloud-sdk-java - org.slf4j - slf4j-log4j12 - - - org.bouncycastle - bcprov-jdk15on + com.squareup.okio + okio - - io.minio - minio - ${minio.version} - diff --git a/ruoyi/src/main/java/com/ruoyi/common/annotation/Anonymous.java b/ruoyi/src/main/java/com/ruoyi/common/annotation/Anonymous.java new file mode 100644 index 000000000..fe2810083 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/annotation/Anonymous.java @@ -0,0 +1,18 @@ +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, ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface Anonymous { +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/annotation/CellMerge.java b/ruoyi/src/main/java/com/ruoyi/common/annotation/CellMerge.java new file mode 100644 index 000000000..4af822eda --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/annotation/CellMerge.java @@ -0,0 +1,24 @@ +package com.ruoyi.common.annotation; + +import com.ruoyi.common.excel.CellMergeStrategy; + +import java.lang.annotation.*; + +/** + * excel 列单元格合并(合并列相同项) + * + * 需搭配 {@link CellMergeStrategy} 策略使用 + * + * @author Lion Li + */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +@Inherited +public @interface CellMerge { + + /** + * col index + */ + int index() default -1; + +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java b/ruoyi/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java index 6885e95cf..9aa75f7a4 100644 --- a/ruoyi/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java +++ b/ruoyi/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java @@ -108,12 +108,6 @@ public class SysUser extends BaseEntity { ) private String password; - @JsonIgnore - @JsonProperty - public String getPassword() { - return password; - } - /** * 帐号状态(0正常 1停用) */ diff --git a/ruoyi/src/main/java/com/ruoyi/common/excel/CellMergeStrategy.java b/ruoyi/src/main/java/com/ruoyi/common/excel/CellMergeStrategy.java new file mode 100644 index 000000000..04a1bbb8a --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/excel/CellMergeStrategy.java @@ -0,0 +1,114 @@ +package com.ruoyi.common.excel; + +import com.alibaba.excel.metadata.Head; +import com.alibaba.excel.write.merge.AbstractMergeStrategy; +import com.ruoyi.common.annotation.CellMerge; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.util.CellRangeAddress; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 列值重复合并策略 + * + * @author Lion Li + */ +@AllArgsConstructor +@Slf4j +public class CellMergeStrategy extends AbstractMergeStrategy { + + private List list; + private boolean hasTitle; + + @Override + protected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) { + List cellList = handle(list, hasTitle); + // judge the list is not null + if (CollectionUtils.isNotEmpty(cellList)) { + // the judge is necessary + if (cell.getRowIndex() == 1 && cell.getColumnIndex() == 0) { + for (CellRangeAddress item : cellList) { + sheet.addMergedRegion(item); + } + } + } + } + + @SneakyThrows + private static List handle(List list, boolean hasTitle) { + List cellList = new ArrayList<>(); + if (CollectionUtils.isEmpty(list)) { + return cellList; + } + Class clazz = list.get(0).getClass(); + Field[] fields = clazz.getDeclaredFields(); + // 有注解的字段 + List mergeFields = new ArrayList<>(); + List mergeFieldsIndex = new ArrayList<>(); + for (int i = 0; i < fields.length; i++) { + Field field = fields[i]; + if (field.isAnnotationPresent(CellMerge.class)) { + CellMerge cm = field.getAnnotation(CellMerge.class); + mergeFields.add(field); + mergeFieldsIndex.add(cm.index() == -1 ? i : cm.index()); + } + } + // 行合并开始下标 + int rowIndex = hasTitle ? 1 : 0; + Map map = new HashMap<>(); + // 生成两两合并单元格 + for (int i = 0; i < list.size(); i++) { + for (int j = 0; j < mergeFields.size(); j++) { + Field field = mergeFields.get(j); + String name = field.getName(); + String methodName = "get" + name.substring(0, 1).toUpperCase() + name.substring(1); + Method readMethod = clazz.getMethod(methodName); + Object val = readMethod.invoke(list.get(i)); + + int colNum = mergeFieldsIndex.get(j); + if (!map.containsKey(field)) { + map.put(field, new RepeatCell(val, i)); + } else { + RepeatCell repeatCell = map.get(field); + Object cellValue = repeatCell.getValue(); + if (cellValue == null || "".equals(cellValue)) { + // 空值跳过不合并 + continue; + } + if (cellValue != val) { + if (i - repeatCell.getCurrent() > 1) { + cellList.add(new CellRangeAddress(repeatCell.getCurrent() + rowIndex, i + rowIndex - 1, colNum, colNum)); + } + map.put(field, new RepeatCell(val, i)); + } else if (i == list.size() - 1) { + if (i > repeatCell.getCurrent()) { + cellList.add(new CellRangeAddress(repeatCell.getCurrent() + rowIndex, i + rowIndex, colNum, colNum)); + } + } + } + } + } + return cellList; + } + + @Data + @AllArgsConstructor + static class RepeatCell { + + private Object value; + + private int current; + + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/helper/DataPermissionHelper.java b/ruoyi/src/main/java/com/ruoyi/common/helper/DataPermissionHelper.java index ec4d56767..0e60485ad 100644 --- a/ruoyi/src/main/java/com/ruoyi/common/helper/DataPermissionHelper.java +++ b/ruoyi/src/main/java/com/ruoyi/common/helper/DataPermissionHelper.java @@ -1,11 +1,11 @@ package com.ruoyi.common.helper; +import cn.dev33.satoken.context.SaHolder; +import cn.dev33.satoken.context.model.SaStorage; import cn.hutool.core.util.ObjectUtil; -import com.ruoyi.common.utils.ServletUtils; import lombok.AccessLevel; import lombok.NoArgsConstructor; -import javax.servlet.http.HttpServletRequest; import java.util.HashMap; import java.util.Map; @@ -33,11 +33,11 @@ public class DataPermissionHelper { } public static Map getContext() { - HttpServletRequest request = ServletUtils.getRequest(); - Object attribute = request.getAttribute(DATA_PERMISSION_KEY); + SaStorage saStorage = SaHolder.getStorage(); + Object attribute = saStorage.get(DATA_PERMISSION_KEY); if (ObjectUtil.isNull(attribute)) { - request.setAttribute(DATA_PERMISSION_KEY, new HashMap<>()); - attribute = request.getAttribute(DATA_PERMISSION_KEY); + saStorage.set(DATA_PERMISSION_KEY, new HashMap<>()); + attribute = saStorage.get(DATA_PERMISSION_KEY); } if (attribute instanceof Map) { return (Map) attribute; diff --git a/ruoyi/src/main/java/com/ruoyi/common/helper/LoginHelper.java b/ruoyi/src/main/java/com/ruoyi/common/helper/LoginHelper.java index 7875c5630..09e1dc757 100644 --- a/ruoyi/src/main/java/com/ruoyi/common/helper/LoginHelper.java +++ b/ruoyi/src/main/java/com/ruoyi/common/helper/LoginHelper.java @@ -1,5 +1,6 @@ package com.ruoyi.common.helper; +import cn.dev33.satoken.context.SaHolder; import cn.dev33.satoken.stp.StpUtil; import cn.hutool.core.util.ObjectUtil; import com.ruoyi.common.constant.UserConstants; @@ -13,7 +14,7 @@ import lombok.NoArgsConstructor; /** * 登录鉴权助手 - * + * * user_type 为 用户类型 同一个用户表 可以有多种用户类型 例如 pc,app * deivce 为 设备类型 同一个用户类型 可以有 多种设备类型 例如 web,ios * 可以组成 用户类型与设备类型多对多的 权限灵活控制 @@ -29,15 +30,13 @@ public class LoginHelper { public static final String JOIN_CODE = ":"; public static final String LOGIN_USER_KEY = "loginUser"; - private static final ThreadLocal LOGIN_CACHE = new ThreadLocal<>(); - /** * 登录系统 * * @param loginUser 登录用户信息 */ public static void login(LoginUser loginUser) { - LOGIN_CACHE.set(loginUser); + SaHolder.getStorage().set(LOGIN_USER_KEY, loginUser); StpUtil.login(loginUser.getLoginId()); setLoginUser(loginUser); } @@ -49,7 +48,7 @@ public class LoginHelper { * @param loginUser 登录用户信息 */ public static void loginByDevice(LoginUser loginUser, DeviceType deviceType) { - LOGIN_CACHE.set(loginUser); + SaHolder.getStorage().set(LOGIN_USER_KEY, loginUser); StpUtil.login(loginUser.getLoginId(), deviceType.getDevice()); setLoginUser(loginUser); } @@ -65,18 +64,13 @@ public class LoginHelper { * 获取用户(多级缓存) */ public static LoginUser getLoginUser() { - LoginUser loginUser = LOGIN_CACHE.get(); + LoginUser loginUser = (LoginUser) SaHolder.getStorage().get(LOGIN_USER_KEY); if (loginUser != null) { return loginUser; } - return (LoginUser) StpUtil.getTokenSession().get(LOGIN_USER_KEY); - } - - /** - * 清除一级缓存 防止内存问题 - */ - public static void clearCache() { - LOGIN_CACHE.remove(); + loginUser = (LoginUser) StpUtil.getTokenSession().get(LOGIN_USER_KEY); + SaHolder.getStorage().set(LOGIN_USER_KEY, loginUser); + return loginUser; } /** diff --git a/ruoyi/src/main/java/com/ruoyi/common/jackson/SensitiveJsonSerializer.java b/ruoyi/src/main/java/com/ruoyi/common/jackson/SensitiveJsonSerializer.java index 55c4e6a7d..404f393fe 100644 --- a/ruoyi/src/main/java/com/ruoyi/common/jackson/SensitiveJsonSerializer.java +++ b/ruoyi/src/main/java/com/ruoyi/common/jackson/SensitiveJsonSerializer.java @@ -27,9 +27,9 @@ public class SensitiveJsonSerializer extends JsonSerializer implements C public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException { SensitiveService sensitiveService = SpringUtils.getBean(SensitiveService.class); if (sensitiveService.isSensitive()) { - gen.writeString(value); - } else { gen.writeString(strategy.desensitizer().apply(value)); + } else { + gen.writeString(value); } } diff --git a/ruoyi/src/main/java/com/ruoyi/common/utils/email/MailUtils.java b/ruoyi/src/main/java/com/ruoyi/common/utils/email/MailUtils.java new file mode 100644 index 000000000..32a3f8252 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/utils/email/MailUtils.java @@ -0,0 +1,468 @@ +package com.ruoyi.common.utils.email; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.io.IoUtil; +import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.CharUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.extra.mail.*; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.spring.SpringUtils; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +import javax.mail.Authenticator; +import javax.mail.Session; +import java.io.File; +import java.io.InputStream; +import java.util.Collection; +import java.util.List; +import java.util.Map; + + +/** + * 邮件工具类 + */ +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class MailUtils { + + private static final MailAccount ACCOUNT = SpringUtils.getBean(MailAccount.class); + + /** + * 获取邮件发送实例 + */ + public static MailAccount getMailAccount() { + return ACCOUNT; + } + + /** + * 获取邮件发送实例 (自定义发送人以及授权码) + * + * @param user 发送人 + * @param pass 授权码 + */ + public static MailAccount getMailAccount(String from, String user, String pass) { + ACCOUNT.setFrom(StringUtils.blankToDefault(from, ACCOUNT.getFrom())); + ACCOUNT.setUser(StringUtils.blankToDefault(user, ACCOUNT.getUser())); + ACCOUNT.setPass(StringUtils.blankToDefault(pass, ACCOUNT.getPass())); + return ACCOUNT; + } + + /** + * 使用配置文件中设置的账户发送文本邮件,发送给单个或多个收件人
+ * 多个收件人可以使用逗号“,”分隔,也可以通过分号“;”分隔 + * + * @param to 收件人 + * @param subject 标题 + * @param content 正文 + * @param files 附件列表 + * @return message-id + * @since 3.2.0 + */ + public static String sendText(String to, String subject, String content, File... files) { + return send(to, subject, content, false, files); + } + + /** + * 使用配置文件中设置的账户发送HTML邮件,发送给单个或多个收件人
+ * 多个收件人可以使用逗号“,”分隔,也可以通过分号“;”分隔 + * + * @param to 收件人 + * @param subject 标题 + * @param content 正文 + * @param files 附件列表 + * @return message-id + * @since 3.2.0 + */ + public static String sendHtml(String to, String subject, String content, File... files) { + return send(to, subject, content, true, files); + } + + /** + * 使用配置文件中设置的账户发送邮件,发送单个或多个收件人
+ * 多个收件人可以使用逗号“,”分隔,也可以通过分号“;”分隔 + * + * @param to 收件人 + * @param subject 标题 + * @param content 正文 + * @param isHtml 是否为HTML + * @param files 附件列表 + * @return message-id + */ + public static String send(String to, String subject, String content, boolean isHtml, File... files) { + return send(splitAddress(to), subject, content, isHtml, files); + } + + /** + * 使用配置文件中设置的账户发送邮件,发送单个或多个收件人
+ * 多个收件人、抄送人、密送人可以使用逗号“,”分隔,也可以通过分号“;”分隔 + * + * @param to 收件人,可以使用逗号“,”分隔,也可以通过分号“;”分隔 + * @param cc 抄送人,可以使用逗号“,”分隔,也可以通过分号“;”分隔 + * @param bcc 密送人,可以使用逗号“,”分隔,也可以通过分号“;”分隔 + * @param subject 标题 + * @param content 正文 + * @param isHtml 是否为HTML + * @param files 附件列表 + * @return message-id + * @since 4.0.3 + */ + public static String send(String to, String cc, String bcc, String subject, String content, boolean isHtml, File... files) { + return send(splitAddress(to), splitAddress(cc), splitAddress(bcc), subject, content, isHtml, files); + } + + /** + * 使用配置文件中设置的账户发送文本邮件,发送给多人 + * + * @param tos 收件人列表 + * @param subject 标题 + * @param content 正文 + * @param files 附件列表 + * @return message-id + */ + public static String sendText(Collection tos, String subject, String content, File... files) { + return send(tos, subject, content, false, files); + } + + /** + * 使用配置文件中设置的账户发送HTML邮件,发送给多人 + * + * @param tos 收件人列表 + * @param subject 标题 + * @param content 正文 + * @param files 附件列表 + * @return message-id + * @since 3.2.0 + */ + public static String sendHtml(Collection tos, String subject, String content, File... files) { + return send(tos, subject, content, true, files); + } + + /** + * 使用配置文件中设置的账户发送邮件,发送给多人 + * + * @param tos 收件人列表 + * @param subject 标题 + * @param content 正文 + * @param isHtml 是否为HTML + * @param files 附件列表 + * @return message-id + */ + public static String send(Collection tos, String subject, String content, boolean isHtml, File... files) { + return send(tos, null, null, subject, content, isHtml, files); + } + + /** + * 使用配置文件中设置的账户发送邮件,发送给多人 + * + * @param tos 收件人列表 + * @param ccs 抄送人列表,可以为null或空 + * @param bccs 密送人列表,可以为null或空 + * @param subject 标题 + * @param content 正文 + * @param isHtml 是否为HTML + * @param files 附件列表 + * @return message-id + * @since 4.0.3 + */ + public static String send(Collection tos, Collection ccs, Collection bccs, String subject, String content, boolean isHtml, File... files) { + return send(getMailAccount(), true, tos, ccs, bccs, subject, content, null, isHtml, files); + } + + // ------------------------------------------------------------------------------------------------------------------------------- Custom MailAccount + + /** + * 发送邮件给多人 + * + * @param mailAccount 邮件认证对象 + * @param to 收件人,多个收件人逗号或者分号隔开 + * @param subject 标题 + * @param content 正文 + * @param isHtml 是否为HTML格式 + * @param files 附件列表 + * @return message-id + * @since 3.2.0 + */ + public static String send(MailAccount mailAccount, String to, String subject, String content, boolean isHtml, File... files) { + return send(mailAccount, splitAddress(to), subject, content, isHtml, files); + } + + /** + * 发送邮件给多人 + * + * @param mailAccount 邮件帐户信息 + * @param tos 收件人列表 + * @param subject 标题 + * @param content 正文 + * @param isHtml 是否为HTML格式 + * @param files 附件列表 + * @return message-id + */ + public static String send(MailAccount mailAccount, Collection tos, String subject, String content, boolean isHtml, File... files) { + return send(mailAccount, tos, null, null, subject, content, isHtml, files); + } + + /** + * 发送邮件给多人 + * + * @param mailAccount 邮件帐户信息 + * @param tos 收件人列表 + * @param ccs 抄送人列表,可以为null或空 + * @param bccs 密送人列表,可以为null或空 + * @param subject 标题 + * @param content 正文 + * @param isHtml 是否为HTML格式 + * @param files 附件列表 + * @return message-id + * @since 4.0.3 + */ + public static String send(MailAccount mailAccount, Collection tos, Collection ccs, Collection bccs, String subject, String content, boolean isHtml, File... files) { + return send(mailAccount, false, tos, ccs, bccs, subject, content, null, isHtml, files); + } + + /** + * 使用配置文件中设置的账户发送HTML邮件,发送给单个或多个收件人
+ * 多个收件人可以使用逗号“,”分隔,也可以通过分号“;”分隔 + * + * @param to 收件人 + * @param subject 标题 + * @param content 正文 + * @param imageMap 图片与占位符,占位符格式为cid:$IMAGE_PLACEHOLDER + * @param files 附件列表 + * @return message-id + * @since 3.2.0 + */ + public static String sendHtml(String to, String subject, String content, Map imageMap, File... files) { + return send(to, subject, content, imageMap, true, files); + } + + /** + * 使用配置文件中设置的账户发送邮件,发送单个或多个收件人
+ * 多个收件人可以使用逗号“,”分隔,也可以通过分号“;”分隔 + * + * @param to 收件人 + * @param subject 标题 + * @param content 正文 + * @param imageMap 图片与占位符,占位符格式为cid:$IMAGE_PLACEHOLDER + * @param isHtml 是否为HTML + * @param files 附件列表 + * @return message-id + */ + public static String send(String to, String subject, String content, Map imageMap, boolean isHtml, File... files) { + return send(splitAddress(to), subject, content, imageMap, isHtml, files); + } + + /** + * 使用配置文件中设置的账户发送邮件,发送单个或多个收件人
+ * 多个收件人、抄送人、密送人可以使用逗号“,”分隔,也可以通过分号“;”分隔 + * + * @param to 收件人,可以使用逗号“,”分隔,也可以通过分号“;”分隔 + * @param cc 抄送人,可以使用逗号“,”分隔,也可以通过分号“;”分隔 + * @param bcc 密送人,可以使用逗号“,”分隔,也可以通过分号“;”分隔 + * @param subject 标题 + * @param content 正文 + * @param imageMap 图片与占位符,占位符格式为cid:$IMAGE_PLACEHOLDER + * @param isHtml 是否为HTML + * @param files 附件列表 + * @return message-id + * @since 4.0.3 + */ + public static String send(String to, String cc, String bcc, String subject, String content, Map imageMap, boolean isHtml, File... files) { + return send(splitAddress(to), splitAddress(cc), splitAddress(bcc), subject, content, imageMap, isHtml, files); + } + + /** + * 使用配置文件中设置的账户发送HTML邮件,发送给多人 + * + * @param tos 收件人列表 + * @param subject 标题 + * @param content 正文 + * @param imageMap 图片与占位符,占位符格式为cid:$IMAGE_PLACEHOLDER + * @param files 附件列表 + * @return message-id + * @since 3.2.0 + */ + public static String sendHtml(Collection tos, String subject, String content, Map imageMap, File... files) { + return send(tos, subject, content, imageMap, true, files); + } + + /** + * 使用配置文件中设置的账户发送邮件,发送给多人 + * + * @param tos 收件人列表 + * @param subject 标题 + * @param content 正文 + * @param imageMap 图片与占位符,占位符格式为cid:$IMAGE_PLACEHOLDER + * @param isHtml 是否为HTML + * @param files 附件列表 + * @return message-id + */ + public static String send(Collection tos, String subject, String content, Map imageMap, boolean isHtml, File... files) { + return send(tos, null, null, subject, content, imageMap, isHtml, files); + } + + /** + * 使用配置文件中设置的账户发送邮件,发送给多人 + * + * @param tos 收件人列表 + * @param ccs 抄送人列表,可以为null或空 + * @param bccs 密送人列表,可以为null或空 + * @param subject 标题 + * @param content 正文 + * @param imageMap 图片与占位符,占位符格式为cid:$IMAGE_PLACEHOLDER + * @param isHtml 是否为HTML + * @param files 附件列表 + * @return message-id + * @since 4.0.3 + */ + public static String send(Collection tos, Collection ccs, Collection bccs, String subject, String content, Map imageMap, boolean isHtml, File... files) { + return send(getMailAccount(), true, tos, ccs, bccs, subject, content, imageMap, isHtml, files); + } + + // ------------------------------------------------------------------------------------------------------------------------------- Custom MailAccount + + /** + * 发送邮件给多人 + * + * @param mailAccount 邮件认证对象 + * @param to 收件人,多个收件人逗号或者分号隔开 + * @param subject 标题 + * @param content 正文 + * @param imageMap 图片与占位符,占位符格式为cid:$IMAGE_PLACEHOLDER + * @param isHtml 是否为HTML格式 + * @param files 附件列表 + * @return message-id + * @since 3.2.0 + */ + public static String send(MailAccount mailAccount, String to, String subject, String content, Map imageMap, boolean isHtml, File... files) { + return send(mailAccount, splitAddress(to), subject, content, imageMap, isHtml, files); + } + + /** + * 发送邮件给多人 + * + * @param mailAccount 邮件帐户信息 + * @param tos 收件人列表 + * @param subject 标题 + * @param content 正文 + * @param imageMap 图片与占位符,占位符格式为cid:$IMAGE_PLACEHOLDER + * @param isHtml 是否为HTML格式 + * @param files 附件列表 + * @return message-id + * @since 4.6.3 + */ + public static String send(MailAccount mailAccount, Collection tos, String subject, String content, Map imageMap, boolean isHtml, File... files) { + return send(mailAccount, tos, null, null, subject, content, imageMap, isHtml, files); + } + + /** + * 发送邮件给多人 + * + * @param mailAccount 邮件帐户信息 + * @param tos 收件人列表 + * @param ccs 抄送人列表,可以为null或空 + * @param bccs 密送人列表,可以为null或空 + * @param subject 标题 + * @param content 正文 + * @param imageMap 图片与占位符,占位符格式为cid:$IMAGE_PLACEHOLDER + * @param isHtml 是否为HTML格式 + * @param files 附件列表 + * @return message-id + * @since 4.6.3 + */ + public static String send(MailAccount mailAccount, Collection tos, Collection ccs, Collection bccs, String subject, String content, Map imageMap, + boolean isHtml, File... files) { + return send(mailAccount, false, tos, ccs, bccs, subject, content, imageMap, isHtml, files); + } + + /** + * 根据配置文件,获取邮件客户端会话 + * + * @param mailAccount 邮件账户配置 + * @param isSingleton 是否单例(全局共享会话) + * @return {@link Session} + * @since 5.5.7 + */ + public static Session getSession(MailAccount mailAccount, boolean isSingleton) { + Authenticator authenticator = null; + if (mailAccount.isAuth()) { + authenticator = new UserPassAuthenticator(mailAccount.getUser(), mailAccount.getPass()); + } + + return isSingleton ? Session.getDefaultInstance(mailAccount.getSmtpProps(), authenticator) // + : Session.getInstance(mailAccount.getSmtpProps(), authenticator); + } + + // ------------------------------------------------------------------------------------------------------------------------ Private method start + + /** + * 发送邮件给多人 + * + * @param mailAccount 邮件帐户信息 + * @param useGlobalSession 是否全局共享Session + * @param tos 收件人列表 + * @param ccs 抄送人列表,可以为null或空 + * @param bccs 密送人列表,可以为null或空 + * @param subject 标题 + * @param content 正文 + * @param imageMap 图片与占位符,占位符格式为cid:${cid} + * @param isHtml 是否为HTML格式 + * @param files 附件列表 + * @return message-id + * @since 4.6.3 + */ + private static String send(MailAccount mailAccount, boolean useGlobalSession, Collection tos, Collection ccs, Collection bccs, String subject, String content, + Map imageMap, boolean isHtml, File... files) { + final Mail mail = Mail.create(mailAccount).setUseGlobalSession(useGlobalSession); + + // 可选抄送人 + if (CollUtil.isNotEmpty(ccs)) { + mail.setCcs(ccs.toArray(new String[0])); + } + // 可选密送人 + if (CollUtil.isNotEmpty(bccs)) { + mail.setBccs(bccs.toArray(new String[0])); + } + + mail.setTos(tos.toArray(new String[0])); + mail.setTitle(subject); + mail.setContent(content); + mail.setHtml(isHtml); + mail.setFiles(files); + + // 图片 + if (MapUtil.isNotEmpty(imageMap)) { + for (Map.Entry entry : imageMap.entrySet()) { + mail.addImage(entry.getKey(), entry.getValue()); + // 关闭流 + IoUtil.close(entry.getValue()); + } + } + + return mail.send(); + } + + /** + * 将多个联系人转为列表,分隔符为逗号或者分号 + * + * @param addresses 多个联系人,如果为空返回null + * @return 联系人列表 + */ + private static List splitAddress(String addresses) { + if (StrUtil.isBlank(addresses)) { + return null; + } + + List result; + if (StrUtil.contains(addresses, CharUtil.COMMA)) { + result = StrUtil.splitTrim(addresses, CharUtil.COMMA); + } else if (StrUtil.contains(addresses, ';')) { + result = StrUtil.splitTrim(addresses, ';'); + } else { + result = CollUtil.newArrayList(addresses); + } + return result; + } + // ------------------------------------------------------------------------------------------------------------------------ Private method end + +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/utils/file/MimeTypeUtils.java b/ruoyi/src/main/java/com/ruoyi/common/utils/file/MimeTypeUtils.java new file mode 100644 index 000000000..6ca97fe60 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/utils/file/MimeTypeUtils.java @@ -0,0 +1,40 @@ +package com.ruoyi.common.utils.file; + +/** + * 媒体类型工具类 + * + * @author ruoyi + */ +public class MimeTypeUtils { + public static final String IMAGE_PNG = "image/png"; + + public static final String IMAGE_JPG = "image/jpg"; + + public static final String IMAGE_JPEG = "image/jpeg"; + + public static final String IMAGE_BMP = "image/bmp"; + + public static final String IMAGE_GIF = "image/gif"; + + public static final String[] IMAGE_EXTENSION = {"bmp", "gif", "jpg", "jpeg", "png"}; + + public static final String[] FLASH_EXTENSION = {"swf", "flv"}; + + public static final String[] MEDIA_EXTENSION = {"swf", "flv", "mp3", "wav", "wma", "wmv", "mid", "avi", "mpg", + "asf", "rm", "rmvb"}; + + public static final String[] VIDEO_EXTENSION = {"mp4", "avi", "rmvb"}; + + public static final String[] DEFAULT_ALLOWED_EXTENSION = { + // 图片 + "bmp", "gif", "jpg", "jpeg", "png", + // word excel powerpoint + "doc", "docx", "xls", "xlsx", "ppt", "pptx", "html", "htm", "txt", + // 压缩文件 + "rar", "zip", "gz", "bz2", + // 视频格式 + "mp4", "avi", "rmvb", + // pdf + "pdf"}; + +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java b/ruoyi/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java index 36dc67fa1..e6a67b26b 100644 --- a/ruoyi/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java +++ b/ruoyi/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java @@ -1,9 +1,17 @@ package com.ruoyi.common.utils.poi; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.io.resource.ClassPathResource; import cn.hutool.core.util.IdUtil; import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.ExcelWriter; +import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder; +import com.alibaba.excel.write.metadata.WriteSheet; +import com.alibaba.excel.write.metadata.fill.FillConfig; +import com.alibaba.excel.write.metadata.fill.FillWrapper; import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy; import com.ruoyi.common.convert.ExcelBigNumberConvert; +import com.ruoyi.common.excel.CellMergeStrategy; import com.ruoyi.common.excel.DefaultExcelListener; import com.ruoyi.common.excel.ExcelListener; import com.ruoyi.common.excel.ExcelResult; @@ -16,7 +24,10 @@ import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.util.Collection; import java.util.List; +import java.util.Map; /** * Excel相关处理 @@ -69,27 +80,125 @@ public class ExcelUtil { * * @param list 导出数据集合 * @param sheetName 工作表的名称 - * @return 结果 + * @param clazz 实体类 + * @param response 响应体 */ public static void exportExcel(List list, String sheetName, Class clazz, HttpServletResponse response) { + exportExcel(list, sheetName, clazz, false, response); + } + + /** + * 导出excel + * + * @param list 导出数据集合 + * @param sheetName 工作表的名称 + * @param clazz 实体类 + * @param merge 是否合并单元格 + * @param response 响应体 + */ + public static void exportExcel(List list, String sheetName, Class clazz, boolean merge, HttpServletResponse response) { try { - String filename = encodingFilename(sheetName); - response.reset(); - FileUtils.setAttachmentResponseHeader(response, filename); - response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8"); + resetResponse(sheetName, response); ServletOutputStream os = response.getOutputStream(); - EasyExcel.write(os, clazz) + ExcelWriterSheetBuilder builder = EasyExcel.write(os, clazz) .autoCloseStream(false) // 自动适配 .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) // 大数值自动转换 防止失真 .registerConverter(new ExcelBigNumberConvert()) - .sheet(sheetName).doWrite(list); + .sheet(sheetName); + if (merge) { + // 合并处理器 + builder.registerWriteHandler(new CellMergeStrategy(list, true)); + } + builder.doWrite(list); } catch (IOException e) { throw new RuntimeException("导出Excel异常"); } } + /** + * 单表多数据模板导出 模板格式为 {.属性} + * + * @param filename 文件名 + * @param templatePath 模板路径 resource 目录下的路径包括模板文件名 + * 例如: excel/temp.xlsx + * 重点: 模板文件必须放置到启动类对应的 resource 目录下 + * @param data 模板需要的数据 + */ + public static void exportTemplate(List data, String filename, String templatePath, HttpServletResponse response) { + try { + resetResponse(filename, response); + ClassPathResource templateResource = new ClassPathResource(templatePath); + ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()) + .withTemplate(templateResource.getStream()) + .autoCloseStream(false) + // 大数值自动转换 防止失真 + .registerConverter(new ExcelBigNumberConvert()) + .build(); + WriteSheet writeSheet = EasyExcel.writerSheet().build(); + if (CollUtil.isEmpty(data)) { + throw new IllegalArgumentException("数据为空"); + } + // 单表多数据导出 模板格式为 {.属性} + for (Object d : data) { + excelWriter.fill(d, writeSheet); + } + excelWriter.finish(); + } catch (IOException e) { + throw new RuntimeException("导出Excel异常"); + } + } + + /** + * 多表多数据模板导出 模板格式为 {key.属性} + * + * @param filename 文件名 + * @param templatePath 模板路径 resource 目录下的路径包括模板文件名 + * 例如: excel/temp.xlsx + * 重点: 模板文件必须放置到启动类对应的 resource 目录下 + * @param data 模板需要的数据 + */ + public static void exportTemplateMultiList(Map data, String filename, String templatePath, HttpServletResponse response) { + try { + resetResponse(filename, response); + ClassPathResource templateResource = new ClassPathResource(templatePath); + ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()) + .withTemplate(templateResource.getStream()) + .autoCloseStream(false) + // 大数值自动转换 防止失真 + .registerConverter(new ExcelBigNumberConvert()) + .build(); + WriteSheet writeSheet = EasyExcel.writerSheet().build(); + if (CollUtil.isEmpty(data)) { + throw new IllegalArgumentException("数据为空"); + } + for (Map.Entry map : data.entrySet()) { + // 设置列表后续还有数据 + FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build(); + if (map.getValue() instanceof Collection) { + // 多表导出必须使用 FillWrapper + excelWriter.fill(new FillWrapper(map.getKey(), (Collection) map.getValue()), fillConfig, writeSheet); + } else { + excelWriter.fill(map.getValue(), writeSheet); + } + } + excelWriter.finish(); + } catch (IOException e) { + throw new RuntimeException("导出Excel异常"); + } + } + + /** + * 重置响应体 + */ + private static void resetResponse(String sheetName, HttpServletResponse response) throws UnsupportedEncodingException { + String filename = encodingFilename(sheetName); + response.reset(); + FileUtils.setAttachmentResponseHeader(response, filename); + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8"); + } + /** * 解析导出值 0=男,1=女,2=未知 * @@ -103,7 +212,7 @@ public class ExcelUtil { String[] convertSource = converterExp.split(","); for (String item : convertSource) { String[] itemArray = item.split("="); - if (StringUtils.containsAny(separator, propertyValue)) { + if (StringUtils.containsAny(propertyValue, separator)) { for (String value : propertyValue.split(separator)) { if (itemArray[0].equals(value)) { propertyString.append(itemArray[1] + separator); @@ -132,7 +241,7 @@ public class ExcelUtil { String[] convertSource = converterExp.split(","); for (String item : convertSource) { String[] itemArray = item.split("="); - if (StringUtils.containsAny(separator, propertyValue)) { + if (StringUtils.containsAny(propertyValue, separator)) { for (String value : propertyValue.split(separator)) { if (itemArray[1].equals(value)) { propertyString.append(itemArray[0] + separator); diff --git a/ruoyi/src/main/java/com/ruoyi/common/utils/redis/RedisUtils.java b/ruoyi/src/main/java/com/ruoyi/common/utils/redis/RedisUtils.java index 5a15d46b7..7ed3b2827 100644 --- a/ruoyi/src/main/java/com/ruoyi/common/utils/redis/RedisUtils.java +++ b/ruoyi/src/main/java/com/ruoyi/common/utils/redis/RedisUtils.java @@ -6,11 +6,11 @@ import lombok.AccessLevel; import lombok.NoArgsConstructor; import org.redisson.api.*; +import java.time.Duration; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.concurrent.TimeUnit; import java.util.function.Consumer; /** @@ -107,7 +107,7 @@ public class RedisUtils { } catch (Exception e) { long timeToLive = bucket.remainTimeToLive(); bucket.set(value); - bucket.expire(timeToLive, TimeUnit.MILLISECONDS); + bucket.expire(Duration.ofMillis(timeToLive)); } } else { bucket.set(value); @@ -119,13 +119,12 @@ public class RedisUtils { * * @param key 缓存的键值 * @param value 缓存的值 - * @param timeout 时间 - * @param timeUnit 时间颗粒度 + * @param duration 时间 */ - public static void setCacheObject(final String key, final T value, final long timeout, final TimeUnit timeUnit) { + public static void setCacheObject(final String key, final T value, final Duration duration) { RBucket result = CLIENT.getBucket(key); result.set(value); - result.expire(timeout, timeUnit); + result.expire(duration); } /** @@ -149,20 +148,19 @@ public class RedisUtils { * @return true=设置成功;false=设置失败 */ public static boolean expire(final String key, final long timeout) { - return expire(key, timeout, TimeUnit.SECONDS); + return expire(key, Duration.ofSeconds(timeout)); } /** * 设置有效时间 * - * @param key Redis键 - * @param timeout 超时时间 - * @param unit 时间单位 + * @param key Redis键 + * @param duration 超时时间 * @return true=设置成功;false=设置失败 */ - public static boolean expire(final String key, final long timeout, final TimeUnit unit) { + public static boolean expire(final String key, final Duration duration) { RBucket rBucket = CLIENT.getBucket(key); - return rBucket.expire(timeout, unit); + return rBucket.expire(duration); } /** @@ -366,6 +364,50 @@ public class RedisUtils { return rMap.getAll(hKeys); } + /** + * 设置原子值 + * + * @param key Redis键 + * @param value 值 + */ + public static void setAtomicValue(String key, long value) { + RAtomicLong atomic = CLIENT.getAtomicLong(key); + atomic.set(value); + } + + /** + * 获取原子值 + * + * @param key Redis键 + * @return 当前值 + */ + public static long getAtomicValue(String key) { + RAtomicLong atomic = CLIENT.getAtomicLong(key); + return atomic.get(); + } + + /** + * 递增原子值 + * + * @param key Redis键 + * @return 当前值 + */ + public static long incrAtomicValue(String key) { + RAtomicLong atomic = CLIENT.getAtomicLong(key); + return atomic.incrementAndGet(); + } + + /** + * 递减原子值 + * + * @param key Redis键 + * @return 当前值 + */ + public static long decrAtomicValue(String key) { + RAtomicLong atomic = CLIENT.getAtomicLong(key); + return atomic.decrementAndGet(); + } + /** * 获得缓存的基本对象列表 * diff --git a/ruoyi/src/main/java/com/ruoyi/demo/controller/MailController.java b/ruoyi/src/main/java/com/ruoyi/demo/controller/MailController.java new file mode 100644 index 000000000..6dabe5132 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/demo/controller/MailController.java @@ -0,0 +1,48 @@ +package com.ruoyi.demo.controller; + +import com.ruoyi.common.core.domain.R; +import com.ruoyi.common.utils.email.MailUtils; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import lombok.RequiredArgsConstructor; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.io.File; + + +/** + * 邮件发送案例 + * + * @author Michelle.Chung + */ +@Validated +@Api(value = "邮件发送案例", tags = {"邮件发送案例"}) +@RequiredArgsConstructor +@RestController +@RequestMapping("/demo/mail") +public class MailController { + + @ApiOperation("发送邮件") + @GetMapping("/sendSimpleMessage") + public R sendSimpleMessage(@ApiParam("接收人") String to, + @ApiParam("标题") String subject, + @ApiParam("内容") String text) { + MailUtils.sendText(to, subject, text); + return R.ok(); + } + + @ApiOperation("发送邮件(带附件)") + @GetMapping("/sendMessageWithAttachment") + public R sendMessageWithAttachment(@ApiParam("接收人") String to, + @ApiParam("标题") String subject, + @ApiParam("内容") String text, + @ApiParam("附件路径") String filePath) { + MailUtils.sendText(to, subject, text, new File(filePath)); + return R.ok(); + } + +} diff --git a/ruoyi/src/main/java/com/ruoyi/demo/controller/RedisCacheController.java b/ruoyi/src/main/java/com/ruoyi/demo/controller/RedisCacheController.java index 98cca18c0..9fc93074f 100644 --- a/ruoyi/src/main/java/com/ruoyi/demo/controller/RedisCacheController.java +++ b/ruoyi/src/main/java/com/ruoyi/demo/controller/RedisCacheController.java @@ -12,7 +12,7 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import java.util.concurrent.TimeUnit; +import java.time.Duration; /** * spring-cache 演示案例 @@ -87,7 +87,7 @@ public class RedisCacheController { @GetMapping("/test6") public R test6(String key, String value) { RedisUtils.setCacheObject(key, value); - boolean flag = RedisUtils.expire(key, 10, TimeUnit.SECONDS); + boolean flag = RedisUtils.expire(key, Duration.ofSeconds(10)); System.out.println("***********" + flag); try { Thread.sleep(11 * 1000); diff --git a/ruoyi/src/main/java/com/ruoyi/demo/controller/SmsController.java b/ruoyi/src/main/java/com/ruoyi/demo/controller/SmsController.java new file mode 100644 index 000000000..b92078624 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/demo/controller/SmsController.java @@ -0,0 +1,72 @@ +package com.ruoyi.demo.controller; + +import com.ruoyi.common.core.domain.R; +import com.ruoyi.common.utils.spring.SpringUtils; +import com.ruoyi.sms.config.properties.SmsProperties; +import com.ruoyi.sms.core.SmsTemplate; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import lombok.RequiredArgsConstructor; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.HashMap; +import java.util.Map; + +/** + * 短信演示案例 + * 请先阅读文档 否则无法使用 + * + * @author Lion Li + * @version 4.2.0 + */ +@Validated +@Api(value = "短信演示案例", tags = {"短信演示案例"}) +@RequiredArgsConstructor +@RestController +@RequestMapping("/demo/sms") +public class SmsController { + + private final SmsProperties smsProperties; +// private final SmsTemplate smsTemplate; // 可以使用spring注入 +// private final AliyunSmsTemplate smsTemplate; // 也可以注入某个厂家的模板工具 + + @ApiOperation("发送短信Aliyun") + @GetMapping("/sendAliyun") + public R sendAliyun(@ApiParam("电话号") String phones, + @ApiParam("模板ID") String templateId) { + if (!smsProperties.getEnabled()) { + return R.fail("当前系统没有开启短信功能!"); + } + if (!SpringUtils.containsBean("aliyunSmsTemplate")) { + return R.fail("阿里云依赖未引入!"); + } + SmsTemplate smsTemplate = SpringUtils.getBean(SmsTemplate.class); + Map map = new HashMap<>(1); + map.put("code", "1234"); + Object send = smsTemplate.send(phones, templateId, map); + return R.ok(send); + } + + @ApiOperation("发送短信Tencent") + @GetMapping("/sendTencent") + public R sendTencent(@ApiParam("电话号") String phones, + @ApiParam("模板ID") String templateId) { + if (!smsProperties.getEnabled()) { + return R.fail("当前系统没有开启短信功能!"); + } + if (!SpringUtils.containsBean("tencentSmsTemplate")) { + return R.fail("腾讯云依赖未引入!"); + } + SmsTemplate smsTemplate = SpringUtils.getBean(SmsTemplate.class); + Map map = new HashMap<>(1); +// map.put("2", "测试测试"); + map.put("1", "1234"); + Object send = smsTemplate.send(phones, templateId, map); + return R.ok(send); + } + +} diff --git a/ruoyi/src/main/java/com/ruoyi/demo/controller/TestDemoController.java b/ruoyi/src/main/java/com/ruoyi/demo/controller/TestDemoController.java index d1f994e5d..9f00c0770 100644 --- a/ruoyi/src/main/java/com/ruoyi/demo/controller/TestDemoController.java +++ b/ruoyi/src/main/java/com/ruoyi/demo/controller/TestDemoController.java @@ -29,6 +29,7 @@ import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletResponse; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; +import java.io.File; import java.util.Arrays; import java.util.List; import java.util.concurrent.TimeUnit; @@ -70,7 +71,7 @@ public class TestDemoController extends BaseController { @ApiOperation("导入测试-校验") @ApiImplicitParams({ - @ApiImplicitParam(name = "file", value = "导入文件", dataType = "java.io.File", required = true), + @ApiImplicitParam(name = "file", value = "导入文件", paramType = "query", dataTypeClass = File.class, required = true), }) @Log(title = "测试单表", businessType = BusinessType.IMPORT) @SaCheckPermission("demo:demo:import") diff --git a/ruoyi/src/main/java/com/ruoyi/demo/controller/TestExcelController.java b/ruoyi/src/main/java/com/ruoyi/demo/controller/TestExcelController.java new file mode 100644 index 000000000..a318b4658 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/demo/controller/TestExcelController.java @@ -0,0 +1,102 @@ +package com.ruoyi.demo.controller; + +import cn.hutool.core.collection.CollUtil; +import com.ruoyi.common.utils.poi.ExcelUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.AllArgsConstructor; +import lombok.Data; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletResponse; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 测试Excel功能 + * + * @author Lion Li + */ +@Api(value = "测试Excel功能", tags = {"测试Excel功能"}) +@RestController +@RequestMapping("/demo/excel") +public class TestExcelController { + + /** + * 单列表多数据 + */ + @ApiOperation(value = "单列表多数据") + @GetMapping("/exportTemplateOne") + public void exportTemplateOne(HttpServletResponse response) { + Map map = new HashMap<>(); + map.put("title","单列表多数据"); + map.put("test1","数据测试1"); + map.put("test2","数据测试2"); + map.put("test3","数据测试3"); + map.put("test4","数据测试4"); + map.put("testTest","666"); + List list = new ArrayList<>(); + list.add(new TestObj("单列表测试1", "列表测试1", "列表测试2", "列表测试3", "列表测试4")); + list.add(new TestObj("单列表测试2", "列表测试5", "列表测试6", "列表测试7", "列表测试8")); + list.add(new TestObj("单列表测试3", "列表测试9", "列表测试10", "列表测试11", "列表测试12")); + ExcelUtil.exportTemplate(CollUtil.newArrayList(map,list),"单列表.xlsx", "excel/单列表.xlsx", response); + } + + /** + * 多列表多数据 + */ + @ApiOperation(value = "多列表多数据") + @GetMapping("/exportTemplateMuliti") + public void exportTemplateMuliti(HttpServletResponse response) { + Map map = new HashMap<>(); + map.put("title1","标题1"); + map.put("title2","标题2"); + map.put("title3","标题3"); + map.put("title4","标题4"); + map.put("author","Lion Li"); + List list1 = new ArrayList<>(); + list1.add(new TestObj1("list1测试1", "list1测试2", "list1测试3")); + list1.add(new TestObj1("list1测试4", "list1测试5", "list1测试6")); + list1.add(new TestObj1("list1测试7", "list1测试8", "list1测试9")); + List list2 = new ArrayList<>(); + list2.add(new TestObj1("list2测试1", "list2测试2", "list2测试3")); + list2.add(new TestObj1("list2测试4", "list2测试5", "list2测试6")); + List list3 = new ArrayList<>(); + list3.add(new TestObj1("list3测试1", "list3测试2", "list3测试3")); + List list4 = new ArrayList<>(); + list4.add(new TestObj1("list4测试1", "list4测试2", "list4测试3")); + list4.add(new TestObj1("list4测试4", "list4测试5", "list4测试6")); + list4.add(new TestObj1("list4测试7", "list4测试8", "list4测试9")); + list4.add(new TestObj1("list4测试10", "list4测试11", "list4测试12")); + Map multiListMap = new HashMap<>(); + multiListMap.put("map",map); + multiListMap.put("data1",list1); + multiListMap.put("data2",list2); + multiListMap.put("data3",list3); + multiListMap.put("data4",list4); + ExcelUtil.exportTemplateMultiList(multiListMap, "多列表.xlsx", "excel/多列表.xlsx", response); + } + + @Data + @AllArgsConstructor + static class TestObj1 { + private String test1; + private String test2; + private String test3; + } + + @Data + @AllArgsConstructor + static class TestObj { + private String name; + private String list1; + private String list2; + private String list3; + private String list4; + } + +} diff --git a/ruoyi/src/main/java/com/ruoyi/demo/domain/bo/TestDemoBo.java b/ruoyi/src/main/java/com/ruoyi/demo/domain/bo/TestDemoBo.java index 5c41204d7..61c10ab16 100644 --- a/ruoyi/src/main/java/com/ruoyi/demo/domain/bo/TestDemoBo.java +++ b/ruoyi/src/main/java/com/ruoyi/demo/domain/bo/TestDemoBo.java @@ -49,7 +49,7 @@ public class TestDemoBo extends BaseEntity { */ @ApiModelProperty("排序号") @NotNull(message = "排序号不能为空", groups = {AddGroup.class, EditGroup.class}) - private Long orderNum; + private Integer orderNum; /** * key键 diff --git a/ruoyi/src/main/java/com/ruoyi/demo/domain/vo/TestDemoVo.java b/ruoyi/src/main/java/com/ruoyi/demo/domain/vo/TestDemoVo.java index ef26ff325..1e896500d 100644 --- a/ruoyi/src/main/java/com/ruoyi/demo/domain/vo/TestDemoVo.java +++ b/ruoyi/src/main/java/com/ruoyi/demo/domain/vo/TestDemoVo.java @@ -48,7 +48,7 @@ public class TestDemoVo { */ @ExcelProperty(value = "排序号") @ApiModelProperty("排序号") - private Long orderNum; + private Integer orderNum; /** * key键 diff --git a/ruoyi/src/main/java/com/ruoyi/demo/mapper/TestDemoMapper.java b/ruoyi/src/main/java/com/ruoyi/demo/mapper/TestDemoMapper.java index b1b80d26e..11a3d50e2 100644 --- a/ruoyi/src/main/java/com/ruoyi/demo/mapper/TestDemoMapper.java +++ b/ruoyi/src/main/java/com/ruoyi/demo/mapper/TestDemoMapper.java @@ -54,5 +54,5 @@ public interface TestDemoMapper extends BaseMapperPlus idList); + int deleteBatchIds(@Param(Constants.COLL) Collection idList); } diff --git a/ruoyi/src/main/java/com/ruoyi/framework/aspectj/RepeatSubmitAspect.java b/ruoyi/src/main/java/com/ruoyi/framework/aspectj/RepeatSubmitAspect.java index aedc4431c..b77acb40e 100644 --- a/ruoyi/src/main/java/com/ruoyi/framework/aspectj/RepeatSubmitAspect.java +++ b/ruoyi/src/main/java/com/ruoyi/framework/aspectj/RepeatSubmitAspect.java @@ -25,9 +25,9 @@ import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import java.time.Duration; import java.util.Collection; import java.util.Map; -import java.util.concurrent.TimeUnit; /** * 防止重复提交(参考美团GTIS防重系统) @@ -66,7 +66,7 @@ public class RepeatSubmitAspect { String cacheRepeatKey = Constants.REPEAT_SUBMIT_KEY + url + submitKey; String key = RedisUtils.getCacheObject(cacheRepeatKey); if (key == null) { - RedisUtils.setCacheObject(cacheRepeatKey, "", interval, TimeUnit.MILLISECONDS); + RedisUtils.setCacheObject(cacheRepeatKey, "", Duration.ofMillis(interval)); KEY_CACHE.set(cacheRepeatKey); } else { String message = repeatSubmit.message(); diff --git a/ruoyi/src/main/java/com/ruoyi/framework/config/JacksonConfig.java b/ruoyi/src/main/java/com/ruoyi/framework/config/JacksonConfig.java index a5d637165..eace537a5 100644 --- a/ruoyi/src/main/java/com/ruoyi/framework/config/JacksonConfig.java +++ b/ruoyi/src/main/java/com/ruoyi/framework/config/JacksonConfig.java @@ -1,17 +1,14 @@ package com.ruoyi.framework.config; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; import com.ruoyi.framework.jackson.BigNumberSerializer; import lombok.extern.slf4j.Slf4j; -import org.springframework.boot.autoconfigure.jackson.JacksonProperties; +import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Primary; -import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; import java.math.BigDecimal; import java.math.BigInteger; @@ -28,23 +25,22 @@ import java.util.TimeZone; @Configuration public class JacksonConfig { - @Primary @Bean - public ObjectMapper getObjectMapper(Jackson2ObjectMapperBuilder builder, JacksonProperties jacksonProperties) { - ObjectMapper objectMapper = builder.createXmlMapper(false).build(); - // 全局配置序列化返回 JSON 处理 - SimpleModule simpleModule = new SimpleModule(); - simpleModule.addSerializer(Long.class, BigNumberSerializer.INSTANCE); - simpleModule.addSerializer(Long.TYPE, BigNumberSerializer.INSTANCE); - simpleModule.addSerializer(BigInteger.class, BigNumberSerializer.INSTANCE); - simpleModule.addSerializer(BigDecimal.class, ToStringSerializer.instance); - DateTimeFormatter formatter = DateTimeFormatter.ofPattern(jacksonProperties.getDateFormat()); - simpleModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(formatter)); - simpleModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(formatter)); - objectMapper.registerModule(simpleModule); - objectMapper.setTimeZone(TimeZone.getDefault()); - log.info("初始化 jackson 配置"); - return objectMapper; + public Jackson2ObjectMapperBuilderCustomizer customizer() { + return builder -> { + // 全局配置序列化返回 JSON 处理 + JavaTimeModule javaTimeModule = new JavaTimeModule(); + javaTimeModule.addSerializer(Long.class, BigNumberSerializer.INSTANCE); + javaTimeModule.addSerializer(Long.TYPE, BigNumberSerializer.INSTANCE); + javaTimeModule.addSerializer(BigInteger.class, BigNumberSerializer.INSTANCE); + javaTimeModule.addSerializer(BigDecimal.class, ToStringSerializer.instance); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(formatter)); + javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(formatter)); + builder.modules(javaTimeModule); + builder.timeZone(TimeZone.getDefault()); + log.info("初始化 jackson 配置"); + }; } } diff --git a/ruoyi/src/main/java/com/ruoyi/framework/config/MailConfig.java b/ruoyi/src/main/java/com/ruoyi/framework/config/MailConfig.java new file mode 100644 index 000000000..20769aa19 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/config/MailConfig.java @@ -0,0 +1,35 @@ +package com.ruoyi.framework.config; + +import cn.hutool.extra.mail.MailAccount; +import com.ruoyi.framework.config.properties.MailProperties; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * JavaMail 配置 + * + * @author Michelle.Chung + */ +@Configuration +public class MailConfig { + + @Bean + @ConditionalOnProperty(value = "mail.enabled", havingValue = "true") + public MailAccount mailAccount(MailProperties mailProperties) { + MailAccount account = new MailAccount(); + account.setHost(mailProperties.getHost()); + account.setPort(mailProperties.getPort()); + account.setAuth(mailProperties.getAuth()); + account.setFrom(mailProperties.getFrom()); + account.setUser(mailProperties.getUser()); + account.setPass(mailProperties.getPass()); + account.setSocketFactoryPort(mailProperties.getPort()); + account.setStarttlsEnable(mailProperties.getStarttlsEnable()); + account.setSslEnable(mailProperties.getSslEnable()); + account.setTimeout(mailProperties.getTimeout()); + account.setConnectionTimeout(mailProperties.getConnectionTimeout()); + return account; + } + +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/config/RedisConfig.java b/ruoyi/src/main/java/com/ruoyi/framework/config/RedisConfig.java index da18cfd17..38a871895 100644 --- a/ruoyi/src/main/java/com/ruoyi/framework/config/RedisConfig.java +++ b/ruoyi/src/main/java/com/ruoyi/framework/config/RedisConfig.java @@ -1,28 +1,25 @@ package com.ruoyi.framework.config; import cn.hutool.core.util.ObjectUtil; -import com.ruoyi.common.utils.StringUtils; +import com.fasterxml.jackson.databind.ObjectMapper; import com.ruoyi.framework.config.properties.RedissonProperties; import lombok.extern.slf4j.Slf4j; -import org.redisson.Redisson; import org.redisson.api.RedissonClient; import org.redisson.codec.JsonJacksonCodec; -import org.redisson.config.Config; import org.redisson.spring.cache.CacheConfig; import org.redisson.spring.cache.RedissonSpringCacheManager; +import org.redisson.spring.starter.RedissonAutoConfigurationCustomizer; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.data.redis.RedisProperties; +import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.CachingConfigurerSupport; import org.springframework.cache.annotation.EnableCaching; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Primary; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; /** * redis配置 @@ -32,72 +29,49 @@ import java.util.stream.Collectors; @Slf4j @Configuration @EnableCaching +@EnableConfigurationProperties(RedissonProperties.class) public class RedisConfig extends CachingConfigurerSupport { - private static final String REDIS_PROTOCOL_PREFIX = "redis://"; - private static final String REDISS_PROTOCOL_PREFIX = "rediss://"; - - @Autowired - private RedisProperties redisProperties; - @Autowired private RedissonProperties redissonProperties; - @Primary - @Bean(destroyMethod = "shutdown") - public RedissonClient redisson() { - String prefix = REDIS_PROTOCOL_PREFIX; - if (redisProperties.isSsl()) { - prefix = REDISS_PROTOCOL_PREFIX; - } - Config config = new Config(); - config.setThreads(redissonProperties.getThreads()) - .setNettyThreads(redissonProperties.getNettyThreads()) - .setCodec(JsonJacksonCodec.INSTANCE); + @Autowired + private ObjectMapper objectMapper; - RedissonProperties.SingleServerConfig singleServerConfig = redissonProperties.getSingleServerConfig(); - if (ObjectUtil.isNotNull(singleServerConfig)) { - // 使用单机模式 - config.useSingleServer() - .setAddress(prefix + redisProperties.getHost() + ":" + redisProperties.getPort()) - .setConnectTimeout(((Long) redisProperties.getTimeout().toMillis()).intValue()) - .setDatabase(redisProperties.getDatabase()) - .setPassword(StringUtils.isNotBlank(redisProperties.getPassword()) ? redisProperties.getPassword() : null) - .setTimeout(singleServerConfig.getTimeout()) - .setClientName(singleServerConfig.getClientName()) - .setIdleConnectionTimeout(singleServerConfig.getIdleConnectionTimeout()) - .setSubscriptionConnectionPoolSize(singleServerConfig.getSubscriptionConnectionPoolSize()) - .setConnectionMinimumIdleSize(singleServerConfig.getConnectionMinimumIdleSize()) - .setConnectionPoolSize(singleServerConfig.getConnectionPoolSize()); - } - // 集群配置方式 参考下方注释 - RedissonProperties.ClusterServersConfig clusterServersConfig = redissonProperties.getClusterServersConfig(); - if (ObjectUtil.isNotNull(clusterServersConfig)) { - // 使用集群模式 - String finalPrefix = prefix; - List nodes = redisProperties.getCluster().getNodes() - .stream() - .map(node -> finalPrefix + node) - .collect(Collectors.toList()); - - config.useClusterServers() - .setConnectTimeout(((Long) redisProperties.getTimeout().toMillis()).intValue()) - .setPassword(StringUtils.isNotBlank(redisProperties.getPassword()) ? redisProperties.getPassword() : null) - .setTimeout(clusterServersConfig.getTimeout()) - .setClientName(clusterServersConfig.getClientName()) - .setIdleConnectionTimeout(clusterServersConfig.getIdleConnectionTimeout()) - .setSubscriptionConnectionPoolSize(clusterServersConfig.getSubscriptionConnectionPoolSize()) - .setMasterConnectionMinimumIdleSize(clusterServersConfig.getMasterConnectionMinimumIdleSize()) - .setMasterConnectionPoolSize(clusterServersConfig.getMasterConnectionPoolSize()) - .setSlaveConnectionMinimumIdleSize(clusterServersConfig.getSlaveConnectionMinimumIdleSize()) - .setSlaveConnectionPoolSize(clusterServersConfig.getSlaveConnectionPoolSize()) - .setReadMode(clusterServersConfig.getReadMode()) - .setSubscriptionMode(clusterServersConfig.getSubscriptionMode()) - .setNodeAddresses(nodes); - } - RedissonClient redissonClient = Redisson.create(config); - log.info("初始化 redis 配置"); - return redissonClient; + @Bean + public RedissonAutoConfigurationCustomizer redissonCustomizer() { + return config -> { + config.setThreads(redissonProperties.getThreads()) + .setNettyThreads(redissonProperties.getNettyThreads()) + .setCodec(new JsonJacksonCodec(objectMapper)); + RedissonProperties.SingleServerConfig singleServerConfig = redissonProperties.getSingleServerConfig(); + if (ObjectUtil.isNotNull(singleServerConfig)) { + // 使用单机模式 + config.useSingleServer() + .setTimeout(singleServerConfig.getTimeout()) + .setClientName(singleServerConfig.getClientName()) + .setIdleConnectionTimeout(singleServerConfig.getIdleConnectionTimeout()) + .setSubscriptionConnectionPoolSize(singleServerConfig.getSubscriptionConnectionPoolSize()) + .setConnectionMinimumIdleSize(singleServerConfig.getConnectionMinimumIdleSize()) + .setConnectionPoolSize(singleServerConfig.getConnectionPoolSize()); + } + // 集群配置方式 参考下方注释 + RedissonProperties.ClusterServersConfig clusterServersConfig = redissonProperties.getClusterServersConfig(); + if (ObjectUtil.isNotNull(clusterServersConfig)) { + config.useClusterServers() + .setTimeout(clusterServersConfig.getTimeout()) + .setClientName(clusterServersConfig.getClientName()) + .setIdleConnectionTimeout(clusterServersConfig.getIdleConnectionTimeout()) + .setSubscriptionConnectionPoolSize(clusterServersConfig.getSubscriptionConnectionPoolSize()) + .setMasterConnectionMinimumIdleSize(clusterServersConfig.getMasterConnectionMinimumIdleSize()) + .setMasterConnectionPoolSize(clusterServersConfig.getMasterConnectionPoolSize()) + .setSlaveConnectionMinimumIdleSize(clusterServersConfig.getSlaveConnectionMinimumIdleSize()) + .setSlaveConnectionPoolSize(clusterServersConfig.getSlaveConnectionPoolSize()) + .setReadMode(clusterServersConfig.getReadMode()) + .setSubscriptionMode(clusterServersConfig.getSubscriptionMode()); + } + log.info("初始化 redis 配置"); + }; } /** @@ -112,7 +86,7 @@ public class RedisConfig extends CachingConfigurerSupport { cacheConfig.setMaxSize(group.getMaxSize()); config.put(group.getGroupId(), cacheConfig); } - return new RedissonSpringCacheManager(redissonClient, config, JsonJacksonCodec.INSTANCE); + return new RedissonSpringCacheManager(redissonClient, config, new JsonJacksonCodec(objectMapper)); } /** diff --git a/ruoyi/src/main/java/com/ruoyi/framework/config/SaTokenConfig.java b/ruoyi/src/main/java/com/ruoyi/framework/config/SaTokenConfig.java index 671400f6f..a5be2678e 100644 --- a/ruoyi/src/main/java/com/ruoyi/framework/config/SaTokenConfig.java +++ b/ruoyi/src/main/java/com/ruoyi/framework/config/SaTokenConfig.java @@ -2,11 +2,12 @@ package com.ruoyi.framework.config; import cn.dev33.satoken.interceptor.SaAnnotationInterceptor; import cn.dev33.satoken.interceptor.SaRouteInterceptor; -import cn.dev33.satoken.jwt.StpLogicJwtForStyle; +import cn.dev33.satoken.jwt.StpLogicJwtForSimple; import cn.dev33.satoken.router.SaRouter; import cn.dev33.satoken.stp.StpLogic; import cn.dev33.satoken.stp.StpUtil; -import com.ruoyi.common.helper.LoginHelper; +import com.ruoyi.common.utils.spring.SpringUtils; +import com.ruoyi.framework.config.properties.ExcludeUrlProperties; import com.ruoyi.framework.config.properties.SecurityProperties; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -15,9 +16,6 @@ import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - /** * sa-token 配置 * @@ -37,12 +35,14 @@ public class SaTokenConfig implements WebMvcConfigurer { public void addInterceptors(InterceptorRegistry registry) { // 注册路由拦截器,自定义验证规则 registry.addInterceptor(new SaRouteInterceptor((request, response, handler) -> { + ExcludeUrlProperties excludeUrlProperties = SpringUtils.getBean(ExcludeUrlProperties.class); // 登录验证 -- 排除多个路径 SaRouter // 获取所有的 .match("/**") // 排除下不需要拦截的 .notMatch(securityProperties.getExcludes()) + .notMatch(excludeUrlProperties.getExcludes()) // 对未排除的路径进行检查 .check(() -> { // 检查是否登录 是否有token @@ -55,20 +55,14 @@ public class SaTokenConfig implements WebMvcConfigurer { // } }); - }) { - @SuppressWarnings("all") - @Override - public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { - LoginHelper.clearCache(); - } - }).addPathPatterns("/**"); + })).addPathPatterns("/**"); registry.addInterceptor(new SaAnnotationInterceptor()).addPathPatterns("/**"); } @Bean public StpLogic getStpLogicJwt() { - // Sa-Token 整合 jwt (Style模式) - return new StpLogicJwtForStyle(); + // Sa-Token 整合 jwt (简单模式) + return new StpLogicJwtForSimple(); } } diff --git a/ruoyi/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java b/ruoyi/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java index 22ef7c1b5..2424981c1 100644 --- a/ruoyi/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java +++ b/ruoyi/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java @@ -109,7 +109,7 @@ public class SwaggerConfig { * 安全模式,这里指定token通过Authorization头请求头传递 */ private List securitySchemes() { - List apiKeyList = new ArrayList(); + List apiKeyList = new ArrayList<>(); String header = saTokenConfig.getTokenName(); apiKeyList.add(new ApiKey(header, header, In.HEADER.toValue())); return apiKeyList; diff --git a/ruoyi/src/main/java/com/ruoyi/framework/config/ThreadPoolConfig.java b/ruoyi/src/main/java/com/ruoyi/framework/config/ThreadPoolConfig.java index ebf236c87..a85ad1e57 100644 --- a/ruoyi/src/main/java/com/ruoyi/framework/config/ThreadPoolConfig.java +++ b/ruoyi/src/main/java/com/ruoyi/framework/config/ThreadPoolConfig.java @@ -33,8 +33,8 @@ public class ThreadPoolConfig { @ConditionalOnProperty(prefix = "thread-pool", name = "enabled", havingValue = "true") public ThreadPoolTaskExecutor threadPoolTaskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); - executor.setMaxPoolSize(core); - executor.setCorePoolSize(core * 2); + executor.setCorePoolSize(core); + executor.setMaxPoolSize(core * 2); executor.setQueueCapacity(threadPoolProperties.getQueueCapacity()); executor.setKeepAliveSeconds(threadPoolProperties.getKeepAliveSeconds()); executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); diff --git a/ruoyi/src/main/java/com/ruoyi/framework/config/UndertowConfig.java b/ruoyi/src/main/java/com/ruoyi/framework/config/UndertowConfig.java new file mode 100644 index 000000000..64e745a86 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/config/UndertowConfig.java @@ -0,0 +1,30 @@ +package com.ruoyi.framework.config; + +import io.undertow.server.DefaultByteBufferPool; +import io.undertow.websockets.jsr.WebSocketDeploymentInfo; +import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory; +import org.springframework.boot.web.server.WebServerFactoryCustomizer; +import org.springframework.context.annotation.Configuration; + +/** + * Undertow 自定义配置 + * + * @author Lion Li + */ +@Configuration +public class UndertowConfig implements WebServerFactoryCustomizer { + + /** + * 设置 Undertow 的 websocket 缓冲池 + */ + @Override + public void customize(UndertowServletWebServerFactory factory) { + // 默认不直接分配内存 如果项目中使用了 websocket 建议直接分配 + factory.addDeploymentInfoCustomizers(deploymentInfo -> { + WebSocketDeploymentInfo webSocketDeploymentInfo = new WebSocketDeploymentInfo(); + webSocketDeploymentInfo.setBuffers(new DefaultByteBufferPool(false, 512)); + deploymentInfo.addServletContextAttribute("io.undertow.websockets.jsr.WebSocketDeploymentInfo", webSocketDeploymentInfo); + }); + } + +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/config/properties/ExcludeUrlProperties.java b/ruoyi/src/main/java/com/ruoyi/framework/config/properties/ExcludeUrlProperties.java new file mode 100644 index 000000000..b4e3eae6d --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/config/properties/ExcludeUrlProperties.java @@ -0,0 +1,61 @@ +package com.ruoyi.framework.config.properties; + +import cn.hutool.core.util.ReUtil; +import com.ruoyi.common.annotation.Anonymous; +import com.ruoyi.common.utils.spring.SpringUtils; +import lombok.Getter; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.context.annotation.Lazy; +import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.stereotype.Component; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.mvc.method.RequestMappingInfo; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; + +import java.util.*; +import java.util.regex.Pattern; + +/** + * 设置注解允许匿名访问的url + * + * @author Lion Li + */ +@Lazy +@Component +public class ExcludeUrlProperties implements InitializingBean { + + private static final Pattern PATTERN = Pattern.compile("\\{(.*?)\\}"); + + @Getter + private final List excludes = new ArrayList<>(); + + @Override + public void afterPropertiesSet() { + String asterisk = "*"; + RequestMappingHandlerMapping mapping = SpringUtils.getBean(RequestMappingHandlerMapping.class); + Map map = mapping.getHandlerMethods(); + + map.keySet().forEach(info -> { + HandlerMethod handlerMethod = map.get(info); + + // 获取方法上边的注解 替代path variable 为 * + Anonymous method = AnnotationUtils.findAnnotation(handlerMethod.getMethod(), Anonymous.class); + Optional.ofNullable(method).ifPresent(anonymous -> { + Set patterns = info.getPatternsCondition().getPatterns(); + patterns.forEach(url -> { + excludes.add(ReUtil.replaceAll(url, PATTERN, asterisk)); + }); + }); + + // 获取类上边的注解, 替代path variable 为 * + Anonymous controller = AnnotationUtils.findAnnotation(handlerMethod.getBeanType(), Anonymous.class); + Optional.ofNullable(controller).ifPresent(anonymous -> { + Set patterns = info.getPatternsCondition().getPatterns(); + patterns.forEach(url -> { + excludes.add(ReUtil.replaceAll(url, PATTERN, asterisk)); + }); + }); + }); + } + +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/config/properties/MailProperties.java b/ruoyi/src/main/java/com/ruoyi/framework/config/properties/MailProperties.java new file mode 100644 index 000000000..95e6cb8ba --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/config/properties/MailProperties.java @@ -0,0 +1,71 @@ +package com.ruoyi.framework.config.properties; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * JavaMail 配置属性 + * + * @author Michelle.Chung + */ +@Data +@Component +@ConfigurationProperties(prefix = "mail") +public class MailProperties { + + /** + * 过滤开关 + */ + private Boolean enabled; + + /** + * SMTP服务器域名 + */ + private String host; + + /** + * SMTP服务端口 + */ + private Integer port; + + /** + * 是否需要用户名密码验证 + */ + private Boolean auth; + + /** + * 用户名 + */ + private String user; + + /** + * 密码 + */ + private String pass; + + /** + * 发送方,遵循RFC-822标准 + */ + private String from; + + /** + * 使用 STARTTLS安全连接,STARTTLS是对纯文本通信协议的扩展。它将纯文本连接升级为加密连接(TLS或SSL), 而不是使用一个单独的加密通信端口。 + */ + private Boolean starttlsEnable; + + /** + * 使用 SSL安全连接 + */ + private Boolean sslEnable; + + /** + * SMTP超时时长,单位毫秒,缺省值不超时 + */ + private Long timeout; + + /** + * Socket连接超时值,单位毫秒,缺省值不超时 + */ + private Long connectionTimeout; +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/listener/UserActionListener.java b/ruoyi/src/main/java/com/ruoyi/framework/listener/UserActionListener.java index 75277c257..dcb9b1996 100644 --- a/ruoyi/src/main/java/com/ruoyi/framework/listener/UserActionListener.java +++ b/ruoyi/src/main/java/com/ruoyi/framework/listener/UserActionListener.java @@ -3,7 +3,6 @@ package com.ruoyi.framework.listener; import cn.dev33.satoken.config.SaTokenConfig; import cn.dev33.satoken.listener.SaTokenListener; import cn.dev33.satoken.stp.SaLoginModel; -import cn.dev33.satoken.stp.StpUtil; import cn.hutool.http.useragent.UserAgent; import cn.hutool.http.useragent.UserAgentUtil; import com.ruoyi.common.constant.Constants; @@ -18,7 +17,7 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; -import java.util.concurrent.TimeUnit; +import java.time.Duration; /** * 用户行为 侦听器的实现 @@ -36,13 +35,12 @@ public class UserActionListener implements SaTokenListener { * 每次登录时触发 */ @Override - public void doLogin(String loginType, Object loginId, SaLoginModel loginModel) { + public void doLogin(String loginType, Object loginId, String tokenValue, SaLoginModel loginModel) { UserType userType = UserType.getUserType(loginId.toString()); if (userType == UserType.SYS_USER) { UserAgent userAgent = UserAgentUtil.parse(ServletUtils.getRequest().getHeader("User-Agent")); String ip = ServletUtils.getClientIP(); LoginUser user = LoginHelper.getLoginUser(); - String tokenValue = StpUtil.getTokenValueByLoginId(loginId); UserOnlineDTO dto = new UserOnlineDTO(); dto.setIpaddr(ip); dto.setLoginLocation(AddressUtils.getRealAddressByIP(ip)); @@ -52,7 +50,7 @@ public class UserActionListener implements SaTokenListener { dto.setTokenId(tokenValue); dto.setUserName(user.getUsername()); dto.setDeptName(user.getDeptName()); - RedisUtils.setCacheObject(Constants.ONLINE_TOKEN_KEY + tokenValue, dto, tokenConfig.getTimeout(), TimeUnit.SECONDS); + RedisUtils.setCacheObject(Constants.ONLINE_TOKEN_KEY + tokenValue, dto, Duration.ofSeconds(tokenConfig.getTimeout())); log.info("user doLogin, userId:{}, token:{}", loginId, tokenValue); } else if (userType == UserType.APP_USER) { // app端 自行根据业务编写 diff --git a/ruoyi/src/main/java/com/ruoyi/framework/satoken/dao/PlusSaTokenDao.java b/ruoyi/src/main/java/com/ruoyi/framework/satoken/dao/PlusSaTokenDao.java index f78e81415..68df5a646 100644 --- a/ruoyi/src/main/java/com/ruoyi/framework/satoken/dao/PlusSaTokenDao.java +++ b/ruoyi/src/main/java/com/ruoyi/framework/satoken/dao/PlusSaTokenDao.java @@ -5,10 +5,10 @@ import cn.dev33.satoken.util.SaFoxUtil; import com.ruoyi.common.utils.redis.RedisUtils; import org.springframework.stereotype.Component; +import java.time.Duration; import java.util.ArrayList; import java.util.Collection; import java.util.List; -import java.util.concurrent.TimeUnit; /** * Sa-Token持久层接口(使用框架自带RedisUtils实现 协议统一) @@ -38,7 +38,7 @@ public class PlusSaTokenDao implements SaTokenDao { if (timeout == SaTokenDao.NEVER_EXPIRE) { RedisUtils.setCacheObject(key, value); } else { - RedisUtils.setCacheObject(key, value, timeout, TimeUnit.SECONDS); + RedisUtils.setCacheObject(key, value, Duration.ofSeconds(timeout)); } } @@ -68,7 +68,8 @@ public class PlusSaTokenDao implements SaTokenDao { */ @Override public long getTimeout(String key) { - return RedisUtils.getTimeToLive(key) / 1000; + long timeout = RedisUtils.getTimeToLive(key); + return timeout < 0 ? timeout : timeout / 1000; } /** @@ -87,7 +88,7 @@ public class PlusSaTokenDao implements SaTokenDao { } return; } - RedisUtils.expire(key, timeout, TimeUnit.SECONDS); + RedisUtils.expire(key, Duration.ofSeconds(timeout)); } @@ -111,7 +112,7 @@ public class PlusSaTokenDao implements SaTokenDao { if (timeout == SaTokenDao.NEVER_EXPIRE) { RedisUtils.setCacheObject(key, object); } else { - RedisUtils.setCacheObject(key, object, timeout, TimeUnit.SECONDS); + RedisUtils.setCacheObject(key, object, Duration.ofSeconds(timeout)); } } @@ -141,7 +142,8 @@ public class PlusSaTokenDao implements SaTokenDao { */ @Override public long getObjectTimeout(String key) { - return RedisUtils.getTimeToLive(key) / 1000; + long timeout = RedisUtils.getTimeToLive(key); + return timeout < 0 ? timeout : timeout / 1000; } /** @@ -160,7 +162,7 @@ public class PlusSaTokenDao implements SaTokenDao { } return; } - RedisUtils.expire(key, timeout, TimeUnit.SECONDS); + RedisUtils.expire(key, Duration.ofSeconds(timeout)); } diff --git a/ruoyi/src/main/java/com/ruoyi/generator/service/GenTableServiceImpl.java b/ruoyi/src/main/java/com/ruoyi/generator/service/GenTableServiceImpl.java index 9dccab2d1..2a99a2e65 100644 --- a/ruoyi/src/main/java/com/ruoyi/generator/service/GenTableServiceImpl.java +++ b/ruoyi/src/main/java/com/ruoyi/generator/service/GenTableServiceImpl.java @@ -33,6 +33,7 @@ import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.Velocity; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import java.io.ByteArrayOutputStream; import java.io.File; @@ -135,6 +136,7 @@ public class GenTableServiceImpl implements IGenTableService { * @param genTable 业务信息 * @return 结果 */ + @Transactional(rollbackFor = Exception.class) @Override public void updateGenTable(GenTable genTable) { String options = JsonUtils.toJsonString(genTable.getParams()); @@ -153,6 +155,7 @@ public class GenTableServiceImpl implements IGenTableService { * @param tableIds 需要删除的数据ID * @return 结果 */ + @Transactional(rollbackFor = Exception.class) @Override public void deleteGenTableByIds(Long[] tableIds) { List ids = Arrays.asList(tableIds); @@ -165,6 +168,7 @@ public class GenTableServiceImpl implements IGenTableService { * * @param tableList 导入表列表 */ + @Transactional(rollbackFor = Exception.class) @Override public void importGenTable(List tableList) { String operName = LoginHelper.getUsername(); @@ -284,6 +288,7 @@ public class GenTableServiceImpl implements IGenTableService { * * @param tableName 表名称 */ + @Transactional(rollbackFor = Exception.class) @Override public void synchDb(String tableName) { GenTable table = baseMapper.selectGenTableByName(tableName); diff --git a/ruoyi/src/main/java/com/ruoyi/oss/constant/OssConstant.java b/ruoyi/src/main/java/com/ruoyi/oss/constant/OssConstant.java index 6c00cd8db..1d1a77708 100644 --- a/ruoyi/src/main/java/com/ruoyi/oss/constant/OssConstant.java +++ b/ruoyi/src/main/java/com/ruoyi/oss/constant/OssConstant.java @@ -35,6 +35,11 @@ public interface OssConstant { */ List SYSTEM_DATA_IDS = Arrays.asList(1, 2, 3, 4); + /** + * 云服务商 + */ + String[] CLOUD_SERVICE = new String[] {"aliyun", "qcloud", "qiniu"}; + /** * https 状态 */ diff --git a/ruoyi/src/main/java/com/ruoyi/oss/core/OssClient.java b/ruoyi/src/main/java/com/ruoyi/oss/core/OssClient.java new file mode 100644 index 000000000..6f6be8f8c --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/oss/core/OssClient.java @@ -0,0 +1,188 @@ +package com.ruoyi.oss.core; + +import cn.hutool.core.util.IdUtil; +import com.amazonaws.ClientConfiguration; +import com.amazonaws.Protocol; +import com.amazonaws.auth.AWSCredentials; +import com.amazonaws.auth.AWSCredentialsProvider; +import com.amazonaws.auth.AWSStaticCredentialsProvider; +import com.amazonaws.auth.BasicAWSCredentials; +import com.amazonaws.client.builder.AwsClientBuilder; +import com.amazonaws.services.s3.AmazonS3; +import com.amazonaws.services.s3.AmazonS3Client; +import com.amazonaws.services.s3.model.CannedAccessControlList; +import com.amazonaws.services.s3.model.CreateBucketRequest; +import com.amazonaws.services.s3.model.ObjectMetadata; +import com.amazonaws.services.s3.model.PutObjectRequest; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.oss.constant.OssConstant; +import com.ruoyi.oss.entity.UploadResult; +import com.ruoyi.oss.enumd.PolicyType; +import com.ruoyi.oss.exception.OssException; +import com.ruoyi.oss.properties.OssProperties; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; + +/** + * S3 存储协议 所有兼容S3协议的云厂商均支持 + * 阿里云 腾讯云 七牛云 minio + * + * @author Lion Li + */ +public class OssClient { + + private final String configKey; + + private final OssProperties properties; + + private final AmazonS3 client; + + public OssClient(String configKey, OssProperties ossProperties) { + this.configKey = configKey; + this.properties = ossProperties; + try { + AwsClientBuilder.EndpointConfiguration endpointConfig = + new AwsClientBuilder.EndpointConfiguration(properties.getEndpoint(), properties.getRegion()); + + AWSCredentials credentials = new BasicAWSCredentials(properties.getAccessKey(), properties.getSecretKey()); + AWSCredentialsProvider credentialsProvider = new AWSStaticCredentialsProvider(credentials); + ClientConfiguration clientConfig = new ClientConfiguration(); + if (OssConstant.IS_HTTPS.equals(properties.getIsHttps())) { + clientConfig.setProtocol(Protocol.HTTPS); + } else { + clientConfig.setProtocol(Protocol.HTTP); + } + this.client = AmazonS3Client.builder() + .withEndpointConfiguration(endpointConfig) + .withClientConfiguration(clientConfig) + .withCredentials(credentialsProvider) + .disableChunkedEncoding() + .build(); + + createBucket(); + } catch (Exception e) { + if (e instanceof OssException) { + throw e; + } + throw new OssException("配置错误! 请检查系统配置:[" + e.getMessage() + "]"); + } + } + + public void createBucket() { + try { + String bucketName = properties.getBucketName(); + if (client.doesBucketExistV2(bucketName)) { + return; + } + CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName); + createBucketRequest.setCannedAcl(CannedAccessControlList.PublicRead); + client.createBucket(createBucketRequest); + client.setBucketPolicy(bucketName, getPolicy(bucketName, PolicyType.READ)); + } catch (Exception e) { + throw new OssException("创建Bucket失败, 请核对配置信息:[" + e.getMessage() + "]"); + } + } + + public UploadResult upload(byte[] data, String path, String contentType) { + return upload(new ByteArrayInputStream(data), path, contentType); + } + + public UploadResult upload(InputStream inputStream, String path, String contentType) { + try { + ObjectMetadata metadata = new ObjectMetadata(); + metadata.setContentType(contentType); + metadata.setContentLength(inputStream.available()); + client.putObject(new PutObjectRequest(properties.getBucketName(), path, inputStream, metadata)); + } catch (Exception e) { + throw new OssException("上传文件失败,请检查配置信息:[" + e.getMessage() + "]"); + } + return UploadResult.builder().url(getUrl() + "/" + path).filename(path).build(); + } + + public void delete(String path) { + path = path.replace(getUrl() + "/", ""); + try { + client.deleteObject(properties.getBucketName(), path); + } catch (Exception e) { + throw new OssException("上传文件失败,请检查配置信息:[" + e.getMessage() + "]"); + } + } + + public UploadResult uploadSuffix(byte[] data, String suffix, String contentType) { + return upload(data, getPath(properties.getPrefix(), suffix), contentType); + } + + public UploadResult uploadSuffix(InputStream inputStream, String suffix, String contentType) { + return upload(inputStream, getPath(properties.getPrefix(), suffix), contentType); + } + + public String getUrl() { + String domain = properties.getDomain(); + if (StringUtils.isNotBlank(domain)) { + return domain; + } + String endpoint = properties.getEndpoint(); + String header = OssConstant.IS_HTTPS.equals(properties.getIsHttps()) ? "https://" : "http://"; + // 云服务商直接返回 + if (StringUtils.containsAny(endpoint, OssConstant.CLOUD_SERVICE)){ + return header + properties.getBucketName() + "." + endpoint; + } + // minio 单独处理 + return header + endpoint + "/" + properties.getBucketName(); + } + + public String getPath(String prefix, String suffix) { + // 生成uuid + String uuid = IdUtil.fastSimpleUUID(); + // 文件路径 + String path = DateUtils.datePath() + "/" + uuid; + if (StringUtils.isNotBlank(prefix)) { + path = prefix + "/" + path; + } + return path + suffix; + } + + + public String getConfigKey() { + return configKey; + } + + private static String getPolicy(String bucketName, PolicyType policyType) { + StringBuilder builder = new StringBuilder(); + builder.append("{\n\"Statement\": [\n{\n\"Action\": [\n"); + if (policyType == PolicyType.WRITE) { + builder.append("\"s3:GetBucketLocation\",\n\"s3:ListBucketMultipartUploads\"\n"); + } else if (policyType == PolicyType.READ_WRITE) { + builder.append("\"s3:GetBucketLocation\",\n\"s3:ListBucket\",\n\"s3:ListBucketMultipartUploads\"\n"); + } else { + builder.append("\"s3:GetBucketLocation\"\n"); + } + builder.append("],\n\"Effect\": \"Allow\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::"); + builder.append(bucketName); + builder.append("\"\n},\n"); + if (policyType == PolicyType.READ) { + builder.append("{\n\"Action\": [\n\"s3:ListBucket\"\n],\n\"Effect\": \"Deny\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::"); + builder.append(bucketName); + builder.append("\"\n},\n"); + } + builder.append("{\n\"Action\": "); + switch (policyType) { + case WRITE: + builder.append("[\n\"s3:AbortMultipartUpload\",\n\"s3:DeleteObject\",\n\"s3:ListMultipartUploadParts\",\n\"s3:PutObject\"\n],\n"); + break; + case READ_WRITE: + builder.append("[\n\"s3:AbortMultipartUpload\",\n\"s3:DeleteObject\",\n\"s3:GetObject\",\n\"s3:ListMultipartUploadParts\",\n\"s3:PutObject\"\n],\n"); + break; + default: + builder.append("\"s3:GetObject\",\n"); + break; + } + builder.append("\"Effect\": \"Allow\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::"); + builder.append(bucketName); + builder.append("/*\"\n}\n],\n\"Version\": \"2012-10-17\"\n}\n"); + return builder.toString(); + } + +} diff --git a/ruoyi/src/main/java/com/ruoyi/oss/enumd/OssEnumd.java b/ruoyi/src/main/java/com/ruoyi/oss/enumd/OssEnumd.java deleted file mode 100644 index e16a67338..000000000 --- a/ruoyi/src/main/java/com/ruoyi/oss/enumd/OssEnumd.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.ruoyi.oss.enumd; - -import com.ruoyi.oss.service.impl.AliyunOssStrategy; -import com.ruoyi.oss.service.impl.MinioOssStrategy; -import com.ruoyi.oss.service.impl.QcloudOssStrategy; -import com.ruoyi.oss.service.impl.QiniuOssStrategy; -import lombok.AllArgsConstructor; -import lombok.Getter; - -/** - * 对象存储服务商枚举 - * - * @author Lion Li - */ -@Getter -@AllArgsConstructor -public enum OssEnumd { - - /** - * 七牛云 - */ - QINIU("qiniu", QiniuOssStrategy.class), - - /** - * 阿里云 - */ - ALIYUN("aliyun", AliyunOssStrategy.class), - - /** - * 腾讯云 - */ - QCLOUD("qcloud", QcloudOssStrategy.class), - - /** - * minio - */ - MINIO("minio", MinioOssStrategy.class); - - private final String value; - - private final Class beanClass; - - public static OssEnumd find(String value) { - for (OssEnumd enumd : values()) { - if (enumd.getValue().equals(value)) { - return enumd; - } - } - return null; - } - -} diff --git a/ruoyi/src/main/java/com/ruoyi/oss/enumd/PolicyType.java b/ruoyi/src/main/java/com/ruoyi/oss/enumd/PolicyType.java index e1925dcfb..606f0f484 100644 --- a/ruoyi/src/main/java/com/ruoyi/oss/enumd/PolicyType.java +++ b/ruoyi/src/main/java/com/ruoyi/oss/enumd/PolicyType.java @@ -1,19 +1,3 @@ -/* - * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * Neither the name of the dreamlu.net developer nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * Author: Chill 庄骞 (smallchill@163.com) - */ package com.ruoyi.oss.enumd; import lombok.AllArgsConstructor; diff --git a/ruoyi/src/main/java/com/ruoyi/oss/factory/OssFactory.java b/ruoyi/src/main/java/com/ruoyi/oss/factory/OssFactory.java index 9ac887e65..7065c4a4a 100644 --- a/ruoyi/src/main/java/com/ruoyi/oss/factory/OssFactory.java +++ b/ruoyi/src/main/java/com/ruoyi/oss/factory/OssFactory.java @@ -3,15 +3,15 @@ package com.ruoyi.oss.factory; import com.ruoyi.common.utils.JsonUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.redis.RedisUtils; -import com.ruoyi.common.utils.spring.SpringUtils; import com.ruoyi.oss.constant.OssConstant; -import com.ruoyi.oss.enumd.OssEnumd; +import com.ruoyi.oss.core.OssClient; import com.ruoyi.oss.exception.OssException; import com.ruoyi.oss.properties.OssProperties; -import com.ruoyi.oss.service.IOssStrategy; -import com.ruoyi.oss.service.abstractd.AbstractOssStrategy; import lombok.extern.slf4j.Slf4j; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + /** * 文件上传Factory * @@ -20,17 +20,19 @@ import lombok.extern.slf4j.Slf4j; @Slf4j public class OssFactory { + private static final Map CLIENT_CACHE = new ConcurrentHashMap<>(); + /** * 初始化工厂 */ public static void init() { log.info("初始化OSS工厂"); - RedisUtils.subscribe(OssConstant.CACHE_CONFIG_KEY, String.class, type -> { - AbstractOssStrategy strategy = getStrategy(type); + RedisUtils.subscribe(OssConstant.CACHE_CONFIG_KEY, String.class, configKey -> { + OssClient client = getClient(configKey); // 未初始化不处理 - if (strategy.isInit) { - refresh(type); - log.info("订阅刷新OSS配置 => " + type); + if (client != null) { + refresh(configKey); + log.info("订阅刷新OSS配置 => " + configKey); } }); } @@ -38,42 +40,38 @@ public class OssFactory { /** * 获取默认实例 */ - public static IOssStrategy instance() { + public static OssClient instance() { // 获取redis 默认类型 - String type = RedisUtils.getCacheObject(OssConstant.CACHE_CONFIG_KEY); - if (StringUtils.isEmpty(type)) { + String configKey = RedisUtils.getCacheObject(OssConstant.CACHE_CONFIG_KEY); + if (StringUtils.isEmpty(configKey)) { throw new OssException("文件存储服务类型无法找到!"); } - return instance(type); + return instance(configKey); } /** * 根据类型获取实例 */ - public static IOssStrategy instance(String type) { - OssEnumd enumd = OssEnumd.find(type); - if (enumd == null) { - throw new OssException("文件存储服务类型无法找到!"); + public static OssClient instance(String configKey) { + OssClient client = getClient(configKey); + if (client == null) { + refresh(configKey); + return getClient(configKey); } - AbstractOssStrategy strategy = getStrategy(type); - if (!strategy.isInit) { - refresh(type); - } - return strategy; + return client; } - private static void refresh(String type) { - Object json = RedisUtils.getCacheObject(OssConstant.SYS_OSS_KEY + type); + private static void refresh(String configKey) { + Object json = RedisUtils.getCacheObject(OssConstant.SYS_OSS_KEY + configKey); OssProperties properties = JsonUtils.parseObject(json.toString(), OssProperties.class); if (properties == null) { - throw new OssException("系统异常, '" + type + "'配置信息不存在!"); + throw new OssException("系统异常, '" + configKey + "'配置信息不存在!"); } - getStrategy(type).init(properties); + CLIENT_CACHE.put(configKey, new OssClient(configKey, properties)); } - private static AbstractOssStrategy getStrategy(String type) { - OssEnumd enumd = OssEnumd.find(type); - return (AbstractOssStrategy) SpringUtils.getBean(enumd.getBeanClass()); + private static OssClient getClient(String configKey) { + return CLIENT_CACHE.get(configKey); } } diff --git a/ruoyi/src/main/java/com/ruoyi/oss/properties/OssProperties.java b/ruoyi/src/main/java/com/ruoyi/oss/properties/OssProperties.java index d09bfdb69..a01777901 100644 --- a/ruoyi/src/main/java/com/ruoyi/oss/properties/OssProperties.java +++ b/ruoyi/src/main/java/com/ruoyi/oss/properties/OssProperties.java @@ -11,10 +11,15 @@ import lombok.Data; public class OssProperties { /** - * 域名 + * 访问站点 */ private String endpoint; + /** + * 自定义域名 + */ + private String domain; + /** * 前缀 */ diff --git a/ruoyi/src/main/java/com/ruoyi/oss/service/IOssStrategy.java b/ruoyi/src/main/java/com/ruoyi/oss/service/IOssStrategy.java deleted file mode 100644 index 981c23e9e..000000000 --- a/ruoyi/src/main/java/com/ruoyi/oss/service/IOssStrategy.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.ruoyi.oss.service; - -import com.ruoyi.oss.entity.UploadResult; -import com.ruoyi.oss.enumd.OssEnumd; - -import java.io.InputStream; - -/** - * 对象存储策略 - * - * @author Lion Li - */ -public interface IOssStrategy { - - /** - * 创建存储桶 - */ - void createBucket(); - - /** - * 获取服务商类型 - * @return 对象存储服务商枚举 - */ - OssEnumd getServiceType(); - - /** - * 文件上传 - * - * @param data 文件字节数组 - * @param path 文件路径,包含文件名 - * @param contentType 文件类型 - * @return 返回http地址 - */ - UploadResult upload(byte[] data, String path, String contentType); - - /** - * 文件删除 - * - * @param path 文件路径,包含文件名 - */ - void delete(String path); - - /** - * 文件上传 - * - * @param data 文件字节数组 - * @param suffix 后缀 - * @param contentType 文件类型 - * @return 返回http地址 - */ - UploadResult uploadSuffix(byte[] data, String suffix, String contentType); - - /** - * 文件上传 - * - * @param inputStream 字节流 - * @param path 文件路径,包含文件名 - * @param contentType 文件类型 - * @return 返回http地址 - */ - UploadResult upload(InputStream inputStream, String path, String contentType); - - /** - * 文件上传 - * - * @param inputStream 字节流 - * @param suffix 后缀 - * @param contentType 文件类型 - * @return 返回http地址 - */ - UploadResult uploadSuffix(InputStream inputStream, String suffix, String contentType); - -} diff --git a/ruoyi/src/main/java/com/ruoyi/oss/service/abstractd/AbstractOssStrategy.java b/ruoyi/src/main/java/com/ruoyi/oss/service/abstractd/AbstractOssStrategy.java deleted file mode 100644 index ae17c19de..000000000 --- a/ruoyi/src/main/java/com/ruoyi/oss/service/abstractd/AbstractOssStrategy.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.ruoyi.oss.service.abstractd; - -import cn.hutool.core.io.IoUtil; -import cn.hutool.core.util.IdUtil; -import com.ruoyi.common.utils.DateUtils; -import com.ruoyi.common.utils.StringUtils; -import com.ruoyi.oss.entity.UploadResult; -import com.ruoyi.oss.enumd.OssEnumd; -import com.ruoyi.oss.properties.OssProperties; -import com.ruoyi.oss.service.IOssStrategy; - -import java.io.InputStream; - -/** - * 对象存储策略(支持七牛、阿里云、腾讯云、minio) - * - * @author Lion Li - */ -public abstract class AbstractOssStrategy implements IOssStrategy { - - protected OssProperties properties; - public boolean isInit = false; - - public void init(OssProperties properties) { - this.properties = properties; - } - - @Override - public abstract void createBucket(); - - @Override - public abstract OssEnumd getServiceType(); - - public String getPath(String prefix, String suffix) { - // 生成uuid - String uuid = IdUtil.fastSimpleUUID(); - // 文件路径 - String path = DateUtils.datePath() + "/" + uuid; - if (StringUtils.isNotBlank(prefix)) { - path = prefix + "/" + path; - } - return path + suffix; - } - - @Override - public abstract UploadResult upload(byte[] data, String path, String contentType); - - @Override - public abstract void delete(String path); - - @Override - public UploadResult upload(InputStream inputStream, String path, String contentType) { - byte[] data = IoUtil.readBytes(inputStream); - return this.upload(data, path, contentType); - } - - @Override - public abstract UploadResult uploadSuffix(byte[] data, String suffix, String contentType); - - @Override - public abstract UploadResult uploadSuffix(InputStream inputStream, String suffix, String contentType); - - /** - * 获取域名访问链接 - * - * @return 域名访问链接 - */ - public abstract String getEndpointLink(); -} diff --git a/ruoyi/src/main/java/com/ruoyi/oss/service/impl/AliyunOssStrategy.java b/ruoyi/src/main/java/com/ruoyi/oss/service/impl/AliyunOssStrategy.java deleted file mode 100644 index 62c29228f..000000000 --- a/ruoyi/src/main/java/com/ruoyi/oss/service/impl/AliyunOssStrategy.java +++ /dev/null @@ -1,120 +0,0 @@ -package com.ruoyi.oss.service.impl; - -import com.aliyun.oss.ClientConfiguration; -import com.aliyun.oss.OSSClient; -import com.aliyun.oss.common.auth.DefaultCredentialProvider; -import com.aliyun.oss.common.comm.Protocol; -import com.aliyun.oss.model.CannedAccessControlList; -import com.aliyun.oss.model.CreateBucketRequest; -import com.aliyun.oss.model.ObjectMetadata; -import com.aliyun.oss.model.PutObjectRequest; -import com.ruoyi.common.utils.StringUtils; -import com.ruoyi.oss.constant.OssConstant; -import com.ruoyi.oss.entity.UploadResult; -import com.ruoyi.oss.enumd.OssEnumd; -import com.ruoyi.oss.exception.OssException; -import com.ruoyi.oss.properties.OssProperties; -import com.ruoyi.oss.service.abstractd.AbstractOssStrategy; -import org.springframework.stereotype.Component; - -import java.io.ByteArrayInputStream; -import java.io.InputStream; - -/** - * 阿里云存储策略 - * - * @author Lion Li - */ -@Component -public class AliyunOssStrategy extends AbstractOssStrategy { - - private OSSClient client; - - @Override - public void init(OssProperties ossProperties) { - super.init(ossProperties); - try { - ClientConfiguration configuration = new ClientConfiguration(); - if (OssConstant.IS_HTTPS.equals(ossProperties.getIsHttps())) { - configuration.setProtocol(Protocol.HTTPS); - } - DefaultCredentialProvider credentialProvider = new DefaultCredentialProvider( - properties.getAccessKey(), properties.getSecretKey()); - client = new OSSClient(properties.getEndpoint(), credentialProvider, configuration); - createBucket(); - } catch (Exception e) { - throw new OssException("阿里云存储配置错误! 请检查系统配置:[" + e.getMessage() + "]"); - } - isInit = true; - } - - @Override - public void createBucket() { - try { - String bucketName = properties.getBucketName(); - if (client.doesBucketExist(bucketName)) { - return; - } - CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName); - createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead); - client.createBucket(createBucketRequest); - } catch (Exception e) { - throw new OssException("创建Bucket失败, 请核对阿里云配置信息:[" + e.getMessage() + "]"); - } - } - - @Override - public OssEnumd getServiceType() { - return OssEnumd.ALIYUN; - } - - @Override - public UploadResult upload(byte[] data, String path, String contentType) { - return upload(new ByteArrayInputStream(data), path, contentType); - } - - @Override - public UploadResult upload(InputStream inputStream, String path, String contentType) { - try { - ObjectMetadata metadata = new ObjectMetadata(); - metadata.setContentType(contentType); - client.putObject(new PutObjectRequest(properties.getBucketName(), path, inputStream, metadata)); - } catch (Exception e) { - throw new OssException("上传文件失败,请检查阿里云配置信息:[" + e.getMessage() + "]"); - } - return UploadResult.builder().url(getEndpointLink() + "/" + path).filename(path).build(); } - - @Override - public void delete(String path) { - path = path.replace(getEndpointLink() + "/", ""); - try { - client.deleteObject(properties.getBucketName(), path); - } catch (Exception e) { - throw new OssException("上传文件失败,请检查阿里云配置信息:[" + e.getMessage() + "]"); - } - } - - @Override - public UploadResult uploadSuffix(byte[] data, String suffix, String contentType) { - return upload(data, getPath(properties.getPrefix(), suffix), contentType); - } - - @Override - public UploadResult uploadSuffix(InputStream inputStream, String suffix, String contentType) { - return upload(inputStream, getPath(properties.getPrefix(), suffix), contentType); - } - - @Override - public String getEndpointLink() { - String endpoint = properties.getEndpoint(); - StringBuilder sb = new StringBuilder(endpoint); - if (StringUtils.containsAnyIgnoreCase(endpoint, "http://")) { - sb.insert(7, properties.getBucketName() + "."); - } else if (StringUtils.containsAnyIgnoreCase(endpoint, "https://")) { - sb.insert(8, properties.getBucketName() + "."); - } else { - throw new OssException("Endpoint配置错误"); - } - return sb.toString(); - } -} diff --git a/ruoyi/src/main/java/com/ruoyi/oss/service/impl/MinioOssStrategy.java b/ruoyi/src/main/java/com/ruoyi/oss/service/impl/MinioOssStrategy.java deleted file mode 100644 index f5be957fa..000000000 --- a/ruoyi/src/main/java/com/ruoyi/oss/service/impl/MinioOssStrategy.java +++ /dev/null @@ -1,194 +0,0 @@ -package com.ruoyi.oss.service.impl; - -import com.ruoyi.common.utils.StringUtils; -import com.ruoyi.oss.constant.OssConstant; -import com.ruoyi.oss.entity.UploadResult; -import com.ruoyi.oss.enumd.OssEnumd; -import com.ruoyi.oss.enumd.PolicyType; -import com.ruoyi.oss.exception.OssException; -import com.ruoyi.oss.properties.OssProperties; -import com.ruoyi.oss.service.abstractd.AbstractOssStrategy; -import io.minio.*; -import io.minio.http.HttpUtils; -import okhttp3.HttpUrl; -import org.springframework.http.MediaType; -import org.springframework.stereotype.Component; - -import java.io.ByteArrayInputStream; -import java.io.InputStream; - -/** - * minio存储策略 - * - * @author Lion Li - */ -@Component -public class MinioOssStrategy extends AbstractOssStrategy { - - private MinioClient minioClient; - - @Override - public void init(OssProperties ossProperties) { - super.init(ossProperties); - try { - MinioClient.Builder builder = MinioClient.builder(); - if (OssConstant.IS_HTTPS.equals(ossProperties.getIsHttps())) { - HttpUrl url = HttpUtils.getBaseUrl(properties.getEndpoint()) - .newBuilder().scheme("https").build(); - builder.endpoint(url); - } else { - builder.endpoint(properties.getEndpoint()); - } - minioClient = builder.credentials(properties.getAccessKey(), properties.getSecretKey()).build(); - createBucket(); - } catch (Exception e) { - throw new OssException("Minio存储配置错误! 请检查系统配置:[" + e.getMessage() + "]"); - } - isInit = true; - } - - @Override - public void createBucket() { - try { - String bucketName = properties.getBucketName(); - boolean exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build()); - if (exists) { - return; - } - // 不存在就创建桶 - minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build()); - minioClient.setBucketPolicy(SetBucketPolicyArgs.builder() - .bucket(bucketName) - .config(getPolicy(bucketName, PolicyType.READ)) - .build()); - } catch (Exception e) { - throw new OssException("创建Bucket失败, 请核对Minio配置信息:[" + e.getMessage() + "]"); - } - } - - @Override - public OssEnumd getServiceType() { - return OssEnumd.MINIO; - } - - @Override - public UploadResult upload(byte[] data, String path, String contentType) { - return upload(new ByteArrayInputStream(data), path, contentType); - } - - @Override - public UploadResult upload(InputStream inputStream, String path, String contentType) { - try { - // 解决 inputStream.available() 再 socket 下传输延迟问题 导致获取数值不精确 - Thread.sleep(1000); - minioClient.putObject(PutObjectArgs.builder() - .bucket(properties.getBucketName()) - .object(path) - .contentType(StringUtils.blankToDefault(contentType, MediaType.APPLICATION_OCTET_STREAM_VALUE)) - .stream(inputStream, inputStream.available(), -1) - .build()); - } catch (Exception e) { - throw new OssException("上传文件失败,请核对Minio配置信息:[" + e.getMessage() + "]"); - } - return UploadResult.builder().url(getEndpointLink() + "/" + path).filename(path).build(); - } - - @Override - public void delete(String path) { - path = path.replace(getEndpointLink() + "/", ""); - try { - minioClient.removeObject(RemoveObjectArgs.builder() - .bucket(properties.getBucketName()) - .object(path) - .build()); - } catch (Exception e) { - throw new OssException(e.getMessage()); - } - } - - @Override - public UploadResult uploadSuffix(byte[] data, String suffix, String contentType) { - return upload(data, getPath(properties.getPrefix(), suffix), contentType); - } - - @Override - public UploadResult uploadSuffix(InputStream inputStream, String suffix, String contentType) { - return upload(inputStream, getPath(properties.getPrefix(), suffix), contentType); - } - - @Override - public String getEndpointLink() { - return properties.getEndpoint() + "/" + properties.getBucketName(); - } - - private String getPolicy(String bucketName, PolicyType policyType) { - StringBuilder builder = new StringBuilder(); - builder.append("{\n"); - builder.append(" \"Statement\": [\n"); - builder.append(" {\n"); - builder.append(" \"Action\": [\n"); - if (policyType == PolicyType.WRITE) { - builder.append(" \"s3:GetBucketLocation\",\n"); - builder.append(" \"s3:ListBucketMultipartUploads\"\n"); - } else if (policyType == PolicyType.READ_WRITE) { - builder.append(" \"s3:GetBucketLocation\",\n"); - builder.append(" \"s3:ListBucket\",\n"); - builder.append(" \"s3:ListBucketMultipartUploads\"\n"); - } else { - builder.append(" \"s3:GetBucketLocation\"\n"); - } - builder.append(" ],\n"); - builder.append(" \"Effect\": \"Allow\",\n"); - builder.append(" \"Principal\": \"*\",\n"); - builder.append(" \"Resource\": \"arn:aws:s3:::"); - builder.append(bucketName); - builder.append("\"\n"); - builder.append(" },\n"); - if (PolicyType.READ.equals(policyType)) { - builder.append(" {\n"); - builder.append(" \"Action\": [\n"); - builder.append(" \"s3:ListBucket\"\n"); - builder.append(" ],\n"); - builder.append(" \"Effect\": \"Deny\",\n"); - builder.append(" \"Principal\": \"*\",\n"); - builder.append(" \"Resource\": \"arn:aws:s3:::"); - builder.append(bucketName); - builder.append("\"\n"); - builder.append(" },\n"); - } - builder.append(" {\n"); - builder.append(" \"Action\": "); - switch (policyType) { - case WRITE: - builder.append("[\n"); - builder.append(" \"s3:AbortMultipartUpload\",\n"); - builder.append(" \"s3:DeleteObject\",\n"); - builder.append(" \"s3:ListMultipartUploadParts\",\n"); - builder.append(" \"s3:PutObject\"\n"); - builder.append(" ],\n"); - break; - case READ_WRITE: - builder.append("[\n"); - builder.append(" \"s3:AbortMultipartUpload\",\n"); - builder.append(" \"s3:DeleteObject\",\n"); - builder.append(" \"s3:GetObject\",\n"); - builder.append(" \"s3:ListMultipartUploadParts\",\n"); - builder.append(" \"s3:PutObject\"\n"); - builder.append(" ],\n"); - break; - default: - builder.append("\"s3:GetObject\",\n"); - break; - } - builder.append(" \"Effect\": \"Allow\",\n"); - builder.append(" \"Principal\": \"*\",\n"); - builder.append(" \"Resource\": \"arn:aws:s3:::"); - builder.append(bucketName); - builder.append("/*\"\n"); - builder.append(" }\n"); - builder.append(" ],\n"); - builder.append(" \"Version\": \"2012-10-17\"\n"); - builder.append("}\n"); - return builder.toString(); - } -} diff --git a/ruoyi/src/main/java/com/ruoyi/oss/service/impl/QcloudOssStrategy.java b/ruoyi/src/main/java/com/ruoyi/oss/service/impl/QcloudOssStrategy.java deleted file mode 100644 index 756462e4d..000000000 --- a/ruoyi/src/main/java/com/ruoyi/oss/service/impl/QcloudOssStrategy.java +++ /dev/null @@ -1,125 +0,0 @@ -package com.ruoyi.oss.service.impl; - -import com.qcloud.cos.COSClient; -import com.qcloud.cos.ClientConfig; -import com.qcloud.cos.auth.BasicCOSCredentials; -import com.qcloud.cos.auth.COSCredentials; -import com.qcloud.cos.http.HttpProtocol; -import com.qcloud.cos.model.*; -import com.qcloud.cos.region.Region; -import com.ruoyi.common.utils.StringUtils; -import com.ruoyi.oss.constant.OssConstant; -import com.ruoyi.oss.entity.UploadResult; -import com.ruoyi.oss.enumd.OssEnumd; -import com.ruoyi.oss.exception.OssException; -import com.ruoyi.oss.properties.OssProperties; -import com.ruoyi.oss.service.abstractd.AbstractOssStrategy; -import org.springframework.stereotype.Component; - -import java.io.ByteArrayInputStream; -import java.io.InputStream; - -/** - * 腾讯云存储策略 - * - * @author Lion Li - */ -@Component -public class QcloudOssStrategy extends AbstractOssStrategy { - - private COSClient client; - - @Override - public void init(OssProperties ossProperties) { - super.init(ossProperties); - try { - COSCredentials credentials = new BasicCOSCredentials( - properties.getAccessKey(), properties.getSecretKey()); - // 初始化客户端配置 - ClientConfig clientConfig = new ClientConfig(); - // 设置bucket所在的区域,华南:gz 华北:tj 华东:sh - clientConfig.setRegion(new Region(properties.getRegion())); - if (OssConstant.IS_HTTPS.equals(properties.getIsHttps())) { - clientConfig.setHttpProtocol(HttpProtocol.https); - } else { - clientConfig.setHttpProtocol(HttpProtocol.http); - } - client = new COSClient(credentials, clientConfig); - createBucket(); - } catch (Exception e) { - throw new OssException("腾讯云存储配置错误! 请检查系统配置:[" + e.getMessage() + "]"); - } - isInit = true; - } - - @Override - public void createBucket() { - try { - String bucketName = properties.getBucketName(); - if (client.doesBucketExist(bucketName)) { - return; - } - CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName); - createBucketRequest.setCannedAcl(CannedAccessControlList.PublicRead); - client.createBucket(createBucketRequest); - } catch (Exception e) { - throw new OssException("创建Bucket失败, 请核对腾讯云配置信息:[" + e.getMessage() + "]"); - } - } - - @Override - public OssEnumd getServiceType() { - return OssEnumd.QCLOUD; - } - - @Override - public UploadResult upload(byte[] data, String path, String contentType) { - return upload(new ByteArrayInputStream(data), path, contentType); - } - - @Override - public UploadResult upload(InputStream inputStream, String path, String contentType) { - try { - ObjectMetadata metadata = new ObjectMetadata(); - metadata.setContentType(contentType); - client.putObject(new PutObjectRequest(properties.getBucketName(), path, inputStream, metadata)); - } catch (Exception e) { - throw new OssException("上传文件失败,请检查腾讯云配置信息:[" + e.getMessage() + "]"); - } - return UploadResult.builder().url(getEndpointLink() + "/" + path).filename(path).build(); - } - - @Override - public void delete(String path) { - path = path.replace(getEndpointLink() + "/", ""); - try { - client.deleteObject(new DeleteObjectRequest(properties.getBucketName(), path)); - } catch (Exception e) { - throw new OssException("上传文件失败,请检腾讯云查配置信息:[" + e.getMessage() + "]"); - } - } - - @Override - public UploadResult uploadSuffix(byte[] data, String suffix, String contentType) { - return upload(data, getPath(properties.getPrefix(), suffix), contentType); - } - - @Override - public UploadResult uploadSuffix(InputStream inputStream, String suffix, String contentType) { - return upload(inputStream, getPath(properties.getPrefix(), suffix), contentType); - } - - @Override - public String getEndpointLink() { - String endpoint = properties.getEndpoint(); - StringBuilder sb = new StringBuilder(endpoint); - if (StringUtils.containsAnyIgnoreCase(endpoint, "http://")) { - sb.insert(7, properties.getBucketName() + "."); - } else if (StringUtils.containsAnyIgnoreCase(endpoint, "https://")) { - sb.insert(8, properties.getBucketName() + "."); - } else { - throw new OssException("Endpoint配置错误"); - } - return sb.toString(); - } -} diff --git a/ruoyi/src/main/java/com/ruoyi/oss/service/impl/QiniuOssStrategy.java b/ruoyi/src/main/java/com/ruoyi/oss/service/impl/QiniuOssStrategy.java deleted file mode 100644 index 20f13eca1..000000000 --- a/ruoyi/src/main/java/com/ruoyi/oss/service/impl/QiniuOssStrategy.java +++ /dev/null @@ -1,127 +0,0 @@ -package com.ruoyi.oss.service.impl; - -import cn.hutool.core.util.ArrayUtil; -import com.qiniu.http.Response; -import com.qiniu.storage.BucketManager; -import com.qiniu.storage.Configuration; -import com.qiniu.storage.Region; -import com.qiniu.storage.UploadManager; -import com.qiniu.util.Auth; -import com.ruoyi.oss.constant.OssConstant; -import com.ruoyi.oss.entity.UploadResult; -import com.ruoyi.oss.enumd.OssEnumd; -import com.ruoyi.oss.exception.OssException; -import com.ruoyi.oss.properties.OssProperties; -import com.ruoyi.oss.service.abstractd.AbstractOssStrategy; -import org.springframework.stereotype.Component; - -import java.io.InputStream; - -/** - * 七牛云存储策略 - * - * @author Lion Li - */ -@Component -public class QiniuOssStrategy extends AbstractOssStrategy { - - private UploadManager uploadManager; - private BucketManager bucketManager; - private Auth auth; - - - @Override - public void init(OssProperties ossProperties) { - super.init(ossProperties); - try { - Configuration config = new Configuration(getRegion(properties.getRegion())); - // https设置 - config.useHttpsDomains = OssConstant.IS_HTTPS.equals(properties.getIsHttps()); - uploadManager = new UploadManager(config); - auth = Auth.create(properties.getAccessKey(), properties.getSecretKey()); - bucketManager = new BucketManager(auth, config); - createBucket(); - } catch (Exception e) { - throw new OssException("七牛云存储配置错误! 请检查系统配置:[" + e.getMessage() + "]"); - } - isInit = true; - } - - @Override - public void createBucket() { - try { - String bucketName = properties.getBucketName(); - if (ArrayUtil.contains(bucketManager.buckets(), bucketName)) { - return; - } - bucketManager.createBucket(bucketName, properties.getRegion()); - } catch (Exception e) { - throw new OssException("创建Bucket失败, 请核对七牛云配置信息:[" + e.getMessage() + "]"); - } - } - - @Override - public OssEnumd getServiceType() { - return OssEnumd.QINIU; - } - - @Override - public UploadResult upload(byte[] data, String path, String contentType) { - try { - String token = auth.uploadToken(properties.getBucketName()); - Response res = uploadManager.put(data, path, token, null, contentType, false); - if (!res.isOK()) { - throw new RuntimeException("上传七牛出错:" + res.error); - } - } catch (Exception e) { - throw new OssException("上传文件失败,请核对七牛配置信息:[" + e.getMessage() + "]"); - } - return UploadResult.builder().url(getEndpointLink() + "/" + path).filename(path).build(); - } - - @Override - public void delete(String path) { - try { - path = path.replace(getEndpointLink() + "/", ""); - Response res = bucketManager.delete(properties.getBucketName(), path); - if (!res.isOK()) { - throw new RuntimeException("删除七牛文件出错:" + res.error); - } - } catch (Exception e) { - throw new OssException(e.getMessage()); - } - } - - @Override - public UploadResult uploadSuffix(byte[] data, String suffix, String contentType) { - return upload(data, getPath(properties.getPrefix(), suffix), contentType); - } - - @Override - public UploadResult uploadSuffix(InputStream inputStream, String suffix, String contentType) { - return upload(inputStream, getPath(properties.getPrefix(), suffix), contentType); - } - - @Override - public String getEndpointLink() { - return properties.getEndpoint(); - } - - private Region getRegion(String region) { - switch (region) { - case "z0": - return Region.region0(); - case "z1": - return Region.region1(); - case "z2": - return Region.region2(); - case "na0": - return Region.regionNa0(); - case "as0": - return Region.regionAs0(); - default: - return Region.autoRegion(); - } - } - -} diff --git a/ruoyi/src/main/java/com/ruoyi/sms/config/SmsConfig.java b/ruoyi/src/main/java/com/ruoyi/sms/config/SmsConfig.java new file mode 100644 index 000000000..e9ce2b4de --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/sms/config/SmsConfig.java @@ -0,0 +1,46 @@ +package com.ruoyi.sms.config; + +import com.ruoyi.sms.config.properties.SmsProperties; +import com.ruoyi.sms.core.AliyunSmsTemplate; +import com.ruoyi.sms.core.SmsTemplate; +import com.ruoyi.sms.core.TencentSmsTemplate; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * 短信配置类 + * 需要哪个 打开哪个的注释即可 + * + * @author Lion Li + * @version 4.2.0 + */ +@Configuration +public class SmsConfig { + +// @Configuration +// @ConditionalOnProperty(value = "sms.enabled", havingValue = "true") +// @ConditionalOnClass(com.aliyun.dysmsapi20170525.Client.class) +// static class AliyunSmsConfig { +// +// @Bean +// public SmsTemplate aliyunSmsTemplate(SmsProperties smsProperties) { +// return new AliyunSmsTemplate(smsProperties); +// } +// +// } + + @Configuration + @ConditionalOnProperty(value = "sms.enabled", havingValue = "true") + @ConditionalOnClass(com.tencentcloudapi.sms.v20190711.SmsClient.class) + static class TencentSmsConfig { + + @Bean + public SmsTemplate tencentSmsTemplate(SmsProperties smsProperties) { + return new TencentSmsTemplate(smsProperties); + } + + } + +} diff --git a/ruoyi/src/main/java/com/ruoyi/sms/config/properties/SmsProperties.java b/ruoyi/src/main/java/com/ruoyi/sms/config/properties/SmsProperties.java new file mode 100644 index 000000000..39359cdfd --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/sms/config/properties/SmsProperties.java @@ -0,0 +1,47 @@ +package com.ruoyi.sms.config.properties; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * SMS短信 配置属性 + * + * @author Lion Li + * @version 4.2.0 + */ +@Data +@Component +@ConfigurationProperties(prefix = "sms") +public class SmsProperties { + + private Boolean enabled; + + /** + * 配置节点 + * 阿里云 dysmsapi.aliyuncs.com + * 腾讯云 sms.tencentcloudapi.com + */ + private String endpoint; + + /** + * key + */ + private String accessKeyId; + + /** + * 密匙 + */ + private String accessKeySecret; + + /* + * 短信签名 + */ + private String signName; + + /** + * 短信应用ID (腾讯专属) + */ + private String sdkAppId; + +} diff --git a/ruoyi/src/main/java/com/ruoyi/sms/core/AliyunSmsTemplate.java b/ruoyi/src/main/java/com/ruoyi/sms/core/AliyunSmsTemplate.java new file mode 100644 index 000000000..eede376e5 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/sms/core/AliyunSmsTemplate.java @@ -0,0 +1,66 @@ +package com.ruoyi.sms.core; + +import com.aliyun.dysmsapi20170525.Client; +import com.aliyun.dysmsapi20170525.models.SendSmsRequest; +import com.aliyun.dysmsapi20170525.models.SendSmsResponse; +import com.aliyun.teaopenapi.models.Config; +import com.ruoyi.common.utils.JsonUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.sms.config.properties.SmsProperties; +import com.ruoyi.sms.entity.SmsResult; +import com.ruoyi.sms.exception.SmsException; +import lombok.SneakyThrows; + +import java.util.Map; + +/** + * Aliyun 短信模板 + * + * @author Lion Li + * @version 4.2.0 + */ +public class AliyunSmsTemplate implements SmsTemplate { + + private SmsProperties properties; + + private Client client; + + @SneakyThrows(Exception.class) + public AliyunSmsTemplate(SmsProperties smsProperties) { + this.properties = smsProperties; + Config config = new Config() + // 您的AccessKey ID + .setAccessKeyId(smsProperties.getAccessKeyId()) + // 您的AccessKey Secret + .setAccessKeySecret(smsProperties.getAccessKeySecret()) + // 访问的域名 + .setEndpoint(smsProperties.getEndpoint()); + this.client = new Client(config); + } + + @Override + public SmsResult send(String phones, String templateId, Map param) { + if (StringUtils.isBlank(phones)) { + throw new SmsException("手机号不能为空"); + } + if (StringUtils.isBlank(templateId)) { + throw new SmsException("模板ID不能为空"); + } + SendSmsRequest req = new SendSmsRequest() + .setPhoneNumbers(phones) + .setSignName(properties.getSignName()) + .setTemplateCode(templateId) + .setTemplateParam(JsonUtils.toJsonString(param)); + try { + SendSmsResponse resp = client.sendSms(req); + return SmsResult.builder() + .isSuccess("OK".equals(resp.getBody().getCode())) + .message(resp.getBody().getMessage()) + .response(resp) + .build(); + } catch (Exception e) { + throw new SmsException(e.getMessage()); + } + } + +} diff --git a/ruoyi/src/main/java/com/ruoyi/sms/core/SmsTemplate.java b/ruoyi/src/main/java/com/ruoyi/sms/core/SmsTemplate.java new file mode 100644 index 000000000..0aec3ddbe --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/sms/core/SmsTemplate.java @@ -0,0 +1,26 @@ +package com.ruoyi.sms.core; + +import com.ruoyi.sms.entity.SmsResult; + +import java.util.Map; + +/** + * 短信模板 + * + * @author Lion Li + * @version 4.2.0 + */ +public interface SmsTemplate { + + /** + * 发送短信 + * + * @param phones 电话号(多个逗号分割) + * @param templateId 模板id + * @param param 模板对应参数 + * 阿里 需使用 模板变量名称对应内容 例如: code=1234 + * 腾讯 需使用 模板变量顺序对应内容 例如: 1=1234, 1为模板内第一个参数 + */ + SmsResult send(String phones, String templateId, Map param); + +} diff --git a/ruoyi/src/main/java/com/ruoyi/sms/core/TencentSmsTemplate.java b/ruoyi/src/main/java/com/ruoyi/sms/core/TencentSmsTemplate.java new file mode 100644 index 000000000..1de8eae14 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/sms/core/TencentSmsTemplate.java @@ -0,0 +1,81 @@ +package com.ruoyi.sms.core; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ArrayUtil; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.sms.config.properties.SmsProperties; +import com.ruoyi.sms.entity.SmsResult; +import com.ruoyi.sms.exception.SmsException; +import com.tencentcloudapi.common.Credential; +import com.tencentcloudapi.common.profile.ClientProfile; +import com.tencentcloudapi.common.profile.HttpProfile; +import com.tencentcloudapi.sms.v20190711.SmsClient; +import com.tencentcloudapi.sms.v20190711.models.SendSmsRequest; +import com.tencentcloudapi.sms.v20190711.models.SendSmsResponse; +import com.tencentcloudapi.sms.v20190711.models.SendStatus; +import lombok.SneakyThrows; + +import java.util.Arrays; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * Tencent 短信模板 + * + * @author Lion Li + * @version 4.2.0 + */ +public class TencentSmsTemplate implements SmsTemplate { + + private SmsProperties properties; + + private SmsClient client; + + @SneakyThrows(Exception.class) + public TencentSmsTemplate(SmsProperties smsProperties) { + this.properties = smsProperties; + Credential credential = new Credential(smsProperties.getAccessKeyId(), smsProperties.getAccessKeySecret()); + HttpProfile httpProfile = new HttpProfile(); + httpProfile.setEndpoint(smsProperties.getEndpoint()); + ClientProfile clientProfile = new ClientProfile(); + clientProfile.setHttpProfile(httpProfile); + this.client = new SmsClient(credential, "", clientProfile); + } + + @Override + public SmsResult send(String phones, String templateId, Map param) { + if (StringUtils.isBlank(phones)) { + throw new SmsException("手机号不能为空"); + } + if (StringUtils.isBlank(templateId)) { + throw new SmsException("模板ID不能为空"); + } + SendSmsRequest req = new SendSmsRequest(); + Set set = Arrays.stream(phones.split(",")).map(p -> "+86" + p).collect(Collectors.toSet()); + req.setPhoneNumberSet(ArrayUtil.toArray(set, String.class)); + if (CollUtil.isNotEmpty(param)) { + req.setTemplateParamSet(ArrayUtil.toArray(param.values(), String.class)); + } + req.setTemplateID(templateId); + req.setSign(properties.getSignName()); + req.setSmsSdkAppid(properties.getSdkAppId()); + try { + SendSmsResponse resp = client.SendSms(req); + SmsResult.SmsResultBuilder builder = SmsResult.builder() + .isSuccess(true) + .message("send success") + .response(resp); + for (SendStatus sendStatus : resp.getSendStatusSet()) { + if (!"Ok".equals(sendStatus.getCode())) { + builder.isSuccess(false).message(sendStatus.getMessage()); + break; + } + } + return builder.build(); + } catch (Exception e) { + throw new SmsException(e.getMessage()); + } + } + +} diff --git a/ruoyi/src/main/java/com/ruoyi/sms/entity/SmsResult.java b/ruoyi/src/main/java/com/ruoyi/sms/entity/SmsResult.java new file mode 100644 index 000000000..3f13b2774 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/sms/entity/SmsResult.java @@ -0,0 +1,29 @@ +package com.ruoyi.sms.entity; + +import lombok.Builder; +import lombok.Data; + +/** + * 上传返回体 + * + * @author Lion Li + */ +@Data +@Builder +public class SmsResult { + + /** + * 是否成功 + */ + private boolean isSuccess; + + /** + * 响应消息 + */ + private String message; + + /** + * 实际响应体 + */ + private Object response; +} diff --git a/ruoyi/src/main/java/com/ruoyi/sms/exception/SmsException.java b/ruoyi/src/main/java/com/ruoyi/sms/exception/SmsException.java new file mode 100644 index 000000000..28632a375 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/sms/exception/SmsException.java @@ -0,0 +1,16 @@ +package com.ruoyi.sms.exception; + +/** + * Sms异常类 + * + * @author Lion Li + */ +public class SmsException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + public SmsException(String msg) { + super(msg); + } + +} diff --git a/ruoyi/src/main/java/com/ruoyi/system/domain/SysOssConfig.java b/ruoyi/src/main/java/com/ruoyi/system/domain/SysOssConfig.java index a8340df77..577f17fb8 100644 --- a/ruoyi/src/main/java/com/ruoyi/system/domain/SysOssConfig.java +++ b/ruoyi/src/main/java/com/ruoyi/system/domain/SysOssConfig.java @@ -5,7 +5,6 @@ import com.baomidou.mybatisplus.annotation.TableName; import com.ruoyi.common.core.domain.BaseEntity; import lombok.Data; import lombok.EqualsAndHashCode; -import lombok.experimental.Accessors; /** * 对象存储配置对象 sys_oss_config @@ -53,6 +52,11 @@ public class SysOssConfig extends BaseEntity { */ private String endpoint; + /** + * 自定义域名 + */ + private String domain; + /** * 是否https(0否 1是) */ diff --git a/ruoyi/src/main/java/com/ruoyi/system/domain/bo/SysOssConfigBo.java b/ruoyi/src/main/java/com/ruoyi/system/domain/bo/SysOssConfigBo.java index 9a66e384b..5ac4e96e4 100644 --- a/ruoyi/src/main/java/com/ruoyi/system/domain/bo/SysOssConfigBo.java +++ b/ruoyi/src/main/java/com/ruoyi/system/domain/bo/SysOssConfigBo.java @@ -35,8 +35,8 @@ public class SysOssConfigBo extends BaseEntity { /** * 配置key */ - @ApiModelProperty(value = "configKey", required = true) - @NotBlank(message = "configKey不能为空", groups = {AddGroup.class, EditGroup.class}) + @ApiModelProperty(value = "配置key", required = true) + @NotBlank(message = "配置key不能为空", groups = {AddGroup.class, EditGroup.class}) @Size(min = 2, max = 100, message = "configKey长度必须介于2和20 之间") private String configKey; @@ -59,8 +59,8 @@ public class SysOssConfigBo extends BaseEntity { /** * 桶名称 */ - @ApiModelProperty(value = "bucketName", required = true) - @NotBlank(message = "bucketName不能为空", groups = {AddGroup.class, EditGroup.class}) + @ApiModelProperty(value = "桶名称", required = true) + @NotBlank(message = "桶名称不能为空", groups = {AddGroup.class, EditGroup.class}) @Size(min = 2, max = 100, message = "bucketName长度必须介于2和100之间") private String bucketName; @@ -73,11 +73,17 @@ public class SysOssConfigBo extends BaseEntity { /** * 访问站点 */ - @ApiModelProperty(value = "endpoint", required = true) - @NotBlank(message = "endpoint不能为空", groups = {AddGroup.class, EditGroup.class}) + @ApiModelProperty(value = "访问站点", required = true) + @NotBlank(message = "访问站点不能为空", groups = {AddGroup.class, EditGroup.class}) @Size(min = 2, max = 100, message = "endpoint长度必须介于2和100之间") private String endpoint; + /** + * 自定义域名 + */ + @ApiModelProperty("自定义域名") + private String domain; + /** * 是否https(Y=是,N=否) */ @@ -93,7 +99,7 @@ public class SysOssConfigBo extends BaseEntity { /** * 域 */ - @ApiModelProperty(value = "region") + @ApiModelProperty(value = "域") private String region; /** @@ -102,4 +108,10 @@ public class SysOssConfigBo extends BaseEntity { @ApiModelProperty(value = "扩展字段") private String ext1; + /** + * 备注 + */ + @ApiModelProperty(value = "备注") + private String remark; + } diff --git a/ruoyi/src/main/java/com/ruoyi/system/domain/vo/SysOssConfigVo.java b/ruoyi/src/main/java/com/ruoyi/system/domain/vo/SysOssConfigVo.java index 0fb08dd00..20edacaa6 100644 --- a/ruoyi/src/main/java/com/ruoyi/system/domain/vo/SysOssConfigVo.java +++ b/ruoyi/src/main/java/com/ruoyi/system/domain/vo/SysOssConfigVo.java @@ -62,6 +62,12 @@ public class SysOssConfigVo { @ApiModelProperty("访问站点") private String endpoint; + /** + * 自定义域名 + */ + @ApiModelProperty("自定义域名") + private String domain; + /** * 是否https(Y=是,N=否) */ diff --git a/ruoyi/src/main/java/com/ruoyi/system/service/ISysOssService.java b/ruoyi/src/main/java/com/ruoyi/system/service/ISysOssService.java index b444e6d06..c55e5bc12 100644 --- a/ruoyi/src/main/java/com/ruoyi/system/service/ISysOssService.java +++ b/ruoyi/src/main/java/com/ruoyi/system/service/ISysOssService.java @@ -8,6 +8,7 @@ import com.ruoyi.system.domain.vo.SysOssVo; import org.springframework.web.multipart.MultipartFile; import java.util.Collection; +import java.util.List; /** * 文件上传 服务层 @@ -18,6 +19,8 @@ public interface ISysOssService { TableDataInfo queryPageList(SysOssBo sysOss, PageQuery pageQuery); + List listByIds(Collection ossIds); + SysOss getById(Long ossId); SysOss upload(MultipartFile file); diff --git a/ruoyi/src/main/java/com/ruoyi/system/service/SysLoginService.java b/ruoyi/src/main/java/com/ruoyi/system/service/SysLoginService.java index e0b53c1fb..1a672e59c 100644 --- a/ruoyi/src/main/java/com/ruoyi/system/service/SysLoginService.java +++ b/ruoyi/src/main/java/com/ruoyi/system/service/SysLoginService.java @@ -27,8 +27,8 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import javax.servlet.http.HttpServletRequest; +import java.time.Duration; import java.util.List; -import java.util.concurrent.TimeUnit; import java.util.function.Supplier; /** @@ -79,7 +79,7 @@ public class SysLoginService { SysUser user = loadUserByPhonenumber(phonenumber); HttpServletRequest request = ServletUtils.getRequest(); - checkLogin(LoginType.SMS, user.getUserName(), () -> !validateSmsCode(phonenumber, smsCode)); + checkLogin(LoginType.SMS, user.getUserName(), () -> !validateSmsCode(phonenumber, smsCode, request)); // 此处可根据登录用户的数据不同 自行创建 loginUser LoginUser loginUser = buildLoginUser(user); // 生成token @@ -121,9 +121,13 @@ public class SysLoginService { /** * 校验短信验证码 */ - private boolean validateSmsCode(String phonenumber, String smsCode) { - // todo 此处使用手机号查询redis验证码与参数验证码是否一致 用户自行实现 - return true; + private boolean validateSmsCode(String phonenumber, String smsCode, HttpServletRequest request) { + String code = RedisUtils.getCacheObject(Constants.CAPTCHA_CODE_KEY + phonenumber); + if (StringUtils.isBlank(code)) { + asyncService.recordLogininfor(phonenumber, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"), request); + throw new CaptchaExpireException(); + } + return code.equals(smsCode); } /** @@ -205,7 +209,7 @@ public class SysLoginService { loginUser.setUserType(user.getUserType()); loginUser.setMenuPermission(permissionService.getMenuPermission(user)); loginUser.setRolePermission(permissionService.getRolePermission(user)); - loginUser.setDeptName(user.getDept().getDeptName()); + loginUser.setDeptName(ObjectUtil.isNull(user.getDept()) ? "" : user.getDept().getDeptName()); List roles = BeanUtil.copyToList(user.getRoles(), RoleDTO.class); loginUser.setRoles(roles); return loginUser; @@ -248,7 +252,7 @@ public class SysLoginService { errorNumber = ObjectUtil.isNull(errorNumber) ? 1 : errorNumber + 1; // 达到规定错误次数 则锁定登录 if (errorNumber.equals(setErrorNumber)) { - RedisUtils.setCacheObject(errorKey, errorNumber, errorLimitTime, TimeUnit.MINUTES); + RedisUtils.setCacheObject(errorKey, errorNumber, Duration.ofMinutes(errorLimitTime)); asyncService.recordLogininfor(username, loginFail, MessageUtils.message(loginType.getRetryLimitExceed(), errorLimitTime), request); throw new UserException(loginType.getRetryLimitExceed(), errorLimitTime); } else { diff --git a/ruoyi/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java b/ruoyi/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java index 2f9d0020a..6525d31e9 100644 --- a/ruoyi/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java +++ b/ruoyi/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java @@ -68,7 +68,7 @@ public class SysMenuServiceImpl implements ISysMenuService { .orderByAsc(SysMenu::getOrderNum)); } else { QueryWrapper wrapper = Wrappers.query(); - wrapper.eq("ur.user_id", userId) + wrapper.eq("sur.user_id", userId) .like(StringUtils.isNotBlank(menu.getMenuName()), "m.menu_name", menu.getMenuName()) .eq(StringUtils.isNotBlank(menu.getVisible()), "m.visible", menu.getVisible()) .eq(StringUtils.isNotBlank(menu.getStatus()), "m.status", menu.getStatus()) diff --git a/ruoyi/src/main/java/com/ruoyi/system/service/impl/SysOssConfigServiceImpl.java b/ruoyi/src/main/java/com/ruoyi/system/service/impl/SysOssConfigServiceImpl.java index f78be1e83..015c156ab 100644 --- a/ruoyi/src/main/java/com/ruoyi/system/service/impl/SysOssConfigServiceImpl.java +++ b/ruoyi/src/main/java/com/ruoyi/system/service/impl/SysOssConfigServiceImpl.java @@ -95,9 +95,10 @@ public class SysOssConfigServiceImpl implements ISysOssConfigService { SysOssConfig config = BeanUtil.toBean(bo, SysOssConfig.class); validEntityBeforeSave(config); LambdaUpdateWrapper luw = new LambdaUpdateWrapper<>(); - luw.set(StringUtils.isBlank(config.getPrefix()), SysOssConfig::getPrefix, ""); - luw.set(StringUtils.isBlank(config.getRegion()), SysOssConfig::getRegion, ""); - luw.set(StringUtils.isBlank(config.getExt1()), SysOssConfig::getExt1, ""); + luw.set(ObjectUtil.isNull(config.getPrefix()), SysOssConfig::getPrefix, ""); + luw.set(ObjectUtil.isNull(config.getRegion()), SysOssConfig::getRegion, ""); + luw.set(ObjectUtil.isNull(config.getExt1()), SysOssConfig::getExt1, ""); + luw.set(ObjectUtil.isNull(config.getRemark()), SysOssConfig::getRemark, ""); luw.eq(SysOssConfig::getOssConfigId, config.getOssConfigId()); return setConfigCache(baseMapper.update(config, luw) > 0, config); } diff --git a/ruoyi/src/main/java/com/ruoyi/system/service/impl/SysOssServiceImpl.java b/ruoyi/src/main/java/com/ruoyi/system/service/impl/SysOssServiceImpl.java index 19423f404..03a6cfca8 100644 --- a/ruoyi/src/main/java/com/ruoyi/system/service/impl/SysOssServiceImpl.java +++ b/ruoyi/src/main/java/com/ruoyi/system/service/impl/SysOssServiceImpl.java @@ -1,5 +1,6 @@ package com.ruoyi.system.service.impl; +import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -7,9 +8,11 @@ import com.ruoyi.common.core.domain.PageQuery; import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.redis.RedisUtils; +import com.ruoyi.oss.constant.OssConstant; +import com.ruoyi.oss.core.OssClient; import com.ruoyi.oss.entity.UploadResult; import com.ruoyi.oss.factory.OssFactory; -import com.ruoyi.oss.service.IOssStrategy; import com.ruoyi.system.domain.SysOss; import com.ruoyi.system.domain.bo.SysOssBo; import com.ruoyi.system.domain.vo.SysOssVo; @@ -20,6 +23,8 @@ import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import java.io.IOException; +import java.time.Duration; +import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; @@ -42,6 +47,21 @@ public class SysOssServiceImpl implements ISysOssService { return TableDataInfo.build(result); } + @Override + public List listByIds(Collection ossIds) { + List list = new ArrayList<>(); + for (Long id : ossIds) { + String key = OssConstant.SYS_OSS_KEY + id; + SysOssVo vo = RedisUtils.getCacheObject(key); + if (ObjectUtil.isNull(vo)) { + vo = baseMapper.selectVoById(id); + RedisUtils.setCacheObject(key, vo, Duration.ofDays(30)); + } + list.add(vo); + } + return list; + } + private LambdaQueryWrapper buildQueryWrapper(SysOssBo bo) { Map params = bo.getParams(); LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); @@ -65,7 +85,7 @@ public class SysOssServiceImpl implements ISysOssService { public SysOss upload(MultipartFile file) { String originalfileName = file.getOriginalFilename(); String suffix = StringUtils.substring(originalfileName, originalfileName.lastIndexOf("."), originalfileName.length()); - IOssStrategy storage = OssFactory.instance(); + OssClient storage = OssFactory.instance(); UploadResult uploadResult; try { uploadResult = storage.uploadSuffix(file.getBytes(), suffix, file.getContentType()); @@ -78,7 +98,7 @@ public class SysOssServiceImpl implements ISysOssService { oss.setFileSuffix(suffix); oss.setFileName(uploadResult.getFilename()); oss.setOriginalName(originalfileName); - oss.setService(storage.getServiceType().getValue()); + oss.setService(storage.getConfigKey()); baseMapper.insert(oss); return oss; } @@ -90,7 +110,7 @@ public class SysOssServiceImpl implements ISysOssService { } List list = baseMapper.selectBatchIds(ids); for (SysOss sysOss : list) { - IOssStrategy storage = OssFactory.instance(sysOss.getService()); + OssClient storage = OssFactory.instance(sysOss.getService()); storage.delete(sysOss.getUrl()); } return baseMapper.deleteBatchIds(ids) > 0; diff --git a/ruoyi/src/main/java/com/ruoyi/system/service/impl/SysSensitiveServiceImpl.java b/ruoyi/src/main/java/com/ruoyi/system/service/impl/SysSensitiveServiceImpl.java index 08d4cc4f9..fe142ca3c 100644 --- a/ruoyi/src/main/java/com/ruoyi/system/service/impl/SysSensitiveServiceImpl.java +++ b/ruoyi/src/main/java/com/ruoyi/system/service/impl/SysSensitiveServiceImpl.java @@ -20,7 +20,7 @@ public class SysSensitiveServiceImpl implements SensitiveService { */ @Override public boolean isSensitive() { - return LoginHelper.isAdmin(); + return !LoginHelper.isAdmin(); } } diff --git a/ruoyi/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java b/ruoyi/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java index 2ef63881c..ed24ab4e9 100644 --- a/ruoyi/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java +++ b/ruoyi/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java @@ -1,6 +1,7 @@ package com.ruoyi.system.service.impl; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; @@ -115,11 +116,11 @@ public class SysUserServiceImpl implements ISysUserService { */ @Override public TableDataInfo selectUnallocatedList(SysUser user, PageQuery pageQuery) { - List userId = userRoleMapper.selectUserIdsByRoleId(user.getRoleId()); + List userIds = userRoleMapper.selectUserIdsByRoleId(user.getRoleId()); QueryWrapper wrapper = Wrappers.query(); wrapper.eq("u.del_flag", UserConstants.USER_NORMAL) .and(w -> w.ne("r.role_id", user.getRoleId()).or().isNull("r.role_id")) - .notIn("u.user_id", userId) + .notIn(CollUtil.isNotEmpty(userIds), "u.user_id", userIds) .like(StringUtils.isNotBlank(user.getUserName()), "u.user_name", user.getUserName()) .like(StringUtils.isNotBlank(user.getPhonenumber()), "u.phonenumber", user.getPhonenumber()); Page page = baseMapper.selectUnallocatedList(pageQuery.build(), wrapper); @@ -402,20 +403,7 @@ public class SysUserServiceImpl implements ISysUserService { * @param user 用户对象 */ public void insertUserRole(SysUser user) { - Long[] roles = user.getRoleIds(); - if (ObjectUtil.isNotNull(roles)) { - // 新增用户与角色管理 - List list = new ArrayList(); - for (Long roleId : roles) { - SysUserRole ur = new SysUserRole(); - ur.setUserId(user.getUserId()); - ur.setRoleId(roleId); - list.add(ur); - } - if (list.size() > 0) { - userRoleMapper.insertBatch(list); - } - } + this.insertUserRole(user.getUserId(), user.getRoleIds()); } /** @@ -425,18 +413,16 @@ public class SysUserServiceImpl implements ISysUserService { */ public void insertUserPost(SysUser user) { Long[] posts = user.getPostIds(); - if (ObjectUtil.isNotNull(posts)) { + if (ArrayUtil.isNotEmpty(posts)) { // 新增用户与岗位管理 - List list = new ArrayList(); + List list = new ArrayList<>(posts.length); for (Long postId : posts) { SysUserPost up = new SysUserPost(); up.setUserId(user.getUserId()); up.setPostId(postId); list.add(up); } - if (list.size() > 0) { - userPostMapper.insertBatch(list); - } + userPostMapper.insertBatch(list); } } @@ -447,18 +433,16 @@ public class SysUserServiceImpl implements ISysUserService { * @param roleIds 角色组 */ public void insertUserRole(Long userId, Long[] roleIds) { - if (ObjectUtil.isNotNull(roleIds)) { + if (ArrayUtil.isNotEmpty(roleIds)) { // 新增用户与角色管理 - List list = new ArrayList(); + List list = new ArrayList<>(roleIds.length); for (Long roleId : roleIds) { SysUserRole ur = new SysUserRole(); ur.setUserId(userId); ur.setRoleId(roleId); list.add(ur); } - if (list.size() > 0) { - userRoleMapper.insertBatch(list); - } + userRoleMapper.insertBatch(list); } } diff --git a/ruoyi/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java b/ruoyi/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java index a19be65ea..0889aabc7 100644 --- a/ruoyi/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java +++ b/ruoyi/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java @@ -4,6 +4,8 @@ import cn.hutool.captcha.AbstractCaptcha; import cn.hutool.captcha.generator.CodeGenerator; import cn.hutool.core.convert.Convert; import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.RandomUtil; +import com.ruoyi.common.annotation.Anonymous; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.enums.CaptchaType; @@ -12,30 +14,68 @@ import com.ruoyi.common.utils.redis.RedisUtils; import com.ruoyi.common.utils.reflect.ReflectUtils; import com.ruoyi.common.utils.spring.SpringUtils; import com.ruoyi.framework.config.properties.CaptchaProperties; +import com.ruoyi.sms.config.properties.SmsProperties; +import com.ruoyi.sms.core.SmsTemplate; +import com.ruoyi.sms.entity.SmsResult; import com.ruoyi.system.service.ISysConfigService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; +import javax.validation.constraints.NotBlank; +import java.time.Duration; import java.util.HashMap; import java.util.Map; -import java.util.concurrent.TimeUnit; /** * 验证码操作处理 * * @author Lion Li */ +@Anonymous +@Slf4j +@Validated @Api(value = "验证码操作处理", tags = {"验证码管理"}) @RequiredArgsConstructor @RestController public class CaptchaController { private final CaptchaProperties captchaProperties; + private final SmsProperties smsProperties; private final ISysConfigService configService; + /** + * 短信验证码 + */ + @ApiOperation("短信验证码") + @GetMapping("/captchaSms") + public R smsCaptcha(@ApiParam("用户手机号") + @NotBlank(message = "{user.phonenumber.not.blank}") + String phonenumber) { + if (smsProperties.getEnabled()) { + R.fail("当前系统没有开启短信功能!"); + } + String key = Constants.CAPTCHA_CODE_KEY + phonenumber; + String code = RandomUtil.randomNumbers(4); + RedisUtils.setCacheObject(key, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION)); + // 验证码模板id 自行处理 (查数据库或写死均可) + String templateId = ""; + Map map = new HashMap<>(1); + map.put("code", code); + SmsTemplate smsTemplate = SpringUtils.getBean(SmsTemplate.class); + SmsResult result = smsTemplate.send(phonenumber, templateId, map); + if (!result.isSuccess()) { + log.error("验证码短信发送异常 => {}", result); + return R.fail(result.getMessage()); + } + return R.ok(); + } + /** * 生成验证码 */ @@ -60,7 +100,7 @@ public class CaptchaController { captcha.setGenerator(codeGenerator); captcha.createCode(); String code = isMath ? getCodeResult(captcha.getCode()) : captcha.getCode(); - RedisUtils.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES); + RedisUtils.setCacheObject(verifyKey, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION)); ajax.put("uuid", uuid); ajax.put("img", captcha.getImageBase64()); return R.ok(ajax); diff --git a/ruoyi/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java b/ruoyi/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java index facf6ce99..cdb1d6cd6 100644 --- a/ruoyi/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java +++ b/ruoyi/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java @@ -2,6 +2,7 @@ package com.ruoyi.web.controller.system; import cn.dev33.satoken.exception.NotLoginException; import cn.dev33.satoken.stp.StpUtil; +import com.ruoyi.common.annotation.Anonymous; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.domain.entity.SysMenu; @@ -51,6 +52,7 @@ public class SysLoginController { * @param loginBody 登录信息 * @return 结果 */ + @Anonymous @ApiOperation("登录方法") @PostMapping("/login") public R> login(@Validated @RequestBody LoginBody loginBody) { @@ -68,6 +70,7 @@ public class SysLoginController { * @param smsLoginBody 登录信息 * @return 结果 */ + @Anonymous @ApiOperation("短信登录(示例)") @PostMapping("/smsLogin") public R> smsLogin(@Validated @RequestBody SmsLoginBody smsLoginBody) { @@ -84,6 +87,7 @@ public class SysLoginController { * @param xcxCode 小程序code * @return 结果 */ + @Anonymous @ApiOperation("小程序登录(示例)") @PostMapping("/xcxLogin") public R> xcxLogin(@NotBlank(message = "{xcx.code.not.blank}") String xcxCode) { @@ -94,12 +98,14 @@ public class SysLoginController { return R.ok(ajax); } + @Anonymous @ApiOperation("登出方法") @PostMapping("/logout") public R logout() { try { + String username = LoginHelper.getUsername(); StpUtil.logout(); - loginService.logout(LoginHelper.getUsername()); + loginService.logout(username); } catch (NotLoginException e) { } return R.ok("退出成功"); diff --git a/ruoyi/src/main/java/com/ruoyi/web/controller/system/SysOssController.java b/ruoyi/src/main/java/com/ruoyi/web/controller/system/SysOssController.java index a128a15ff..d4e52acc6 100644 --- a/ruoyi/src/main/java/com/ruoyi/web/controller/system/SysOssController.java +++ b/ruoyi/src/main/java/com/ruoyi/web/controller/system/SysOssController.java @@ -32,6 +32,7 @@ import java.io.File; import java.io.IOException; import java.util.Arrays; import java.util.HashMap; +import java.util.List; import java.util.Map; /** @@ -58,6 +59,19 @@ public class SysOssController extends BaseController { return iSysOssService.queryPageList(bo, pageQuery); } + /** + * 查询OSS对象基于id串 + */ + @ApiOperation("查询OSS对象基于ID") + @SaCheckPermission("system:oss:list") + @GetMapping("/listByIds/{ossIds}") + public R> listByIds(@ApiParam("OSS对象ID串") + @NotEmpty(message = "主键不能为空") + @PathVariable Long[] ossIds) { + List list = iSysOssService.listByIds(Arrays.asList(ossIds)); + return R.ok(list); + } + /** * 上传OSS对象存储 */ diff --git a/ruoyi/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java b/ruoyi/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java index 84d4c0b3d..22b506f36 100644 --- a/ruoyi/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java +++ b/ruoyi/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java @@ -1,6 +1,7 @@ package com.ruoyi.web.controller.system; import cn.dev33.satoken.secure.BCrypt; +import cn.hutool.core.io.FileUtil; import com.ruoyi.common.annotation.Log; import com.ruoyi.common.constant.UserConstants; import com.ruoyi.common.core.controller.BaseController; @@ -9,6 +10,7 @@ import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.helper.LoginHelper; import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.file.MimeTypeUtils; import com.ruoyi.system.domain.SysOss; import com.ruoyi.system.service.ISysOssService; import com.ruoyi.system.service.ISysUserService; @@ -22,6 +24,7 @@ import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import java.io.File; +import java.util.Arrays; import java.util.HashMap; import java.util.Map; @@ -117,6 +120,10 @@ public class SysProfileController extends BaseController { public R> avatar(@RequestPart("avatarfile") MultipartFile file) { Map ajax = new HashMap<>(); if (!file.isEmpty()) { + String extension = FileUtil.extName(file.getOriginalFilename()); + if (!StringUtils.equalsAnyIgnoreCase(extension, MimeTypeUtils.IMAGE_EXTENSION)) { + return R.fail("文件格式不正确,请上传" + Arrays.toString(MimeTypeUtils.IMAGE_EXTENSION) + "格式"); + } SysOss oss = iSysOssService.upload(file); String avatar = oss.getUrl(); if (userService.updateUserAvatar(getUsername(), avatar)) { diff --git a/ruoyi/src/main/java/com/ruoyi/web/controller/system/SysRegisterController.java b/ruoyi/src/main/java/com/ruoyi/web/controller/system/SysRegisterController.java index 6595f06df..b8cedd67a 100644 --- a/ruoyi/src/main/java/com/ruoyi/web/controller/system/SysRegisterController.java +++ b/ruoyi/src/main/java/com/ruoyi/web/controller/system/SysRegisterController.java @@ -1,5 +1,6 @@ package com.ruoyi.web.controller.system; +import com.ruoyi.common.annotation.Anonymous; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.domain.model.RegisterBody; @@ -27,6 +28,7 @@ public class SysRegisterController extends BaseController { private final SysRegisterService registerService; private final ISysConfigService configService; + @Anonymous @ApiOperation("用户注册") @PostMapping("/register") public R register(@Validated @RequestBody RegisterBody user) { diff --git a/ruoyi/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java b/ruoyi/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java index 5d9a20615..9b7cb268b 100644 --- a/ruoyi/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java +++ b/ruoyi/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java @@ -148,7 +148,7 @@ public class SysRoleController extends BaseController { @SaCheckPermission("system:role:remove") @Log(title = "角色管理", businessType = BusinessType.DELETE) @DeleteMapping("/{roleIds}") - public R remove(@ApiParam("岗位ID串") @PathVariable Long[] roleIds) { + public R remove(@ApiParam("角色ID串") @PathVariable Long[] roleIds) { return toAjax(roleService.deleteRoleByIds(roleIds)); } diff --git a/ruoyi/src/main/resources/application-dev.yml b/ruoyi/src/main/resources/application-dev.yml index 45eb5be97..f9327f779 100644 --- a/ruoyi/src/main/resources/application-dev.yml +++ b/ruoyi/src/main/resources/application-dev.yml @@ -130,8 +130,8 @@ spring: port: 6379 # 数据库索引 database: 0 - # 密码 - password: + # 密码(如没有密码请注释掉) + # password: # 连接超时时间 timeout: 10s # 是否开启ssl @@ -156,3 +156,37 @@ redisson: timeout: 3000 # 发布和订阅连接池大小 subscriptionConnectionPoolSize: 50 + +--- # mail 邮件发送 +mail: + enabled: false + host: smtp.163.com + port: 465 + # 是否需要用户名密码验证 + auth: true + # 发送方,遵循RFC-822标准 + from: xxx@163.com + # 用户名(注意:如果使用foxmail邮箱,此处user为qq号) + user: xxx@163.com + # 密码(注意,某些邮箱需要为SMTP服务单独设置密码,详情查看相关帮助) + pass: xxxxxxxxxx + # 使用 STARTTLS安全连接,STARTTLS是对纯文本通信协议的扩展。 + starttlsEnable: true + # 使用SSL安全连接 + sslEnable: true + # SMTP超时时长,单位毫秒,缺省值不超时 + timeout: 0 + # Socket连接超时值,单位毫秒,缺省值不超时 + connectionTimeout: 0 + +--- # sms 短信 +sms: + enabled: false + # 阿里云 dysmsapi.aliyuncs.com + # 腾讯云 sms.tencentcloudapi.com + endpoint: "dysmsapi.aliyuncs.com" + accessKeyId: xxxxxxx + accessKeySecret: xxxxxx + signName: 测试 + # 腾讯专用 + sdkAppId: diff --git a/ruoyi/src/main/resources/application-prod.yml b/ruoyi/src/main/resources/application-prod.yml index 6a28bccfb..def5f1666 100644 --- a/ruoyi/src/main/resources/application-prod.yml +++ b/ruoyi/src/main/resources/application-prod.yml @@ -133,8 +133,8 @@ spring: port: 6379 # 数据库索引 database: 0 - # 密码 - password: + # 密码(如没有密码请注释掉) + # password: # 连接超时时间 timeout: 10s # 是否开启ssl @@ -159,3 +159,37 @@ redisson: timeout: 3000 # 发布和订阅连接池大小 subscriptionConnectionPoolSize: 50 + +--- # mail 邮件发送 +mail: + enabled: false + host: smtp.163.com + port: 465 + # 是否需要用户名密码验证 + auth: true + # 发送方,遵循RFC-822标准 + from: xxx@163.com + # 用户名(注意:如果使用foxmail邮箱,此处user为qq号) + user: xxx@163.com + # 密码(注意,某些邮箱需要为SMTP服务单独设置密码,详情查看相关帮助) + pass: xxxxxxxxxx + # 使用 STARTTLS安全连接,STARTTLS是对纯文本通信协议的扩展。 + starttlsEnable: true + # 使用SSL安全连接 + sslEnable: true + # SMTP超时时长,单位毫秒,缺省值不超时 + timeout: 0 + # Socket连接超时值,单位毫秒,缺省值不超时 + connectionTimeout: 0 + +--- # sms 短信 +sms: + enabled: false + # 阿里云 dysmsapi.aliyuncs.com + # 腾讯云 sms.tencentcloudapi.com + endpoint: "dysmsapi.aliyuncs.com" + accessKeyId: xxxxxxx + accessKeySecret: xxxxxx + signName: 测试 + # 腾讯专用 + sdkAppId: diff --git a/ruoyi/src/main/resources/application.yml b/ruoyi/src/main/resources/application.yml index c692fc267..ceaaf9561 100644 --- a/ruoyi/src/main/resources/application.yml +++ b/ruoyi/src/main/resources/application.yml @@ -118,12 +118,6 @@ sa-token: security: # 排除路径 excludes: - - /login - - /smsLogin - - /xcxLogin - - /logout - - /register - - /captchaImage # 静态资源 - /*.html - /**/*.html diff --git a/ruoyi/src/main/resources/excel/单列表.xlsx b/ruoyi/src/main/resources/excel/单列表.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..0f7347d652c06ae29eca9fa6cd1055ec6ae6c6e3 GIT binary patch literal 10787 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 NOlDzVs8R*l4gkIgmH7Yw literal 0 HcmV?d00001 diff --git a/ruoyi/src/main/resources/excel/多列表.xlsx b/ruoyi/src/main/resources/excel/多列表.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..c7d11dcce51c7ebc9237827cd6caac0d4b474012 GIT binary patch literal 10761 zcmWIWW@h1H0D*SDM-CtwhB+A+7*g_+1B&tsiuFOtL>L$tI2b_6rfsnOY0b#Mkj2En zAb_kav7kV&A~$F5q=R0}h9a)toBj)I$~Vq+U6K;SB3RD1<&{<1y)BJ1Q#|H5zuvy% zLhA$h9T)cpel$Mgv%t^Q{N20LwRh%7A4-3{N`=>A{aVkL88ZTy+-}CqPW93kTi&ef zW#cvZ^d%{emuxn3JOA3wvy5(b=AGBV@i=&w)0*Wym0O#ye5^it;+FfXs+S-5-rP}JFZ7WWHK1iP4C+G|85sPS7#IYR13Eds zC>0day^|ch4;zRaf8TU};gfr6cei+DSO?rZ+4#Waqe9D*T(Q|(R4(S3zi+A#Wcm7x z{lg3PqF<(GcCGXKqVVL?kN@}e|9`J2%vUOY&$ZHPwq;g`6I*@7U`r{AEIo z0w(dcry7h5417!s48kZ;P+DA)p9_kFr4wU8k3=9kvIp9(Ty8=Flg7W;L?Ba~n)DrX( z>9gxrsHG`FaI?Qv;;)8 zAD(qQ(Ues&<#<5oq>E?tv_2IGx^7Q&tn8fI-up*b{!zgL&1!*{I}?_c`Kg><$@cHn z5$&s0)o1^mh*!(xt=g1My4Nhj&w8Du?45h ziEb$L3_h!`lUOPDm_6y$i}v26cZx1Ij!N9y{!uRXZp~DUWcI3arAnXP+gx5QasTnP zZ~ZIm4eM+&6*hB)Npx;LS9x;Z2JX{|jy>XP0a`^Lxc0Aju>W}$p@xTo-ahp%)&wBddzMJ~Ns)EKd zc0Vt8Ca{{DZn*6gsQiNe!l6~=!U7*wXk|&w%$YXf_?12XIT(@;a+riA?0vH+x1zCS zDR0ty0l$pRDury(u8J)$lN#@R-pIhP(P4(3*vuoJ1iKBDJ_?@ZGfZNBIXj)1A%S^S zNlw^Y_0?zZx!>s#?Cjt1RzTTo!^=uD1_rb3%x168O-_C+kR83+jQ`w&sN5OsH!jua z1am%~>;L(I^0LYgg8NT0=VZ>~Wl#$(G{3pCe}}xXki6qBBRSQizhbfs4098mC#ZR!8vtM=f=>~!Xa%vhhMx9c5#Wo+}CtUY1hMz@^` z2Hj_jjW`ytynH)riceL+{RFn&ixGd$DNML#&a~?=@2cJW7VEa|Ei{^#xhSZJ_0npS zX%EgiPyV4U_mW?-+$83(PhbBNsb%?F3|E?;_nVN(+!J{g{WWpzLxui z8_V~jS~F~JB|0q(nd5z-p7s9Xb5;@wX9O*_t~WdRYF6!D&zw}Bk19=`8b;cO-ih)E zirQ}4ztZMY(84*g4K5-M<=*BkH>!2DvRkDp#iZKSeS68WS)W<=L2>^@M~=I84g!zA zcfKrc)rvCwd8Gc}3f{R&D(#xr`L-LbYq>J1C^y0~z5iOb;!WSjyZIh+1?18?I)kkyKNxg`knO`Kg)N)r`K{{IRpjVFu3K~xWIF^scx^zA(eL3 z$|%4ai>q5`b<&oj>nH#>i$$ZZOI&+yf`QPQ+)aDZv8o|leSHi z(w*{$lWG6Dd;7K7zWlzxEYQs&?R8Ihr?#Tg-R6mk&g^DoQD5AGd}`I3J}b;FIg#;E z@w`2^^3xEwe9B17oJqewd_uyFfs*I31k1D>NagP49o?EVa<=^Oo0)9zm z_rCKL+MDe&S3U18kg?+UNn=TS{tawvg%lP>Q@7cylHqkd>R0x``Iq0#114KOuD99!hX=e2>|MkROINFWTfV%f?EoRV&KO=8G&9l28J2ZkTx1z z8CWs6;(r@?KVRBZrr!Ng{f2k7*_YH}gLUW5GKoxl9cFs-g52Eh;^#-p?QZ(*-s5}w zv5LwOhiXTsJs%nxJZG~AJ)XZXIfEzjKU4he^6ACJ3*Uw{Hn@fsr`P}a`}gm!?B|b` zS_?Y=cJVm%cv-k@{6~S#TDv8M7rx|u+5P;Qjf!Yr`;3n>O!jI{ytlOX`~BS=*F!y& zni6Vtt`}bBp6YdN`m`ndha=`a=j=?(JL1|Rx~D54Q{w~Uh29&Nik5ELC6Xvrt#M3n z!d^S6!1)WF+yDFWX|?v|PXJ>Z2PG9dX@seo5@E1dBK`8&`u9GsAXo zJ=VH*&OSy1)Be{bR&V`Gm!~t_`0g02?L9GV?e4JLR1Fsl^U(KS5RmDYXClYb$;h;r# zb-iSFzYB;jIO)!HchQR0%$1(MN*=IW%DHIPdqDrP(cFVq`*O?j7Kx>&M&(be73bt^ zjO_eSdq~DO?wD}vVxvj5G8-2iT%RO5jq~PguKgXaJy_@QaXemOtP(VB?M^+1`%RbE zC#(oxns-0(@(EWi*W;-s>yyrPpU}0-Yq#(^wZT@Z-SrK75szZmMZNIU53=vlI_lW% zA5<*dogegQ$L}9b1NYWcp`O=OlTOAJ_VobEqK{>UT&xl%P|W_EFooNEdP zueyh{?iEnKusz(?S7n0cONT`*-WK|^9tPc#;@`V})AF;s?AmXfQrvj!p|ka#MeUm( zyZIgS5S?M1do06M*g|vjRBp|{3vYdAgl-K`e->uCXy&391*b!=shK@5GN@c9#q;c1 z%Q-ejdzP@c*30|Tc%RFjIT3LC?k|nv?vIBecX_l`cm&C3?tNYxV(ND)Db-JKZ96Yp zZJEunEY>_;-*37*<{t5ME!)ca#_0Xt-szh-=2dd8ko9#J6Q4Z!=!*p}O<$cZ<^O4s zS*2{DbvSuS!}Xf*^I5s}RaKaMY9u->&!b+O>b(2F-)1#_)`&zcrw z7wGck&_hP44V^a*Kd6&kwcz{&uN@x^L>>1Z_&R6XwwXoU#j{F|dK)%xemp}}(eLzH zzl%DPb?=BQiDCO3Ccs~!J@u|ec~z*-sreJNjvD-%zjD!c;T=s8l3Dye3OscTF3r63 zWk-NwyVjJJEAP27WPIK>WHf5W&1hTDv^wjv?umW>wppfU&e+m6dC9HCj6x#cltsCm z$`fUWz5vLWivnEYrY_^uFe^))r zvDv}g@@P%5R^-0#w`6|oww9lLX2F!`c390N(A0F*FW-!Ctg)>G)@h|^3d#xHbABoqzThD)A zuubX5Unk+_4UH@8(xv&Aa4(USad@1m_TaSs&h96lq-;ST@11&(MB`X#JT-&9@)C(EV{U;n0*V zTX-`b`=d5$mQ9s5IM2nvP!h(#zzgZS7ME1!q!xo(GFM}A`)@~x{_8tZzai#eyQuNU z=(sy`eO{&<6S~wCmNjt#L+HFCGdDiD(foMIOjqsFm(v!NA>= zb+hch&*XD8xAq^{`Tf?u?`qdOmrGlpbD4Fc@4V&t%DwBqUEBJ&QT=Y&p@q^vawG4C zq@4V?+wuHY{#&2E=SNBFMoPJDyT5twf%03QI*q5S&#nKP9ew!4k>WfVD?b%R?)n?k z_!qx;k+s(Bjhq#8^$tlHOS?ap_zyM89?Yx=kd|xhyDP1#E}L z$W=+jEi+{ce3NH}iE!=?IZ<26{c2jC>GV}0VHqlVn=jlqT02A4VB3;;-qU88SGr41 zJip|9(bZ^$4XlngwX|71Do>?en6vPt<@#2O;;H2)&lNwnUZ1(pKk=2JsikMz((C%? z=J~u1@-Zs7v|)YM7diFZYcp0%dFlOi-U_?p^Ng)~t1@-@O{`ySYI*qXkbsr#y5~!4 zWB2y$ax6%#etn`(N&Sni#l%OCXREtk;QX}keQ(fWw|CJ6-yJjNuaM$9P{VTgKyfw4 zQAhUjy_0x6XLtYo!G8U{<#E0*N2Pb{4ozlw&N^L{`?>w4jSi88N{1$>6 za?Z8aYjuMA!Ph+4;Kki>A8wOby-bN=GLi zPI>92)IKqO-M`FfQDMu2`_|9w+9MQg{OR=8uQ^krI%|rLh6?d->C!)TwrG*0f4suRJe@ zDGaB4oj>Te@t=@5TD)1GIVjH{g7M9cJ1VY^&hs{PcHA)$y&NiIcTq7;P;I7wd40+@ z&xG%B2DiS?F)7?}J6^YoQAE*ajg_iW<^-J?e~y1%FyV&AZSi#PLlc4x(%jSc-wZkL zY54jYs}f6Fj6-3h>`}MHn~x~zieEbOYUc!(1uvauoqnZdbhod~?()*=dG?ZBk+$L; z0vS6Sl-Bpvbe(&0EM#}6%dgZ~p+&-({oZ|ahSa{n_AbdG*Q}2XKj)u9P-5g#XOXU(3 z=F_^K*TnoxMC;x&)-3@%E^6zyct>o#6V>%7^bX_f>|>iQcNwleb>pj0T5RfuLo)Yn zMM~z@$8SE6uee$kU$l|<(%ho9EOM82Q zclNXP7Mr8)BR{`A^w$jGJyXBDkceJ5$?v!4hr_3Qj)vIE zHqCEZ6*ObxPKM)GS!P~+(%AaEV*2|Ck=bIAe>qM}>r!yBy}M-Iih;?Ql=&o-^eF-#X) zzA1Fl!H%jsSNTttW{7+(^>|l$BDX?m+akr2Pk3z(#0O5unfm0}qVS7P*KW-Ikm5Qo zvZsFQ){2)q{;%r(l+cv&h3B8Q8(U0i<7>`(qb|kCUkW7qGf(``vb^0X{(N$A+Md?9 z4+-koUoRyJ?8-l=WxqMw;a6sc{N0ki#HaJ$ES+`JX#%sZL%i~q3mM_ky4P1X7=;)_ zZRrn;^O6aX(N4d9DqW&|+b79m3tJ~QC7a#*tkM$|^LF7r z%gdkl-%mAo-yg$2FH-fZ?6y0;!gK!r{`ljiwS7q4oC^*Hh9*A_&d-$c{n@rfvDg0p zn?Lg9>ig|w?JFxjer$if|5u1tZ>to8R)qTcW)HLeqXFmV+e_T9p3>p!wp_&E?37N^ zg$+EZ8XuP3%UtmIcX_D(dU^4w< z{du7+D;_)KUvDW(eW+HFVdD7m#B9lBJU1gcM1B7RtF_(O@qcIe#|J;3n6GsIaAQ^w zXYG$q{pSzvn!JDi`~$A9je9iy9C^Ja)Xvua_oGJ-Z=UAAXFGr5srJ4LYbMwK{rc$3 z-VhaeD~4zRtC?nAs|Dk@7r%OSXv2(}lB$m%<(F(JJTQBOhG6Bh`l$P#)$1kyf3x+N za5;r*+!PHl9F@;cNm&>{As^4||(gR@W0J=QF&k+|AgD55=mn_7n0)Q_q; zazY$Eok7Nr)(Z5vwlvOr*&AXe#~WZ~b+6Mp_eO--TC18j2RvdJEP~5kh4k`k+?b+~ z(7fvU%k<9t4&#srkZ? z(75A_7VnWIp3PcEtaj*~k#U^4{M@s{Tw*LN79OE9uQvAUZCKDy_UZiPlXL&8R(xz> zNKQ>;>yfwhe*e5%&}S33OU#|0Kf9Ov2MO7=m?UzfMv29E>2yzb(+G0bh)lR?^6%q> zxke49L5yE~WTx=SrzAKq&OWoPZ_~rayw?<2bBr!7dAR8FN4K~urgN{%%+Q#x@rLEA|O6ZD!KyZCriu+p}w?Q>bk8{KK+=p`P!`AVtW4_PE2)Ktg^C?XR3g$r=wR_W97fk zKX?7F=zdmc(?9wDj?<{@!rbn%K8`xpE|n;I^Vkg>62WMHsh zVqoBh^cq03V@dh>*`R(y??hkk!wv#%@05#+#$&Pf>|~u*YE6qRXCsoG*?QEc`B7TVK6v=h7qW%Pc3m zIlJyZc)7H;cI&HN>l&$I1&#~*7R7Ru%}m|*(!tQ)P|UahrS#ID+BYnhMLvI|T( z(`6H%(#7e^e(2KQ_QYFZCLa=JEoPEs>tH^~bnE-v4fC$84)eIdD=nDzmOJ>xZxzjn zXWHHMm_Bq(i%I=R}{#>CqdAEs^H}B-L*Ct9#>b#i~cV_aV?=QddgOVxsQAjoh28Q^e z)Ex8)$ZCtSJ^vXP816GMFmS`w=z&zOopj#oh=IVd_f78wp6&B37Zto&qObJEH>I{= zhR^>CYQmEu-|pM%7^rh)7kmHApU-CBuSwZ0eODpQa9Q7;rqaMBhx`*|`vO1IR7Biu z@>sL?DsyE>!6BC2uRbOHZfSmIGv$_^%EZ{3pbJLr)|!(uFTM;3aF}mx>bl(0K3Tch zY;Rsb-lY0UmYotejD{N%e-7o7d+aQX7{ zLkA~bjNWqE!>UDf(d+*zM#qmlnO13M8t+l`Nq2QQ?y!W8=wb^_g&*%Ee={&JTw!Kl zkb{%f95t9v`snRDW1&DNaTUzl5L>ja{WX1zRIfB#_j zj<)%+f%cd#aUp(3KrE_}ZseqUFo~1`G^m|;f`fxn& ziL_a-A|yDDCvm?r`SR$`{%!iF)sBnLuP=M?qpNkhI&GZzGKkovhXQTA}96Guu>hU#&%O?+M}KOI;^T^D*-_c-fnH zNp;4PV+PY_e0igvwjUI-pkfoUC?~&?RjHVffkBoHG6){+oS#>cnpYAZQdy8%91AKG zwoW;ncL)?#Q-ASK+%9SuuyU0aQ@7nT-JqB3JHEBJ9O19zY2E++h=ZyC>!l06D#zzl zzl*VFTfB7LB-RR@wI?I=-)>^**|N&ya!;*KoYi-og9<%DQ%xsq6jhMsUB8}f@>FJ@ z6}J+ObqU;Iey+iNfhqX)feSu)d&L^t>Q2p_U~I^G?|s?(9b42IIOhgrZ+Q5Cv&eA0 z)2BU4?q{pZX{DTeT$OnC)Qp04T1z>eOwsSTwYbErWs25gDIKqN^OWX~%`H{W$`34i z*SqNB(xw!hnhMcbIR&XtZ$!7x;aPe-l<&rt$~Z5D-kr-hf>uO_EwJiSIoK{#XCt5L z{d%Eg&FsL~yE80~CzKXHi#u#|Y7S?7m<;zr$GzO#?%FIEb0aW^bjUE*F{9m01s z?l;G3F1ADarD~OH=D7#Qb)9b2uFAas zb=|~W`!()daQ}a(@z2%cZ|i?Q_*f`k#~k3z$Rq-;+_1+IXtfn1g8~Bs!yaV@1}t#~ zF#vaA1Tp}!3QJ58Q8b}iie5N@^gt}Ng6jciCVZBGaw|w9#4->IX>}N?edz1MK#C#u zsWTugDub>TgIJ14$moln5V|KYBI$-LfkM}gzF-HTU6>hJJAC;L!~pCe3|g21G63S~ z92V#@6_9taYd{U9Bqgv0NYMqc2jNfjG7e-9B$PUlwPBQa=;oleq7dff%Ym)OXj7q^ zuncVk5@ABAFvJA-cqBwCF@B%G1J+ssov#B08N%;B&}QrqHf~4O2G$Iozk}F|FaW*z zgD_yVJlJ03V1sDJ?r1)cPA~?oWbB2+Fi10a(GaMbM|C;+N+Xa~NUZI|& - - - - - - - - - + diff --git a/ruoyi/src/main/resources/mapper/system/SysMenuMapper.xml b/ruoyi/src/main/resources/mapper/system/SysMenuMapper.xml index 08838c599..2f69197b3 100644 --- a/ruoyi/src/main/resources/mapper/system/SysMenuMapper.xml +++ b/ruoyi/src/main/resources/mapper/system/SysMenuMapper.xml @@ -32,8 +32,8 @@ m.perms, m.is_frame, m.is_cache, m.menu_type, m.icon, m.order_num, m.create_time from sys_menu m left join sys_role_menu rm on m.menu_id = rm.menu_id - left join sys_user_role ur on rm.role_id = ur.role_id - left join sys_role ro on ur.role_id = ro.role_id + left join sys_user_role sur on rm.role_id = sur.role_id + left join sys_role ro on sur.role_id = ro.role_id ${ew.getCustomSqlSegment} @@ -55,9 +55,9 @@ m.create_time from sys_menu m left join sys_role_menu rm on m.menu_id = rm.menu_id - left join sys_user_role ur on rm.role_id = ur.role_id - left join sys_role ro on ur.role_id = ro.role_id - left join sys_user u on ur.user_id = u.user_id + left join sys_user_role sur on rm.role_id = sur.role_id + left join sys_role ro on sur.role_id = ro.role_id + left join sys_user u on sur.user_id = u.user_id where u.user_id = #{userId} and m.menu_type in ('M', 'C') and m.status = '0' @@ -81,18 +81,18 @@ select distinct m.perms from sys_menu m left join sys_role_menu rm on m.menu_id = rm.menu_id - left join sys_user_role ur on rm.role_id = ur.role_id + left join sys_user_role sur on rm.role_id = sur.role_id diff --git a/ruoyi/src/main/resources/mapper/system/SysRoleMapper.xml b/ruoyi/src/main/resources/mapper/system/SysRoleMapper.xml index dc54c7e9f..90dff5051 100644 --- a/ruoyi/src/main/resources/mapper/system/SysRoleMapper.xml +++ b/ruoyi/src/main/resources/mapper/system/SysRoleMapper.xml @@ -34,8 +34,8 @@ r.create_time, r.remark from sys_role r - left join sys_user_role ur on ur.role_id = r.role_id - left join sys_user u on u.user_id = ur.user_id + left join sys_user_role sur on sur.role_id = r.role_id + left join sys_user u on u.user_id = sur.user_id left join sys_dept d on u.dept_id = d.dept_id @@ -51,14 +51,14 @@ diff --git a/ruoyi/src/main/resources/mapper/system/SysUserMapper.xml b/ruoyi/src/main/resources/mapper/system/SysUserMapper.xml index 0b388d136..dacdcd8a6 100644 --- a/ruoyi/src/main/resources/mapper/system/SysUserMapper.xml +++ b/ruoyi/src/main/resources/mapper/system/SysUserMapper.xml @@ -80,12 +80,12 @@ r.status as role_status from sys_user u left join sys_dept d on u.dept_id = d.dept_id - left join sys_user_role ur on u.user_id = ur.user_id - left join sys_role r on r.role_id = ur.role_id + left join sys_user_role sur on u.user_id = sur.user_id + left join sys_role r on r.role_id = sur.role_id @@ -113,8 +113,8 @@ select distinct u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.phonenumber, u.status, u.create_time from sys_user u left join sys_dept d on u.dept_id = d.dept_id - left join sys_user_role ur on u.user_id = ur.user_id - left join sys_role r on r.role_id = ur.role_id + left join sys_user_role sur on u.user_id = sur.user_id + left join sys_role r on r.role_id = sur.role_id ${ew.getCustomSqlSegment} diff --git a/ruoyi/src/main/resources/mapper/system/SysUserRoleMapper.xml b/ruoyi/src/main/resources/mapper/system/SysUserRoleMapper.xml index 63a846d30..5a55fcb1e 100644 --- a/ruoyi/src/main/resources/mapper/system/SysUserRoleMapper.xml +++ b/ruoyi/src/main/resources/mapper/system/SysUserRoleMapper.xml @@ -10,8 +10,8 @@ diff --git a/ruoyi/src/main/resources/vm/java/controller.java.vm b/ruoyi/src/main/resources/vm/java/controller.java.vm index 20580d860..6b2fc6582 100644 --- a/ruoyi/src/main/resources/vm/java/controller.java.vm +++ b/ruoyi/src/main/resources/vm/java/controller.java.vm @@ -53,11 +53,11 @@ public class ${ClassName}Controller extends BaseController { @SaCheckPermission("${permissionPrefix}:list") @GetMapping("/list") #if($table.crud || $table.sub) - public TableDataInfo<${ClassName}Vo> list(@Validated(QueryGroup.class) ${ClassName}Bo bo, PageQuery pageQuery) { + public TableDataInfo<${ClassName}Vo> list(${ClassName}Bo bo, PageQuery pageQuery) { return i${ClassName}Service.queryPageList(bo, pageQuery); } #elseif($table.tree) - public R> list(@Validated(QueryGroup.class) ${ClassName}Bo bo) { + public R> list(${ClassName}Bo bo) { List<${ClassName}Vo> list = i${ClassName}Service.queryList(bo); return R.ok(list); } @@ -70,7 +70,7 @@ public class ${ClassName}Controller extends BaseController { @SaCheckPermission("${permissionPrefix}:export") @Log(title = "${functionName}", businessType = BusinessType.EXPORT) @PostMapping("/export") - public void export(@Validated ${ClassName}Bo bo, HttpServletResponse response) { + public void export(${ClassName}Bo bo, HttpServletResponse response) { List<${ClassName}Vo> list = i${ClassName}Service.queryList(bo); ExcelUtil.exportExcel(list, "${functionName}", ${ClassName}Vo.class, response); } @@ -82,8 +82,8 @@ public class ${ClassName}Controller extends BaseController { @SaCheckPermission("${permissionPrefix}:query") @GetMapping("/{${pkColumn.javaField}}") public R<${ClassName}Vo> getInfo(@ApiParam("主键") - @NotNull(message = "主键不能为空") - @PathVariable("${pkColumn.javaField}") ${pkColumn.javaType} ${pkColumn.javaField}) { + @NotNull(message = "主键不能为空") + @PathVariable("${pkColumn.javaField}") ${pkColumn.javaType} ${pkColumn.javaField}) { return R.ok(i${ClassName}Service.queryById(${pkColumn.javaField})); } diff --git a/ruoyi/src/main/resources/vm/java/domain.java.vm b/ruoyi/src/main/resources/vm/java/domain.java.vm index 8fde4adea..28ca34c0f 100644 --- a/ruoyi/src/main/resources/vm/java/domain.java.vm +++ b/ruoyi/src/main/resources/vm/java/domain.java.vm @@ -2,7 +2,7 @@ package ${packageName}.domain; import com.baomidou.mybatisplus.annotation.*; import lombok.Data; -import lombok.NoArgsConstructor; +import lombok.EqualsAndHashCode; import java.io.Serializable; import java.util.Date; import java.math.BigDecimal; @@ -28,6 +28,7 @@ import com.ruoyi.common.core.domain.TreeEntity; #set($Entity="TreeEntity<${ClassName}>") #end @Data +@EqualsAndHashCode(callSuper = true) @TableName("${tableName}") public class ${ClassName} extends ${Entity} { diff --git a/ruoyi/src/main/resources/vm/java/service.java.vm b/ruoyi/src/main/resources/vm/java/service.java.vm index 309328ca3..0f9137a5d 100644 --- a/ruoyi/src/main/resources/vm/java/service.java.vm +++ b/ruoyi/src/main/resources/vm/java/service.java.vm @@ -21,52 +21,33 @@ public interface I${ClassName}Service { /** * 查询${functionName} - * - * @param ${pkColumn.javaField} ${functionName}主键 - * @return ${functionName} */ ${ClassName}Vo queryById(${pkColumn.javaType} ${pkColumn.javaField}); #if($table.crud || $table.sub) /** * 查询${functionName}列表 - * - * @param ${className} ${functionName} - * @return ${functionName}集合 */ TableDataInfo<${ClassName}Vo> queryPageList(${ClassName}Bo bo, PageQuery pageQuery); #end /** * 查询${functionName}列表 - * - * @param ${className} ${functionName} - * @return ${functionName}集合 */ List<${ClassName}Vo> queryList(${ClassName}Bo bo); /** * 修改${functionName} - * - * @param ${className} ${functionName} - * @return 结果 */ Boolean insertByBo(${ClassName}Bo bo); /** * 修改${functionName} - * - * @param ${className} ${functionName} - * @return 结果 */ Boolean updateByBo(${ClassName}Bo bo); /** * 校验并批量删除${functionName}信息 - * - * @param ${pkColumn.javaField}s 需要删除的${functionName}主键集合 - * @param isValid 是否校验,true-删除前校验,false-不校验 - * @return 结果 */ Boolean deleteWithValidByIds(Collection<${pkColumn.javaType}> ids, Boolean isValid); } diff --git a/ruoyi/src/main/resources/vm/java/serviceImpl.java.vm b/ruoyi/src/main/resources/vm/java/serviceImpl.java.vm index 005c84a9f..776738219 100644 --- a/ruoyi/src/main/resources/vm/java/serviceImpl.java.vm +++ b/ruoyi/src/main/resources/vm/java/serviceImpl.java.vm @@ -35,9 +35,6 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service { /** * 查询${functionName} - * - * @param ${pkColumn.javaField} ${functionName}主键 - * @return ${functionName} */ @Override public ${ClassName}Vo queryById(${pkColumn.javaType} ${pkColumn.javaField}){ @@ -47,9 +44,6 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service { #if($table.crud || $table.sub) /** * 查询${functionName}列表 - * - * @param bo ${functionName} - * @return ${functionName} */ @Override public TableDataInfo<${ClassName}Vo> queryPageList(${ClassName}Bo bo, PageQuery pageQuery) { @@ -61,9 +55,6 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service { /** * 查询${functionName}列表 - * - * @param bo ${functionName} - * @return ${functionName} */ @Override public List<${ClassName}Vo> queryList(${ClassName}Bo bo) { @@ -100,9 +91,6 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service { /** * 新增${functionName} - * - * @param bo ${functionName} - * @return 结果 */ @Override public Boolean insertByBo(${ClassName}Bo bo) { @@ -118,9 +106,6 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service { /** * 修改${functionName} - * - * @param bo ${functionName} - * @return 结果 */ @Override public Boolean updateByBo(${ClassName}Bo bo) { @@ -131,8 +116,6 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service { /** * 保存前的数据校验 - * - * @param entity 实体类数据 */ private void validEntityBeforeSave(${ClassName} entity){ //TODO 做一些数据校验,如唯一约束 @@ -140,9 +123,6 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service { /** * 批量删除${functionName} - * - * @param ${pkColumn.javaField}s 需要删除的${functionName}主键 - * @return 结果 */ @Override public Boolean deleteWithValidByIds(Collection<${pkColumn.javaType}> ids, Boolean isValid) { diff --git a/ruoyi/src/main/resources/vm/vue/v3/index-tree.vue.vm b/ruoyi/src/main/resources/vm/vue/v3/index-tree.vue.vm index 6776687d9..5db196710 100644 --- a/ruoyi/src/main/resources/vm/vue/v3/index-tree.vue.vm +++ b/ruoyi/src/main/resources/vm/vue/v3/index-tree.vue.vm @@ -173,11 +173,13 @@ #set($dictType=$column.dictType) #if("" != $treeParentCode && $column.javaField == $treeParentCode) - #elseif($column.htmlType == "input") @@ -353,8 +355,8 @@ function getList() { } /** 查询${functionName}下拉树结构 */ -async function getTreeselect() { - await list${BusinessName}().then(response => { +function getTreeselect() { + list${BusinessName}().then(response => { ${businessName}Options.value = []; const data = { ${treeCode}: 0, ${treeName}: '顶级节点', children: [] }; data.children = proxy.handleTree(response.data, "${treeCode}", "${treeParentCode}"); @@ -403,9 +405,9 @@ function resetQuery() { } /** 新增按钮操作 */ -async function handleAdd(row) { +function handleAdd(row) { reset(); - await getTreeselect(); + getTreeselect(); if (row != null && row.${treeCode}) { form.value.${treeParentCode} = row.${treeCode}; } else { diff --git a/script/docker/docker-compose.yml b/script/docker/docker-compose.yml index e80f75b0a..3dcdf32c6 100644 --- a/script/docker/docker-compose.yml +++ b/script/docker/docker-compose.yml @@ -2,7 +2,7 @@ version: '3' services: mysql: - image: mysql:8.0.27 + image: mysql:8.0.29 container_name: mysql environment: # 时区上海 @@ -32,7 +32,7 @@ services: ipv4_address: 172.30.0.36 nginx-web: - image: nginx:1.21.3 + image: nginx:1.21.6 container_name: nginx-web environment: # 时区上海 @@ -55,7 +55,7 @@ services: - ruoyi_net redis: - image: redis:6.2.6 + image: redis:6.2.7 container_name: redis ports: - "6379:6379" @@ -75,7 +75,7 @@ services: ipv4_address: 172.30.0.48 minio: - image: minio/minio:RELEASE.2021-10-27T16-29-42Z + image: minio/minio:RELEASE.2022-05-26T05-48-41Z container_name: minio ports: # api 端口 @@ -110,7 +110,7 @@ services: ipv4_address: 172.30.0.54 ruoyi-server1: - image: ruoyi/ruoyi-server:4.1.0 + image: ruoyi/ruoyi-server:4.2.0 container_name: ruoyi-server1 environment: # 时区上海 @@ -125,7 +125,7 @@ services: ipv4_address: 172.30.0.60 ruoyi-server2: - image: "ruoyi/ruoyi-server:4.1.0" + image: "ruoyi/ruoyi-server:4.2.0" container_name: ruoyi-server2 environment: # 时区上海 @@ -140,7 +140,7 @@ services: ipv4_address: 172.30.0.61 ruoyi-monitor-admin: - image: ruoyi/ruoyi-monitor-admin:4.1.0 + image: ruoyi/ruoyi-monitor-admin:4.2.0 container_name: ruoyi-monitor-admin environment: # 时区上海 @@ -155,7 +155,7 @@ services: ipv4_address: 172.30.0.90 ruoyi-xxl-job-admin: - image: ruoyi/ruoyi-xxl-job-admin:4.1.0 + image: ruoyi/ruoyi-xxl-job-admin:4.2.0 container_name: ruoyi-xxl-job-admin environment: # 时区上海 diff --git a/script/docker/nginx/nginx.conf b/script/docker/nginx/nginx.conf index 07df78391..daa2acf49 100644 --- a/script/docker/nginx/nginx.conf +++ b/script/docker/nginx/nginx.conf @@ -23,16 +23,16 @@ http { upstream server { ip_hash; - server 172.30.0.60:8080; - server 172.30.0.61:8080; + server 127.0.0.1:8080; + server 127.0.0.1:8080; } upstream monitor-admin { - server 172.30.0.90:9090; + server 127.0.0.1:9090; } upstream xxljob-admin { - server 172.30.0.92:9100; + server 127.0.0.1:9100; } server { @@ -62,6 +62,11 @@ http { # return 200 '{"msg":"演示模式,不允许操作","code":500}'; # } + # 限制外网访问内网 actuator 相关路径 + location ~ ^(/[^/]*)?/actuator(/.*)?$ { + return 403; + } + location / { root /usr/share/nginx/html; try_files $uri $uri/ /index.html; diff --git a/script/sql/oracle/oracle_ry_vue_4.X.sql b/script/sql/oracle/oracle_ry_vue_4.X.sql index 68b29e998..eabf91910 100644 --- a/script/sql/oracle/oracle_ry_vue_4.X.sql +++ b/script/sql/oracle/oracle_ry_vue_4.X.sql @@ -812,7 +812,7 @@ comment on column gen_table.remark is '备注'; -- ---------------------------- create table gen_table_column ( column_id number(20) not null, - table_id varchar2(64), + table_id number(20), column_name varchar2(200), column_comment varchar2(500), column_type varchar2(100), @@ -904,6 +904,7 @@ create table sys_oss_config ( bucket_name varchar(255) default '', prefix varchar(255) default '', endpoint varchar(255) default '', + domain varchar(255) default '', is_https char(1) default 'N', region varchar(255) default '', status char(1) default '1', @@ -925,6 +926,7 @@ comment on column sys_oss_config.secret_key is '秘钥'; comment on column sys_oss_config.bucket_name is '桶名称'; comment on column sys_oss_config.prefix is '前缀'; comment on column sys_oss_config.endpoint is '访问站点'; +comment on column sys_oss_config.domain is '自定义域名'; comment on column sys_oss_config.is_https is '是否https(Y=是,N=否)'; comment on column sys_oss_config.region is '域'; comment on column sys_oss_config.status is '状态(0=正常,1=停用)'; @@ -935,10 +937,12 @@ comment on column sys_oss_config.create_time is '创建时间'; comment on column sys_oss_config.update_by is '更新者'; comment on column sys_oss_config.update_time is '更新时间'; -insert into sys_oss_config values (1, 'minio', 'ruoyi', 'ruoyi123', 'ruoyi', '', 'http://localhost:9000', 'N', '', '0', '', NULL, 'admin', sysdate, 'admin', sysdate); -insert into sys_oss_config values (2, 'qiniu', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi', '', 'http://XXX.XXXX.com', 'N', 'z0', '1', '', NULL, 'admin', sysdate, 'admin', sysdate); -insert into sys_oss_config values (3, 'aliyun', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi', '', 'http://oss-cn-beijing.aliyuncs.com', 'N', '', '1', '', NULL, 'admin', sysdate, 'admin', sysdate); -insert into sys_oss_config values (4, 'qcloud', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi-1250000000', '', 'http://cos.ap-beijing.myqcloud.com', 'N', 'ap-beijing', '1', '', NULL, 'admin', sysdate, 'admin', sysdate); +insert into sys_oss_config values (1, 'minio', 'ruoyi', 'ruoyi123', 'ruoyi', '', '127.0.0.1:9000', '','N', '', '0', '', NULL, 'admin', sysdate, 'admin', sysdate); +insert into sys_oss_config values (2, 'qiniu', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi', '', 's3-cn-north-1.qiniucs.com', '','N', '', '1', '', NULL, 'admin', sysdate, 'admin', sysdate); +insert into sys_oss_config values (3, 'aliyun', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi', '', 'oss-cn-beijing.aliyuncs.com', '','N', '', '1', '', NULL, 'admin', sysdate, 'admin', sysdate); +insert into sys_oss_config values (4, 'qcloud', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi-1250000000', '', 'cos.ap-beijing.myqcloud.com', '','N', 'ap-beijing', '1', '', NULL, 'admin', sysdate, 'admin', sysdate); +insert into sys_oss_config values (5, 'image', 'ruoyi', 'ruoyi123', 'ruoyi', 'image', '127.0.0.1:9000', '','N', '', '1', '', NULL, 'admin', sysdate, 'admin', sysdate); + -- ---------------------------- -- 钩子 ,用于session连接之后 自动设置默认的date类型格式化 简化时间查询 diff --git a/script/sql/postgres/postgres_ry_vue_4.X.sql b/script/sql/postgres/postgres_ry_vue_4.X.sql index 850491fc6..316d3bbd5 100644 --- a/script/sql/postgres/postgres_ry_vue_4.X.sql +++ b/script/sql/postgres/postgres_ry_vue_4.X.sql @@ -205,8 +205,8 @@ create table if not exists sys_menu path varchar(200) default ''::varchar, component varchar(255) default null::varchar, query_param varchar(255) default null::varchar, - is_frame int4 default 1, - is_cache int4 default 0, + is_frame char default '1'::bpchar, + is_cache char default '0'::bpchar, menu_type char default ''::bpchar, visible char default '0'::bpchar, status char default '0'::bpchar, @@ -245,109 +245,109 @@ comment on column sys_menu.remark is '备注'; -- 初始化-菜单信息表数据 -- ---------------------------- -- 一级菜单 -insert into sys_menu values('1', '系统管理', '0', '1', 'system', null, '', 1, 0, 'M', '0', '0', '', 'system', 'admin', now(), '', null, '系统管理目录'); -insert into sys_menu values('2', '系统监控', '0', '2', 'monitor', null, '', 1, 0, 'M', '0', '0', '', 'monitor', 'admin', now(), '', null, '系统监控目录'); -insert into sys_menu values('3', '系统工具', '0', '3', 'tool', null, '', 1, 0, 'M', '0', '0', '', 'tool', 'admin', now(), '', null, '系统工具目录'); -insert into sys_menu values('4', 'PLUS官网', '0', '4', 'https://gitee.com/JavaLionLi/RuoYi-Vue-Plus', null, '', 0, 0, 'M', '0', '0', '', 'guide', 'admin', now(), '', null, 'RuoYi-Vue-Plus官网地址'); +insert into sys_menu values('1', '系统管理', '0', '1', 'system', null, '', '1', '0', 'M', '0', '0', '', 'system', 'admin', now(), '', null, '系统管理目录'); +insert into sys_menu values('2', '系统监控', '0', '2', 'monitor', null, '', '1', '0', 'M', '0', '0', '', 'monitor', 'admin', now(), '', null, '系统监控目录'); +insert into sys_menu values('3', '系统工具', '0', '3', 'tool', null, '', '1', '0', 'M', '0', '0', '', 'tool', 'admin', now(), '', null, '系统工具目录'); +insert into sys_menu values('4', 'PLUS官网', '0', '4', 'https://gitee.com/JavaLionLi/RuoYi-Vue-Plus', null, '', '0', '0', 'M', '0', '0', '', 'guide', 'admin', now(), '', null, 'RuoYi-Vue-Plus官网地址'); -- 二级菜单 -insert into sys_menu values('100', '用户管理', '1', '1', 'user', 'system/user/index', '', 1, 0, 'C', '0', '0', 'system:user:list', 'user', 'admin', now(), '', null, '用户管理菜单'); -insert into sys_menu values('101', '角色管理', '1', '2', 'role', 'system/role/index', '', 1, 0, 'C', '0', '0', 'system:role:list', 'peoples', 'admin', now(), '', null, '角色管理菜单'); -insert into sys_menu values('102', '菜单管理', '1', '3', 'menu', 'system/menu/index', '', 1, 0, 'C', '0', '0', 'system:menu:list', 'tree-table', 'admin', now(), '', null, '菜单管理菜单'); -insert into sys_menu values('103', '部门管理', '1', '4', 'dept', 'system/dept/index', '', 1, 0, 'C', '0', '0', 'system:dept:list', 'tree', 'admin', now(), '', null, '部门管理菜单'); -insert into sys_menu values('104', '岗位管理', '1', '5', 'post', 'system/post/index', '', 1, 0, 'C', '0', '0', 'system:post:list', 'post', 'admin', now(), '', null, '岗位管理菜单'); -insert into sys_menu values('105', '字典管理', '1', '6', 'dict', 'system/dict/index', '', 1, 0, 'C', '0', '0', 'system:dict:list', 'dict', 'admin', now(), '', null, '字典管理菜单'); -insert into sys_menu values('106', '参数设置', '1', '7', 'config', 'system/config/index', '', 1, 0, 'C', '0', '0', 'system:config:list', 'edit', 'admin', now(), '', null, '参数设置菜单'); -insert into sys_menu values('107', '通知公告', '1', '8', 'notice', 'system/notice/index', '', 1, 0, 'C', '0', '0', 'system:notice:list', 'message', 'admin', now(), '', null, '通知公告菜单'); -insert into sys_menu values('108', '日志管理', '1', '9', 'log', '', '', 1, 0, 'M', '0', '0', '', 'log', 'admin', now(), '', null, '日志管理菜单'); -insert into sys_menu values('109', '在线用户', '2', '1', 'online', 'monitor/online/index', '', 1, 0, 'C', '0', '0', 'monitor:online:list', 'online', 'admin', now(), '', null, '在线用户菜单'); -insert into sys_menu values('111', '数据监控', '2', '3', 'druid', 'monitor/druid/index', '', 1, 0, 'C', '0', '0', 'monitor:druid:list', 'druid', 'admin', now(), '', null, '数据监控菜单'); -insert into sys_menu values('113', '缓存监控', '2', '5', 'cache', 'monitor/cache/index', '', 1, 0, 'C', '0', '0', 'monitor:cache:list', 'redis', 'admin', now(), '', null, '缓存监控菜单'); -insert into sys_menu values('114', '表单构建', '3', '1', 'build', 'tool/build/index', '', 1, 0, 'C', '0', '0', 'tool:build:list', 'build', 'admin', now(), '', null, '表单构建菜单'); -insert into sys_menu values('115', '代码生成', '3', '2', 'gen', 'tool/gen/index', '', 1, 0, 'C', '0', '0', 'tool:gen:list', 'code', 'admin', now(), '', null, '代码生成菜单'); -insert into sys_menu values('116', '系统接口', '3', '3', 'swagger', 'tool/swagger/index', '', 1, 0, 'C', '0', '0', 'tool:swagger:list', 'swagger', 'admin', now(), '', null, '系统接口菜单'); +insert into sys_menu values('100', '用户管理', '1', '1', 'user', 'system/user/index', '', '1', '0', 'C', '0', '0', 'system:user:list', 'user', 'admin', now(), '', null, '用户管理菜单'); +insert into sys_menu values('101', '角色管理', '1', '2', 'role', 'system/role/index', '', '1', '0', 'C', '0', '0', 'system:role:list', 'peoples', 'admin', now(), '', null, '角色管理菜单'); +insert into sys_menu values('102', '菜单管理', '1', '3', 'menu', 'system/menu/index', '', '1', '0', 'C', '0', '0', 'system:menu:list', 'tree-table', 'admin', now(), '', null, '菜单管理菜单'); +insert into sys_menu values('103', '部门管理', '1', '4', 'dept', 'system/dept/index', '', '1', '0', 'C', '0', '0', 'system:dept:list', 'tree', 'admin', now(), '', null, '部门管理菜单'); +insert into sys_menu values('104', '岗位管理', '1', '5', 'post', 'system/post/index', '', '1', '0', 'C', '0', '0', 'system:post:list', 'post', 'admin', now(), '', null, '岗位管理菜单'); +insert into sys_menu values('105', '字典管理', '1', '6', 'dict', 'system/dict/index', '', '1', '0', 'C', '0', '0', 'system:dict:list', 'dict', 'admin', now(), '', null, '字典管理菜单'); +insert into sys_menu values('106', '参数设置', '1', '7', 'config', 'system/config/index', '', '1', '0', 'C', '0', '0', 'system:config:list', 'edit', 'admin', now(), '', null, '参数设置菜单'); +insert into sys_menu values('107', '通知公告', '1', '8', 'notice', 'system/notice/index', '', '1', '0', 'C', '0', '0', 'system:notice:list', 'message', 'admin', now(), '', null, '通知公告菜单'); +insert into sys_menu values('108', '日志管理', '1', '9', 'log', '', '', '1', '0', 'M', '0', '0', '', 'log', 'admin', now(), '', null, '日志管理菜单'); +insert into sys_menu values('109', '在线用户', '2', '1', 'online', 'monitor/online/index', '', '1', '0', 'C', '0', '0', 'monitor:online:list', 'online', 'admin', now(), '', null, '在线用户菜单'); +insert into sys_menu values('111', '数据监控', '2', '3', 'druid', 'monitor/druid/index', '', '1', '0', 'C', '0', '0', 'monitor:druid:list', 'druid', 'admin', now(), '', null, '数据监控菜单'); +insert into sys_menu values('113', '缓存监控', '2', '5', 'cache', 'monitor/cache/index', '', '1', '0', 'C', '0', '0', 'monitor:cache:list', 'redis', 'admin', now(), '', null, '缓存监控菜单'); +insert into sys_menu values('114', '表单构建', '3', '1', 'build', 'tool/build/index', '', '1', '0', 'C', '0', '0', 'tool:build:list', 'build', 'admin', now(), '', null, '表单构建菜单'); +insert into sys_menu values('115', '代码生成', '3', '2', 'gen', 'tool/gen/index', '', '1', '0', 'C', '0', '0', 'tool:gen:list', 'code', 'admin', now(), '', null, '代码生成菜单'); +insert into sys_menu values('116', '系统接口', '3', '3', 'swagger', 'tool/swagger/index', '', '1', '0', 'C', '0', '0', 'tool:swagger:list', 'swagger', 'admin', now(), '', null, '系统接口菜单'); -- springboot-admin监控 -insert into sys_menu values('117', 'Admin监控', '2', '5', 'Admin', 'monitor/admin/index', '', 1, 0, 'C', '0', '0', 'monitor:admin:list', 'dashboard', 'admin', now(), '', null, 'Admin监控菜单'); +insert into sys_menu values('117', 'Admin监控', '2', '5', 'Admin', 'monitor/admin/index', '', '1', '0', 'C', '0', '0', 'monitor:admin:list', 'dashboard', 'admin', now(), '', null, 'Admin监控菜单'); -- oss菜单 -insert into sys_menu values('118', '文件管理', '1', '10', 'oss', 'system/oss/index', '', 1, 0, 'C', '0', '0', 'system:oss:list', 'upload', 'admin', now(), '', null, '文件管理菜单'); +insert into sys_menu values('118', '文件管理', '1', '10', 'oss', 'system/oss/index', '', '1', '0', 'C', '0', '0', 'system:oss:list', 'upload', 'admin', now(), '', null, '文件管理菜单'); -- xxl-job-admin控制台 -insert into sys_menu values('120', '任务调度中心', '2', '5', 'XxlJob', 'monitor/xxljob/index', '', 1, 0, 'C', '0', '0', 'monitor:xxljob:list', 'job', 'admin', now(), '', null, 'Xxl-Job控制台菜单'); +insert into sys_menu values('120', '任务调度中心', '2', '5', 'XxlJob', 'monitor/xxljob/index', '', '1', '0', 'C', '0', '0', 'monitor:xxljob:list', 'job', 'admin', now(), '', null, 'Xxl-Job控制台菜单'); -- 三级菜单 -insert into sys_menu values('500', '操作日志', '108', '1', 'operlog', 'monitor/operlog/index', '', 1, 0, 'C', '0', '0', 'monitor:operlog:list', 'form', 'admin', now(), '', null, '操作日志菜单'); -insert into sys_menu values('501', '登录日志', '108', '2', 'logininfor', 'monitor/logininfor/index', '', 1, 0, 'C', '0', '0', 'monitor:logininfor:list', 'logininfor', 'admin', now(), '', null, '登录日志菜单'); +insert into sys_menu values('500', '操作日志', '108', '1', 'operlog', 'monitor/operlog/index', '', '1', '0', 'C', '0', '0', 'monitor:operlog:list', 'form', 'admin', now(), '', null, '操作日志菜单'); +insert into sys_menu values('501', '登录日志', '108', '2', 'logininfor', 'monitor/logininfor/index', '', '1', '0', 'C', '0', '0', 'monitor:logininfor:list', 'logininfor', 'admin', now(), '', null, '登录日志菜单'); -- 用户管理按钮 -insert into sys_menu values('1001', '用户查询', '100', '1', '', '', '', 1, 0, 'F', '0', '0', 'system:user:query', '#', 'admin', now(), '', null, ''); -insert into sys_menu values('1002', '用户新增', '100', '2', '', '', '', 1, 0, 'F', '0', '0', 'system:user:add', '#', 'admin', now(), '', null, ''); -insert into sys_menu values('1003', '用户修改', '100', '3', '', '', '', 1, 0, 'F', '0', '0', 'system:user:edit', '#', 'admin', now(), '', null, ''); -insert into sys_menu values('1004', '用户删除', '100', '4', '', '', '', 1, 0, 'F', '0', '0', 'system:user:remove', '#', 'admin', now(), '', null, ''); -insert into sys_menu values('1005', '用户导出', '100', '5', '', '', '', 1, 0, 'F', '0', '0', 'system:user:export', '#', 'admin', now(), '', null, ''); -insert into sys_menu values('1006', '用户导入', '100', '6', '', '', '', 1, 0, 'F', '0', '0', 'system:user:import', '#', 'admin', now(), '', null, ''); -insert into sys_menu values('1007', '重置密码', '100', '7', '', '', '', 1, 0, 'F', '0', '0', 'system:user:resetPwd', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1001', '用户查询', '100', '1', '', '', '', '1', '0', 'F', '0', '0', 'system:user:query', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1002', '用户新增', '100', '2', '', '', '', '1', '0', 'F', '0', '0', 'system:user:add', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1003', '用户修改', '100', '3', '', '', '', '1', '0', 'F', '0', '0', 'system:user:edit', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1004', '用户删除', '100', '4', '', '', '', '1', '0', 'F', '0', '0', 'system:user:remove', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1005', '用户导出', '100', '5', '', '', '', '1', '0', 'F', '0', '0', 'system:user:export', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1006', '用户导入', '100', '6', '', '', '', '1', '0', 'F', '0', '0', 'system:user:import', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1007', '重置密码', '100', '7', '', '', '', '1', '0', 'F', '0', '0', 'system:user:resetPwd', '#', 'admin', now(), '', null, ''); -- 角色管理按钮 -insert into sys_menu values('1008', '角色查询', '101', '1', '', '', '', 1, 0, 'F', '0', '0', 'system:role:query', '#', 'admin', now(), '', null, ''); -insert into sys_menu values('1009', '角色新增', '101', '2', '', '', '', 1, 0, 'F', '0', '0', 'system:role:add', '#', 'admin', now(), '', null, ''); -insert into sys_menu values('1010', '角色修改', '101', '3', '', '', '', 1, 0, 'F', '0', '0', 'system:role:edit', '#', 'admin', now(), '', null, ''); -insert into sys_menu values('1011', '角色删除', '101', '4', '', '', '', 1, 0, 'F', '0', '0', 'system:role:remove', '#', 'admin', now(), '', null, ''); -insert into sys_menu values('1012', '角色导出', '101', '5', '', '', '', 1, 0, 'F', '0', '0', 'system:role:export', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1008', '角色查询', '101', '1', '', '', '', '1', '0', 'F', '0', '0', 'system:role:query', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1009', '角色新增', '101', '2', '', '', '', '1', '0', 'F', '0', '0', 'system:role:add', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1010', '角色修改', '101', '3', '', '', '', '1', '0', 'F', '0', '0', 'system:role:edit', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1011', '角色删除', '101', '4', '', '', '', '1', '0', 'F', '0', '0', 'system:role:remove', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1012', '角色导出', '101', '5', '', '', '', '1', '0', 'F', '0', '0', 'system:role:export', '#', 'admin', now(), '', null, ''); -- 菜单管理按钮 -insert into sys_menu values('1013', '菜单查询', '102', '1', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:query', '#', 'admin', now(), '', null, ''); -insert into sys_menu values('1014', '菜单新增', '102', '2', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:add', '#', 'admin', now(), '', null, ''); -insert into sys_menu values('1015', '菜单修改', '102', '3', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:edit', '#', 'admin', now(), '', null, ''); -insert into sys_menu values('1016', '菜单删除', '102', '4', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:remove', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1013', '菜单查询', '102', '1', '', '', '', '1', '0', 'F', '0', '0', 'system:menu:query', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1014', '菜单新增', '102', '2', '', '', '', '1', '0', 'F', '0', '0', 'system:menu:add', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1015', '菜单修改', '102', '3', '', '', '', '1', '0', 'F', '0', '0', 'system:menu:edit', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1016', '菜单删除', '102', '4', '', '', '', '1', '0', 'F', '0', '0', 'system:menu:remove', '#', 'admin', now(), '', null, ''); -- 部门管理按钮 -insert into sys_menu values('1017', '部门查询', '103', '1', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:query', '#', 'admin', now(), '', null, ''); -insert into sys_menu values('1018', '部门新增', '103', '2', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:add', '#', 'admin', now(), '', null, ''); -insert into sys_menu values('1019', '部门修改', '103', '3', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:edit', '#', 'admin', now(), '', null, ''); -insert into sys_menu values('1020', '部门删除', '103', '4', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:remove', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1017', '部门查询', '103', '1', '', '', '', '1', '0', 'F', '0', '0', 'system:dept:query', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1018', '部门新增', '103', '2', '', '', '', '1', '0', 'F', '0', '0', 'system:dept:add', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1019', '部门修改', '103', '3', '', '', '', '1', '0', 'F', '0', '0', 'system:dept:edit', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1020', '部门删除', '103', '4', '', '', '', '1', '0', 'F', '0', '0', 'system:dept:remove', '#', 'admin', now(), '', null, ''); -- 岗位管理按钮 -insert into sys_menu values('1021', '岗位查询', '104', '1', '', '', '', 1, 0, 'F', '0', '0', 'system:post:query', '#', 'admin', now(), '', null, ''); -insert into sys_menu values('1022', '岗位新增', '104', '2', '', '', '', 1, 0, 'F', '0', '0', 'system:post:add', '#', 'admin', now(), '', null, ''); -insert into sys_menu values('1023', '岗位修改', '104', '3', '', '', '', 1, 0, 'F', '0', '0', 'system:post:edit', '#', 'admin', now(), '', null, ''); -insert into sys_menu values('1024', '岗位删除', '104', '4', '', '', '', 1, 0, 'F', '0', '0', 'system:post:remove', '#', 'admin', now(), '', null, ''); -insert into sys_menu values('1025', '岗位导出', '104', '5', '', '', '', 1, 0, 'F', '0', '0', 'system:post:export', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1021', '岗位查询', '104', '1', '', '', '', '1', '0', 'F', '0', '0', 'system:post:query', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1022', '岗位新增', '104', '2', '', '', '', '1', '0', 'F', '0', '0', 'system:post:add', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1023', '岗位修改', '104', '3', '', '', '', '1', '0', 'F', '0', '0', 'system:post:edit', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1024', '岗位删除', '104', '4', '', '', '', '1', '0', 'F', '0', '0', 'system:post:remove', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1025', '岗位导出', '104', '5', '', '', '', '1', '0', 'F', '0', '0', 'system:post:export', '#', 'admin', now(), '', null, ''); -- 字典管理按钮 -insert into sys_menu values('1026', '字典查询', '105', '1', '#', '', '', 1, 0, 'F', '0', '0', 'system:dict:query', '#', 'admin', now(), '', null, ''); -insert into sys_menu values('1027', '字典新增', '105', '2', '#', '', '', 1, 0, 'F', '0', '0', 'system:dict:add', '#', 'admin', now(), '', null, ''); -insert into sys_menu values('1028', '字典修改', '105', '3', '#', '', '', 1, 0, 'F', '0', '0', 'system:dict:edit', '#', 'admin', now(), '', null, ''); -insert into sys_menu values('1029', '字典删除', '105', '4', '#', '', '', 1, 0, 'F', '0', '0', 'system:dict:remove', '#', 'admin', now(), '', null, ''); -insert into sys_menu values('1030', '字典导出', '105', '5', '#', '', '', 1, 0, 'F', '0', '0', 'system:dict:export', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1026', '字典查询', '105', '1', '#', '', '', '1', '0', 'F', '0', '0', 'system:dict:query', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1027', '字典新增', '105', '2', '#', '', '', '1', '0', 'F', '0', '0', 'system:dict:add', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1028', '字典修改', '105', '3', '#', '', '', '1', '0', 'F', '0', '0', 'system:dict:edit', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1029', '字典删除', '105', '4', '#', '', '', '1', '0', 'F', '0', '0', 'system:dict:remove', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1030', '字典导出', '105', '5', '#', '', '', '1', '0', 'F', '0', '0', 'system:dict:export', '#', 'admin', now(), '', null, ''); -- 参数设置按钮 -insert into sys_menu values('1031', '参数查询', '106', '1', '#', '', '', 1, 0, 'F', '0', '0', 'system:config:query', '#', 'admin', now(), '', null, ''); -insert into sys_menu values('1032', '参数新增', '106', '2', '#', '', '', 1, 0, 'F', '0', '0', 'system:config:add', '#', 'admin', now(), '', null, ''); -insert into sys_menu values('1033', '参数修改', '106', '3', '#', '', '', 1, 0, 'F', '0', '0', 'system:config:edit', '#', 'admin', now(), '', null, ''); -insert into sys_menu values('1034', '参数删除', '106', '4', '#', '', '', 1, 0, 'F', '0', '0', 'system:config:remove', '#', 'admin', now(), '', null, ''); -insert into sys_menu values('1035', '参数导出', '106', '5', '#', '', '', 1, 0, 'F', '0', '0', 'system:config:export', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1031', '参数查询', '106', '1', '#', '', '', '1', '0', 'F', '0', '0', 'system:config:query', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1032', '参数新增', '106', '2', '#', '', '', '1', '0', 'F', '0', '0', 'system:config:add', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1033', '参数修改', '106', '3', '#', '', '', '1', '0', 'F', '0', '0', 'system:config:edit', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1034', '参数删除', '106', '4', '#', '', '', '1', '0', 'F', '0', '0', 'system:config:remove', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1035', '参数导出', '106', '5', '#', '', '', '1', '0', 'F', '0', '0', 'system:config:export', '#', 'admin', now(), '', null, ''); -- 通知公告按钮 -insert into sys_menu values('1036', '公告查询', '107', '1', '#', '', '', 1, 0, 'F', '0', '0', 'system:notice:query', '#', 'admin', now(), '', null, ''); -insert into sys_menu values('1037', '公告新增', '107', '2', '#', '', '', 1, 0, 'F', '0', '0', 'system:notice:add', '#', 'admin', now(), '', null, ''); -insert into sys_menu values('1038', '公告修改', '107', '3', '#', '', '', 1, 0, 'F', '0', '0', 'system:notice:edit', '#', 'admin', now(), '', null, ''); -insert into sys_menu values('1039', '公告删除', '107', '4', '#', '', '', 1, 0, 'F', '0', '0', 'system:notice:remove', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1036', '公告查询', '107', '1', '#', '', '', '1', '0', 'F', '0', '0', 'system:notice:query', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1037', '公告新增', '107', '2', '#', '', '', '1', '0', 'F', '0', '0', 'system:notice:add', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1038', '公告修改', '107', '3', '#', '', '', '1', '0', 'F', '0', '0', 'system:notice:edit', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1039', '公告删除', '107', '4', '#', '', '', '1', '0', 'F', '0', '0', 'system:notice:remove', '#', 'admin', now(), '', null, ''); -- 操作日志按钮 -insert into sys_menu values('1040', '操作查询', '500', '1', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:query', '#', 'admin', now(), '', null, ''); -insert into sys_menu values('1041', '操作删除', '500', '2', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:remove', '#', 'admin', now(), '', null, ''); -insert into sys_menu values('1042', '日志导出', '500', '4', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:export', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1040', '操作查询', '500', '1', '#', '', '', '1', '0', 'F', '0', '0', 'monitor:operlog:query', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1041', '操作删除', '500', '2', '#', '', '', '1', '0', 'F', '0', '0', 'monitor:operlog:remove', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1042', '日志导出', '500', '4', '#', '', '', '1', '0', 'F', '0', '0', 'monitor:operlog:export', '#', 'admin', now(), '', null, ''); -- 登录日志按钮 -insert into sys_menu values('1043', '登录查询', '501', '1', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:query', '#', 'admin', now(), '', null, ''); -insert into sys_menu values('1044', '登录删除', '501', '2', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:remove', '#', 'admin', now(), '', null, ''); -insert into sys_menu values('1045', '日志导出', '501', '3', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:export', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1043', '登录查询', '501', '1', '#', '', '', '1', '0', 'F', '0', '0', 'monitor:logininfor:query', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1044', '登录删除', '501', '2', '#', '', '', '1', '0', 'F', '0', '0', 'monitor:logininfor:remove', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1045', '日志导出', '501', '3', '#', '', '', '1', '0', 'F', '0', '0', 'monitor:logininfor:export', '#', 'admin', now(), '', null, ''); -- 在线用户按钮 -insert into sys_menu values('1046', '在线查询', '109', '1', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:online:query', '#', 'admin', now(), '', null, ''); -insert into sys_menu values('1047', '批量强退', '109', '2', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:online:batchLogout', '#', 'admin', now(), '', null, ''); -insert into sys_menu values('1048', '单条强退', '109', '3', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:online:forceLogout', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1046', '在线查询', '109', '1', '#', '', '', '1', '0', 'F', '0', '0', 'monitor:online:query', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1047', '批量强退', '109', '2', '#', '', '', '1', '0', 'F', '0', '0', 'monitor:online:batchLogout', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1048', '单条强退', '109', '3', '#', '', '', '1', '0', 'F', '0', '0', 'monitor:online:forceLogout', '#', 'admin', now(), '', null, ''); -- 代码生成按钮 -insert into sys_menu values('1055', '生成查询', '115', '1', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:query', '#', 'admin', now(), '', null, ''); -insert into sys_menu values('1056', '生成修改', '115', '2', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:edit', '#', 'admin', now(), '', null, ''); -insert into sys_menu values('1057', '生成删除', '115', '3', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:remove', '#', 'admin', now(), '', null, ''); -insert into sys_menu values('1058', '导入代码', '115', '2', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:import', '#', 'admin', now(), '', null, ''); -insert into sys_menu values('1059', '预览代码', '115', '4', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:preview', '#', 'admin', now(), '', null, ''); -insert into sys_menu values('1060', '生成代码', '115', '5', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:code', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1055', '生成查询', '115', '1', '#', '', '', '1', '0', 'F', '0', '0', 'tool:gen:query', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1056', '生成修改', '115', '2', '#', '', '', '1', '0', 'F', '0', '0', 'tool:gen:edit', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1057', '生成删除', '115', '3', '#', '', '', '1', '0', 'F', '0', '0', 'tool:gen:remove', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1058', '导入代码', '115', '2', '#', '', '', '1', '0', 'F', '0', '0', 'tool:gen:import', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1059', '预览代码', '115', '4', '#', '', '', '1', '0', 'F', '0', '0', 'tool:gen:preview', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1060', '生成代码', '115', '5', '#', '', '', '1', '0', 'F', '0', '0', 'tool:gen:code', '#', 'admin', now(), '', null, ''); -- oss相关按钮 -insert into sys_menu values('1600', '文件查询', '118', '1', '#', '', '', 1, 0, 'F', '0', '0', 'system:oss:query', '#', 'admin', now(), '', null, ''); -insert into sys_menu values('1601', '文件上传', '118', '2', '#', '', '', 1, 0, 'F', '0', '0', 'system:oss:upload', '#', 'admin', now(), '', null, ''); -insert into sys_menu values('1602', '文件下载', '118', '3', '#', '', '', 1, 0, 'F', '0', '0', 'system:oss:download', '#', 'admin', now(), '', null, ''); -insert into sys_menu values('1603', '文件删除', '118', '4', '#', '', '', 1, 0, 'F', '0', '0', 'system:oss:remove', '#', 'admin', now(), '', null, ''); -insert into sys_menu values('1604', '配置添加', '118', '5', '#', '', '', 1, 0, 'F', '0', '0', 'system:oss:add', '#', 'admin', now(), '', null, ''); -insert into sys_menu values('1605', '配置编辑', '118', '6', '#', '', '', 1, 0, 'F', '0', '0', 'system:oss:edit', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1600', '文件查询', '118', '1', '#', '', '', '1', '0', 'F', '0', '0', 'system:oss:query', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1601', '文件上传', '118', '2', '#', '', '', '1', '0', 'F', '0', '0', 'system:oss:upload', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1602', '文件下载', '118', '3', '#', '', '', '1', '0', 'F', '0', '0', 'system:oss:download', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1603', '文件删除', '118', '4', '#', '', '', '1', '0', 'F', '0', '0', 'system:oss:remove', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1604', '配置添加', '118', '5', '#', '', '', '1', '0', 'F', '0', '0', 'system:oss:add', '#', 'admin', now(), '', null, ''); +insert into sys_menu values('1605', '配置编辑', '118', '6', '#', '', '', '1', '0', 'F', '0', '0', 'system:oss:edit', '#', 'admin', now(), '', null, ''); -- ---------------------------- @@ -917,6 +917,7 @@ create table if not exists sys_oss_config bucket_name varchar(255) default ''::varchar, prefix varchar(255) default ''::varchar, endpoint varchar(255) default ''::varchar, + domain varchar(255) default ''::varchar, is_https char default 'N'::bpchar, region varchar(255) default ''::varchar, status char default '1'::bpchar, @@ -937,6 +938,7 @@ comment on column sys_oss_config.secret_key is '秘钥'; comment on column sys_oss_config.bucket_name is '桶名称'; comment on column sys_oss_config.prefix is '前缀'; comment on column sys_oss_config.endpoint is '访问站点'; +comment on column sys_oss_config.domain is '自定义域名'; comment on column sys_oss_config.is_https is '是否https(Y=是,N=否)'; comment on column sys_oss_config.region is '域'; comment on column sys_oss_config.status is '状态(0=正常,1=停用)'; @@ -947,7 +949,9 @@ comment on column sys_oss_config.update_by is '更新者'; comment on column sys_oss_config.update_time is '更新时间'; comment on column sys_oss_config.remark is '备注'; -insert into sys_oss_config values (1, 'minio', 'ruoyi', 'ruoyi123', 'ruoyi', '', 'http://localhost:9000', 'N', '', '0', '', 'admin', now(), 'admin', now(), null); -insert into sys_oss_config values (2, 'qiniu', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi', '', 'http://XXX.XXXX.com', 'N', 'z0', '1', '', 'admin', now(), 'admin', now(), null); -insert into sys_oss_config values (3, 'aliyun', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi', '', 'http://oss-cn-beijing.aliyuncs.com', 'N', '', '1', '', 'admin', now(), 'admin', now(), null); -insert into sys_oss_config values (4, 'qcloud', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi-1250000000', '', 'http://cos.ap-beijing.myqcloud.com', 'N', 'ap-beijing', '1', '', 'admin', now(), 'admin', now(), null); +insert into sys_oss_config values (1, 'minio', 'ruoyi', 'ruoyi123', 'ruoyi', '', '127.0.0.1:9000', '','N', '', '0', '', 'admin', now(), 'admin', now(), null); +insert into sys_oss_config values (2, 'qiniu', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi', '', 's3-cn-north-1.qiniucs.com', '','N', '', '1', '', 'admin', now(), 'admin', now(), null); +insert into sys_oss_config values (3, 'aliyun', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi', '', 'oss-cn-beijing.aliyuncs.com', '','N', '', '1', '', 'admin', now(), 'admin', now(), null); +insert into sys_oss_config values (4, 'qcloud', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi-1250000000', '', 'cos.ap-beijing.myqcloud.com', '','N', 'ap-beijing', '1', '', 'admin', now(), 'admin', now(), null); +insert into sys_oss_config values (5, 'image', 'ruoyi', 'ruoyi123', 'ruoyi', 'image', '127.0.0.1:9000', '','N', '', '1', '', 'admin', now(), 'admin', now(), NULL); + diff --git a/script/sql/ry_vue_4.0.sql b/script/sql/ry_vue_4.0.sql deleted file mode 100644 index 9b57bd010..000000000 --- a/script/sql/ry_vue_4.0.sql +++ /dev/null @@ -1,686 +0,0 @@ --- ---------------------------- --- 1、部门表 --- ---------------------------- -drop table if exists sys_dept; -create table sys_dept ( - dept_id bigint(20) not null auto_increment comment '部门id', - parent_id bigint(20) default 0 comment '父部门id', - ancestors varchar(50) default '' comment '祖级列表', - dept_name varchar(30) default '' comment '部门名称', - order_num int(4) default 0 comment '显示顺序', - leader varchar(20) default null comment '负责人', - phone varchar(11) default null comment '联系电话', - email varchar(50) default null comment '邮箱', - status char(1) default '0' comment '部门状态(0正常 1停用)', - del_flag char(1) default '0' comment '删除标志(0代表存在 2代表删除)', - create_by varchar(64) default '' comment '创建者', - create_time datetime comment '创建时间', - update_by varchar(64) default '' comment '更新者', - update_time datetime comment '更新时间', - primary key (dept_id) -) engine=innodb auto_increment=200 comment = '部门表'; - --- ---------------------------- --- 初始化-部门表数据 --- ---------------------------- -insert into sys_dept values(100, 0, '0', '若依科技', 0, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); -insert into sys_dept values(101, 100, '0,100', '深圳总公司', 1, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); -insert into sys_dept values(102, 100, '0,100', '长沙分公司', 2, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); -insert into sys_dept values(103, 101, '0,100,101', '研发部门', 1, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); -insert into sys_dept values(104, 101, '0,100,101', '市场部门', 2, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); -insert into sys_dept values(105, 101, '0,100,101', '测试部门', 3, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); -insert into sys_dept values(106, 101, '0,100,101', '财务部门', 4, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); -insert into sys_dept values(107, 101, '0,100,101', '运维部门', 5, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); -insert into sys_dept values(108, 102, '0,100,102', '市场部门', 1, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); -insert into sys_dept values(109, 102, '0,100,102', '财务部门', 2, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); - - --- ---------------------------- --- 2、用户信息表 --- ---------------------------- -drop table if exists sys_user; -create table sys_user ( - user_id bigint(20) not null auto_increment comment '用户ID', - dept_id bigint(20) default null comment '部门ID', - user_name varchar(30) not null comment '用户账号', - nick_name varchar(30) not null comment '用户昵称', - user_type varchar(10) default 'sys_user' comment '用户类型(sys_user系统用户)', - email varchar(50) default '' comment '用户邮箱', - phonenumber varchar(11) default '' comment '手机号码', - sex char(1) default '0' comment '用户性别(0男 1女 2未知)', - avatar varchar(100) default '' comment '头像地址', - password varchar(100) default '' comment '密码', - status char(1) default '0' comment '帐号状态(0正常 1停用)', - del_flag char(1) default '0' comment '删除标志(0代表存在 2代表删除)', - login_ip varchar(128) default '' comment '最后登录IP', - login_date datetime comment '最后登录时间', - create_by varchar(64) default '' comment '创建者', - create_time datetime comment '创建时间', - update_by varchar(64) default '' comment '更新者', - update_time datetime comment '更新时间', - remark varchar(500) default null comment '备注', - primary key (user_id) -) engine=innodb auto_increment=100 comment = '用户信息表'; - --- ---------------------------- --- 初始化-用户信息表数据 --- ---------------------------- -insert into sys_user values(1, 103, 'admin', '疯狂的狮子Li', 'sys_user', 'crazyLionLi@163.com', '15888888888', '1', '', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', sysdate(), 'admin', sysdate(), '', null, '管理员'); -insert into sys_user values(2, 105, 'lionli', '疯狂的狮子Li', 'sys_user', 'crazyLionLi@qq.com', '15666666666', '1', '', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', sysdate(), 'admin', sysdate(), '', null, '测试员'); - - --- ---------------------------- --- 3、岗位信息表 --- ---------------------------- -drop table if exists sys_post; -create table sys_post -( - post_id bigint(20) not null auto_increment comment '岗位ID', - post_code varchar(64) not null comment '岗位编码', - post_name varchar(50) not null comment '岗位名称', - post_sort int(4) not null comment '显示顺序', - status char(1) not null comment '状态(0正常 1停用)', - create_by varchar(64) default '' comment '创建者', - create_time datetime comment '创建时间', - update_by varchar(64) default '' comment '更新者', - update_time datetime comment '更新时间', - remark varchar(500) default null comment '备注', - primary key (post_id) -) engine=innodb comment = '岗位信息表'; - --- ---------------------------- --- 初始化-岗位信息表数据 --- ---------------------------- -insert into sys_post values(1, 'ceo', '董事长', 1, '0', 'admin', sysdate(), '', null, ''); -insert into sys_post values(2, 'se', '项目经理', 2, '0', 'admin', sysdate(), '', null, ''); -insert into sys_post values(3, 'hr', '人力资源', 3, '0', 'admin', sysdate(), '', null, ''); -insert into sys_post values(4, 'user', '普通员工', 4, '0', 'admin', sysdate(), '', null, ''); - - --- ---------------------------- --- 4、角色信息表 --- ---------------------------- -drop table if exists sys_role; -create table sys_role ( - role_id bigint(20) not null auto_increment comment '角色ID', - role_name varchar(30) not null comment '角色名称', - role_key varchar(100) not null comment '角色权限字符串', - role_sort int(4) not null comment '显示顺序', - data_scope char(1) default '1' comment '数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限)', - menu_check_strictly tinyint(1) default 1 comment '菜单树选择项是否关联显示', - dept_check_strictly tinyint(1) default 1 comment '部门树选择项是否关联显示', - status char(1) not null comment '角色状态(0正常 1停用)', - del_flag char(1) default '0' comment '删除标志(0代表存在 2代表删除)', - create_by varchar(64) default '' comment '创建者', - create_time datetime comment '创建时间', - update_by varchar(64) default '' comment '更新者', - update_time datetime comment '更新时间', - remark varchar(500) default null comment '备注', - primary key (role_id) -) engine=innodb auto_increment=100 comment = '角色信息表'; - --- ---------------------------- --- 初始化-角色信息表数据 --- ---------------------------- -insert into sys_role values('1', '超级管理员', 'admin', 1, 1, 1, 1, '0', '0', 'admin', sysdate(), '', null, '超级管理员'); -insert into sys_role values('2', '普通角色', 'common', 2, 2, 1, 1, '0', '0', 'admin', sysdate(), '', null, '普通角色'); - - --- ---------------------------- --- 5、菜单权限表 --- ---------------------------- -drop table if exists sys_menu; -create table sys_menu ( - menu_id bigint(20) not null auto_increment comment '菜单ID', - menu_name varchar(50) not null comment '菜单名称', - parent_id bigint(20) default 0 comment '父菜单ID', - order_num int(4) default 0 comment '显示顺序', - path varchar(200) default '' comment '路由地址', - component varchar(255) default null comment '组件路径', - query varchar(255) default null comment '路由参数', - is_frame int(1) default 1 comment '是否为外链(0是 1否)', - is_cache int(1) default 0 comment '是否缓存(0缓存 1不缓存)', - menu_type char(1) default '' comment '菜单类型(M目录 C菜单 F按钮)', - visible char(1) default 0 comment '菜单状态(0显示 1隐藏)', - status char(1) default 0 comment '菜单状态(0正常 1停用)', - perms varchar(100) default null comment '权限标识', - icon varchar(100) default '#' comment '菜单图标', - create_by varchar(64) default '' comment '创建者', - create_time datetime comment '创建时间', - update_by varchar(64) default '' comment '更新者', - update_time datetime comment '更新时间', - remark varchar(500) default '' comment '备注', - primary key (menu_id) -) engine=innodb auto_increment=2000 comment = '菜单权限表'; - --- ---------------------------- --- 初始化-菜单信息表数据 --- ---------------------------- --- 一级菜单 -insert into sys_menu values('1', '系统管理', '0', '1', 'system', null, '', 1, 0, 'M', '0', '0', '', 'system', 'admin', sysdate(), '', null, '系统管理目录'); -insert into sys_menu values('2', '系统监控', '0', '2', 'monitor', null, '', 1, 0, 'M', '0', '0', '', 'monitor', 'admin', sysdate(), '', null, '系统监控目录'); -insert into sys_menu values('3', '系统工具', '0', '3', 'tool', null, '', 1, 0, 'M', '0', '0', '', 'tool', 'admin', sysdate(), '', null, '系统工具目录'); -insert into sys_menu values('4', 'PLUS官网', '0', '4', 'https://gitee.com/JavaLionLi/RuoYi-Vue-Plus', null, '', 0, 0, 'M', '0', '0', '', 'guide', 'admin', sysdate(), '', null, 'RuoYi-Vue-Plus官网地址'); --- 二级菜单 -insert into sys_menu values('100', '用户管理', '1', '1', 'user', 'system/user/index', '', 1, 0, 'C', '0', '0', 'system:user:list', 'user', 'admin', sysdate(), '', null, '用户管理菜单'); -insert into sys_menu values('101', '角色管理', '1', '2', 'role', 'system/role/index', '', 1, 0, 'C', '0', '0', 'system:role:list', 'peoples', 'admin', sysdate(), '', null, '角色管理菜单'); -insert into sys_menu values('102', '菜单管理', '1', '3', 'menu', 'system/menu/index', '', 1, 0, 'C', '0', '0', 'system:menu:list', 'tree-table', 'admin', sysdate(), '', null, '菜单管理菜单'); -insert into sys_menu values('103', '部门管理', '1', '4', 'dept', 'system/dept/index', '', 1, 0, 'C', '0', '0', 'system:dept:list', 'tree', 'admin', sysdate(), '', null, '部门管理菜单'); -insert into sys_menu values('104', '岗位管理', '1', '5', 'post', 'system/post/index', '', 1, 0, 'C', '0', '0', 'system:post:list', 'post', 'admin', sysdate(), '', null, '岗位管理菜单'); -insert into sys_menu values('105', '字典管理', '1', '6', 'dict', 'system/dict/index', '', 1, 0, 'C', '0', '0', 'system:dict:list', 'dict', 'admin', sysdate(), '', null, '字典管理菜单'); -insert into sys_menu values('106', '参数设置', '1', '7', 'config', 'system/config/index', '', 1, 0, 'C', '0', '0', 'system:config:list', 'edit', 'admin', sysdate(), '', null, '参数设置菜单'); -insert into sys_menu values('107', '通知公告', '1', '8', 'notice', 'system/notice/index', '', 1, 0, 'C', '0', '0', 'system:notice:list', 'message', 'admin', sysdate(), '', null, '通知公告菜单'); -insert into sys_menu values('108', '日志管理', '1', '9', 'log', '', '', 1, 0, 'M', '0', '0', '', 'log', 'admin', sysdate(), '', null, '日志管理菜单'); -insert into sys_menu values('109', '在线用户', '2', '1', 'online', 'monitor/online/index', '', 1, 0, 'C', '0', '0', 'monitor:online:list', 'online', 'admin', sysdate(), '', null, '在线用户菜单'); -insert into sys_menu values('111', '数据监控', '2', '3', 'druid', 'monitor/druid/index', '', 1, 0, 'C', '0', '0', 'monitor:druid:list', 'druid', 'admin', sysdate(), '', null, '数据监控菜单'); -insert into sys_menu values('113', '缓存监控', '2', '5', 'cache', 'monitor/cache/index', '', 1, 0, 'C', '0', '0', 'monitor:cache:list', 'redis', 'admin', sysdate(), '', null, '缓存监控菜单'); -insert into sys_menu values('114', '表单构建', '3', '1', 'build', 'tool/build/index', '', 1, 0, 'C', '0', '0', 'tool:build:list', 'build', 'admin', sysdate(), '', null, '表单构建菜单'); -insert into sys_menu values('115', '代码生成', '3', '2', 'gen', 'tool/gen/index', '', 1, 0, 'C', '0', '0', 'tool:gen:list', 'code', 'admin', sysdate(), '', null, '代码生成菜单'); -insert into sys_menu values('116', '系统接口', '3', '3', 'swagger', 'tool/swagger/index', '', 1, 0, 'C', '0', '0', 'tool:swagger:list', 'swagger', 'admin', sysdate(), '', null, '系统接口菜单'); --- springboot-admin监控 -insert into sys_menu values('117', 'Admin监控', '2', '5', 'Admin', 'monitor/admin/index', '', 1, 0, 'C', '0', '0', 'monitor:admin:list', 'dashboard', 'admin', sysdate(), '', null, 'Admin监控菜单'); --- oss菜单 -insert into sys_menu values('118', '文件管理', '1', '10', 'oss', 'system/oss/index', '', 1, 0, 'C', '0', '0', 'system:oss:list', 'upload', 'admin', sysdate(), '', null, '文件管理菜单'); --- xxl-job-admin控制台 -insert into sys_menu values('120', '任务调度中心', '2', '5', 'XxlJob', 'monitor/xxljob/index', '', 1, 0, 'C', '0', '0', 'monitor:xxljob:list', 'job', 'admin', sysdate(), '', null, 'Xxl-Job控制台菜单'); - --- 三级菜单 -insert into sys_menu values('500', '操作日志', '108', '1', 'operlog', 'monitor/operlog/index', '', 1, 0, 'C', '0', '0', 'monitor:operlog:list', 'form', 'admin', sysdate(), '', null, '操作日志菜单'); -insert into sys_menu values('501', '登录日志', '108', '2', 'logininfor', 'monitor/logininfor/index', '', 1, 0, 'C', '0', '0', 'monitor:logininfor:list', 'logininfor', 'admin', sysdate(), '', null, '登录日志菜单'); --- 用户管理按钮 -insert into sys_menu values('1001', '用户查询', '100', '1', '', '', '', 1, 0, 'F', '0', '0', 'system:user:query', '#', 'admin', sysdate(), '', null, ''); -insert into sys_menu values('1002', '用户新增', '100', '2', '', '', '', 1, 0, 'F', '0', '0', 'system:user:add', '#', 'admin', sysdate(), '', null, ''); -insert into sys_menu values('1003', '用户修改', '100', '3', '', '', '', 1, 0, 'F', '0', '0', 'system:user:edit', '#', 'admin', sysdate(), '', null, ''); -insert into sys_menu values('1004', '用户删除', '100', '4', '', '', '', 1, 0, 'F', '0', '0', 'system:user:remove', '#', 'admin', sysdate(), '', null, ''); -insert into sys_menu values('1005', '用户导出', '100', '5', '', '', '', 1, 0, 'F', '0', '0', 'system:user:export', '#', 'admin', sysdate(), '', null, ''); -insert into sys_menu values('1006', '用户导入', '100', '6', '', '', '', 1, 0, 'F', '0', '0', 'system:user:import', '#', 'admin', sysdate(), '', null, ''); -insert into sys_menu values('1007', '重置密码', '100', '7', '', '', '', 1, 0, 'F', '0', '0', 'system:user:resetPwd', '#', 'admin', sysdate(), '', null, ''); --- 角色管理按钮 -insert into sys_menu values('1008', '角色查询', '101', '1', '', '', '', 1, 0, 'F', '0', '0', 'system:role:query', '#', 'admin', sysdate(), '', null, ''); -insert into sys_menu values('1009', '角色新增', '101', '2', '', '', '', 1, 0, 'F', '0', '0', 'system:role:add', '#', 'admin', sysdate(), '', null, ''); -insert into sys_menu values('1010', '角色修改', '101', '3', '', '', '', 1, 0, 'F', '0', '0', 'system:role:edit', '#', 'admin', sysdate(), '', null, ''); -insert into sys_menu values('1011', '角色删除', '101', '4', '', '', '', 1, 0, 'F', '0', '0', 'system:role:remove', '#', 'admin', sysdate(), '', null, ''); -insert into sys_menu values('1012', '角色导出', '101', '5', '', '', '', 1, 0, 'F', '0', '0', 'system:role:export', '#', 'admin', sysdate(), '', null, ''); --- 菜单管理按钮 -insert into sys_menu values('1013', '菜单查询', '102', '1', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:query', '#', 'admin', sysdate(), '', null, ''); -insert into sys_menu values('1014', '菜单新增', '102', '2', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:add', '#', 'admin', sysdate(), '', null, ''); -insert into sys_menu values('1015', '菜单修改', '102', '3', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:edit', '#', 'admin', sysdate(), '', null, ''); -insert into sys_menu values('1016', '菜单删除', '102', '4', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:remove', '#', 'admin', sysdate(), '', null, ''); --- 部门管理按钮 -insert into sys_menu values('1017', '部门查询', '103', '1', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:query', '#', 'admin', sysdate(), '', null, ''); -insert into sys_menu values('1018', '部门新增', '103', '2', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:add', '#', 'admin', sysdate(), '', null, ''); -insert into sys_menu values('1019', '部门修改', '103', '3', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:edit', '#', 'admin', sysdate(), '', null, ''); -insert into sys_menu values('1020', '部门删除', '103', '4', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:remove', '#', 'admin', sysdate(), '', null, ''); --- 岗位管理按钮 -insert into sys_menu values('1021', '岗位查询', '104', '1', '', '', '', 1, 0, 'F', '0', '0', 'system:post:query', '#', 'admin', sysdate(), '', null, ''); -insert into sys_menu values('1022', '岗位新增', '104', '2', '', '', '', 1, 0, 'F', '0', '0', 'system:post:add', '#', 'admin', sysdate(), '', null, ''); -insert into sys_menu values('1023', '岗位修改', '104', '3', '', '', '', 1, 0, 'F', '0', '0', 'system:post:edit', '#', 'admin', sysdate(), '', null, ''); -insert into sys_menu values('1024', '岗位删除', '104', '4', '', '', '', 1, 0, 'F', '0', '0', 'system:post:remove', '#', 'admin', sysdate(), '', null, ''); -insert into sys_menu values('1025', '岗位导出', '104', '5', '', '', '', 1, 0, 'F', '0', '0', 'system:post:export', '#', 'admin', sysdate(), '', null, ''); --- 字典管理按钮 -insert into sys_menu values('1026', '字典查询', '105', '1', '#', '', '', 1, 0, 'F', '0', '0', 'system:dict:query', '#', 'admin', sysdate(), '', null, ''); -insert into sys_menu values('1027', '字典新增', '105', '2', '#', '', '', 1, 0, 'F', '0', '0', 'system:dict:add', '#', 'admin', sysdate(), '', null, ''); -insert into sys_menu values('1028', '字典修改', '105', '3', '#', '', '', 1, 0, 'F', '0', '0', 'system:dict:edit', '#', 'admin', sysdate(), '', null, ''); -insert into sys_menu values('1029', '字典删除', '105', '4', '#', '', '', 1, 0, 'F', '0', '0', 'system:dict:remove', '#', 'admin', sysdate(), '', null, ''); -insert into sys_menu values('1030', '字典导出', '105', '5', '#', '', '', 1, 0, 'F', '0', '0', 'system:dict:export', '#', 'admin', sysdate(), '', null, ''); --- 参数设置按钮 -insert into sys_menu values('1031', '参数查询', '106', '1', '#', '', '', 1, 0, 'F', '0', '0', 'system:config:query', '#', 'admin', sysdate(), '', null, ''); -insert into sys_menu values('1032', '参数新增', '106', '2', '#', '', '', 1, 0, 'F', '0', '0', 'system:config:add', '#', 'admin', sysdate(), '', null, ''); -insert into sys_menu values('1033', '参数修改', '106', '3', '#', '', '', 1, 0, 'F', '0', '0', 'system:config:edit', '#', 'admin', sysdate(), '', null, ''); -insert into sys_menu values('1034', '参数删除', '106', '4', '#', '', '', 1, 0, 'F', '0', '0', 'system:config:remove', '#', 'admin', sysdate(), '', null, ''); -insert into sys_menu values('1035', '参数导出', '106', '5', '#', '', '', 1, 0, 'F', '0', '0', 'system:config:export', '#', 'admin', sysdate(), '', null, ''); --- 通知公告按钮 -insert into sys_menu values('1036', '公告查询', '107', '1', '#', '', '', 1, 0, 'F', '0', '0', 'system:notice:query', '#', 'admin', sysdate(), '', null, ''); -insert into sys_menu values('1037', '公告新增', '107', '2', '#', '', '', 1, 0, 'F', '0', '0', 'system:notice:add', '#', 'admin', sysdate(), '', null, ''); -insert into sys_menu values('1038', '公告修改', '107', '3', '#', '', '', 1, 0, 'F', '0', '0', 'system:notice:edit', '#', 'admin', sysdate(), '', null, ''); -insert into sys_menu values('1039', '公告删除', '107', '4', '#', '', '', 1, 0, 'F', '0', '0', 'system:notice:remove', '#', 'admin', sysdate(), '', null, ''); --- 操作日志按钮 -insert into sys_menu values('1040', '操作查询', '500', '1', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:query', '#', 'admin', sysdate(), '', null, ''); -insert into sys_menu values('1041', '操作删除', '500', '2', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:remove', '#', 'admin', sysdate(), '', null, ''); -insert into sys_menu values('1042', '日志导出', '500', '4', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:export', '#', 'admin', sysdate(), '', null, ''); --- 登录日志按钮 -insert into sys_menu values('1043', '登录查询', '501', '1', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:query', '#', 'admin', sysdate(), '', null, ''); -insert into sys_menu values('1044', '登录删除', '501', '2', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:remove', '#', 'admin', sysdate(), '', null, ''); -insert into sys_menu values('1045', '日志导出', '501', '3', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:export', '#', 'admin', sysdate(), '', null, ''); --- 在线用户按钮 -insert into sys_menu values('1046', '在线查询', '109', '1', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:online:query', '#', 'admin', sysdate(), '', null, ''); -insert into sys_menu values('1047', '批量强退', '109', '2', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:online:batchLogout', '#', 'admin', sysdate(), '', null, ''); -insert into sys_menu values('1048', '单条强退', '109', '3', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:online:forceLogout', '#', 'admin', sysdate(), '', null, ''); --- 代码生成按钮 -insert into sys_menu values('1055', '生成查询', '115', '1', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:query', '#', 'admin', sysdate(), '', null, ''); -insert into sys_menu values('1056', '生成修改', '115', '2', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:edit', '#', 'admin', sysdate(), '', null, ''); -insert into sys_menu values('1057', '生成删除', '115', '3', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:remove', '#', 'admin', sysdate(), '', null, ''); -insert into sys_menu values('1058', '导入代码', '115', '2', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:import', '#', 'admin', sysdate(), '', null, ''); -insert into sys_menu values('1059', '预览代码', '115', '4', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:preview', '#', 'admin', sysdate(), '', null, ''); -insert into sys_menu values('1060', '生成代码', '115', '5', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:code', '#', 'admin', sysdate(), '', null, ''); --- oss相关按钮 -insert into sys_menu values('1600', '文件查询', '118', '1', '#', '', '', 1, 0, 'F', '0', '0', 'system:oss:query', '#', 'admin', sysdate(), '', null, ''); -insert into sys_menu values('1601', '文件上传', '118', '2', '#', '', '', 1, 0, 'F', '0', '0', 'system:oss:upload', '#', 'admin', sysdate(), '', null, ''); -insert into sys_menu values('1602', '文件下载', '118', '3', '#', '', '', 1, 0, 'F', '0', '0', 'system:oss:download', '#', 'admin', sysdate(), '', null, ''); -insert into sys_menu values('1603', '文件删除', '118', '4', '#', '', '', 1, 0, 'F', '0', '0', 'system:oss:remove', '#', 'admin', sysdate(), '', null, ''); -insert into sys_menu values('1604', '配置添加', '118', '5', '#', '', '', 1, 0, 'F', '0', '0', 'system:oss:add', '#', 'admin', sysdate(), '', null, ''); -insert into sys_menu values('1605', '配置编辑', '118', '6', '#', '', '', 1, 0, 'F', '0', '0', 'system:oss:edit', '#', 'admin', sysdate(), '', null, ''); - - --- ---------------------------- --- 6、用户和角色关联表 用户N-1角色 --- ---------------------------- -drop table if exists sys_user_role; -create table sys_user_role ( - user_id bigint(20) not null comment '用户ID', - role_id bigint(20) not null comment '角色ID', - primary key(user_id, role_id) -) engine=innodb comment = '用户和角色关联表'; - --- ---------------------------- --- 初始化-用户和角色关联表数据 --- ---------------------------- -insert into sys_user_role values ('1', '1'); -insert into sys_user_role values ('2', '2'); - - --- ---------------------------- --- 7、角色和菜单关联表 角色1-N菜单 --- ---------------------------- -drop table if exists sys_role_menu; -create table sys_role_menu ( - role_id bigint(20) not null comment '角色ID', - menu_id bigint(20) not null comment '菜单ID', - primary key(role_id, menu_id) -) engine=innodb comment = '角色和菜单关联表'; - --- ---------------------------- --- 初始化-角色和菜单关联表数据 --- ---------------------------- -insert into sys_role_menu values ('2', '1'); -insert into sys_role_menu values ('2', '2'); -insert into sys_role_menu values ('2', '3'); -insert into sys_role_menu values ('2', '4'); -insert into sys_role_menu values ('2', '100'); -insert into sys_role_menu values ('2', '101'); -insert into sys_role_menu values ('2', '102'); -insert into sys_role_menu values ('2', '103'); -insert into sys_role_menu values ('2', '104'); -insert into sys_role_menu values ('2', '105'); -insert into sys_role_menu values ('2', '106'); -insert into sys_role_menu values ('2', '107'); -insert into sys_role_menu values ('2', '108'); -insert into sys_role_menu values ('2', '109'); -insert into sys_role_menu values ('2', '110'); -insert into sys_role_menu values ('2', '111'); -insert into sys_role_menu values ('2', '112'); -insert into sys_role_menu values ('2', '113'); -insert into sys_role_menu values ('2', '114'); -insert into sys_role_menu values ('2', '115'); -insert into sys_role_menu values ('2', '116'); -insert into sys_role_menu values ('2', '500'); -insert into sys_role_menu values ('2', '501'); -insert into sys_role_menu values ('2', '1000'); -insert into sys_role_menu values ('2', '1001'); -insert into sys_role_menu values ('2', '1002'); -insert into sys_role_menu values ('2', '1003'); -insert into sys_role_menu values ('2', '1004'); -insert into sys_role_menu values ('2', '1005'); -insert into sys_role_menu values ('2', '1006'); -insert into sys_role_menu values ('2', '1007'); -insert into sys_role_menu values ('2', '1008'); -insert into sys_role_menu values ('2', '1009'); -insert into sys_role_menu values ('2', '1010'); -insert into sys_role_menu values ('2', '1011'); -insert into sys_role_menu values ('2', '1012'); -insert into sys_role_menu values ('2', '1013'); -insert into sys_role_menu values ('2', '1014'); -insert into sys_role_menu values ('2', '1015'); -insert into sys_role_menu values ('2', '1016'); -insert into sys_role_menu values ('2', '1017'); -insert into sys_role_menu values ('2', '1018'); -insert into sys_role_menu values ('2', '1019'); -insert into sys_role_menu values ('2', '1020'); -insert into sys_role_menu values ('2', '1021'); -insert into sys_role_menu values ('2', '1022'); -insert into sys_role_menu values ('2', '1023'); -insert into sys_role_menu values ('2', '1024'); -insert into sys_role_menu values ('2', '1025'); -insert into sys_role_menu values ('2', '1026'); -insert into sys_role_menu values ('2', '1027'); -insert into sys_role_menu values ('2', '1028'); -insert into sys_role_menu values ('2', '1029'); -insert into sys_role_menu values ('2', '1030'); -insert into sys_role_menu values ('2', '1031'); -insert into sys_role_menu values ('2', '1032'); -insert into sys_role_menu values ('2', '1033'); -insert into sys_role_menu values ('2', '1034'); -insert into sys_role_menu values ('2', '1035'); -insert into sys_role_menu values ('2', '1036'); -insert into sys_role_menu values ('2', '1037'); -insert into sys_role_menu values ('2', '1038'); -insert into sys_role_menu values ('2', '1039'); -insert into sys_role_menu values ('2', '1040'); -insert into sys_role_menu values ('2', '1041'); -insert into sys_role_menu values ('2', '1042'); -insert into sys_role_menu values ('2', '1043'); -insert into sys_role_menu values ('2', '1044'); -insert into sys_role_menu values ('2', '1045'); -insert into sys_role_menu values ('2', '1046'); -insert into sys_role_menu values ('2', '1047'); -insert into sys_role_menu values ('2', '1048'); -insert into sys_role_menu values ('2', '1055'); -insert into sys_role_menu values ('2', '1056'); -insert into sys_role_menu values ('2', '1057'); -insert into sys_role_menu values ('2', '1058'); -insert into sys_role_menu values ('2', '1059'); -insert into sys_role_menu values ('2', '1060'); - --- ---------------------------- --- 8、角色和部门关联表 角色1-N部门 --- ---------------------------- -drop table if exists sys_role_dept; -create table sys_role_dept ( - role_id bigint(20) not null comment '角色ID', - dept_id bigint(20) not null comment '部门ID', - primary key(role_id, dept_id) -) engine=innodb comment = '角色和部门关联表'; - --- ---------------------------- --- 初始化-角色和部门关联表数据 --- ---------------------------- -insert into sys_role_dept values ('2', '100'); -insert into sys_role_dept values ('2', '101'); -insert into sys_role_dept values ('2', '105'); - - --- ---------------------------- --- 9、用户与岗位关联表 用户1-N岗位 --- ---------------------------- -drop table if exists sys_user_post; -create table sys_user_post -( - user_id bigint(20) not null comment '用户ID', - post_id bigint(20) not null comment '岗位ID', - primary key (user_id, post_id) -) engine=innodb comment = '用户与岗位关联表'; - --- ---------------------------- --- 初始化-用户与岗位关联表数据 --- ---------------------------- -insert into sys_user_post values ('1', '1'); -insert into sys_user_post values ('2', '2'); - - --- ---------------------------- --- 10、操作日志记录 --- ---------------------------- -drop table if exists sys_oper_log; -create table sys_oper_log ( - oper_id bigint(20) not null auto_increment comment '日志主键', - title varchar(50) default '' comment '模块标题', - business_type int(2) default 0 comment '业务类型(0其它 1新增 2修改 3删除)', - method varchar(100) default '' comment '方法名称', - request_method varchar(10) default '' comment '请求方式', - operator_type int(1) default 0 comment '操作类别(0其它 1后台用户 2手机端用户)', - oper_name varchar(50) default '' comment '操作人员', - dept_name varchar(50) default '' comment '部门名称', - oper_url varchar(255) default '' comment '请求URL', - oper_ip varchar(128) default '' comment '主机地址', - oper_location varchar(255) default '' comment '操作地点', - oper_param varchar(2000) default '' comment '请求参数', - json_result varchar(2000) default '' comment '返回参数', - status int(1) default 0 comment '操作状态(0正常 1异常)', - error_msg varchar(2000) default '' comment '错误消息', - oper_time datetime comment '操作时间', - primary key (oper_id) -) engine=innodb auto_increment=100 comment = '操作日志记录'; - - --- ---------------------------- --- 11、字典类型表 --- ---------------------------- -drop table if exists sys_dict_type; -create table sys_dict_type -( - dict_id bigint(20) not null auto_increment comment '字典主键', - dict_name varchar(100) default '' comment '字典名称', - dict_type varchar(100) default '' comment '字典类型', - status char(1) default '0' comment '状态(0正常 1停用)', - create_by varchar(64) default '' comment '创建者', - create_time datetime comment '创建时间', - update_by varchar(64) default '' comment '更新者', - update_time datetime comment '更新时间', - remark varchar(500) default null comment '备注', - primary key (dict_id), - unique (dict_type) -) engine=innodb auto_increment=100 comment = '字典类型表'; - -insert into sys_dict_type values(1, '用户性别', 'sys_user_sex', '0', 'admin', sysdate(), '', null, '用户性别列表'); -insert into sys_dict_type values(2, '菜单状态', 'sys_show_hide', '0', 'admin', sysdate(), '', null, '菜单状态列表'); -insert into sys_dict_type values(3, '系统开关', 'sys_normal_disable', '0', 'admin', sysdate(), '', null, '系统开关列表'); -insert into sys_dict_type values(6, '系统是否', 'sys_yes_no', '0', 'admin', sysdate(), '', null, '系统是否列表'); -insert into sys_dict_type values(7, '通知类型', 'sys_notice_type', '0', 'admin', sysdate(), '', null, '通知类型列表'); -insert into sys_dict_type values(8, '通知状态', 'sys_notice_status', '0', 'admin', sysdate(), '', null, '通知状态列表'); -insert into sys_dict_type values(9, '操作类型', 'sys_oper_type', '0', 'admin', sysdate(), '', null, '操作类型列表'); -insert into sys_dict_type values(10, '系统状态', 'sys_common_status', '0', 'admin', sysdate(), '', null, '登录状态列表'); - - --- ---------------------------- --- 12、字典数据表 --- ---------------------------- -drop table if exists sys_dict_data; -create table sys_dict_data -( - dict_code bigint(20) not null auto_increment comment '字典编码', - dict_sort int(4) default 0 comment '字典排序', - dict_label varchar(100) default '' comment '字典标签', - dict_value varchar(100) default '' comment '字典键值', - dict_type varchar(100) default '' comment '字典类型', - css_class varchar(100) default null comment '样式属性(其他样式扩展)', - list_class varchar(100) default null comment '表格回显样式', - is_default char(1) default 'N' comment '是否默认(Y是 N否)', - status char(1) default '0' comment '状态(0正常 1停用)', - create_by varchar(64) default '' comment '创建者', - create_time datetime comment '创建时间', - update_by varchar(64) default '' comment '更新者', - update_time datetime comment '更新时间', - remark varchar(500) default null comment '备注', - primary key (dict_code) -) engine=innodb auto_increment=100 comment = '字典数据表'; - -insert into sys_dict_data values(1, 1, '男', '0', 'sys_user_sex', '', '', 'Y', '0', 'admin', sysdate(), '', null, '性别男'); -insert into sys_dict_data values(2, 2, '女', '1', 'sys_user_sex', '', '', 'N', '0', 'admin', sysdate(), '', null, '性别女'); -insert into sys_dict_data values(3, 3, '未知', '2', 'sys_user_sex', '', '', 'N', '0', 'admin', sysdate(), '', null, '性别未知'); -insert into sys_dict_data values(4, 1, '显示', '0', 'sys_show_hide', '', 'primary', 'Y', '0', 'admin', sysdate(), '', null, '显示菜单'); -insert into sys_dict_data values(5, 2, '隐藏', '1', 'sys_show_hide', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '隐藏菜单'); -insert into sys_dict_data values(6, 1, '正常', '0', 'sys_normal_disable', '', 'primary', 'Y', '0', 'admin', sysdate(), '', null, '正常状态'); -insert into sys_dict_data values(7, 2, '停用', '1', 'sys_normal_disable', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '停用状态'); -insert into sys_dict_data values(12, 1, '是', 'Y', 'sys_yes_no', '', 'primary', 'Y', '0', 'admin', sysdate(), '', null, '系统默认是'); -insert into sys_dict_data values(13, 2, '否', 'N', 'sys_yes_no', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '系统默认否'); -insert into sys_dict_data values(14, 1, '通知', '1', 'sys_notice_type', '', 'warning', 'Y', '0', 'admin', sysdate(), '', null, '通知'); -insert into sys_dict_data values(15, 2, '公告', '2', 'sys_notice_type', '', 'success', 'N', '0', 'admin', sysdate(), '', null, '公告'); -insert into sys_dict_data values(16, 1, '正常', '0', 'sys_notice_status', '', 'primary', 'Y', '0', 'admin', sysdate(), '', null, '正常状态'); -insert into sys_dict_data values(17, 2, '关闭', '1', 'sys_notice_status', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '关闭状态'); -insert into sys_dict_data values(18, 1, '新增', '1', 'sys_oper_type', '', 'info', 'N', '0', 'admin', sysdate(), '', null, '新增操作'); -insert into sys_dict_data values(19, 2, '修改', '2', 'sys_oper_type', '', 'info', 'N', '0', 'admin', sysdate(), '', null, '修改操作'); -insert into sys_dict_data values(20, 3, '删除', '3', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '删除操作'); -insert into sys_dict_data values(21, 4, '授权', '4', 'sys_oper_type', '', 'primary', 'N', '0', 'admin', sysdate(), '', null, '授权操作'); -insert into sys_dict_data values(22, 5, '导出', '5', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', sysdate(), '', null, '导出操作'); -insert into sys_dict_data values(23, 6, '导入', '6', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', sysdate(), '', null, '导入操作'); -insert into sys_dict_data values(24, 7, '强退', '7', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '强退操作'); -insert into sys_dict_data values(25, 8, '生成代码', '8', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', sysdate(), '', null, '生成操作'); -insert into sys_dict_data values(26, 9, '清空数据', '9', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '清空操作'); -insert into sys_dict_data values(27, 1, '成功', '0', 'sys_common_status', '', 'primary', 'N', '0', 'admin', sysdate(), '', null, '正常状态'); -insert into sys_dict_data values(28, 2, '失败', '1', 'sys_common_status', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '停用状态'); - - --- ---------------------------- --- 13、参数配置表 --- ---------------------------- -drop table if exists sys_config; -create table sys_config ( - config_id int(5) not null auto_increment comment '参数主键', - config_name varchar(100) default '' comment '参数名称', - config_key varchar(100) default '' comment '参数键名', - config_value varchar(500) default '' comment '参数键值', - config_type char(1) default 'N' comment '系统内置(Y是 N否)', - create_by varchar(64) default '' comment '创建者', - create_time datetime comment '创建时间', - update_by varchar(64) default '' comment '更新者', - update_time datetime comment '更新时间', - remark varchar(500) default null comment '备注', - primary key (config_id) -) engine=innodb auto_increment=100 comment = '参数配置表'; - -insert into sys_config values(1, '主框架页-默认皮肤样式名称', 'sys.index.skinName', 'skin-blue', 'Y', 'admin', sysdate(), '', null, '蓝色 skin-blue、绿色 skin-green、紫色 skin-purple、红色 skin-red、黄色 skin-yellow' ); -insert into sys_config values(2, '用户管理-账号初始密码', 'sys.user.initPassword', '123456', 'Y', 'admin', sysdate(), '', null, '初始化密码 123456' ); -insert into sys_config values(3, '主框架页-侧边栏主题', 'sys.index.sideTheme', 'theme-dark', 'Y', 'admin', sysdate(), '', null, '深色主题theme-dark,浅色主题theme-light' ); -insert into sys_config values(4, '账号自助-验证码开关', 'sys.account.captchaOnOff', 'true', 'Y', 'admin', sysdate(), '', null, '是否开启验证码功能(true开启,false关闭)'); -insert into sys_config values(5, '账号自助-是否开启用户注册功能', 'sys.account.registerUser', 'false', 'Y', 'admin', sysdate(), '', null, '是否开启注册用户功能(true开启,false关闭)'); -insert into sys_config values(11, 'OSS预览列表资源开关', 'sys.oss.previewListResource', 'true', 'Y', 'admin', sysdate(), '', null, 'true:开启, false:关闭'); - - --- ---------------------------- --- 14、系统访问记录 --- ---------------------------- -drop table if exists sys_logininfor; -create table sys_logininfor ( - info_id bigint(20) not null auto_increment comment '访问ID', - user_name varchar(50) default '' comment '用户账号', - ipaddr varchar(128) default '' comment '登录IP地址', - login_location varchar(255) default '' comment '登录地点', - browser varchar(50) default '' comment '浏览器类型', - os varchar(50) default '' comment '操作系统', - status char(1) default '0' comment '登录状态(0成功 1失败)', - msg varchar(255) default '' comment '提示消息', - login_time datetime comment '访问时间', - primary key (info_id) -) engine=innodb auto_increment=100 comment = '系统访问记录'; - - --- ---------------------------- --- 17、通知公告表 --- ---------------------------- -drop table if exists sys_notice; -create table sys_notice ( - notice_id int(4) not null auto_increment comment '公告ID', - notice_title varchar(50) not null comment '公告标题', - notice_type char(1) not null comment '公告类型(1通知 2公告)', - notice_content longblob default null comment '公告内容', - status char(1) default '0' comment '公告状态(0正常 1关闭)', - create_by varchar(64) default '' comment '创建者', - create_time datetime comment '创建时间', - update_by varchar(64) default '' comment '更新者', - update_time datetime comment '更新时间', - remark varchar(255) default null comment '备注', - primary key (notice_id) -) engine=innodb auto_increment=10 comment = '通知公告表'; - --- ---------------------------- --- 初始化-公告信息表数据 --- ---------------------------- -insert into sys_notice values('1', '温馨提醒:2018-07-01 新版本发布啦', '2', '新版本内容', '0', 'admin', sysdate(), '', null, '管理员'); -insert into sys_notice values('2', '维护通知:2018-07-01 系统凌晨维护', '1', '维护内容', '0', 'admin', sysdate(), '', null, '管理员'); - - --- ---------------------------- --- 18、代码生成业务表 --- ---------------------------- -drop table if exists gen_table; -create table gen_table ( - table_id bigint(20) not null auto_increment comment '编号', - table_name varchar(200) default '' comment '表名称', - table_comment varchar(500) default '' comment '表描述', - sub_table_name varchar(64) default null comment '关联子表的表名', - sub_table_fk_name varchar(64) default null comment '子表关联的外键名', - class_name varchar(100) default '' comment '实体类名称', - tpl_category varchar(200) default 'crud' comment '使用的模板(crud单表操作 tree树表操作)', - package_name varchar(100) comment '生成包路径', - module_name varchar(30) comment '生成模块名', - business_name varchar(30) comment '生成业务名', - function_name varchar(50) comment '生成功能名', - function_author varchar(50) comment '生成功能作者', - gen_type char(1) default '0' comment '生成代码方式(0zip压缩包 1自定义路径)', - gen_path varchar(200) default '/' comment '生成路径(不填默认项目路径)', - options varchar(1000) comment '其它生成选项', - create_by varchar(64) default '' comment '创建者', - create_time datetime comment '创建时间', - update_by varchar(64) default '' comment '更新者', - update_time datetime comment '更新时间', - remark varchar(500) default null comment '备注', - primary key (table_id) -) engine=innodb auto_increment=1 comment = '代码生成业务表'; - - --- ---------------------------- --- 19、代码生成业务表字段 --- ---------------------------- -drop table if exists gen_table_column; -create table gen_table_column ( - column_id bigint(20) not null auto_increment comment '编号', - table_id varchar(64) comment '归属表编号', - column_name varchar(200) comment '列名称', - column_comment varchar(500) comment '列描述', - column_type varchar(100) comment '列类型', - java_type varchar(500) comment 'JAVA类型', - java_field varchar(200) comment 'JAVA字段名', - is_pk char(1) comment '是否主键(1是)', - is_increment char(1) comment '是否自增(1是)', - is_required char(1) comment '是否必填(1是)', - is_insert char(1) comment '是否为插入字段(1是)', - is_edit char(1) comment '是否编辑字段(1是)', - is_list char(1) comment '是否列表字段(1是)', - is_query char(1) comment '是否查询字段(1是)', - query_type varchar(200) default 'EQ' comment '查询方式(等于、不等于、大于、小于、范围)', - html_type varchar(200) comment '显示类型(文本框、文本域、下拉框、复选框、单选框、日期控件)', - dict_type varchar(200) default '' comment '字典类型', - sort int comment '排序', - create_by varchar(64) default '' comment '创建者', - create_time datetime comment '创建时间', - update_by varchar(64) default '' comment '更新者', - update_time datetime comment '更新时间', - primary key (column_id) -) engine=innodb auto_increment=1 comment = '代码生成业务表字段'; - --- ---------------------------- --- OSS对象存储表 --- ---------------------------- -drop table if exists sys_oss; -create table sys_oss ( - oss_id bigint(20) not null auto_increment comment '对象存储主键', - file_name varchar(255) not null default '' comment '文件名', - original_name varchar(255) not null default '' comment '原名', - file_suffix varchar(10) not null default '' comment '文件后缀名', - url varchar(500) not null comment 'URL地址', - create_time datetime default null comment '创建时间', - create_by varchar(64) default '' comment '上传人', - update_time datetime default null comment '更新时间', - update_by varchar(64) default '' comment '更新人', - service varchar(10) not null default 'minio' comment '服务商', - primary key (oss_id) -) engine=innodb comment ='OSS对象存储表'; - --- ---------------------------- --- OSS对象存储动态配置表 --- ---------------------------- -drop table if exists sys_oss_config; -create table sys_oss_config ( - oss_config_id bigint(20) not null auto_increment comment '主建', - config_key varchar(255) not null default '' comment '配置key', - access_key varchar(255) default '' comment 'accessKey', - secret_key varchar(255) default '' comment '秘钥', - bucket_name varchar(255) default '' comment '桶名称', - prefix varchar(255) default '' comment '前缀', - endpoint varchar(255) default '' comment '访问站点', - is_https char(1) default 'N' comment '是否https(Y=是,N=否)', - region varchar(255) default '' comment '域', - status char(1) default '1' comment '状态(0=正常,1=停用)', - ext1 varchar(255) default '' comment '扩展字段', - create_by varchar(64) default '' comment '创建者', - create_time datetime default null comment '创建时间', - update_by varchar(64) default '' comment '更新者', - update_time datetime default null comment '更新时间', - remark varchar(500) default null comment '备注', - primary key (oss_config_id) -) engine=innodb comment='对象存储配置表'; - -insert into sys_oss_config values (1, 'minio', 'ruoyi', 'ruoyi123', 'ruoyi', '', 'http://localhost:9000', 'N', '', '0', '', 'admin', sysdate(), 'admin', sysdate(), NULL); -insert into sys_oss_config values (2, 'qiniu', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi', '', 'http://XXX.XXXX.com', 'N', 'z0', '1', '', 'admin', sysdate(), 'admin', sysdate(), NULL); -insert into sys_oss_config values (3, 'aliyun', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi', '', 'http://oss-cn-beijing.aliyuncs.com', 'N', '', '1', '', 'admin', sysdate(), 'admin', sysdate(), NULL); -insert into sys_oss_config values (4, 'qcloud', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi-1250000000', '', 'http://cos.ap-beijing.myqcloud.com', 'N', 'ap-beijing', '1', '', 'admin', sysdate(), 'admin', sysdate(), NULL); diff --git a/script/sql/ry_vue_4.X.sql b/script/sql/ry_vue_4.X.sql index e190186ba..560f3fc53 100644 --- a/script/sql/ry_vue_4.X.sql +++ b/script/sql/ry_vue_4.X.sql @@ -515,7 +515,7 @@ insert into sys_dict_data values(28, 2, '失败', '1', 'sys_common_st -- ---------------------------- drop table if exists sys_config; create table sys_config ( - config_id int(5) not null comment '参数主键', + config_id bigint(20) not null comment '参数主键', config_name varchar(100) default '' comment '参数名称', config_key varchar(100) default '' comment '参数键名', config_value varchar(500) default '' comment '参数键值', @@ -559,7 +559,7 @@ create table sys_logininfor ( -- ---------------------------- drop table if exists sys_notice; create table sys_notice ( - notice_id int(4) not null comment '公告ID', + notice_id bigint(20) not null comment '公告ID', notice_title varchar(50) not null comment '公告标题', notice_type char(1) not null comment '公告类型(1通知 2公告)', notice_content longblob default null comment '公告内容', @@ -614,7 +614,7 @@ create table gen_table ( drop table if exists gen_table_column; create table gen_table_column ( column_id bigint(20) not null comment '编号', - table_id varchar(64) comment '归属表编号', + table_id bigint(20) comment '归属表编号', column_name varchar(200) comment '列名称', column_comment varchar(500) comment '列描述', column_type varchar(100) comment '列类型', @@ -668,6 +668,7 @@ create table sys_oss_config ( bucket_name varchar(255) default '' comment '桶名称', prefix varchar(255) default '' comment '前缀', endpoint varchar(255) default '' comment '访问站点', + domain varchar(255) default '' comment '自定义域名', is_https char(1) default 'N' comment '是否https(Y=是,N=否)', region varchar(255) default '' comment '域', status char(1) default '1' comment '状态(0=正常,1=停用)', @@ -680,7 +681,9 @@ create table sys_oss_config ( primary key (oss_config_id) ) engine=innodb comment='对象存储配置表'; -insert into sys_oss_config values (1, 'minio', 'ruoyi', 'ruoyi123', 'ruoyi', '', 'http://localhost:9000', 'N', '', '0', '', 'admin', sysdate(), 'admin', sysdate(), NULL); -insert into sys_oss_config values (2, 'qiniu', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi', '', 'http://XXX.XXXX.com', 'N', 'z0', '1', '', 'admin', sysdate(), 'admin', sysdate(), NULL); -insert into sys_oss_config values (3, 'aliyun', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi', '', 'http://oss-cn-beijing.aliyuncs.com', 'N', '', '1', '', 'admin', sysdate(), 'admin', sysdate(), NULL); -insert into sys_oss_config values (4, 'qcloud', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi-1250000000', '', 'http://cos.ap-beijing.myqcloud.com', 'N', 'ap-beijing', '1', '', 'admin', sysdate(), 'admin', sysdate(), NULL); +insert into sys_oss_config values (1, 'minio', 'ruoyi', 'ruoyi123', 'ruoyi', '', '127.0.0.1:9000', '','N', '', '0', '', 'admin', sysdate(), 'admin', sysdate(), NULL); +insert into sys_oss_config values (2, 'qiniu', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi', '', 's3-cn-north-1.qiniucs.com', '','N', '', '1', '', 'admin', sysdate(), 'admin', sysdate(), NULL); +insert into sys_oss_config values (3, 'aliyun', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi', '', 'oss-cn-beijing.aliyuncs.com', '','N', '', '1', '', 'admin', sysdate(), 'admin', sysdate(), NULL); +insert into sys_oss_config values (4, 'qcloud', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi-1250000000', '', 'cos.ap-beijing.myqcloud.com', '','N', 'ap-beijing', '1', '', 'admin', sysdate(), 'admin', sysdate(), NULL); +insert into sys_oss_config values (5, 'image', 'ruoyi', 'ruoyi123', 'ruoyi', 'image', '127.0.0.1:9000', '','N', '', '1', '', 'admin', sysdate(), 'admin', sysdate(), NULL); + diff --git a/script/sql/sqlserver/sqlserver_ry_vue_4.X.sql b/script/sql/sqlserver/sqlserver_ry_vue_4.X.sql index d37f1b40e..97b8be1cd 100644 --- a/script/sql/sqlserver/sqlserver_ry_vue_4.X.sql +++ b/script/sql/sqlserver/sqlserver_ry_vue_4.X.sql @@ -157,7 +157,7 @@ GO CREATE TABLE [gen_table_column] ( [column_id] bigint NOT NULL, - [table_id] nvarchar(64) NULL, + [table_id] bigint NULL, [column_name] nvarchar(200) NULL, [column_comment] nvarchar(500) NULL, [column_type] nvarchar(100) NULL, @@ -2193,6 +2193,7 @@ CREATE TABLE [sys_oss_config] [bucket_name] nvarchar(255) DEFAULT '' NULL, [prefix] nvarchar(255) DEFAULT '' NULL, [endpoint] nvarchar(255) DEFAULT '' NULL, + [domain] nvarchar(255) DEFAULT '' NULL, [is_https] nchar(1) DEFAULT ('N') NULL, [region] nvarchar(255) DEFAULT '' NULL, [status] nchar(1) DEFAULT ('1') NULL, @@ -2251,6 +2252,12 @@ EXEC sp_addextendedproperty 'TABLE', N'sys_oss_config', 'COLUMN', N'endpoint' GO +EXEC sp_addextendedproperty + 'MS_Description', N'自定义域名', + 'SCHEMA', N'dbo', + 'TABLE', N'sys_oss_config', + 'COLUMN', N'domain' +GO EXEC sp_addextendedproperty 'MS_Description', N'是否https(Y=是,N=否)', 'SCHEMA', N'dbo', @@ -2311,11 +2318,13 @@ EXEC sp_addextendedproperty 'TABLE', N'sys_oss_config' GO -INSERT INTO [sys_oss_config] ([oss_config_id], [config_key], [access_key], [secret_key], [bucket_name], [prefix], [endpoint], [is_https], [region], [status], [ext1], [create_by], [create_time], [update_by], [update_time], [remark]) VALUES (N'1', N'minio', N'lihongbo', N'lihongbo.123', N'ruoyi', N'', N'http://81.70.150.73:9000', N'N', N'', N'0', N'', N'admin', getdate(), N'admin', getdate(), NULL) +INSERT INTO [sys_oss_config] ([oss_config_id], [config_key], [access_key], [secret_key], [bucket_name], [prefix], [endpoint], [domain], [is_https], [region], [status], [ext1], [create_by], [create_time], [update_by], [update_time], [remark]) VALUES (N'1', N'minio', N'ruoyi', N'ruoyi123', N'ruoyi', N'', N'127.0.0.1:9000', N'',N'N', N'', N'0', N'', N'admin', getdate(), N'admin', getdate(), NULL) GO -INSERT INTO [sys_oss_config] ([oss_config_id], [config_key], [access_key], [secret_key], [bucket_name], [prefix], [endpoint], [is_https], [region], [status], [ext1], [create_by], [create_time], [update_by], [update_time], [remark]) VALUES (N'2', N'qiniu', N'XXXXXXXXXXXXXXXX', N'XXXXXXXXXXXXXXX', N'ruoyi', N'', N'http://XXX.XXXX.com', N'N', N'z0', N'1', N'', N'admin', getdate(), N'admin', getdate(), NULL) +INSERT INTO [sys_oss_config] ([oss_config_id], [config_key], [access_key], [secret_key], [bucket_name], [prefix], [endpoint], [domain], [is_https], [region], [status], [ext1], [create_by], [create_time], [update_by], [update_time], [remark]) VALUES (N'2', N'qiniu', N'XXXXXXXXXXXXXXXX', N'XXXXXXXXXXXXXXX', N'ruoyi', N'', N's3-cn-north-1.qiniucs.com', N'',N'N', N'', N'1', N'', N'admin', getdate(), N'admin', getdate(), NULL) GO -INSERT INTO [sys_oss_config] ([oss_config_id], [config_key], [access_key], [secret_key], [bucket_name], [prefix], [endpoint], [is_https], [region], [status], [ext1], [create_by], [create_time], [update_by], [update_time], [remark]) VALUES (N'3', N'aliyun', N'XXXXXXXXXXXXXXX', N'XXXXXXXXXXXXXXX', N'ruoyi', N'', N'http://oss-cn-beijing.aliyuncs.com', N'N', N'', N'1', N'', N'admin', getdate(), N'admin', getdate(), NULL) +INSERT INTO [sys_oss_config] ([oss_config_id], [config_key], [access_key], [secret_key], [bucket_name], [prefix], [endpoint], [domain], [is_https], [region], [status], [ext1], [create_by], [create_time], [update_by], [update_time], [remark]) VALUES (N'3', N'aliyun', N'XXXXXXXXXXXXXXX', N'XXXXXXXXXXXXXXX', N'ruoyi', N'', N'oss-cn-beijing.aliyuncs.com', N'',N'N', N'', N'1', N'', N'admin', getdate(), N'admin', getdate(), NULL) GO -INSERT INTO [sys_oss_config] ([oss_config_id], [config_key], [access_key], [secret_key], [bucket_name], [prefix], [endpoint], [is_https], [region], [status], [ext1], [create_by], [create_time], [update_by], [update_time], [remark]) VALUES (N'4', N'qcloud', N'XXXXXXXXXXXXXXX', N'XXXXXXXXXXXXXXX', N'ruoyi-1250000000', N'', N'http://cos.ap-beijing.myqcloud.com', N'N', N'ap-beijing', N'1', N'', N'admin', getdate(), N'admin', getdate(), NULL) +INSERT INTO [sys_oss_config] ([oss_config_id], [config_key], [access_key], [secret_key], [bucket_name], [prefix], [endpoint], [domain], [is_https], [region], [status], [ext1], [create_by], [create_time], [update_by], [update_time], [remark]) VALUES (N'4', N'qcloud', N'XXXXXXXXXXXXXXX', N'XXXXXXXXXXXXXXX', N'ruoyi-1250000000', N'', N'cos.ap-beijing.myqcloud.com', N'',N'N', N'ap-beijing', N'1', N'', N'admin', getdate(), N'admin', getdate(), NULL) +GO +INSERT INTO [sys_oss_config] ([oss_config_id], [config_key], [access_key], [secret_key], [bucket_name], [prefix], [endpoint], [domain], [is_https], [region], [status], [ext1], [create_by], [create_time], [update_by], [update_time], [remark]) VALUES (N'5', N'image', N'ruoyi', N'ruoyi123', N'ruoyi', N'image', N'127.0.0.1:9000', N'',N'N', N'', N'1', N'', N'admin', getdate(), N'admin', getdate(), NULL) GO diff --git a/script/sql/update/oracle/update-4.1-4.2.sql b/script/sql/update/oracle/update-4.1-4.2.sql new file mode 100644 index 000000000..a4cbf248c --- /dev/null +++ b/script/sql/update/oracle/update-4.1-4.2.sql @@ -0,0 +1,12 @@ +ALTER TABLE "SYS_OSS_CONFIG" ADD ("DOMAIN" VARCHAR2(255)); + +COMMENT ON COLUMN "SYS_OSS_CONFIG"."DOMAIN" IS '自定义域名'; + +update sys_oss_config set endpoint = '127.0.0.1:9000' where oss_config_id = 1; +update sys_oss_config set endpoint = 's3-cn-north-1.qiniucs.com', region = '' where oss_config_id = 2; +update sys_oss_config set endpoint = 'oss-cn-beijing.aliyuncs.com' where oss_config_id = 3; +update sys_oss_config set endpoint = 'cos.ap-beijing.myqcloud.com' where oss_config_id = 4; + +insert into sys_oss_config values (5, 'image', 'ruoyi', 'ruoyi123', 'ruoyi', 'image', '127.0.0.1:9000', 'N', '', '1', '', NULL, 'admin', sysdate, 'admin', sysdate, ''); + +ALTER TABLE "GEN_TABLE_COLUMN" MODIFY ("TABLE_ID" NUMBER(20,0)); diff --git a/script/sql/update/postgres/update-4.1-4.2.sql b/script/sql/update/postgres/update-4.1-4.2.sql new file mode 100644 index 000000000..5ea2cf531 --- /dev/null +++ b/script/sql/update/postgres/update-4.1-4.2.sql @@ -0,0 +1,11 @@ +ALTER TABLE "sys_oss_config" ADD COLUMN "domain" varchar(255); + +COMMENT ON COLUMN "sys_oss_config"."domain" IS '自定义域名'; + +update sys_oss_config set endpoint = '127.0.0.1:9000' where oss_config_id = 1; +update sys_oss_config set endpoint = 's3-cn-north-1.qiniucs.com', region = '' where oss_config_id = 2; +update sys_oss_config set endpoint = 'oss-cn-beijing.aliyuncs.com' where oss_config_id = 3; +update sys_oss_config set endpoint = 'cos.ap-beijing.myqcloud.com' where oss_config_id = 4; + +insert into sys_oss_config values (5, 'image', 'ruoyi', 'ruoyi123', 'ruoyi', 'image', '127.0.0.1:9000', 'N', '', '1', '', 'admin', now(), 'admin', now(), NULL, ''); + diff --git a/script/sql/update/sqlserver/update-4.1-4.2.sql b/script/sql/update/sqlserver/update-4.1-4.2.sql new file mode 100644 index 000000000..9e217ec7b --- /dev/null +++ b/script/sql/update/sqlserver/update-4.1-4.2.sql @@ -0,0 +1,27 @@ +ALTER TABLE [sys_oss_config] ADD [domain] nvarchar(255) DEFAULT '' NULL +GO + +EXEC sp_addextendedproperty +'MS_Description', N'自定义域名', +'SCHEMA', N'dbo', +'TABLE', N'sys_oss_config', +'COLUMN', N'domain' +GO + +UPDATE [sys_oss_config] SET [access_key] = N'ruoyi', [secret_key] = N'ruoyi123', [endpoint] = N'127.0.0.1:9000' WHERE [oss_config_id] = 1 +GO + +UPDATE [sys_oss_config] SET [endpoint] = N's3-cn-north-1.qiniucs.com' WHERE [oss_config_id] = 2 +GO + +UPDATE [sys_oss_config] SET [endpoint] = N'oss-cn-beijing.aliyuncs.com' WHERE [oss_config_id] = 3 +GO + +UPDATE [sys_oss_config] SET [endpoint] = N'cos.ap-beijing.myqcloud.com' WHERE [oss_config_id] = 4 +GO + +INSERT INTO [sys_oss_config] ([oss_config_id], [config_key], [access_key], [secret_key], [bucket_name], [prefix], [endpoint], [domain], [is_https], [region], [status], [ext1], [create_by], [create_time], [update_by], [update_time], [remark]) VALUES (N'5', N'image', N'ruoyi', N'ruoyi123', N'ruoyi', N'image', N'127.0.0.1:9000', N'',N'N', N'', N'1', N'', N'admin', getdate(), N'admin', getdate(), NULL) +GO + +ALTER TABLE [gen_table_column] ALTER COLUMN [table_id] bigint NULL +GO diff --git a/script/sql/update/update-4.1-4.2.sql b/script/sql/update/update-4.1-4.2.sql new file mode 100644 index 000000000..1d9cf508f --- /dev/null +++ b/script/sql/update/update-4.1-4.2.sql @@ -0,0 +1,14 @@ +alter table sys_oss_config add column domain varchar(255) null default '' COMMENT '自定义域名'; + +update sys_oss_config set endpoint = '127.0.0.1:9000' where oss_config_id = 1; +update sys_oss_config set endpoint = 's3-cn-north-1.qiniucs.com', region = '' where oss_config_id = 2; +update sys_oss_config set endpoint = 'oss-cn-beijing.aliyuncs.com' where oss_config_id = 3; +update sys_oss_config set endpoint = 'cos.ap-beijing.myqcloud.com' where oss_config_id = 4; + +insert into sys_oss_config values (5, 'image', 'ruoyi', 'ruoyi123', 'ruoyi', 'image', '127.0.0.1:9000', 'N', '', '1', '', 'admin', sysdate(), 'admin', sysdate(), NULL, ''); + +alter table gen_table_column modify column table_id bigint(0) null default null COMMENT '归属表编号'; + +alter table sys_notice modify column notice_id bigint(0) not null COMMENT '公告ID'; + +alter table sys_config modify column config_id bigint(0) not null COMMENT '参数主键';