From 6f14087a1690da6b077297d094a2740b0af4c76d Mon Sep 17 00:00:00 2001 From: RuoYi Date: Mon, 25 Apr 2022 10:23:47 +0800 Subject: [PATCH 001/112] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E9=A1=BA=E5=BA=8ForderNum=E7=B1=BB=E5=9E=8B=E4=B8=BA=E6=95=B4?= =?UTF-8?q?=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/ruoyi/common/core/domain/entity/SysDept.java | 9 +++++---- .../src/main/resources/mapper/system/SysDeptMapper.xml | 6 +++--- .../src/main/resources/mapper/system/SysMenuMapper.xml | 6 +++--- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDept.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDept.java index 423ef6852..693461b9f 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDept.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDept.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.List; import javax.validation.constraints.Email; import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; @@ -31,7 +32,7 @@ public class SysDept extends BaseEntity private String deptName; /** 显示顺序 */ - private String orderNum; + private Integer orderNum; /** 负责人 */ private String leader; @@ -96,13 +97,13 @@ public class SysDept extends BaseEntity this.deptName = deptName; } - @NotBlank(message = "显示顺序不能为空") - public String getOrderNum() + @NotNull(message = "显示顺序不能为空") + public Integer getOrderNum() { return orderNum; } - public void setOrderNum(String orderNum) + public void setOrderNum(Integer orderNum) { this.orderNum = orderNum; } diff --git a/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml index 44bd8689a..984f89ccc 100644 --- a/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml @@ -91,7 +91,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" parent_id, dept_name, ancestors, - order_num, + order_num, leader, phone, email, @@ -103,7 +103,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{parentId}, #{deptName}, #{ancestors}, - #{orderNum}, + #{orderNum}, #{leader}, #{phone}, #{email}, @@ -119,7 +119,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" parent_id = #{parentId}, dept_name = #{deptName}, ancestors = #{ancestors}, - order_num = #{orderNum}, + order_num = #{orderNum}, leader = #{leader}, phone = #{phone}, email = #{email}, diff --git a/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml index 81e7b705a..f11402c7f 100644 --- a/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml @@ -130,7 +130,7 @@ menu_name = #{menuName}, parent_id = #{parentId}, - order_num = #{orderNum}, + order_num = #{orderNum}, path = #{path}, component = #{component}, `query` = #{query}, @@ -153,7 +153,7 @@ menu_id, parent_id, menu_name, - order_num, + order_num, path, component, `query`, @@ -171,7 +171,7 @@ #{menuId}, #{parentId}, #{menuName}, - #{orderNum}, + #{orderNum}, #{path}, #{component}, #{query}, From 7414bc492e3b9cc4640d4bb1269d0908b9c346f7 Mon Sep 17 00:00:00 2001 From: RuoYi Date: Mon, 25 Apr 2022 10:27:06 +0800 Subject: [PATCH 002/112] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E7=94=9F=E6=88=90=E6=A0=91=E9=80=89=E6=8B=A9=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/resources/vm/vue/v3/index-tree.vue.vm | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/ruoyi-generator/src/main/resources/vm/vue/v3/index-tree.vue.vm b/ruoyi-generator/src/main/resources/vm/vue/v3/index-tree.vue.vm index 11bbe52e3..862297c79 100644 --- a/ruoyi-generator/src/main/resources/vm/vue/v3/index-tree.vue.vm +++ b/ruoyi-generator/src/main/resources/vm/vue/v3/index-tree.vue.vm @@ -174,11 +174,13 @@ #set($dictType=$column.dictType) #if("" != $treeParentCode && $column.javaField == $treeParentCode) - #elseif($column.htmlType == "input") @@ -354,8 +356,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}"); @@ -404,9 +406,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 { From eaef38f79c2d428f44fed4090753a8e037700251 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90Li?= <15040126243@163.com> Date: Mon, 25 Apr 2022 15:24:10 +0800 Subject: [PATCH 003/112] =?UTF-8?q?fix=20=E4=BF=AE=E5=A4=8D=20ExcelUtil=20?= =?UTF-8?q?=E8=A1=A8=E8=BE=BE=E5=BC=8F=E8=A7=A3=E6=9E=90=20=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E6=B7=BB=E5=8F=8D=E5=AF=BC=E8=87=B4=E6=97=A0=E6=B3=95?= =?UTF-8?q?=E8=A7=A3=E6=9E=90=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java index 36dc67fa1..78d5915ee 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java @@ -103,7 +103,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 +132,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); From c7972aa5e66396486a5aa3059cf5008dc504fe53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90Li?= <15040126243@163.com> Date: Mon, 25 Apr 2022 15:25:43 +0800 Subject: [PATCH 004/112] =?UTF-8?q?fix=20=E4=BF=AE=E5=A4=8D=20=E5=85=A8?= =?UTF-8?q?=E5=B1=80=E7=BA=BF=E7=A8=8B=E6=B1=A0=E9=85=8D=E7=BD=AE=20?= =?UTF-8?q?=E6=A0=B8=E5=BF=83=E7=BA=BF=E7=A8=8B=E4=B8=8E=E6=9C=80=E5=A4=A7?= =?UTF-8?q?=E7=BA=BF=E7=A8=8B=20=E5=8F=82=E6=95=B0=E5=A1=AB=E5=8F=8D?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/ruoyi/framework/config/ThreadPoolConfig.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ThreadPoolConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ThreadPoolConfig.java index ebf236c87..a85ad1e57 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ThreadPoolConfig.java +++ b/ruoyi-framework/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()); From 7ba8fc256b1bc2ce271b8c09f353ac5778f025bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90li?= <15040126243@163.com> Date: Thu, 28 Apr 2022 10:16:13 +0800 Subject: [PATCH 005/112] =?UTF-8?q?fix=20=E4=BF=AE=E5=A4=8D=20=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E6=9C=AA=E5=88=86=E9=85=8D=E7=94=A8=E6=88=B7=E8=A7=92?= =?UTF-8?q?=E8=89=B2=E5=88=97=E8=A1=A8=20=E8=A7=92=E8=89=B2=E6=97=A0?= =?UTF-8?q?=E7=BB=91=E5=AE=9A=E7=94=A8=E6=88=B7=E6=83=85=E5=86=B5=E4=B8=8B?= =?UTF-8?q?=20=E7=A9=BA=E5=88=97=E8=A1=A8=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/ruoyi/system/service/impl/SysUserServiceImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java index 2ef63881c..ec919f63a 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java @@ -115,11 +115,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); From f32813951f368b2fd5b97bc9bb25689c53ccf3bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90li?= <15040126243@163.com> Date: Fri, 29 Apr 2022 11:35:51 +0800 Subject: [PATCH 006/112] =?UTF-8?q?update=20=E4=BC=98=E5=8C=96=20redis=20?= =?UTF-8?q?=E5=BA=8F=E5=88=97=E5=8C=96=20=E4=BD=BF=E7=94=A8=E7=B3=BB?= =?UTF-8?q?=E7=BB=9F=E8=87=AA=E5=B8=A6json=E5=B7=A5=E5=85=B7=20=E5=85=A8?= =?UTF-8?q?=E5=B1=80=E7=BB=9F=E4=B8=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/ruoyi/framework/config/RedisConfig.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/RedisConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/RedisConfig.java index da18cfd17..d8cbba25d 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/RedisConfig.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/RedisConfig.java @@ -1,6 +1,7 @@ package com.ruoyi.framework.config; import cn.hutool.core.util.ObjectUtil; +import com.ruoyi.common.utils.JsonUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.framework.config.properties.RedissonProperties; import lombok.extern.slf4j.Slf4j; @@ -53,7 +54,7 @@ public class RedisConfig extends CachingConfigurerSupport { Config config = new Config(); config.setThreads(redissonProperties.getThreads()) .setNettyThreads(redissonProperties.getNettyThreads()) - .setCodec(JsonJacksonCodec.INSTANCE); + .setCodec(new JsonJacksonCodec(JsonUtils.getObjectMapper())); RedissonProperties.SingleServerConfig singleServerConfig = redissonProperties.getSingleServerConfig(); if (ObjectUtil.isNotNull(singleServerConfig)) { From e18cf51c0170490c80bb9b7c794f6f4ed1fad938 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90Li?= <15040126243@163.com> Date: Sat, 30 Apr 2022 22:21:49 +0800 Subject: [PATCH 007/112] =?UTF-8?q?update=20=E4=BC=98=E5=8C=96=20RedisUtil?= =?UTF-8?q?s=20=E9=87=8D=E6=9E=84=E8=BF=87=E6=9C=9F=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/common/CaptchaController.java | 4 ++-- .../ruoyi/common/utils/redis/RedisUtils.java | 22 +++++++++---------- .../demo/controller/RedisCacheController.java | 4 ++-- .../framework/aspectj/RepeatSubmitAspect.java | 4 ++-- .../ruoyi/framework/config/SwaggerConfig.java | 2 +- .../listener/UserActionListener.java | 4 ++-- .../framework/satoken/dao/PlusSaTokenDao.java | 10 ++++----- .../ruoyi/system/service/SysLoginService.java | 4 ++-- 8 files changed, 26 insertions(+), 28 deletions(-) diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java index a19be65ea..2b9917f7c 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java @@ -19,9 +19,9 @@ import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; +import java.time.Duration; import java.util.HashMap; import java.util.Map; -import java.util.concurrent.TimeUnit; /** * 验证码操作处理 @@ -60,7 +60,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-common/src/main/java/com/ruoyi/common/utils/redis/RedisUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/redis/RedisUtils.java index 5a15d46b7..b0f35d878 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/redis/RedisUtils.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/redis/RedisUtils.java @@ -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); } /** diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisCacheController.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisCacheController.java index 98cca18c0..9fc93074f 100644 --- a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisCacheController.java +++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisCacheController.java @@ -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-framework/src/main/java/com/ruoyi/framework/aspectj/RepeatSubmitAspect.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RepeatSubmitAspect.java index aedc4431c..b77acb40e 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RepeatSubmitAspect.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RepeatSubmitAspect.java @@ -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-framework/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java index 22ef7c1b5..2424981c1 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java @@ -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-framework/src/main/java/com/ruoyi/framework/listener/UserActionListener.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/listener/UserActionListener.java index 75277c257..88b23648e 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/listener/UserActionListener.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/listener/UserActionListener.java @@ -18,7 +18,7 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; -import java.util.concurrent.TimeUnit; +import java.time.Duration; /** * 用户行为 侦听器的实现 @@ -52,7 +52,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-framework/src/main/java/com/ruoyi/framework/satoken/dao/PlusSaTokenDao.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/satoken/dao/PlusSaTokenDao.java index f78e81415..a08503dc1 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/satoken/dao/PlusSaTokenDao.java +++ b/ruoyi-framework/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)); } } @@ -87,7 +87,7 @@ public class PlusSaTokenDao implements SaTokenDao { } return; } - RedisUtils.expire(key, timeout, TimeUnit.SECONDS); + RedisUtils.expire(key, Duration.ofSeconds(timeout)); } @@ -111,7 +111,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)); } } @@ -160,7 +160,7 @@ public class PlusSaTokenDao implements SaTokenDao { } return; } - RedisUtils.expire(key, timeout, TimeUnit.SECONDS); + RedisUtils.expire(key, Duration.ofSeconds(timeout)); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/SysLoginService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/SysLoginService.java index e0b53c1fb..f60419f05 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/SysLoginService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/SysLoginService.java @@ -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; /** @@ -248,7 +248,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 { From cbe405f6eaf7631ac74023efa6cf0800e043e44d Mon Sep 17 00:00:00 2001 From: RuoYi Date: Sun, 1 May 2022 20:22:25 +0800 Subject: [PATCH 008/112] ui code format --- ruoyi-ui/src/assets/styles/element-variables.scss | 2 +- ruoyi-ui/src/views/tool/gen/index.vue | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ruoyi-ui/src/assets/styles/element-variables.scss b/ruoyi-ui/src/assets/styles/element-variables.scss index 039d1e480..5bf2fbb10 100644 --- a/ruoyi-ui/src/assets/styles/element-variables.scss +++ b/ruoyi-ui/src/assets/styles/element-variables.scss @@ -17,7 +17,7 @@ $--button-font-weight: 400; $--border-color-light: #dfe4ed; $--border-color-lighter: #e6ebf5; -$--table-border:1px solid#dfe6ec; +$--table-border: 1px solid #dfe6ec; /* icon font path, required */ $--font-path: '~element-ui/lib/theme-chalk/fonts'; diff --git a/ruoyi-ui/src/views/tool/gen/index.vue b/ruoyi-ui/src/views/tool/gen/index.vue index 381e30f6e..4cd9e9910 100644 --- a/ruoyi-ui/src/views/tool/gen/index.vue +++ b/ruoyi-ui/src/views/tool/gen/index.vue @@ -305,7 +305,7 @@ export default { return result.value || ' '; }, /** 复制代码成功 */ - clipboardSuccess(){ + clipboardSuccess() { this.$modal.msgSuccess("复制成功"); }, // 多选框选中数据 From 9476f7f61671f54fc288647594ce3db5ad621dd5 Mon Sep 17 00:00:00 2001 From: RuoYi Date: Sun, 1 May 2022 20:22:35 +0800 Subject: [PATCH 009/112] =?UTF-8?q?=E5=8D=87=E7=BA=A7spring-boot=E5=88=B0?= =?UTF-8?q?=E6=9C=80=E6=96=B0=E7=89=88=E6=9C=AC2.5.13?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b693251fc..65abb93bc 100644 --- a/pom.xml +++ b/pom.xml @@ -43,7 +43,7 @@ org.springframework.boot spring-boot-dependencies - 2.5.12 + 2.5.13 pom import From 92f030887b45604744d488131a506abbda14b4b5 Mon Sep 17 00:00:00 2001 From: zlyx <1242874891@qq.com> Date: Mon, 2 May 2022 21:21:14 +0800 Subject: [PATCH 010/112] =?UTF-8?q?[add]:=201.=20(common)=20pom.xml=20-=20?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=82=AE=E4=BB=B6=E4=BE=9D=E8=B5=96=20;=202.?= =?UTF-8?q?=20(admin)=20application-dev.yml=20-=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E9=82=AE=E4=BB=B6=E9=85=8D=E7=BD=AE=20;=203.=20(framework)=20M?= =?UTF-8?q?ailProperties,=20MailConfig=20-=20=E5=A2=9E=E5=8A=A0=E9=82=AE?= =?UTF-8?q?=E4=BB=B6=E5=B1=9E=E6=80=A7=E9=85=8D=E7=BD=AE=20;=204.=20(commo?= =?UTF-8?q?n)=20MailUtils=20-=20=E9=87=8D=E5=86=99=20Hutool=20MailUtil?= =?UTF-8?q?=E6=96=B9=E6=B3=95=20;=205.=20(demo)=20MailController=20-=20?= =?UTF-8?q?=E9=82=AE=E4=BB=B6=E5=8F=91=E9=80=81=E6=B5=8B=E8=AF=95=E6=96=B9?= =?UTF-8?q?=E6=B3=95=20;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 1 + .../src/main/resources/application-dev.yml | 28 ++ ruoyi-common/pom.xml | 6 + .../ruoyi/common/utils/email/MailUtils.java | 468 ++++++++++++++++++ .../ruoyi/demo/controller/MailController.java | 54 ++ .../ruoyi/framework/config/MailConfig.java | 39 ++ .../config/properties/MailProperties.java | 65 +++ 7 files changed, 661 insertions(+) create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/email/MailUtils.java create mode 100644 ruoyi-demo/src/main/java/com/ruoyi/demo/controller/MailController.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/config/MailConfig.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/MailProperties.java diff --git a/pom.xml b/pom.xml index 4fc098f5b..71963f204 100644 --- a/pom.xml +++ b/pom.xml @@ -38,6 +38,7 @@ 3.5.1 1.3.6 2.3.0 + 1.6.2 3.0.1 diff --git a/ruoyi-admin/src/main/resources/application-dev.yml b/ruoyi-admin/src/main/resources/application-dev.yml index 45eb5be97..50e060b62 100644 --- a/ruoyi-admin/src/main/resources/application-dev.yml +++ b/ruoyi-admin/src/main/resources/application-dev.yml @@ -137,6 +137,34 @@ spring: # 是否开启ssl ssl: false + # 邮件 + mail: + enabled: false + # 邮件服务地址 (enabled = true 时打开该配置) +# host: smtp.qq.com + # 用户名 + username: xxx@qq.com + # 授权码 (设置 - 账户 - POP3/SMTP服务) + password: xxx + # QQ邮箱加密端口,不同邮箱的端口不一样 + port: 465 + properties: + mail: + smtp: + socketFactory: + class: javax.net.ssl.SSLSocketFactory + ssl: + trust: smtp.qq.com + # 是否需要用户认证 + auth: true + starttls: + # 启用TLS加密 + enable: true + required: true + # 传输协议 starttls.enable = true 时为 smtps + protocol: smtps + debug: true + redisson: # 线程池数量 threads: 4 diff --git a/ruoyi-common/pom.xml b/ruoyi-common/pom.xml index bb476cbdd..fd6a999fe 100644 --- a/ruoyi-common/pom.xml +++ b/ruoyi-common/pom.xml @@ -159,6 +159,12 @@ lock4j-redisson-spring-boot-starter + + com.sun.mail + javax.mail + ${mail.version} + + diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/email/MailUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/email/MailUtils.java new file mode 100644 index 000000000..92fa89ae4 --- /dev/null +++ b/ruoyi-common/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 username 发送人 + * @param password 授权码 + */ + public static MailAccount getMailAccount(String username, String password) { + ACCOUNT.setFrom(StringUtils.blankToDefault(username, ACCOUNT.getUser())); + ACCOUNT.setUser(StringUtils.blankToDefault(username, ACCOUNT.getUser())); + ACCOUNT.setPass(StringUtils.blankToDefault(password, 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-demo/src/main/java/com/ruoyi/demo/controller/MailController.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/MailController.java new file mode 100644 index 000000000..53f130f26 --- /dev/null +++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/MailController.java @@ -0,0 +1,54 @@ +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 lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; +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; + + +/** + * 测试邮件发送 Controller + * + * @author Michelle.Chung + */ +@Validated +@Api(value = "邮件控制器", tags = {"测试邮件发送"}) +@RequiredArgsConstructor(onConstructor_ = @Autowired) +@RequestMapping("/demo/mail") +@RestController +public class MailController { + + /** + * 发送邮件 + * + * @param to 接收人 + * @param subject 标题 + * @param text 内容 + */ + @GetMapping("/sendSimpleMessage") + public R sendSimpleMessage(String to, String subject, String text) { + MailUtils.send(to, subject, text, false); + return R.ok("操作成功"); + } + + /** + * 发送邮件(带附件) + * + * @param to 接收人 + * @param subject 标题 + * @param text 内容 + */ + @GetMapping("/sendMessageWithAttachment") + public R sendMessageWithAttachment(String to, String subject, String text, String filePath) { + MailUtils.send(to, subject, text, false, new File(filePath)); + return R.ok("操作成功"); + } + +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/MailConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/MailConfig.java new file mode 100644 index 000000000..d4ff8a7d5 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/MailConfig.java @@ -0,0 +1,39 @@ +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; + +import javax.annotation.Resource; + +/** + * JavaMail 配置 + * + * @author Michelle.Chung + */ +@Configuration +public class MailConfig { + + @Resource + private MailProperties mailProperties; + + /** + * 初始化 JavaMailSender + */ + @Bean + @ConditionalOnProperty(value = "spring.mail.enabled", havingValue = "true") + public MailAccount mailAccount() { + MailAccount account = new MailAccount(); + account.setFrom(mailProperties.getUsername()); + account.setUser(mailProperties.getUsername()); + account.setPass(mailProperties.getPassword()); + account.setPort(mailProperties.getPort()); + account.setAuth(mailProperties.getAuth()); + account.setDebug(mailProperties.getDebug()); + account.setStarttlsEnable(mailProperties.getStarttlsEnable()); + return account; + } + +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/MailProperties.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/MailProperties.java new file mode 100644 index 000000000..ce2103fea --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/MailProperties.java @@ -0,0 +1,65 @@ +package com.ruoyi.framework.config.properties; + +import lombok.Data; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * JavaMail 配置属性 + * + * @author Michelle.Chung + */ +@Data +@Component +@ConfigurationProperties(prefix = "spring.mail") +public class MailProperties { + + /** + * 过滤开关 + */ + private String enabled; + + /** + * 邮件服务地址 + */ + private String host; + + /** + * 用户名 + */ + private String username; + + /** + * 授权码 (设置 - 账户 - POP3/SMTP服务) + */ + private String password; + + /** + * 邮箱加密端口,不同邮箱的端口不一样 + */ + private Integer port; + + /** + * 是否需要用户认证 + */ + @Value("${spring.mail.properties.mail.smtp.auth}") + private Boolean auth; + + /** + * 是否启用TLS加密 + */ + @Value("${spring.mail.properties.mail.smtp.starttls.enable}") + private Boolean starttlsEnable; + + @Value("${spring.mail.properties.mail.smtp.ssl.trust}") + private String sslTrust; + + private Boolean debug; + + /** + * 传输协议 starttls.enable = true 时为 smtps + */ + private String protocol; + +} From 4941aaa5c1c59f17881d3587f1679b93736bd01e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90Li?= <15040126243@163.com> Date: Mon, 2 May 2022 23:10:47 +0800 Subject: [PATCH 011/112] =?UTF-8?q?update=20=E9=87=8D=E6=9E=84=20pr=5F172?= =?UTF-8?q?=20=E9=9B=86=E6=88=90=E9=82=AE=E4=BB=B6=E5=8F=91=E9=80=81?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 1 - .../src/main/resources/application-dev.yml | 50 +++++++--------- .../src/main/resources/application-prod.yml | 22 +++++++ ruoyi-common/pom.xml | 11 ++-- .../ruoyi/common/utils/email/MailUtils.java | 12 ++-- .../ruoyi/demo/controller/MailController.java | 39 ++++++------- .../ruoyi/framework/config/MailConfig.java | 24 ++++---- .../config/properties/MailProperties.java | 58 ++++++++++--------- 8 files changed, 114 insertions(+), 103 deletions(-) diff --git a/pom.xml b/pom.xml index 71963f204..4fc098f5b 100644 --- a/pom.xml +++ b/pom.xml @@ -38,7 +38,6 @@ 3.5.1 1.3.6 2.3.0 - 1.6.2 3.0.1 diff --git a/ruoyi-admin/src/main/resources/application-dev.yml b/ruoyi-admin/src/main/resources/application-dev.yml index 50e060b62..6be268bf0 100644 --- a/ruoyi-admin/src/main/resources/application-dev.yml +++ b/ruoyi-admin/src/main/resources/application-dev.yml @@ -137,34 +137,6 @@ spring: # 是否开启ssl ssl: false - # 邮件 - mail: - enabled: false - # 邮件服务地址 (enabled = true 时打开该配置) -# host: smtp.qq.com - # 用户名 - username: xxx@qq.com - # 授权码 (设置 - 账户 - POP3/SMTP服务) - password: xxx - # QQ邮箱加密端口,不同邮箱的端口不一样 - port: 465 - properties: - mail: - smtp: - socketFactory: - class: javax.net.ssl.SSLSocketFactory - ssl: - trust: smtp.qq.com - # 是否需要用户认证 - auth: true - starttls: - # 启用TLS加密 - enable: true - required: true - # 传输协议 starttls.enable = true 时为 smtps - protocol: smtps - debug: true - redisson: # 线程池数量 threads: 4 @@ -184,3 +156,25 @@ 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 diff --git a/ruoyi-admin/src/main/resources/application-prod.yml b/ruoyi-admin/src/main/resources/application-prod.yml index 6a28bccfb..4966a41e8 100644 --- a/ruoyi-admin/src/main/resources/application-prod.yml +++ b/ruoyi-admin/src/main/resources/application-prod.yml @@ -159,3 +159,25 @@ 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 diff --git a/ruoyi-common/pom.xml b/ruoyi-common/pom.xml index fd6a999fe..7f0e384f9 100644 --- a/ruoyi-common/pom.xml +++ b/ruoyi-common/pom.xml @@ -127,6 +127,11 @@ hutool-extra + + com.sun.mail + jakarta.mail + + org.projectlombok lombok @@ -159,12 +164,6 @@ lock4j-redisson-spring-boot-starter - - com.sun.mail - javax.mail - ${mail.version} - - diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/email/MailUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/email/MailUtils.java index 92fa89ae4..32a3f8252 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/email/MailUtils.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/email/MailUtils.java @@ -38,13 +38,13 @@ public class MailUtils { /** * 获取邮件发送实例 (自定义发送人以及授权码) * - * @param username 发送人 - * @param password 授权码 + * @param user 发送人 + * @param pass 授权码 */ - public static MailAccount getMailAccount(String username, String password) { - ACCOUNT.setFrom(StringUtils.blankToDefault(username, ACCOUNT.getUser())); - ACCOUNT.setUser(StringUtils.blankToDefault(username, ACCOUNT.getUser())); - ACCOUNT.setPass(StringUtils.blankToDefault(password, ACCOUNT.getPass())); + 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; } diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/MailController.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/MailController.java index 53f130f26..74e9e3398 100644 --- a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/MailController.java +++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/MailController.java @@ -3,6 +3,8 @@ 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.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; @@ -14,41 +16,34 @@ import java.io.File; /** - * 测试邮件发送 Controller + * 邮件发送案例 * * @author Michelle.Chung */ @Validated -@Api(value = "邮件控制器", tags = {"测试邮件发送"}) +@Api(value = "邮件发送案例", tags = {"邮件发送案例"}) @RequiredArgsConstructor(onConstructor_ = @Autowired) @RequestMapping("/demo/mail") @RestController public class MailController { - /** - * 发送邮件 - * - * @param to 接收人 - * @param subject 标题 - * @param text 内容 - */ + @ApiOperation("发送邮件") @GetMapping("/sendSimpleMessage") - public R sendSimpleMessage(String to, String subject, String text) { - MailUtils.send(to, subject, text, false); - return R.ok("操作成功"); + public R sendSimpleMessage(@ApiParam("接收人") String to, + @ApiParam("标题") String subject, + @ApiParam("内容") String text) { + MailUtils.sendText(to, subject, text); + return R.ok(); } - /** - * 发送邮件(带附件) - * - * @param to 接收人 - * @param subject 标题 - * @param text 内容 - */ + @ApiOperation("发送邮件(带附件)") @GetMapping("/sendMessageWithAttachment") - public R sendMessageWithAttachment(String to, String subject, String text, String filePath) { - MailUtils.send(to, subject, text, false, new File(filePath)); - return R.ok("操作成功"); + 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-framework/src/main/java/com/ruoyi/framework/config/MailConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/MailConfig.java index d4ff8a7d5..20769aa19 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/MailConfig.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/MailConfig.java @@ -6,8 +6,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import javax.annotation.Resource; - /** * JavaMail 配置 * @@ -16,23 +14,21 @@ import javax.annotation.Resource; @Configuration public class MailConfig { - @Resource - private MailProperties mailProperties; - - /** - * 初始化 JavaMailSender - */ @Bean - @ConditionalOnProperty(value = "spring.mail.enabled", havingValue = "true") - public MailAccount mailAccount() { + @ConditionalOnProperty(value = "mail.enabled", havingValue = "true") + public MailAccount mailAccount(MailProperties mailProperties) { MailAccount account = new MailAccount(); - account.setFrom(mailProperties.getUsername()); - account.setUser(mailProperties.getUsername()); - account.setPass(mailProperties.getPassword()); + account.setHost(mailProperties.getHost()); account.setPort(mailProperties.getPort()); account.setAuth(mailProperties.getAuth()); - account.setDebug(mailProperties.getDebug()); + 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-framework/src/main/java/com/ruoyi/framework/config/properties/MailProperties.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/MailProperties.java index ce2103fea..66d3698c3 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/MailProperties.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/MailProperties.java @@ -1,7 +1,6 @@ package com.ruoyi.framework.config.properties; import lombok.Data; -import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; @@ -12,7 +11,7 @@ import org.springframework.stereotype.Component; */ @Data @Component -@ConfigurationProperties(prefix = "spring.mail") +@ConfigurationProperties(prefix = "mail") public class MailProperties { /** @@ -21,45 +20,52 @@ public class MailProperties { private String enabled; /** - * 邮件服务地址 + * SMTP服务器域名 */ private String host; /** - * 用户名 - */ - private String username; - - /** - * 授权码 (设置 - 账户 - POP3/SMTP服务) - */ - private String password; - - /** - * 邮箱加密端口,不同邮箱的端口不一样 + * SMTP服务端口 */ private Integer port; /** - * 是否需要用户认证 + * 是否需要用户名密码验证 */ - @Value("${spring.mail.properties.mail.smtp.auth}") private Boolean auth; /** - * 是否启用TLS加密 + * 用户名 */ - @Value("${spring.mail.properties.mail.smtp.starttls.enable}") - private Boolean starttlsEnable; - - @Value("${spring.mail.properties.mail.smtp.ssl.trust}") - private String sslTrust; - - private Boolean debug; + private String user; /** - * 传输协议 starttls.enable = true 时为 smtps + * 密码 */ - private String protocol; + 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; } From b01d45cf5c50082c1aad562a443a83a02811b395 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90li?= <15040126243@163.com> Date: Thu, 5 May 2022 15:07:23 +0800 Subject: [PATCH 012/112] =?UTF-8?q?add=20=E5=A2=9E=E5=8A=A0=20RedisUtils?= =?UTF-8?q?=20=E6=93=8D=E4=BD=9C=E5=8E=9F=E5=AD=90=E5=80=BC=E6=96=B9?= =?UTF-8?q?=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ruoyi/common/utils/redis/RedisUtils.java | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/redis/RedisUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/redis/RedisUtils.java index b0f35d878..7ed3b2827 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/redis/RedisUtils.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/redis/RedisUtils.java @@ -364,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(); + } + /** * 获得缓存的基本对象列表 * From 781ae8d5c89a0780356acb9541624ba33d598134 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90li?= <15040126243@163.com> Date: Fri, 6 May 2022 17:19:35 +0800 Subject: [PATCH 013/112] =?UTF-8?q?update=20=E4=BF=AE=E6=94=B9=E9=82=AE?= =?UTF-8?q?=E4=BB=B6=E5=BC=80=E5=85=B3=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/ruoyi/demo/controller/MailController.java | 5 ++--- .../ruoyi/framework/config/properties/MailProperties.java | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/MailController.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/MailController.java index 74e9e3398..6dabe5132 100644 --- a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/MailController.java +++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/MailController.java @@ -6,7 +6,6 @@ import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; @@ -22,9 +21,9 @@ import java.io.File; */ @Validated @Api(value = "邮件发送案例", tags = {"邮件发送案例"}) -@RequiredArgsConstructor(onConstructor_ = @Autowired) -@RequestMapping("/demo/mail") +@RequiredArgsConstructor @RestController +@RequestMapping("/demo/mail") public class MailController { @ApiOperation("发送邮件") diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/MailProperties.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/MailProperties.java index 66d3698c3..95e6cb8ba 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/MailProperties.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/MailProperties.java @@ -17,7 +17,7 @@ public class MailProperties { /** * 过滤开关 */ - private String enabled; + private Boolean enabled; /** * SMTP服务器域名 From e57d11d55a95ceafc793f714710d488bb1afc585 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90li?= <15040126243@163.com> Date: Fri, 6 May 2022 18:07:00 +0800 Subject: [PATCH 014/112] =?UTF-8?q?add=20=E5=A2=9E=E5=8A=A0=20ruoyi-sms=20?= =?UTF-8?q?=E7=9F=AD=E4=BF=A1=E6=A8=A1=E5=9D=97=20=E6=95=B4=E5=90=88=20?= =?UTF-8?q?=E9=98=BF=E9=87=8C=E4=BA=91=E3=80=81=E8=85=BE=E8=AE=AF=E4=BA=91?= =?UTF-8?q?=20=E7=9F=AD=E4=BF=A1=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 24 ++++++ .../src/main/resources/application-dev.yml | 12 +++ .../src/main/resources/application-prod.yml | 12 +++ ruoyi-sms/pom.xml | 40 ++++++++++ .../java/com/ruoyi/sms/config/SmsConfig.java | 44 ++++++++++ .../sms/config/properties/SmsProperties.java | 47 +++++++++++ .../com/ruoyi/sms/core/AliyunSmsTemplate.java | 65 +++++++++++++++ .../java/com/ruoyi/sms/core/SmsTemplate.java | 26 ++++++ .../ruoyi/sms/core/TencentSmsTemplate.java | 80 +++++++++++++++++++ .../java/com/ruoyi/sms/entity/SmsResult.java | 29 +++++++ .../com/ruoyi/sms/exception/SmsException.java | 16 ++++ 11 files changed, 395 insertions(+) create mode 100644 ruoyi-sms/pom.xml create mode 100644 ruoyi-sms/src/main/java/com/ruoyi/sms/config/SmsConfig.java create mode 100644 ruoyi-sms/src/main/java/com/ruoyi/sms/config/properties/SmsProperties.java create mode 100644 ruoyi-sms/src/main/java/com/ruoyi/sms/core/AliyunSmsTemplate.java create mode 100644 ruoyi-sms/src/main/java/com/ruoyi/sms/core/SmsTemplate.java create mode 100644 ruoyi-sms/src/main/java/com/ruoyi/sms/core/TencentSmsTemplate.java create mode 100644 ruoyi-sms/src/main/java/com/ruoyi/sms/entity/SmsResult.java create mode 100644 ruoyi-sms/src/main/java/com/ruoyi/sms/exception/SmsException.java diff --git a/pom.xml b/pom.xml index 4fc098f5b..bd822674a 100644 --- a/pom.xml +++ b/pom.xml @@ -50,6 +50,10 @@ 5.6.72 8.3.8 + + 2.0.9 + 3.1.500 + localhost http://${docker.registry.url}:2375 @@ -192,6 +196,18 @@ ${okhttp.version} + + com.aliyun + dysmsapi20170525 + ${aliyun.sms.version} + + + + com.tencentcloudapi + tencentcloud-sdk-java + ${tencent.sms.version} + + de.codecentric spring-boot-admin-starter-server @@ -297,6 +313,13 @@ ${ruoyi-vue-plus.version} + + + com.ruoyi + ruoyi-sms + ${ruoyi-vue-plus.version} + + com.ruoyi @@ -317,6 +340,7 @@ ruoyi-demo ruoyi-extend ruoyi-oss + ruoyi-sms pom diff --git a/ruoyi-admin/src/main/resources/application-dev.yml b/ruoyi-admin/src/main/resources/application-dev.yml index 6be268bf0..d14047f3f 100644 --- a/ruoyi-admin/src/main/resources/application-dev.yml +++ b/ruoyi-admin/src/main/resources/application-dev.yml @@ -178,3 +178,15 @@ mail: 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-admin/src/main/resources/application-prod.yml b/ruoyi-admin/src/main/resources/application-prod.yml index 4966a41e8..6619e0554 100644 --- a/ruoyi-admin/src/main/resources/application-prod.yml +++ b/ruoyi-admin/src/main/resources/application-prod.yml @@ -181,3 +181,15 @@ mail: 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-sms/pom.xml b/ruoyi-sms/pom.xml new file mode 100644 index 000000000..8550e8c75 --- /dev/null +++ b/ruoyi-sms/pom.xml @@ -0,0 +1,40 @@ + + + + ruoyi-vue-plus + com.ruoyi + 4.1.0 + + 4.0.0 + + ruoyi-sms + + + SMS短信模块 + + + + + + + com.ruoyi + ruoyi-common + + + + com.aliyun + dysmsapi20170525 + true + + + + com.tencentcloudapi + tencentcloud-sdk-java + true + + + + + diff --git a/ruoyi-sms/src/main/java/com/ruoyi/sms/config/SmsConfig.java b/ruoyi-sms/src/main/java/com/ruoyi/sms/config/SmsConfig.java new file mode 100644 index 000000000..abc4bb97c --- /dev/null +++ b/ruoyi-sms/src/main/java/com/ruoyi/sms/config/SmsConfig.java @@ -0,0 +1,44 @@ +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 +@ConditionalOnProperty(value = "sms.enabled", havingValue = "true") +public class SmsConfig { + + @Configuration + @ConditionalOnClass(com.aliyun.dysmsapi20170525.Client.class) + static class AliyunSmsConfig { + + @Bean + public SmsTemplate aliyunSmsTemplate(SmsProperties smsProperties) { + return new AliyunSmsTemplate(smsProperties); + } + + } + + @Configuration + @ConditionalOnClass(com.tencentcloudapi.sms.v20190711.SmsClient.class) + static class TencentSmsConfig { + + @Bean + public SmsTemplate tencentSmsTemplate(SmsProperties smsProperties) { + return new TencentSmsTemplate(smsProperties); + } + + } + +} diff --git a/ruoyi-sms/src/main/java/com/ruoyi/sms/config/properties/SmsProperties.java b/ruoyi-sms/src/main/java/com/ruoyi/sms/config/properties/SmsProperties.java new file mode 100644 index 000000000..39359cdfd --- /dev/null +++ b/ruoyi-sms/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-sms/src/main/java/com/ruoyi/sms/core/AliyunSmsTemplate.java b/ruoyi-sms/src/main/java/com/ruoyi/sms/core/AliyunSmsTemplate.java new file mode 100644 index 000000000..87c3f3bdb --- /dev/null +++ b/ruoyi-sms/src/main/java/com/ruoyi/sms/core/AliyunSmsTemplate.java @@ -0,0 +1,65 @@ +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); + } + + 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-sms/src/main/java/com/ruoyi/sms/core/SmsTemplate.java b/ruoyi-sms/src/main/java/com/ruoyi/sms/core/SmsTemplate.java new file mode 100644 index 000000000..0aec3ddbe --- /dev/null +++ b/ruoyi-sms/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-sms/src/main/java/com/ruoyi/sms/core/TencentSmsTemplate.java b/ruoyi-sms/src/main/java/com/ruoyi/sms/core/TencentSmsTemplate.java new file mode 100644 index 000000000..ce82c3c69 --- /dev/null +++ b/ruoyi-sms/src/main/java/com/ruoyi/sms/core/TencentSmsTemplate.java @@ -0,0 +1,80 @@ +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); + } + + 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-sms/src/main/java/com/ruoyi/sms/entity/SmsResult.java b/ruoyi-sms/src/main/java/com/ruoyi/sms/entity/SmsResult.java new file mode 100644 index 000000000..3f13b2774 --- /dev/null +++ b/ruoyi-sms/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-sms/src/main/java/com/ruoyi/sms/exception/SmsException.java b/ruoyi-sms/src/main/java/com/ruoyi/sms/exception/SmsException.java new file mode 100644 index 000000000..28632a375 --- /dev/null +++ b/ruoyi-sms/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); + } + +} From 416088a2ded29ab7782b213e98c5f914852febce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90li?= <15040126243@163.com> Date: Fri, 6 May 2022 18:07:43 +0800 Subject: [PATCH 015/112] =?UTF-8?q?add=20=E5=A2=9E=E5=8A=A0=20demo=20?= =?UTF-8?q?=E7=9F=AD=E4=BF=A1=E6=BC=94=E7=A4=BA=E6=A1=88=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ruoyi-demo/pom.xml | 16 ++++++ .../ruoyi/demo/controller/SmsController.java | 53 +++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 ruoyi-demo/src/main/java/com/ruoyi/demo/controller/SmsController.java diff --git a/ruoyi-demo/pom.xml b/ruoyi-demo/pom.xml index 2fe2c184e..ca5d965f4 100644 --- a/ruoyi-demo/pom.xml +++ b/ruoyi-demo/pom.xml @@ -23,6 +23,22 @@ ruoyi-common + + com.ruoyi + ruoyi-sms + + + + + + + + + + com.tencentcloudapi + tencentcloud-sdk-java + + diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/SmsController.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/SmsController.java new file mode 100644 index 000000000..de8f212b2 --- /dev/null +++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/SmsController.java @@ -0,0 +1,53 @@ +package com.ruoyi.demo.controller; + +import com.ruoyi.common.core.domain.R; +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 SmsTemplate smsTemplate; + + @ApiOperation("发送短信Aliyun") + @GetMapping("/sendAliyun") + public R sendSimpleMessage(@ApiParam("电话号") String phones, + @ApiParam("模板ID") String templateId) { + 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 sendMessageWithAttachment(@ApiParam("电话号") String phones, + @ApiParam("模板ID") String templateId) { + Map map = new HashMap<>(1); +// map.put("2", "测试测试"); + map.put("1", "1234"); + Object send = smsTemplate.send(phones, templateId, map); + return R.ok(send); + } + +} From 71e392c1f9e73a5c8fbc3b1141495afbb0307ef0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90li?= <15040126243@163.com> Date: Fri, 6 May 2022 18:08:16 +0800 Subject: [PATCH 016/112] =?UTF-8?q?add=20=E5=A2=9E=E5=8A=A0=20=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=E7=9F=AD=E4=BF=A1=E9=AA=8C=E8=AF=81=E7=A0=81=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/common/CaptchaController.java | 24 +++++++++++++++++++ .../src/main/resources/application.yml | 1 + ruoyi-system/pom.xml | 6 +++++ .../ruoyi/system/service/SysLoginService.java | 12 ++++++---- ruoyi-ui/src/api/login.js | 12 ++++++++++ 5 files changed, 51 insertions(+), 4 deletions(-) diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java index 2b9917f7c..95acba2cd 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java @@ -4,6 +4,7 @@ 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.constant.Constants; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.enums.CaptchaType; @@ -12,13 +13,17 @@ 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.system.service.ISysConfigService; 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.RestController; +import javax.validation.constraints.NotBlank; import java.time.Duration; import java.util.HashMap; import java.util.Map; @@ -28,14 +33,33 @@ import java.util.Map; * * @author Lion Li */ +@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)); + return R.ok(); + } + /** * 生成验证码 */ diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml index c692fc267..56076b3b6 100644 --- a/ruoyi-admin/src/main/resources/application.yml +++ b/ruoyi-admin/src/main/resources/application.yml @@ -124,6 +124,7 @@ security: - /logout - /register - /captchaImage + - /captchaSms # 静态资源 - /*.html - /**/*.html diff --git a/ruoyi-system/pom.xml b/ruoyi-system/pom.xml index 57ec06c08..5e243aa10 100644 --- a/ruoyi-system/pom.xml +++ b/ruoyi-system/pom.xml @@ -29,6 +29,12 @@ ruoyi-oss + + + com.ruoyi + ruoyi-sms + + diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/SysLoginService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/SysLoginService.java index f60419f05..7b42952de 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/SysLoginService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/SysLoginService.java @@ -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.isNotBlank(code)) { + asyncService.recordLogininfor(phonenumber, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"), request); + throw new CaptchaExpireException(); + } + return code.equals(smsCode); } /** diff --git a/ruoyi-ui/src/api/login.js b/ruoyi-ui/src/api/login.js index 0327e6f9a..3c5bcfe21 100644 --- a/ruoyi-ui/src/api/login.js +++ b/ruoyi-ui/src/api/login.js @@ -57,3 +57,15 @@ export function getCodeImg() { timeout: 20000 }) } + +// 短信验证码 +export function getCodeSms() { + return request({ + url: '/captchaSms', + headers: { + isToken: false + }, + method: 'get', + timeout: 20000 + }) +} From 44a8025e0f080839ac5cec9d1420fa381559fa03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90li?= <15040126243@163.com> Date: Fri, 6 May 2022 18:15:31 +0800 Subject: [PATCH 017/112] =?UTF-8?q?update=20=E6=9B=B4=E6=AD=A3=20=E7=9F=AD?= =?UTF-8?q?=E4=BF=A1=E6=BC=94=E7=A4=BA=E6=A1=88=E4=BE=8B=20=E6=96=B9?= =?UTF-8?q?=E6=B3=95=E5=91=BD=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/ruoyi/demo/controller/SmsController.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/SmsController.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/SmsController.java index de8f212b2..51472de2b 100644 --- a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/SmsController.java +++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/SmsController.java @@ -31,7 +31,7 @@ public class SmsController { @ApiOperation("发送短信Aliyun") @GetMapping("/sendAliyun") - public R sendSimpleMessage(@ApiParam("电话号") String phones, + public R sendAliyun(@ApiParam("电话号") String phones, @ApiParam("模板ID") String templateId) { Map map = new HashMap<>(1); map.put("code", "1234"); @@ -41,7 +41,7 @@ public class SmsController { @ApiOperation("发送短信Tencent") @GetMapping("/sendTencent") - public R sendMessageWithAttachment(@ApiParam("电话号") String phones, + public R sendTencent(@ApiParam("电话号") String phones, @ApiParam("模板ID") String templateId) { Map map = new HashMap<>(1); // map.put("2", "测试测试"); From d2fe2a7fc5d64241a963c8fcd7e7715930b65a47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90li?= <15040126243@163.com> Date: Sat, 7 May 2022 09:39:11 +0800 Subject: [PATCH 018/112] =?UTF-8?q?fix=20=E4=BF=AE=E5=A4=8D=20=E8=85=BE?= =?UTF-8?q?=E8=AE=AF=E7=9F=AD=E4=BF=A1=20=E4=B8=8E=20minio=20okhttp?= =?UTF-8?q?=E4=BE=9D=E8=B5=96=E5=86=B2=E7=AA=81=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pom.xml b/pom.xml index bd822674a..b5e00a9fa 100644 --- a/pom.xml +++ b/pom.xml @@ -206,6 +206,12 @@ com.tencentcloudapi tencentcloud-sdk-java ${tencent.sms.version} + + + com.squareup.okio + okio + + From 5e6a895fef92840dea31b76ef06d9f4986d3d581 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90li?= <15040126243@163.com> Date: Sat, 7 May 2022 10:30:46 +0800 Subject: [PATCH 019/112] =?UTF-8?q?update=20=E6=9B=B4=E6=96=B0=20readme=20?= =?UTF-8?q?=E7=9F=AD=E4=BF=A1=E6=A8=A1=E5=9D=97=E8=AF=B4=E6=98=8E=20?= =?UTF-8?q?=E4=B8=8E=20=E6=96=87=E6=A1=A3=E5=9C=B0=E5=9D=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 203a03dbc..ee0f24aba 100644 --- a/README.md +++ b/README.md @@ -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) | 性能优异 扩展性强 | From 7d1d3d3f05f24ab8e0371c3158c0bb8edee57ec2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90li?= <15040126243@163.com> Date: Sat, 7 May 2022 11:18:14 +0800 Subject: [PATCH 020/112] =?UTF-8?q?update=20=E5=AE=8C=E5=96=84=E7=9F=AD?= =?UTF-8?q?=E4=BF=A1=E9=AA=8C=E8=AF=81=E7=A0=81=E5=8F=91=E9=80=81=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/ruoyi/web/controller/common/CaptchaController.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java index 95acba2cd..fdfd3e253 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java @@ -14,6 +14,7 @@ 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.system.service.ISysConfigService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -41,6 +42,7 @@ public class CaptchaController { private final CaptchaProperties captchaProperties; private final SmsProperties smsProperties; + private final SmsTemplate smsTemplate; private final ISysConfigService configService; /** @@ -57,6 +59,11 @@ public class CaptchaController { 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.send(phonenumber, templateId, map); return R.ok(); } From c40aa1f950a696b541616960f9470f664337e7ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90li?= <15040126243@163.com> Date: Sat, 7 May 2022 11:22:46 +0800 Subject: [PATCH 021/112] =?UTF-8?q?update=20=E5=AE=8C=E5=96=84=E7=9F=AD?= =?UTF-8?q?=E4=BF=A1=E9=AA=8C=E8=AF=81=E7=A0=81=E5=8F=91=E9=80=81=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ruoyi/web/controller/common/CaptchaController.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java index fdfd3e253..8feaca916 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java @@ -15,11 +15,13 @@ 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; @@ -34,6 +36,7 @@ import java.util.Map; * * @author Lion Li */ +@Slf4j @Validated @Api(value = "验证码操作处理", tags = {"验证码管理"}) @RequiredArgsConstructor @@ -63,7 +66,11 @@ public class CaptchaController { String templateId = ""; Map map = new HashMap<>(1); map.put("code", code); - smsTemplate.send(phonenumber, templateId, map); + SmsResult result = smsTemplate.send(phonenumber, templateId, map); + if (!result.isSuccess()) { + log.error("验证码短信发送异常 => {}", result); + return R.fail(result.getMessage()); + } return R.ok(); } From ce14b5e9fb0ac17e7e41996620ccb48b73375788 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90li?= <15040126243@163.com> Date: Sat, 7 May 2022 15:10:58 +0800 Subject: [PATCH 022/112] =?UTF-8?q?fix=20=E4=BF=AE=E5=A4=8D=20=E5=85=B3?= =?UTF-8?q?=E9=97=AD=E7=9F=AD=E4=BF=A1=E5=8A=9F=E8=83=BD=20=E6=89=BE?= =?UTF-8?q?=E4=B8=8D=E5=88=B0bean=E5=BC=82=E5=B8=B8=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../web/controller/common/CaptchaController.java | 2 +- .../com/ruoyi/demo/controller/SmsController.java | 13 ++++++++++++- .../main/java/com/ruoyi/sms/config/SmsConfig.java | 3 ++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java index 8feaca916..aa55c925d 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java @@ -45,7 +45,6 @@ public class CaptchaController { private final CaptchaProperties captchaProperties; private final SmsProperties smsProperties; - private final SmsTemplate smsTemplate; private final ISysConfigService configService; /** @@ -66,6 +65,7 @@ public class CaptchaController { 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); diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/SmsController.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/SmsController.java index 51472de2b..833144534 100644 --- a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/SmsController.java +++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/SmsController.java @@ -1,6 +1,8 @@ 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; @@ -27,12 +29,17 @@ import java.util.Map; @RequestMapping("/demo/sms") public class SmsController { - private final SmsTemplate smsTemplate; + private final SmsProperties smsProperties; +// private final SmsTemplate smsTemplate; // 可以使用spring注入 @ApiOperation("发送短信Aliyun") @GetMapping("/sendAliyun") public R sendAliyun(@ApiParam("电话号") String phones, @ApiParam("模板ID") String templateId) { + if (smsProperties.getEnabled()) { + R.fail("当前系统没有开启短信功能!"); + } + SmsTemplate smsTemplate = SpringUtils.getBean(SmsTemplate.class); Map map = new HashMap<>(1); map.put("code", "1234"); Object send = smsTemplate.send(phones, templateId, map); @@ -43,6 +50,10 @@ public class SmsController { @GetMapping("/sendTencent") public R sendTencent(@ApiParam("电话号") String phones, @ApiParam("模板ID") String templateId) { + if (smsProperties.getEnabled()) { + R.fail("当前系统没有开启短信功能!"); + } + SmsTemplate smsTemplate = SpringUtils.getBean(SmsTemplate.class); Map map = new HashMap<>(1); // map.put("2", "测试测试"); map.put("1", "1234"); diff --git a/ruoyi-sms/src/main/java/com/ruoyi/sms/config/SmsConfig.java b/ruoyi-sms/src/main/java/com/ruoyi/sms/config/SmsConfig.java index abc4bb97c..753773e87 100644 --- a/ruoyi-sms/src/main/java/com/ruoyi/sms/config/SmsConfig.java +++ b/ruoyi-sms/src/main/java/com/ruoyi/sms/config/SmsConfig.java @@ -16,10 +16,10 @@ import org.springframework.context.annotation.Configuration; * @version 4.2.0 */ @Configuration -@ConditionalOnProperty(value = "sms.enabled", havingValue = "true") public class SmsConfig { @Configuration + @ConditionalOnProperty(value = "sms.enabled", havingValue = "true") @ConditionalOnClass(com.aliyun.dysmsapi20170525.Client.class) static class AliyunSmsConfig { @@ -31,6 +31,7 @@ public class SmsConfig { } @Configuration + @ConditionalOnProperty(value = "sms.enabled", havingValue = "true") @ConditionalOnClass(com.tencentcloudapi.sms.v20190711.SmsClient.class) static class TencentSmsConfig { From f9131832c73196dddddc5c2e81a3c76a51fa234c Mon Sep 17 00:00:00 2001 From: SPPan Date: Sat, 7 May 2022 15:17:08 +0800 Subject: [PATCH 023/112] =?UTF-8?q?=E7=9F=AD=E4=BF=A1=E9=AA=8C=E8=AF=81?= =?UTF-8?q?=E7=A0=81=E6=A0=A1=E9=AA=8C=E9=80=BB=E8=BE=91BUG=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/ruoyi/system/service/SysLoginService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/SysLoginService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/SysLoginService.java index 7b42952de..440bca5d3 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/SysLoginService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/SysLoginService.java @@ -123,7 +123,7 @@ public class SysLoginService { */ private boolean validateSmsCode(String phonenumber, String smsCode, HttpServletRequest request) { String code = RedisUtils.getCacheObject(Constants.CAPTCHA_CODE_KEY + phonenumber); - if (StringUtils.isNotBlank(code)) { + if (StringUtils.isBlank(code)) { asyncService.recordLogininfor(phonenumber, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"), request); throw new CaptchaExpireException(); } From 1c41b701dd3aa904020309223738a446e52882a8 Mon Sep 17 00:00:00 2001 From: RuoYi Date: Mon, 9 May 2022 17:37:33 +0800 Subject: [PATCH 024/112] =?UTF-8?q?=E4=BC=98=E5=8C=96excel=E5=88=9B?= =?UTF-8?q?=E5=BB=BA=E8=A1=A8=E6=A0=BC=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/ruoyi/common/utils/poi/ExcelUtil.java | 70 +++++++++++-------- 1 file changed, 41 insertions(+), 29 deletions(-) diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java index 4fc3ff4fc..e868511aa 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java @@ -672,6 +672,46 @@ public class ExcelUtil style.setFont(totalFont); styles.put("total", style); + styles.putAll(annotationStyles(wb)); + + return styles; + } + + /** + * 根据Excel注解创建表格样式 + * + * @param wb 工作薄对象 + * @return 自定义样式列表 + */ + private Map annotationStyles(Workbook wb) + { + Map styles = new HashMap(); + for (Object[] os : fields) + { + Excel excel = (Excel) os[1]; + String key = "data_" + excel.align() + "_" + excel.color(); + if (!styles.containsKey(key)) + { + CellStyle style = wb.createCellStyle(); + style = wb.createCellStyle(); + style.setAlignment(excel.align()); + style.setVerticalAlignment(VerticalAlignment.CENTER); + style.setBorderRight(BorderStyle.THIN); + style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderLeft(BorderStyle.THIN); + style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderTop(BorderStyle.THIN); + style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderBottom(BorderStyle.THIN); + style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + Font dataFont = wb.createFont(); + dataFont.setFontName("Arial"); + dataFont.setFontHeightInPoints((short) 10); + dataFont.setColor(excel.color().index); + style.setFont(dataFont); + styles.put(key, style); + } + } return styles; } @@ -793,7 +833,7 @@ public class ExcelUtil { // 创建cell cell = row.createCell(column); - setDataCell(cell, attr); + cell.setCellStyle(styles.get("data_" + attr.align() + "_" + attr.color())); // 用于读取对象中的属性 Object value = getTargetValue(vo, field, attr); @@ -836,34 +876,6 @@ public class ExcelUtil return cell; } - /** - * 设置单元格样式 - * - * @param cell 单元格 - * @param excel 注解信息 - */ - public void setDataCell(Cell cell, Excel excel) - { - CellStyle style = wb.createCellStyle(); - style.setAlignment(HorizontalAlignment.CENTER); - style.setVerticalAlignment(VerticalAlignment.CENTER); - style.setBorderRight(BorderStyle.THIN); - style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); - style.setBorderLeft(BorderStyle.THIN); - style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); - style.setBorderTop(BorderStyle.THIN); - style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); - style.setBorderBottom(BorderStyle.THIN); - style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); - style.setAlignment(excel.align()); - Font dataFont = wb.createFont(); - dataFont.setFontName("Arial"); - dataFont.setFontHeightInPoints((short) 10); - dataFont.setColor(excel.color().index); - style.setFont(dataFont); - cell.setCellStyle(style); - } - /** * 设置 POI XSSFSheet 单元格提示或选择框 * From 0055f479cb5b4eeaa75f5e3ee324c963e3a76a5c Mon Sep 17 00:00:00 2001 From: RuoYi Date: Mon, 9 May 2022 20:27:09 +0800 Subject: [PATCH 025/112] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=AD=97=E5=85=B8?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E6=98=BE=E7=A4=BA=E4=B8=8D=E5=85=A8=E9=97=AE?= =?UTF-8?q?=E9=A2=98(I55MR3)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ruoyi-ui/src/views/system/dict/data.vue | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ruoyi-ui/src/views/system/dict/data.vue b/ruoyi-ui/src/views/system/dict/data.vue index 2bd8cbb5c..1d0be70a5 100644 --- a/ruoyi-ui/src/views/system/dict/data.vue +++ b/ruoyi-ui/src/views/system/dict/data.vue @@ -191,7 +191,7 @@ diff --git a/ruoyi-ui/src/components/ImageUpload/index.vue b/ruoyi-ui/src/components/ImageUpload/index.vue index 2d1ed577c..62199795d 100644 --- a/ruoyi-ui/src/components/ImageUpload/index.vue +++ b/ruoyi-ui/src/components/ImageUpload/index.vue @@ -44,7 +44,7 @@ From f668089e64c31653c8dace04cab32ef168423fe5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90Li?= <15040126243@163.com> Date: Fri, 13 May 2022 00:24:49 +0800 Subject: [PATCH 037/112] =?UTF-8?q?fix=20=E4=BF=AE=E5=A4=8D=20TestDemo=20?= =?UTF-8?q?=E7=9A=84=20bo=20=E5=92=8C=20vo=20=E4=B8=8E=20entity=20?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E7=B1=BB=E5=9E=8B=E4=B8=8D=E5=8C=B9=E9=85=8D?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/ruoyi/demo/domain/bo/TestDemoBo.java | 2 +- .../src/main/java/com/ruoyi/demo/domain/vo/TestDemoVo.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/bo/TestDemoBo.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/bo/TestDemoBo.java index 5c41204d7..61c10ab16 100644 --- a/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/bo/TestDemoBo.java +++ b/ruoyi-demo/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-demo/src/main/java/com/ruoyi/demo/domain/vo/TestDemoVo.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/vo/TestDemoVo.java index ef26ff325..1e896500d 100644 --- a/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/vo/TestDemoVo.java +++ b/ruoyi-demo/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键 From 3a918ae8f6009dac395202b874c5c874f2c24b3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90li?= <15040126243@163.com> Date: Fri, 13 May 2022 09:37:34 +0800 Subject: [PATCH 038/112] =?UTF-8?q?update=20=E8=B0=83=E6=95=B4=20CacheMana?= =?UTF-8?q?ger=20=E4=BD=BF=E7=94=A8=E7=B3=BB=E7=BB=9F=20=E7=B3=BB=E7=BB=9F?= =?UTF-8?q?=E5=BA=8F=E5=88=97=E5=8C=96=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/ruoyi/framework/config/RedisConfig.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/RedisConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/RedisConfig.java index d8cbba25d..8364c646f 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/RedisConfig.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/RedisConfig.java @@ -1,7 +1,7 @@ package com.ruoyi.framework.config; import cn.hutool.core.util.ObjectUtil; -import com.ruoyi.common.utils.JsonUtils; +import com.fasterxml.jackson.databind.ObjectMapper; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.framework.config.properties.RedissonProperties; import lombok.extern.slf4j.Slf4j; @@ -44,9 +44,12 @@ public class RedisConfig extends CachingConfigurerSupport { @Autowired private RedissonProperties redissonProperties; + @Autowired + private ObjectMapper objectMapper; + @Primary @Bean(destroyMethod = "shutdown") - public RedissonClient redisson() { + public RedissonClient redisson(RedisProperties redisProperties, RedissonProperties redissonProperties, ObjectMapper objectMapper) { String prefix = REDIS_PROTOCOL_PREFIX; if (redisProperties.isSsl()) { prefix = REDISS_PROTOCOL_PREFIX; @@ -54,7 +57,7 @@ public class RedisConfig extends CachingConfigurerSupport { Config config = new Config(); config.setThreads(redissonProperties.getThreads()) .setNettyThreads(redissonProperties.getNettyThreads()) - .setCodec(new JsonJacksonCodec(JsonUtils.getObjectMapper())); + .setCodec(new JsonJacksonCodec(objectMapper)); RedissonProperties.SingleServerConfig singleServerConfig = redissonProperties.getSingleServerConfig(); if (ObjectUtil.isNotNull(singleServerConfig)) { @@ -113,7 +116,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)); } /** From 6a69be88c52d374d36a2538d81f75af60737594c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90li?= <15040126243@163.com> Date: Fri, 13 May 2022 09:41:54 +0800 Subject: [PATCH 039/112] =?UTF-8?q?update=20=E8=B0=83=E6=95=B4=20=E5=9B=BE?= =?UTF-8?q?=E7=89=87=E9=A2=84=E8=A7=88=E7=BB=84=E4=BB=B6=20=E5=8E=BB?= =?UTF-8?q?=E9=99=A4=E6=97=A0=E7=94=A8=E6=A0=B9=E7=9B=AE=E5=BD=95=E6=8B=BC?= =?UTF-8?q?=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ruoyi-ui/src/components/ImagePreview/index.vue | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/ruoyi-ui/src/components/ImagePreview/index.vue b/ruoyi-ui/src/components/ImagePreview/index.vue index 743d8d51d..671eda323 100644 --- a/ruoyi-ui/src/components/ImagePreview/index.vue +++ b/ruoyi-ui/src/components/ImagePreview/index.vue @@ -12,7 +12,6 @@