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 000000000..0f7347d65 Binary files /dev/null and b/ruoyi/src/main/resources/excel/单列表.xlsx differ diff --git a/ruoyi/src/main/resources/excel/多列表.xlsx b/ruoyi/src/main/resources/excel/多列表.xlsx new file mode 100644 index 000000000..c7d11dcce Binary files /dev/null and b/ruoyi/src/main/resources/excel/多列表.xlsx differ diff --git a/ruoyi/src/main/resources/logback.xml b/ruoyi/src/main/resources/logback.xml index 4d6b910d3..b78044b35 100644 --- a/ruoyi/src/main/resources/logback.xml +++ b/ruoyi/src/main/resources/logback.xml @@ -97,17 +97,9 @@ - - - - - - - - - + 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 '参数主键';