Forráskód Böngészése

新增日历数据

车车 3 hónapja
szülő
commit
36b84a12b1

+ 6 - 5
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/holiday/HolidayController.java

@@ -9,6 +9,7 @@ import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
 import cn.iocoder.yudao.module.iscs.controller.admin.holiday.vo.HolidayPageReqVO;
 import cn.iocoder.yudao.module.iscs.controller.admin.holiday.vo.HolidayRespVO;
 import cn.iocoder.yudao.module.iscs.controller.admin.holiday.vo.HolidaySaveReqVO;
+import cn.iocoder.yudao.module.iscs.controller.admin.holiday.vo.HolidayUpdateListVO;
 import cn.iocoder.yudao.module.iscs.dal.dataobject.holiday.HolidayDO;
 import cn.iocoder.yudao.module.iscs.service.holiday.HolidayService;
 import io.swagger.v3.oas.annotations.Operation;
@@ -36,11 +37,11 @@ public class HolidayController {
     @Resource
     private HolidayService holidayService;
 
-    @PostMapping("/insertHoliday")
-    @Operation(summary = "创建节假日设置")
-    @PreAuthorize("@ss.hasPermission('iscs:holiday:create')")
-    public CommonResult<Long> insertHoliday(@Valid @RequestBody HolidaySaveReqVO createReqVO) {
-        return success(holidayService.createHoliday(createReqVO));
+    @PostMapping("/updateHolidayList")
+    @Operation(summary = "批量更新节假日设置")
+    @PreAuthorize("@ss.hasPermission('iscs:holiday:update')")
+    public CommonResult<Boolean> updateHolidayList(@Valid @RequestBody HolidayUpdateListVO vo) {
+        return success(holidayService.updateHolidayList(vo));
     }
 
     @PutMapping("/updateHoliday")

+ 1 - 1
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/holiday/vo/HolidaySaveReqVO.java

@@ -15,7 +15,7 @@ public class HolidaySaveReqVO {
     @Schema(description = "日期")
     private String theDay;
 
-    @Schema(description = "日期类型", example = "1")
+    @Schema(description = "日期类型", example = "HOLIDAY / WORKDAY")
     private String holidayType;
 
     @Schema(description = "开始时间")

+ 25 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/holiday/vo/HolidayUpdateListVO.java

@@ -0,0 +1,25 @@
+package cn.iocoder.yudao.module.iscs.controller.admin.holiday.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+@Schema(description = "管理后台 - 节假日设置新增/修改 Request VO")
+@Data
+public class HolidayUpdateListVO {
+
+    @Schema(description = "开始日期")
+    private String startDay;
+
+    @Schema(description = "结束日期")
+    private String endDay;
+
+    @Schema(description = "设置单位(0周 / 1号)")
+    private String unit;
+
+    @Schema(description = "设置内容(星期一 / 周一 / 15)")
+    private String value;
+
+    @Schema(description = "日期类型", example = "HOLIDAY / WORKDAY")
+    private String holidayType;
+
+}

+ 2 - 1
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/service/holiday/HolidayService.java

@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.iscs.service.holiday;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.module.iscs.controller.admin.holiday.vo.HolidayPageReqVO;
 import cn.iocoder.yudao.module.iscs.controller.admin.holiday.vo.HolidaySaveReqVO;
+import cn.iocoder.yudao.module.iscs.controller.admin.holiday.vo.HolidayUpdateListVO;
 import cn.iocoder.yudao.module.iscs.dal.dataobject.holiday.HolidayDO;
 import com.baomidou.mybatisplus.extension.service.IService;
 import jakarta.validation.Valid;
@@ -22,7 +23,7 @@ public interface HolidayService extends IService<HolidayDO> {
      * @param createReqVO 创建信息
      * @return 编号
      */
-    Long createHoliday(@Valid HolidaySaveReqVO createReqVO);
+    Boolean updateHolidayList(@Valid HolidayUpdateListVO vo);
 
     /**
      * 更新节假日设置

+ 69 - 7
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/service/holiday/HolidayServiceImpl.java

@@ -1,16 +1,23 @@
 package cn.iocoder.yudao.module.iscs.service.holiday;
 
+import cn.hutool.core.lang.Assert;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.module.iscs.controller.admin.holiday.vo.HolidayPageReqVO;
 import cn.iocoder.yudao.module.iscs.controller.admin.holiday.vo.HolidaySaveReqVO;
+import cn.iocoder.yudao.module.iscs.controller.admin.holiday.vo.HolidayUpdateListVO;
 import cn.iocoder.yudao.module.iscs.dal.dataobject.holiday.HolidayDO;
 import cn.iocoder.yudao.module.iscs.dal.mysql.holiday.HolidayMapper;
+import cn.iocoder.yudao.module.iscs.utils.SuperDateUtils;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import jakarta.annotation.Resource;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 
+import java.time.LocalDate;
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -25,21 +32,76 @@ public class HolidayServiceImpl extends ServiceImpl<HolidayMapper, HolidayDO> im
     @Resource
     private HolidayMapper holidayMapper;
 
+    @Transactional
     @Override
-    public Long createHoliday(HolidaySaveReqVO createReqVO) {
-        // 插入
-        HolidayDO holiday = BeanUtils.toBean(createReqVO, HolidayDO.class);
-        holidayMapper.insert(holiday);
+    public Boolean updateHolidayList(HolidayUpdateListVO vo) {
+        Assert.notBlank(vo.getStartDay(), "开始日期不能为空!");
+        Assert.notBlank(vo.getEndDay(), "结束日期不能为空!");
+        Assert.notBlank(vo.getUnit(), "设置的单位不能为空!");
+        if (vo.getUnit().equals("0")) {
+            // 按周几来设置
+            List<String> datesByWeekday = SuperDateUtils.getDatesByWeekday(vo.getStartDay(), vo.getEndDay(), vo.getValue());
+            if (!datesByWeekday.isEmpty()) {
+                List<HolidayDO> updateList = list(Wrappers.<HolidayDO>lambdaQuery().eq(HolidayDO::getTheDay, datesByWeekday));
+                if (!updateList.isEmpty()) {
+                    // 存在的全部更新一下
+                    updateList.forEach(o -> o.setHolidayType(vo.getHolidayType()));
+                    updateBatchById(updateList);
+                }
+                // 别的全部需要新增
+                datesByWeekday.removeIf(item -> updateList.stream().map(HolidayDO::getTheDay).toList().contains(item));
+                ArrayList<HolidayDO> holidayDOS = new ArrayList<>();
+                for (String s : datesByWeekday) {
+                    HolidayDO holidayDO = new HolidayDO();
+                    holidayDO.setTheDay(s);
+                    holidayDO.setHolidayType(vo.getHolidayType());
+                    holidayDOS.add(holidayDO);
+                }
+                saveBatch(holidayDOS);
+            }
+        }
 
+        if (vo.getUnit().equals("1")) {
+            // 按号来设置
+            List<String> datesWithDayInRange = SuperDateUtils.getDatesWithDayInRange(vo.getStartDay(), vo.getEndDay(), Integer.valueOf(vo.getValue()));
+            if (!datesWithDayInRange.isEmpty()) {
+                List<HolidayDO> updateList = list(Wrappers.<HolidayDO>lambdaQuery().eq(HolidayDO::getTheDay, datesWithDayInRange));
+                if (!updateList.isEmpty()) {
+                    // 存在的全部更新一下
+                    updateList.forEach(o -> o.setHolidayType(vo.getHolidayType()));
+                    updateBatchById(updateList);
+                }
+                // 别的全部需要新增
+                datesWithDayInRange.removeIf(item -> updateList.stream().map(HolidayDO::getTheDay).toList().contains(item));
+                ArrayList<HolidayDO> holidayDOS = new ArrayList<>();
+                for (String s : datesWithDayInRange) {
+                    HolidayDO holidayDO = new HolidayDO();
+                    holidayDO.setTheDay(s);
+                    holidayDO.setHolidayType(vo.getHolidayType());
+                    holidayDOS.add(holidayDO);
+                }
+                saveBatch(holidayDOS);
+            }
+        }
         // 返回
-        return holiday.getId();
+        return true;
     }
 
     @Override
     public void updateHoliday(HolidaySaveReqVO updateReqVO) {
-        // 更新
+        Assert.notBlank(updateReqVO.getTheDay(), "日期不能为空!");
+        Assert.notBlank(updateReqVO.getHolidayType(), "日期类型不能为空!");
         HolidayDO updateObj = BeanUtils.toBean(updateReqVO, HolidayDO.class);
-        holidayMapper.updateById(updateObj);
+        // 检查这个日期有没有设置,如果有设置,直接更新,没有在创建
+        HolidayDO holidayDO = getOne(Wrappers.<HolidayDO>lambdaQuery()
+                .eq(HolidayDO::getTheDay, updateReqVO.getTheDay()));
+        if (holidayDO != null) {
+            updateObj.setId(holidayDO.getId());
+            updateById(updateObj);
+        } else {
+            // 更新
+            save(updateObj);
+        }
     }
 
     @Override

+ 241 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/utils/SuperDateUtils.java

@@ -0,0 +1,241 @@
+package cn.iocoder.yudao.module.iscs.utils;
+
+import java.time.DayOfWeek;
+import java.time.LocalDate;
+import java.time.YearMonth;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class SuperDateUtils {
+
+
+    // ------------------------------------- 获取指定时间段内的所有日期 ---------------------------------------------------
+
+    /**
+     * 获取指定时间段内的所有日期
+     *
+     * @param startStr 起始日期,格式为yyyy-MM-dd
+     * @param endStr   结束日期,格式为yyyy-MM-dd
+     * @return 包含所有日期的列表(含起止日期)
+     */
+    public static List<String> getAllDatesBetween(String startStr, String endStr) {
+        // 定义日期格式
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+
+        // 解析输入字符串为LocalDate对象
+        LocalDate startDate = LocalDate.parse(startStr, formatter);
+        LocalDate endDate = LocalDate.parse(endStr, formatter);
+
+        // 确保startDate <= endDate(自动纠正顺序)
+        if (startDate.isAfter(endDate)) {
+            LocalDate temp = startDate;
+            startDate = endDate;
+            endDate = temp;
+        }
+
+        // 生成日期列表
+        List<String> result = new ArrayList<>();
+        LocalDate current = startDate;
+        while (!current.isAfter(endDate)) { // 包含边界值
+            result.add(current.format(formatter));
+            current = current.plusDays(1);
+        }
+
+        return result;
+    }
+
+    // 测试示例
+    /*public static void main(String[] args) {
+        List<String> dates = getAllDatesBetween("2025-07-23", "2025-08-02");
+        System.out.println(dates);
+        // 输出: [2025-07-23, 2025-07-24, 2025-07-25]
+
+        // 测试逆序输入
+        dates = getAllDatesBetween("2025-07-25", "2025-07-23");
+        System.out.println(dates);
+        // 输出: [2025-07-23, 2025-07-24, 2025-07-25]
+    }*/
+
+    // ---------------------------------- 获取指定时间段内的所有周几的日期 -----------------------------------------------------
+    private static final Map<String, DayOfWeek> WEEKDAY_MAP = new HashMap<>();
+
+    static {
+        WEEKDAY_MAP.put("周一", DayOfWeek.MONDAY);
+        WEEKDAY_MAP.put("周二", DayOfWeek.TUESDAY);
+        WEEKDAY_MAP.put("周三", DayOfWeek.WEDNESDAY);
+        WEEKDAY_MAP.put("周四", DayOfWeek.THURSDAY);
+        WEEKDAY_MAP.put("周五", DayOfWeek.FRIDAY);
+        WEEKDAY_MAP.put("周六", DayOfWeek.SATURDAY);
+        WEEKDAY_MAP.put("周日", DayOfWeek.SUNDAY);
+        // 兼容全称写法
+        WEEKDAY_MAP.put("星期一", DayOfWeek.MONDAY);
+        WEEKDAY_MAP.put("星期二", DayOfWeek.TUESDAY);
+        WEEKDAY_MAP.put("星期三", DayOfWeek.WEDNESDAY);
+        WEEKDAY_MAP.put("星期四", DayOfWeek.THURSDAY);
+        WEEKDAY_MAP.put("星期五", DayOfWeek.FRIDAY);
+        WEEKDAY_MAP.put("星期六", DayOfWeek.SATURDAY);
+        WEEKDAY_MAP.put("星期日", DayOfWeek.SUNDAY);
+        WEEKDAY_MAP.put("星期天", DayOfWeek.SUNDAY); // 部分地区使用
+    }
+
+    /**
+     * 获取指定时间段内所有匹配给定星期的日期
+     *
+     * @param startDateStr 开始日期,格式为yyyy-MM-dd
+     * @param endDateStr   结束日期,格式为yyyy-MM-dd
+     * @param weekday      星期几(如"周三"、"星期三")
+     * @return 匹配的日期列表
+     */
+    public static List<String> getDatesByWeekday(String startDateStr, String endDateStr, String weekday) {
+        // 校验星期参数
+        DayOfWeek targetDay = WEEKDAY_MAP.get(weekday);
+        if (targetDay == null) {
+            throw new IllegalArgumentException("无效的星期参数: " + weekday);
+        }
+
+        // 解析日期
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+        LocalDate startDate = LocalDate.parse(startDateStr, formatter);
+        LocalDate endDate = LocalDate.parse(endDateStr, formatter);
+
+        // 自动校正日期顺序
+        if (startDate.isAfter(endDate)) {
+            LocalDate temp = startDate;
+            startDate = endDate;
+            endDate = temp;
+        }
+
+        // 遍历日期并收集结果
+        List<String> result = new ArrayList<>();
+        LocalDate current = startDate;
+        while (!current.isAfter(endDate)) {
+            if (current.getDayOfWeek() == targetDay) {
+                result.add(current.format(formatter));
+            }
+            current = current.plusDays(1);
+        }
+
+        return result;
+    }
+
+    // 示例用法
+    /*public static void main(String[] args) {
+        List<String> dates = getDatesByWeekday("2025-07-23", "2025-08-25", "周三");
+        System.out.println(dates); // 输出: [2025-07-23]
+    }*/
+
+    // ---------------------------------- 获取指定时间段内的所有指定号日期 -----------------------------------------------------
+    /**
+     * 根据时间段和指定日期中的“日”部分,获取所有匹配的日期。
+     *
+     * @param startStr  开始日期字符串,格式为yyyy-MM-dd
+     * @param endStr    结束日期字符串,格式为yyyy-MM-dd
+     * @param targetDay 目标日期的“日”部分(如24)
+     * @return 符合条件的日期列表
+     */
+    public static List<String> getDatesWithDayInRange(String startStr, String endStr, int targetDay) {
+        // 解析输入的日期字符串
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+        LocalDate startDate = LocalDate.parse(startStr);
+        LocalDate endDate = LocalDate.parse(endStr);
+
+        // 确保startDate不晚于endDate
+        if (startDate.isAfter(endDate)) {
+            LocalDate temp = startDate;
+            startDate = endDate;
+            endDate = temp;
+        }
+
+        List<String> result = new ArrayList<>();
+        // 获取开始和结束的YearMonth
+        YearMonth startYearMonth = YearMonth.from(startDate);
+        YearMonth endYearMonth = YearMonth.from(endDate);
+
+        YearMonth currentYearMonth = startYearMonth;
+        // 遍历每个月
+        while (!currentYearMonth.isAfter(endYearMonth)) {
+            int daysInMonth = currentYearMonth.lengthOfMonth(); // 获取当前月的总天数
+            if (targetDay <= daysInMonth) {
+                LocalDate targetDate = currentYearMonth.atDay(targetDay);
+                // 检查目标日期是否在范围内
+                if (!targetDate.isBefore(startDate) && !targetDate.isAfter(endDate)) {
+                    result.add(targetDate.format(formatter));
+                }
+            }
+            // 进入下一个月
+            currentYearMonth = currentYearMonth.plusMonths(1);
+        }
+
+        return result;
+    }
+
+    // 测试示例
+    /*public static void main(String[] args) {
+        List<LocalDate> dates = getDatesWithDayInRange("2025-01-23", "2025-12-31", 29);
+        dates.forEach(System.out::println); // 输出:2025-06-24 和 2025-07-24
+    }*/
+
+// ---------------------------------- 获取指定时间段内的所有指定第多少天,如果超过则输出最后一天 -----------------------------------------------------
+
+    /**
+     * 获取指定时间段内每月的第指定天数的日期。
+     * @param startStr 起始日期字符串,格式为yyyy-MM-dd
+     * @param endStr 结束日期字符串,格式为yyyy-MM-dd
+     * @param dayOfMonth 每月的第几天(如1表示每月1日)
+     * @return 符合条件的日期列表
+     */
+    public static List<LocalDate> getDatesByDayOfMonth(String startStr, String endStr, int dayOfMonth) {
+        // 解析输入日期
+        LocalDate startDate = LocalDate.parse(startStr);
+        LocalDate endDate = LocalDate.parse(endStr);
+
+        // 如果起始日期晚于结束日期,交换顺序
+        if (startDate.isAfter(endDate)) {
+            LocalDate temp = startDate;
+            startDate = endDate;
+            endDate = temp;
+        }
+
+        List<LocalDate> result = new ArrayList<>();
+        YearMonth startMonth = YearMonth.from(startDate);
+        YearMonth endMonth = YearMonth.from(endDate);
+
+        // 遍历从起始月份到结束月份的所有月份
+        for (YearMonth ym = startMonth; !ym.isAfter(endMonth); ym = ym.plusMonths(1)) {
+            int maxDay = ym.lengthOfMonth(); // 获取当月最大天数
+            int targetDay = Math.min(dayOfMonth, maxDay); // 防止超过最大天数
+            LocalDate targetDate = ym.atDay(targetDay);
+
+            // 检查目标日期是否在时间范围内
+            if ((!targetDate.isBefore(startDate)) && (!targetDate.isAfter(endDate))) {
+                result.add(targetDate);
+            }
+        }
+
+        return result;
+    }
+
+    // 测试示例
+    /*public static void main(String[] args) {
+        // 示例1:输入2025-08-23到2025-10-25,每月第1天
+        List<LocalDate> dates1 = getDatesByDayOfMonth("2025-08-23", "2025-10-25", 23);
+        // dates1.forEach(System.out::println); // 输出:2025-09-01 和 2025-10-01
+
+        // 示例2:输入2025-09-01到2025-10-31,每月第31天
+        List<LocalDate> dates2 = getDatesByDayOfMonth("2025-01-01", "2025-12-31", 31);
+        dates2.forEach(System.out::println); // 输出:2025-09-30 和 2025-10-31
+
+        // 其他测试用例
+        // 跨年测试:2024-12-15到2025-02-10,每月第5天
+        List<LocalDate> dates3 = getDatesByDayOfMonth("2024-12-15", "2025-02-10", 5);
+        // dates3.forEach(System.out::println); // 输出:2025-01-05
+
+        // 单月测试:2025-03-01到2025-03-31,每月第31天
+        List<LocalDate> dates4 = getDatesByDayOfMonth("2025-03-01", "2025-03-31", 31);
+        // dates4.forEach(System.out::println); // 输出:2025-03-31
+    }*/
+
+}