From b1f846dc52b13c99624a8c0871e55b46ecd2304d Mon Sep 17 00:00:00 2001 From: AprilWind <2100166581@qq.com> Date: Thu, 8 Aug 2024 15:13:04 +0800 Subject: [PATCH 1/8] =?UTF-8?q?add=20=E6=96=B0=E5=A2=9E=E5=B7=A5=E4=BD=9C?= =?UTF-8?q?=E6=97=A5=E5=B7=A5=E5=85=B7=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/core/utils/WorkDaysUtils.java | 174 ++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/WorkDaysUtils.java diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/WorkDaysUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/WorkDaysUtils.java new file mode 100644 index 000000000..4dc318d7a --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/WorkDaysUtils.java @@ -0,0 +1,174 @@ +package org.dromara.common.core.utils; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +import java.util.*; + +/** + * 工作日工具类 + * + * @author AprilWind + */ +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class WorkDaysUtils { + + private static final Map DAYS_IN_YEARS = new HashMap<>(); + + /** + * 计算两个日期之间的工作日天数 + * + * @param start 开始日期 + * @param end 结束日期 + * @return 实际工作日天数 + */ + public static int calculateWorkDays(Date start, Date end) { + if (start.after(end)) { + throw new IllegalArgumentException("开始日期不能晚于结束日期"); + } + int workDays = 0; + + // 获取开始和结束日期的年份 + int startYear = getYear(start); + int endYear = getYear(end); + + // 如果在同一年 + if (startYear == endYear) { + //开始日期年份天 + Integer[] daysArray = daysInYear(startYear); + for (int i = getDayOfYearIndex(start); i <= getDayOfYearIndex(end); i++) { + if (daysArray[i] == 0) { + workDays++; + } + } + } else {//跨年 + // 处理开始年份 + Integer[] startYearDaysArray = daysInYear(startYear); + int startIndex = getDayOfYearIndex(start); + for (int i = startIndex; i < startYearDaysArray.length; i++) { + if (startYearDaysArray[i] == 0) { + workDays++; + } + } + + // 处理结束年份 + Integer[] endYearDaysArray = daysInYear(endYear); + int endIndex = getDayOfYearIndex(end); + for (int i = 0; i <= endIndex; i++) { + if (endYearDaysArray[i] == 0) { + workDays++; + } + } + + // 处理中间的完整年份 + for (int year = startYear + 1; year < endYear; year++) { + Integer[] fullYearDaysArray = daysInYear(year); + for (Integer integer : fullYearDaysArray) { + if (integer == 0) { + workDays++; + } + } + } + } + return workDays; + } + + /** + * 获取指定年份的天数数组。如果指定年份的数据不存在,则生成并缓存数据 + * + * @param year 指定年份 + * @return 表示一年中每一天的状态数组,0 表示工作日,1 表示周末 + */ + private static Integer[] daysInYear(Integer year) { + if (DAYS_IN_YEARS.containsKey(year)) { + return DAYS_IN_YEARS.get(year); + } else { + // 如果年份数据不存在,则生成指定年份的数据 + Integer[] daysArray = generateDaysArray(year); + DAYS_IN_YEARS.put(year, daysArray); + return daysArray; + } + } + + /** + * 根据指定年份生成天数数组,其中工作日用 0 表示,周末用 1 表示 + * + * @param year 指定年份 + * @return 表示一年中每一天的状态数组 + */ + private static Integer[] generateDaysArray(int year) { + Calendar calendar = Calendar.getInstance(); + calendar.set(year, Calendar.JANUARY, 1); + + int daysInYear = getDaysInYear(year); + Integer[] daysArray = new Integer[daysInYear]; + + for (int i = 0; i < daysInYear; i++) { + int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK); + daysArray[i] = (dayOfWeek == Calendar.SATURDAY || dayOfWeek == Calendar.SUNDAY) ? 1 : 0; + calendar.add(Calendar.DAY_OF_MONTH, 1); + } + //todo 更新节假日 + return updateDaysArray(daysArray, new ArrayList<>()); + } + + /** + * 根据节假日下标更新 daysArray,将对应下标的值改为1 + * + * @param daysArray 原始的天数数组 + * @param holidays 节假日日期列表 + * @return 更新后的天数数组 + */ + private static Integer[] updateDaysArray(Integer[] daysArray, List holidays) { + if (holidays == null || holidays.isEmpty()) { + return daysArray; + } + // 遍历节假日下标数组,将对应的 daysArray 元素设置为1 + for (Date holiday : holidays) { + int index = getDayOfYearIndex(holiday); + // 确保下标在有效范围内 + if (index >= 0 && index < daysArray.length) { + daysArray[index] = 1; + } + } + return daysArray; + } + + /** + * 获取日期在一年中的下标(天数) + * + * @param date 指定日期 + * @return 日期在该年份的下标(天数) + */ + private static int getDayOfYearIndex(Date date) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + int dayOfYear = calendar.get(Calendar.DAY_OF_YEAR); + return dayOfYear - 1; + } + + /** + * 获取指定日期的年份 + * + * @param date 指定日期 + * @return 年份 + */ + private static int getYear(Date date) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + return calendar.get(Calendar.YEAR); + } + + /** + * 获取指定年份的天数 + * + * @param year 指定年份 + * @return 年份中的天数 + */ + private static int getDaysInYear(int year) { + Calendar calendar = Calendar.getInstance(); + calendar.set(year, Calendar.DECEMBER, 31); + return calendar.get(Calendar.DAY_OF_YEAR); + } + +} From 3cec83a7cac28801d6c86f73984d6af3044ef064 Mon Sep 17 00:00:00 2001 From: AprilWind <2100166581@qq.com> Date: Thu, 8 Aug 2024 15:59:32 +0800 Subject: [PATCH 2/8] =?UTF-8?q?update=20=E6=B7=BB=E5=8A=A0=E6=A0=B9?= =?UTF-8?q?=E6=8D=AE=E5=BC=80=E5=A7=8B=E6=97=A5=E6=9C=9F=E5=92=8C=E5=B7=A5?= =?UTF-8?q?=E4=BD=9C=E6=97=A5=E6=95=B0=E8=AE=A1=E7=AE=97=E6=88=AA=E6=AD=A2?= =?UTF-8?q?=E6=97=A5=E6=9C=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/core/utils/WorkDaysUtils.java | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/WorkDaysUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/WorkDaysUtils.java index 4dc318d7a..8997f2ee6 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/WorkDaysUtils.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/WorkDaysUtils.java @@ -15,6 +15,46 @@ public class WorkDaysUtils { private static final Map DAYS_IN_YEARS = new HashMap<>(); + /** + * 根据开始日期和工作日数计算截止日期 + * + * @param startDate 开始日期 + * @param workDays 工作日数 + * @return 截止日期 + */ + public static Date calculateEndDate(Date startDate, int workDays) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(startDate); + // 获取开始日期的年份 + int startYear = getYear(startDate); + //开始日期年份天 + Integer[] daysArray = daysInYear(startYear); + int startIndex = getDayOfYearIndex(startDate); + int endIndex = startIndex; + // 循环找到指定的工作日数 + while (workDays > 0) { + // 检查当前日期是否是工作日 + if (daysArray[endIndex] == 0) { + workDays--; + } + // 结束条件:工作日数为零 + if (workDays <= 0) { + break; + } + // 移动到下一天 + endIndex++; + // 如果移动到下一年 + if (endIndex >= daysArray.length) { + startYear++; + daysArray = daysInYear(startYear); + endIndex = 0; + } + } + // 设置截止日期 + calendar.set(Calendar.DAY_OF_YEAR, endIndex + 1); // +1 因为 Calendar.DAY_OF_YEAR 从 1 开始 + return calendar.getTime(); + } + /** * 计算两个日期之间的工作日天数 * From 3277a11db954c3ad237efb40fa64d85228bab662 Mon Sep 17 00:00:00 2001 From: AprilWind <2100166581@qq.com> Date: Thu, 8 Aug 2024 16:05:32 +0800 Subject: [PATCH 3/8] =?UTF-8?q?fix=20=E8=B7=A8=E5=B9=B4=E6=97=B6=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E5=B9=B4=E4=BB=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/dromara/common/core/utils/WorkDaysUtils.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/WorkDaysUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/WorkDaysUtils.java index 8997f2ee6..110225c8c 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/WorkDaysUtils.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/WorkDaysUtils.java @@ -48,10 +48,12 @@ public class WorkDaysUtils { startYear++; daysArray = daysInYear(startYear); endIndex = 0; + // 更新年份 + calendar.set(Calendar.YEAR, startYear); } } // 设置截止日期 - calendar.set(Calendar.DAY_OF_YEAR, endIndex + 1); // +1 因为 Calendar.DAY_OF_YEAR 从 1 开始 + calendar.set(Calendar.DAY_OF_YEAR, endIndex + 1); return calendar.getTime(); } From 1f465c6f045cfbbbeb386ce05ce99412996bfe1f Mon Sep 17 00:00:00 2001 From: AprilWind <2100166581@qq.com> Date: Thu, 8 Aug 2024 17:03:20 +0800 Subject: [PATCH 4/8] =?UTF-8?q?update=20=E4=BC=98=E5=8C=96=E8=8A=82?= =?UTF-8?q?=E5=81=87=E6=97=A5=E4=B8=8E=E5=91=A8=E6=9C=AB=E8=A1=A5=E7=8F=AD?= =?UTF-8?q?=E6=83=85=E5=86=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/core/utils/WorkDaysUtils.java | 41 ++++++++++++++++--- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/WorkDaysUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/WorkDaysUtils.java index 110225c8c..6aa60593c 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/WorkDaysUtils.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/WorkDaysUtils.java @@ -150,27 +150,58 @@ public class WorkDaysUtils { daysArray[i] = (dayOfWeek == Calendar.SATURDAY || dayOfWeek == Calendar.SUNDAY) ? 1 : 0; calendar.add(Calendar.DAY_OF_MONTH, 1); } - //todo 更新节假日 - return updateDaysArray(daysArray, new ArrayList<>()); + + // 将工作日设置为休息日(假设用于标记节假日) + markWorkdaysAsRestdays(daysArray, new ArrayList<>()); + // 将休息日设置为工作日(假设用于标记补班的工作日) + markRestdaysAsWorkdays(daysArray, new ArrayList<>()); + return daysArray; } /** - * 根据节假日下标更新 daysArray,将对应下标的值改为1 + * 将工作日设置为休息日(假设用于标记节假日) * * @param daysArray 原始的天数数组 * @param holidays 节假日日期列表 * @return 更新后的天数数组 */ - private static Integer[] updateDaysArray(Integer[] daysArray, List holidays) { + private static Integer[] markWorkdaysAsRestdays(Integer[] daysArray, List holidays) { + return updateDaysArray(daysArray, holidays, true); + } + + /** + * 将休息日设置为工作日(假设用于标记补班的工作日) + * + * @param daysArray 原始的天数数组 + * @param holidays 休息日日期列表 + * @return 更新后的天数数组 + */ + private static Integer[] markRestdaysAsWorkdays(Integer[] daysArray, List holidays) { + return updateDaysArray(daysArray, holidays, false); + } + + /** + * 根据节假日下标更新 daysArray,将对应下标的值改为指定值 + * + * @param daysArray 原始的天数数组 + * @param holidays 节假日日期列表 + * @param isHoliday 是否为节假日,如果为 true 则表示节假日;如果为 false 则表示工作日 + * @return 更新后的天数数组 + */ + private static Integer[] updateDaysArray(Integer[] daysArray, List holidays, Boolean isHoliday) { if (holidays == null || holidays.isEmpty()) { return daysArray; } + + // 节假日用 1,工作日用 0 + int valueToSet = isHoliday ? 1 : 0; + // 遍历节假日下标数组,将对应的 daysArray 元素设置为1 for (Date holiday : holidays) { int index = getDayOfYearIndex(holiday); // 确保下标在有效范围内 if (index >= 0 && index < daysArray.length) { - daysArray[index] = 1; + daysArray[index] = valueToSet; } } return daysArray; From ed5127647c659e831726fdc33d1caadd7f8bc5d0 Mon Sep 17 00:00:00 2001 From: AprilWind <2100166581@qq.com> Date: Fri, 9 Aug 2024 10:22:18 +0800 Subject: [PATCH 5/8] =?UTF-8?q?update=20=E4=BC=98=E5=8C=96=E7=BC=93?= =?UTF-8?q?=E5=AD=98=E5=8A=A0=E9=94=81=EF=BC=8C=E6=B8=85=E7=A9=BA=EF=BC=8C?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E5=B7=A5=E4=BD=9C=E6=97=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/core/utils/WorkDaysUtils.java | 97 +++++++++---------- 1 file changed, 48 insertions(+), 49 deletions(-) diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/WorkDaysUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/WorkDaysUtils.java index 6aa60593c..49c0d30eb 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/WorkDaysUtils.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/WorkDaysUtils.java @@ -1,9 +1,12 @@ package org.dromara.common.core.utils; +import cn.hutool.core.collection.CollUtil; import lombok.AccessLevel; import lombok.NoArgsConstructor; import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.locks.ReentrantLock; /** * 工作日工具类 @@ -13,7 +16,12 @@ import java.util.*; @NoArgsConstructor(access = AccessLevel.PRIVATE) public class WorkDaysUtils { - private static final Map DAYS_IN_YEARS = new HashMap<>(); + private static final Map DAYS_IN_YEARS = new ConcurrentHashMap<>(); + private static final ReentrantLock LOCK = new ReentrantLock(); + //工作日 + public static final int WORKDAY = 0; + //休息日 + public static final int RESTDAY = 1; /** * 根据开始日期和工作日数计算截止日期 @@ -34,7 +42,7 @@ public class WorkDaysUtils { // 循环找到指定的工作日数 while (workDays > 0) { // 检查当前日期是否是工作日 - if (daysArray[endIndex] == 0) { + if (daysArray[endIndex] == WORKDAY) { workDays--; } // 结束条件:工作日数为零 @@ -79,7 +87,7 @@ public class WorkDaysUtils { //开始日期年份天 Integer[] daysArray = daysInYear(startYear); for (int i = getDayOfYearIndex(start); i <= getDayOfYearIndex(end); i++) { - if (daysArray[i] == 0) { + if (daysArray[i] == WORKDAY) { workDays++; } } @@ -88,7 +96,7 @@ public class WorkDaysUtils { Integer[] startYearDaysArray = daysInYear(startYear); int startIndex = getDayOfYearIndex(start); for (int i = startIndex; i < startYearDaysArray.length; i++) { - if (startYearDaysArray[i] == 0) { + if (startYearDaysArray[i] == WORKDAY) { workDays++; } } @@ -97,7 +105,7 @@ public class WorkDaysUtils { Integer[] endYearDaysArray = daysInYear(endYear); int endIndex = getDayOfYearIndex(end); for (int i = 0; i <= endIndex; i++) { - if (endYearDaysArray[i] == 0) { + if (endYearDaysArray[i] == WORKDAY) { workDays++; } } @@ -106,7 +114,7 @@ public class WorkDaysUtils { for (int year = startYear + 1; year < endYear; year++) { Integer[] fullYearDaysArray = daysInYear(year); for (Integer integer : fullYearDaysArray) { - if (integer == 0) { + if (integer == WORKDAY) { workDays++; } } @@ -115,6 +123,13 @@ public class WorkDaysUtils { return workDays; } + /** + * 清空所有年份的数据 + */ + public static void clearAllData() { + DAYS_IN_YEARS.clear(); + } + /** * 获取指定年份的天数数组。如果指定年份的数据不存在,则生成并缓存数据 * @@ -122,13 +137,25 @@ public class WorkDaysUtils { * @return 表示一年中每一天的状态数组,0 表示工作日,1 表示周末 */ private static Integer[] daysInYear(Integer year) { + // 先检查缓存 if (DAYS_IN_YEARS.containsKey(year)) { return DAYS_IN_YEARS.get(year); - } else { + } + + // 如果缓存中不存在,则进行加锁 + LOCK.lock(); + try { + // 再次检查缓存,防止在等待锁期间其他线程已经生成了数据 + if (DAYS_IN_YEARS.containsKey(year)) { + return DAYS_IN_YEARS.get(year); + } + // 如果年份数据不存在,则生成指定年份的数据 Integer[] daysArray = generateDaysArray(year); DAYS_IN_YEARS.put(year, daysArray); return daysArray; + } finally { + LOCK.unlock(); } } @@ -147,64 +174,36 @@ public class WorkDaysUtils { for (int i = 0; i < daysInYear; i++) { int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK); - daysArray[i] = (dayOfWeek == Calendar.SATURDAY || dayOfWeek == Calendar.SUNDAY) ? 1 : 0; + daysArray[i] = (dayOfWeek == Calendar.SATURDAY || dayOfWeek == Calendar.SUNDAY) ? RESTDAY : WORKDAY; calendar.add(Calendar.DAY_OF_MONTH, 1); } - - // 将工作日设置为休息日(假设用于标记节假日) - markWorkdaysAsRestdays(daysArray, new ArrayList<>()); - // 将休息日设置为工作日(假设用于标记补班的工作日) - markRestdaysAsWorkdays(daysArray, new ArrayList<>()); + //设置为工作日(假设用于标记补班的工作日) + updateDaysArray(daysArray, Collections.emptyList(), WORKDAY); + //设置为休息日(假设用于标记节假日) + updateDaysArray(daysArray, Collections.emptyList(), RESTDAY); return daysArray; } /** - * 将工作日设置为休息日(假设用于标记节假日) + * 根据日期下标更新 daysArray,将对应下标的值改为指定值 * - * @param daysArray 原始的天数数组 - * @param holidays 节假日日期列表 - * @return 更新后的天数数组 + * @param daysArray 原始的天数数组 + * @param days 要修改的日期列表 + * @param valueToSet 休息日用 1,工作日用 0 */ - private static Integer[] markWorkdaysAsRestdays(Integer[] daysArray, List holidays) { - return updateDaysArray(daysArray, holidays, true); - } - - /** - * 将休息日设置为工作日(假设用于标记补班的工作日) - * - * @param daysArray 原始的天数数组 - * @param holidays 休息日日期列表 - * @return 更新后的天数数组 - */ - private static Integer[] markRestdaysAsWorkdays(Integer[] daysArray, List holidays) { - return updateDaysArray(daysArray, holidays, false); - } - - /** - * 根据节假日下标更新 daysArray,将对应下标的值改为指定值 - * - * @param daysArray 原始的天数数组 - * @param holidays 节假日日期列表 - * @param isHoliday 是否为节假日,如果为 true 则表示节假日;如果为 false 则表示工作日 - * @return 更新后的天数数组 - */ - private static Integer[] updateDaysArray(Integer[] daysArray, List holidays, Boolean isHoliday) { - if (holidays == null || holidays.isEmpty()) { - return daysArray; + private static void updateDaysArray(Integer[] daysArray, List days, int valueToSet) { + if (CollUtil.isEmpty(days)) { + return; } - // 节假日用 1,工作日用 0 - int valueToSet = isHoliday ? 1 : 0; - - // 遍历节假日下标数组,将对应的 daysArray 元素设置为1 - for (Date holiday : holidays) { + // 遍历日期下标数组,将对应的 daysArray 元素设置为1 + for (Date holiday : days) { int index = getDayOfYearIndex(holiday); // 确保下标在有效范围内 if (index >= 0 && index < daysArray.length) { daysArray[index] = valueToSet; } } - return daysArray; } /** From bf6b3f9b86507cb93688cf3121ab88cd1e98b48b Mon Sep 17 00:00:00 2001 From: AprilWind <2100166581@qq.com> Date: Fri, 9 Aug 2024 10:50:01 +0800 Subject: [PATCH 6/8] =?UTF-8?q?update=20=E4=BC=98=E5=8C=96=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E5=88=86=E5=B8=83=E5=BC=8F=E7=BC=93=E5=AD=98=EF=BC=8C?= =?UTF-8?q?=E4=BB=A5=E5=8F=8A=E5=88=86=E5=B8=83=E5=BC=8F=E9=94=81=E5=A4=84?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../workflow}/utils/WorkDaysUtils.java | 48 +++++++++++-------- 1 file changed, 27 insertions(+), 21 deletions(-) rename {ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core => ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow}/utils/WorkDaysUtils.java (84%) diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/WorkDaysUtils.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/utils/WorkDaysUtils.java similarity index 84% rename from ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/WorkDaysUtils.java rename to ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/utils/WorkDaysUtils.java index 49c0d30eb..7addf873c 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/WorkDaysUtils.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/utils/WorkDaysUtils.java @@ -1,12 +1,19 @@ -package org.dromara.common.core.utils; +package org.dromara.workflow.utils; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ArrayUtil; +import com.baomidou.lock.LockInfo; +import com.baomidou.lock.LockTemplate; import lombok.AccessLevel; import lombok.NoArgsConstructor; +import org.dromara.common.core.constant.GlobalConstants; +import org.dromara.common.core.utils.SpringUtils; +import org.dromara.common.redis.utils.RedisUtils; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.locks.ReentrantLock; +import java.util.Calendar; +import java.util.Collections; +import java.util.Date; +import java.util.List; /** * 工作日工具类 @@ -16,8 +23,8 @@ import java.util.concurrent.locks.ReentrantLock; @NoArgsConstructor(access = AccessLevel.PRIVATE) public class WorkDaysUtils { - private static final Map DAYS_IN_YEARS = new ConcurrentHashMap<>(); - private static final ReentrantLock LOCK = new ReentrantLock(); + private static final String DAYS_IN_YEARS_KEY = GlobalConstants.GLOBAL_REDIS_KEY + "DAYS_IN_YEARS:"; + private static final LockTemplate LOCK_TEMPLATE = SpringUtils.getBean(LockTemplate.class); //工作日 public static final int WORKDAY = 0; //休息日 @@ -124,10 +131,10 @@ public class WorkDaysUtils { } /** - * 清空所有年份的数据 + * 删除指定年份的数据 */ - public static void clearAllData() { - DAYS_IN_YEARS.clear(); + public static void clearData(Integer year) { + RedisUtils.deleteObject(DAYS_IN_YEARS_KEY + year); } /** @@ -137,25 +144,24 @@ public class WorkDaysUtils { * @return 表示一年中每一天的状态数组,0 表示工作日,1 表示周末 */ private static Integer[] daysInYear(Integer year) { - // 先检查缓存 - if (DAYS_IN_YEARS.containsKey(year)) { - return DAYS_IN_YEARS.get(year); + String key = DAYS_IN_YEARS_KEY + year; + Integer[] daysInYears = RedisUtils.getCacheObject(key); + if (ArrayUtil.isNotEmpty(daysInYears)) { + return daysInYears; } - - // 如果缓存中不存在,则进行加锁 - LOCK.lock(); + LockInfo lock = LOCK_TEMPLATE.lock(key); try { - // 再次检查缓存,防止在等待锁期间其他线程已经生成了数据 - if (DAYS_IN_YEARS.containsKey(year)) { - return DAYS_IN_YEARS.get(year); + // 再次检查缓存,防止缓存穿透 + daysInYears = RedisUtils.getCacheObject(key); + if (ArrayUtil.isNotEmpty(daysInYears)) { + return daysInYears; } - // 如果年份数据不存在,则生成指定年份的数据 Integer[] daysArray = generateDaysArray(year); - DAYS_IN_YEARS.put(year, daysArray); + RedisUtils.setCacheObject(key, daysArray); return daysArray; } finally { - LOCK.unlock(); + LOCK_TEMPLATE.releaseLock(lock); } } From d97bb2e17c83157f5c543ddda54a50097c8132ea Mon Sep 17 00:00:00 2001 From: AprilWind <2100166581@qq.com> Date: Fri, 9 Aug 2024 11:15:17 +0800 Subject: [PATCH 7/8] =?UTF-8?q?update=20=E5=A2=9E=E5=8A=A0=E4=B8=AA?= =?UTF-8?q?=E4=BA=BA=E7=9A=84=E5=8A=A0=E7=8F=AD=E5=92=8C=E8=B0=83=E4=BC=91?= =?UTF-8?q?=E6=97=A5=E6=9C=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dromara/workflow/utils/WorkDaysUtils.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/utils/WorkDaysUtils.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/utils/WorkDaysUtils.java index 7addf873c..a1f3c3188 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/utils/WorkDaysUtils.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/utils/WorkDaysUtils.java @@ -137,6 +137,24 @@ public class WorkDaysUtils { RedisUtils.deleteObject(DAYS_IN_YEARS_KEY + year); } + /** + * 计算指定年份的工作日数组,标记个人的加班和调休日期 + * + * @param year 指定年份 + * @param overtime 个人加班日期列表 + * @param adjustments 个人调休日期列表 + * @return 表示每一天状态的数组,0 表示工作日,1 表示休息日 + */ + public static Integer[] calculateWorkdays(Integer year, List overtime, List adjustments) { + //获取指定年份天数 + Integer[] daysArray = daysInYear(year); + //设置为工作日(假设用于标记补班的工作日) + updateDaysArray(daysArray, overtime, WORKDAY); + //设置为休息日(假设用于标记节假日) + updateDaysArray(daysArray, adjustments, RESTDAY); + return daysArray; + } + /** * 获取指定年份的天数数组。如果指定年份的数据不存在,则生成并缓存数据 * From 9665492634ab82c0802f8d26819850f8c26379f5 Mon Sep 17 00:00:00 2001 From: AprilWind <2100166581@qq.com> Date: Fri, 9 Aug 2024 11:30:52 +0800 Subject: [PATCH 8/8] =?UTF-8?q?update=20=E4=BC=98=E5=8C=96=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 --- .../src/main/java/org/dromara/workflow/utils/WorkDaysUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/utils/WorkDaysUtils.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/utils/WorkDaysUtils.java index a1f3c3188..ac14bb36f 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/utils/WorkDaysUtils.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/utils/WorkDaysUtils.java @@ -145,7 +145,7 @@ public class WorkDaysUtils { * @param adjustments 个人调休日期列表 * @return 表示每一天状态的数组,0 表示工作日,1 表示休息日 */ - public static Integer[] calculateWorkdays(Integer year, List overtime, List adjustments) { + public static Integer[] calculateWorkDays(Integer year, List overtime, List adjustments) { //获取指定年份天数 Integer[] daysArray = daysInYear(year); //设置为工作日(假设用于标记补班的工作日)