From fff78232a2b9912611e5e101e480ce071277c249 Mon Sep 17 00:00:00 2001 From: MagicJson Date: Fri, 12 Jul 2024 15:28:03 +0800 Subject: [PATCH 1/2] =?UTF-8?q?1.DateUtils=E6=8F=90=E5=8D=87parseDateToStr?= =?UTF-8?q?=E6=80=A7=E8=83=BD=E4=B8=8E=E5=AE=89=E5=85=A8=E6=80=A7=202.Exce?= =?UTF-8?q?ptionUtil=E4=BD=BF=E7=94=A8try-with-resources=E5=85=B3=E9=97=AD?= =?UTF-8?q?=E9=9C=80=E8=A6=81=E5=85=B3=E9=97=AD=E7=9A=84=E6=B5=81=203.?= =?UTF-8?q?=E8=A7=A3=E5=86=B3=E4=BD=BF=E7=94=A8@Excel=E5=AD=97=E5=85=B8?= =?UTF-8?q?=E5=80=BC=E5=B1=9E=E6=80=A7=E6=97=B6=EF=BC=8C=E5=AF=BC=E5=85=A5?= =?UTF-8?q?=E5=AF=BC=E5=87=BA=E5=8A=9F=E8=83=BD=E4=B8=AD=E5=BD=93=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E4=B8=8A=E9=80=81=E5=AD=97=E5=85=B8=E5=80=BC=E4=BC=9A?= =?UTF-8?q?=E5=AF=BC=E8=87=B4=E4=BD=BF=E7=94=A8=E8=AF=A5=E5=AD=97=E5=85=B8?= =?UTF-8?q?=E5=80=BC=E7=9A=84=E5=AD=97=E6=AE=B5=E8=AE=BE=E7=BD=AE=E4=B8=8D?= =?UTF-8?q?=E4=BA=86=E5=B8=8C=E6=9C=9B=E8=AE=BE=E7=BD=AE=E7=9A=84=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/ruoyi/common/utils/DateUtils.java | 82 +++++++--- .../com/ruoyi/common/utils/DictUtils.java | 150 +++++++++++------- .../com/ruoyi/common/utils/ExceptionUtil.java | 11 +- 3 files changed, 155 insertions(+), 88 deletions(-) diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java index 20dbbb746..5b33facdd 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java @@ -1,38 +1,40 @@ package com.ruoyi.common.utils; +import org.apache.commons.lang3.time.DateFormatUtils; + import java.lang.management.ManagementFactory; import java.text.ParseException; import java.text.SimpleDateFormat; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.LocalTime; -import java.time.ZoneId; -import java.time.ZonedDateTime; +import java.time.*; +import java.time.format.DateTimeFormatter; import java.util.Date; -import org.apache.commons.lang3.time.DateFormatUtils; +import java.util.concurrent.ConcurrentHashMap; /** * 时间工具类 * * @author ruoyi */ -public class DateUtils extends org.apache.commons.lang3.time.DateUtils +public final class DateUtils extends org.apache.commons.lang3.time.DateUtils { - public static String YYYY = "yyyy"; - public static String YYYY_MM = "yyyy-MM"; + public static final String YYYY_MM_DD = "yyyy-MM-dd"; - public static String YYYY_MM_DD = "yyyy-MM-dd"; + public static final String YYYYMMDDHHMMSS = "yyyyMMddHHmmss"; - public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss"; - - public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss"; + public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss"; private static String[] parsePatterns = { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM", "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM", "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"}; + /** + * 线程安全的 Map,用于缓存不同格式的 DateTimeFormatter 实例 + * 建议构建时间日期格式类工具时使用 + */ + private static final ConcurrentHashMap datetimeFormatterMap = new ConcurrentHashMap<>(); + /** * 获取当前Date型日期 * @@ -53,32 +55,64 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils return dateTimeNow(YYYY_MM_DD); } - public static final String getTime() + public static String getTime() { return dateTimeNow(YYYY_MM_DD_HH_MM_SS); } - public static final String dateTimeNow() + public static String dateTimeNow() { return dateTimeNow(YYYYMMDDHHMMSS); } - public static final String dateTimeNow(final String format) + public static String dateTimeNow(final String format) { return parseDateToStr(format, new Date()); } - public static final String dateTime(final Date date) + public static String dateTime(final Date date) { return parseDateToStr(YYYY_MM_DD, date); } - - public static final String parseDateToStr(final String format, final Date date) - { - return new SimpleDateFormat(format).format(date); + /** + * 将 java.util.Date 对象格式化为指定格式的字符串。 + * + * @param format 日期时间格式字符串 + * @param date 要格式化的 java.util.Date 对象 + * @return 格式化后的日期时间字符串 + */ + public static String parseDateToStr(final String format, final Date date){ + return toLocalDateTime(date).format(getDateTimeFormatter(format)); } - public static final Date dateTime(final String format, final String ts) + /** + * 将 java.util.Date 对象转换为 java.time.LocalDateTime 对象。 + * + * @param date 要转换的 java.util.Date 对象 + * @return 转换后的 java.time.LocalDateTime 对象 + */ + public static LocalDateTime toLocalDateTime(Date date) { + // 将 java.util.Date 对象转换为 java.time.Instant 对象 + return date.toInstant() + // 将 Instant 对象转化为带有时区信息的 ZonedDateTime 对象,时区使用系统默认时区 + .atZone(ZoneId.systemDefault()) + // 将 ZonedDateTime 对象转换为 LocalDateTime 对象 + .toLocalDateTime(); + } + + /** + * 获取指定格式的 DateTimeFormatter 实例。 + * 如果指定格式的 DateTimeFormatter 不存在,则创建并缓存它。 + * + * @param format 日期时间格式字符串 + * @return 指定格式的 DateTimeFormatter 实例 + */ + public static DateTimeFormatter getDateTimeFormatter(String format){ + return datetimeFormatterMap.computeIfAbsent(format, DateTimeFormatter::ofPattern); + } + + + public static Date dateTime(final String format, final String ts) { try { @@ -93,7 +127,7 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils /** * 日期路径 即年/月/日 如2018/08/08 */ - public static final String datePath() + public static String datePath() { Date now = new Date(); return DateFormatUtils.format(now, "yyyy/MM/dd"); @@ -102,7 +136,7 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils /** * 日期路径 即年/月/日 如20180808 */ - public static final String dateTime() + public static String dateTime() { Date now = new Date(); return DateFormatUtils.format(now, "yyyyMMdd"); diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/DictUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/DictUtils.java index ad0dd5411..bd028d108 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/DictUtils.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/DictUtils.java @@ -1,9 +1,14 @@ package com.ruoyi.common.utils; -import java.util.List; -import org.springframework.stereotype.Component; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.core.domain.entity.SysDictData; +import com.ruoyi.common.utils.reflect.ReflectUtils; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; +import java.util.stream.Stream; /** * 字典工具类 @@ -17,7 +22,8 @@ public class DictUtils * 分隔符 */ public static final String SEPARATOR = ","; - + public static final String DICT_LABEL = "dictLabel"; + public static final String DICT_VALUE = "dictValue"; /** * 设置字典缓存 * @@ -79,7 +85,7 @@ public class DictUtils /** * 根据字典类型和字典值获取字典标签 - * + * * @param dictType 字典类型 * @param dictValue 字典值 * @param separator 分隔符 @@ -87,37 +93,7 @@ public class DictUtils */ public static String getDictLabel(String dictType, String dictValue, String separator) { - StringBuilder propertyString = new StringBuilder(); - List datas = getDictCache(dictType); - if (StringUtils.isNull(datas)) - { - return StringUtils.EMPTY; - } - if (StringUtils.containsAny(dictValue, separator)) - { - for (SysDictData dict : datas) - { - for (String value : dictValue.split(separator)) - { - if (value.equals(dict.getDictValue())) - { - propertyString.append(dict.getDictLabel()).append(separator); - break; - } - } - } - } - else - { - for (SysDictData dict : datas) - { - if (dictValue.equals(dict.getDictValue())) - { - return dict.getDictLabel(); - } - } - } - return StringUtils.stripEnd(propertyString.toString(), separator); + return getDictElement(dictType, dictValue, separator, DICT_LABEL); } /** @@ -130,37 +106,89 @@ public class DictUtils */ public static String getDictValue(String dictType, String dictLabel, String separator) { - StringBuilder propertyString = new StringBuilder(); - List datas = getDictCache(dictType); - if (StringUtils.isNull(datas)) - { + return getDictElement(dictType, dictLabel, separator,DICT_VALUE); + } + + + /** + * 根据字典类型和字典条件获取字典内容 + * + * @param dictType 字典类型 + * @param dictCondition 字典条件(字典标签或字典值) + * @param separator 分隔符 + * @return 字典内容 + */ + public static String getDictElement(String dictType, String dictCondition + , String separator, String filedAttr) { + // 获取字典缓存 + List dictData = getDictCache(dictType); + if (StringUtils.isNull(dictData)) { return StringUtils.EMPTY; } - if (StringUtils.containsAny(dictLabel, separator)) - { - for (SysDictData dict : datas) - { - for (String label : dictLabel.split(separator)) - { - if (label.equals(dict.getDictLabel())) - { - propertyString.append(dict.getDictValue()).append(separator); - break; - } - } + // 处理单个标签的情况 + if (!StringUtils.containsAny(dictCondition, separator)) { + return getSingleDictElement(dictData, dictCondition, filedAttr); + } + // 处理多个标签的情况 + return getMultipleDictElements(dictData, dictCondition, separator, filedAttr); + } + /** + * 获取字典元素 + * + * @param dictData 字典数据列表 + * @param dictCondition 条件值 + * @param dictAttr 字典属性 + * @return 符合条件的字典属性值,未找到返回空字符串 + */ + private static String getDictElement(List dictData, String dictCondition, String dictAttr) { + // 遍历字典数据 + for (SysDictData dict : dictData) { + // 判断需要转换的字典属性是DICT_LABEL还是DICT_VALUE + String dictTransV = Objects.equals(DICT_LABEL, dictAttr) ? DICT_VALUE : DICT_LABEL; + // 获取转换后的字典属性值 + String retValue = ReflectUtils.invokeGetter(dict, dictTransV); + // 如果转换后的值和条件值相等,则返回所需的字典属性值 + if (Objects.equals(dictCondition, retValue)) { + return ReflectUtils.invokeGetter(dict, dictAttr); } } - else - { - for (SysDictData dict : datas) - { - if (dictLabel.equals(dict.getDictLabel())) - { - return dict.getDictValue(); - } - } + return StringUtils.EMPTY; // 没有找到匹配的标签,返回空字符串 + } + + /** + * 获取单个字典元素 + * + * @param dictData 字典数据列表 + * @param dictCondition 条件值 + * @param dictAttr 字典属性 + * @return 符合条件的字典属性值 + */ + private static String getSingleDictElement(List dictData, String dictCondition, String dictAttr) { + // 如果字典属性是DICT_VALUE并且条件是数字,则直接返回条件 + if (Objects.equals(DICT_VALUE, dictAttr) && StringUtils.isNumeric(dictCondition)) { + return dictCondition; } - return StringUtils.stripEnd(propertyString.toString(), separator); + return getDictElement(dictData, dictCondition, dictAttr); + } + + /** + * 处理多个标签的情况 + * + * @param dictData 字典数据列表 + * @param dictCondition 标签条件 + * @param separator 分隔符 + * @param dictAttr 字典属性 + * @return 拼接的字典值 + */ + private static String getMultipleDictElements(List dictData, String dictCondition, String separator, String dictAttr) { + // 分割条件值,得到多个条件 + String[] conditions = dictCondition.split(separator); + + // 使用Stream处理多个条件 + return Stream.of(conditions) + .map(condition -> getDictElement(dictData, condition, dictAttr)) + .filter(StringUtils::isNotEmpty) // 过滤掉空值 + .collect(Collectors.joining(separator)); // 拼接结果 } /** diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/ExceptionUtil.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/ExceptionUtil.java index 50b10fe89..2a2dc02c9 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/ExceptionUtil.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/ExceptionUtil.java @@ -1,8 +1,9 @@ package com.ruoyi.common.utils; +import org.apache.commons.lang3.exception.ExceptionUtils; + import java.io.PrintWriter; import java.io.StringWriter; -import org.apache.commons.lang3.exception.ExceptionUtils; /** * 错误信息处理类。 @@ -16,9 +17,13 @@ public class ExceptionUtil */ public static String getExceptionMessage(Throwable e) { + // StringWriter#close()关闭是否都可以 但放入try-with-resources还需要处理抛出的IO异常 StringWriter sw = new StringWriter(); - e.printStackTrace(new PrintWriter(sw, true)); - return sw.toString(); + // PrintWriter#close()建议关闭 使用try-with-resources简洁关闭pw + try(PrintWriter pw = new PrintWriter(sw, true)){ + e.printStackTrace(pw); + return sw.toString(); + } } public static String getRootErrorMessage(Exception e) From 092d6a0d5231cc6ef7c5cff82ba8649068e118e7 Mon Sep 17 00:00:00 2001 From: MagicJson Date: Fri, 12 Jul 2024 16:46:34 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E8=A7=A3=E5=86=B3=E4=BD=BF=E7=94=A8@Excel?= =?UTF-8?q?=E5=AD=97=E5=85=B8=E5=80=BCreadConverterExp=20=3D=20"0=3D?= =?UTF-8?q?=E7=94=B7,1=3D=E5=A5=B3,2=3D=E6=9C=AA=E7=9F=A5"=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=E6=97=B6=EF=BC=8C=E5=AF=BC=E5=85=A5=E5=AF=BC=E5=87=BA?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E4=B8=AD=E5=BD=93=E7=94=A8=E6=88=B7=E4=B8=8A?= =?UTF-8?q?=E9=80=81=E5=AD=97=E5=85=B8=E5=80=BC=E4=BC=9A=E5=AF=BC=E8=87=B4?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E8=AF=A5=E5=AD=97=E5=85=B8=E5=80=BC=E7=9A=84?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E8=AE=BE=E7=BD=AE=E4=B8=8D=E4=BA=86=E5=B8=8C?= =?UTF-8?q?=E6=9C=9B=E8=AE=BE=E7=BD=AE=E5=80=BC=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/ruoyi/common/utils/poi/ExcelUtil.java | 14 ++++---------- 1 file changed, 4 insertions(+), 10 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 49dea95e2..2b0cb3871 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 @@ -12,16 +12,7 @@ import java.math.BigDecimal; import java.text.DecimalFormat; import java.time.LocalDate; import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Comparator; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; +import java.util.*; import java.util.stream.Collectors; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang3.ArrayUtils; @@ -1272,6 +1263,9 @@ public class ExcelUtil */ public static String reverseByExp(String propertyValue, String converterExp, String separator) { + if (StringUtils.isNumeric(propertyValue)) { + return propertyValue; + } StringBuilder propertyString = new StringBuilder(); String[] convertSource = converterExp.split(","); for (String item : convertSource)