Przeglądaj źródła

【feat】【v3】
1.优化公用枚举的命名和存放位置
2.增加节假日信息的获取和判断逻辑

ChenYL 11 miesięcy temu
rodzic
commit
9220a316fb
27 zmienionych plików z 537 dodań i 40 usunięć
  1. 19 0
      doc/sql/update-v3.sql
  2. 32 0
      doc/技术文档.md
  3. 3 3
      src/main/java/com/punchsettle/server/atomic/entity/PunchInMultiTask.java
  4. 9 10
      src/main/java/com/punchsettle/server/atomic/entity/PunchInTask.java
  5. 72 0
      src/main/java/com/punchsettle/server/atomic/entity/SysCalendar.java
  6. 3 3
      src/main/java/com/punchsettle/server/atomic/entity/SysDict.java
  7. 3 3
      src/main/java/com/punchsettle/server/atomic/entity/SysDictItem.java
  8. 15 0
      src/main/java/com/punchsettle/server/atomic/mapper/SysCalendarMapper.java
  9. 33 0
      src/main/java/com/punchsettle/server/atomic/service/ISysCalendarService.java
  10. 3 3
      src/main/java/com/punchsettle/server/common/constant/CommonEnableStatusEnum.java
  11. 23 0
      src/main/java/com/punchsettle/server/common/constant/CommonYesNoEnum.java
  12. 5 0
      src/main/java/com/punchsettle/server/constant/CacheNameConstant.java
  13. 23 0
      src/main/java/com/punchsettle/server/constant/CalendarStatusEnum.java
  14. 7 1
      src/main/java/com/punchsettle/server/feign/OneApiFeign.java
  15. 1 1
      src/main/java/com/punchsettle/server/feign/dto/OneApiResponse.java
  16. 3 3
      src/main/java/com/punchsettle/server/pojo/dict/DictItemQuery.java
  17. 3 3
      src/main/java/com/punchsettle/server/pojo/dict/DictQuery.java
  18. 16 0
      src/main/java/com/punchsettle/server/service/controller/OpController.java
  19. 31 0
      src/main/java/com/punchsettle/server/service/manager/ICalendarManager.java
  20. 11 0
      src/main/java/com/punchsettle/server/service/manager/IOpManager.java
  21. 0 2
      src/main/java/com/punchsettle/server/service/manager/IPunchInManager.java
  22. 108 0
      src/main/java/com/punchsettle/server/service/manager/impl/CalendarManagerImpl.java
  23. 18 0
      src/main/java/com/punchsettle/server/service/manager/impl/OpManagerImpl.java
  24. 5 7
      src/main/java/com/punchsettle/server/service/manager/impl/PunchInManagerImpl.java
  25. 53 0
      src/main/java/com/punchsettle/server/service/manager/impl/SysCalendarServiceImpl.java
  26. 37 0
      src/main/java/com/punchsettle/server/task/CalendarTask.java
  27. 1 1
      src/main/resources/application.yaml

+ 19 - 0
doc/sql/update-v3.sql

@@ -385,6 +385,25 @@ CREATE TABLE `settle_points_history` (
   KEY `idx_SPointsHis_STaskHisId` (`settle_task_history_id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='结算积分记录表';
 
+CREATE TABLE `sys_calendar` (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
+  `gregorian_date` char(10) NOT NULL COMMENT '公历日期,格式:yyyy-MM-dd',
+  `lunar_date` char(10) DEFAULT NULL COMMENT '农历日期,格式:yyyy-MM-dd',
+  `week_day` int DEFAULT NULL COMMENT '周内天数(1-7),周一为1,周日为7',
+  `status` char(7) DEFAULT NULL COMMENT '状态:WORKDAY-上班, HOLIDAY-放假;上班:含正常工作日及补班;放假:含周末及节假日。',
+  `festival` varchar(30) DEFAULT NULL COMMENT '国家法定节日:元旦节, 春节, 清明节, 劳动节, 端午节, 中秋节, 国庆节。',
+  `bad_day` char(1) DEFAULT NULL COMMENT '是否补班:Y-是,N-否;需要补班,真是难受的一天!仅当需要补班时有该字段。',
+  `description` varchar(300) DEFAULT NULL COMMENT '描述,表示什么时候补班,例如劳动节前补班、国庆节后补班等。仅需要补班时有该字段。',
+  `statutory` char(1) DEFAULT NULL COMMENT '是否法定节假日:Y-是,N-否;如果是法定节假日则返回1,仅当是法定节假日时有该字段。',
+  `created_by` bigint NOT NULL COMMENT '创建人',
+  `creation_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+  `last_updated_by` bigint NOT NULL COMMENT '最后更新人',
+  `last_update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间',
+  `version` bigint NOT NULL DEFAULT '1' COMMENT '版本号',
+  `delete_flag` tinyint NOT NULL DEFAULT '0' COMMENT '逻辑删除标志(0-未删除,1-已删除)',
+  PRIMARY KEY (`id`),
+  KEY `idx_SysCalendar_GregorianDate` (`gregorian_date`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='系统日历表';
 
 CREATE TABLE `sys_schedule_task` (
   `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',

+ 32 - 0
doc/技术文档.md

@@ -323,6 +323,14 @@ ui设计工具:即时设计
 
 
 
+## 定时任务
+
+| 定时任务名称 | 执行时间                 | cron表达式  | 实现类       |
+| ------------ | ------------------------ | ----------- | ------------ |
+| 日历定时任务 | 每年1月1日零点零一秒执行 | 1 0 0 1 1 ? | CalendarTask |
+|              |                          |             |              |
+|              |                          |             |              |
+
 
 
 ## 字典
@@ -1062,6 +1070,30 @@ ui设计工具:即时设计
 
 
 
+### 系统日历表
+
+表名:sys_calendar
+
+| 字段             | 类型         | 描述                                                         | 索引     |
+| ---------------- | ------------ | ------------------------------------------------------------ | -------- |
+| id               | bigint       | 主键                                                         | 主键索引 |
+| gregorian_date   | char(10)     | 公历日期,格式:yyyy-MM-dd                                   | 普通索引 |
+| lunar_date       | char(10)     | 农历日期,格式:yyyy-MM-dd                                   |          |
+| week_day         | int          | 周内天数(1-7),周一为1,周日为7                            |          |
+| status           | char(7)      | 状态:WORKDAY-上班, HOLIDAY-放假;上班:含正常工作日及补班;放假:含周末及节假日。 |          |
+| festival         | varhcar(30)  | 国家法定节日:元旦节, 春节, 清明节, 劳动节, 端午节, 中秋节, 国庆节。 |          |
+| bad_day          | char(1)      | 是否补班:Y-是,N-否。需要补班,真是难受的一天!仅当需要补班时有该字段。 |          |
+| description      | varhcar(300) | 描述,表示什么时候补班,例如劳动节前补班、国庆节后补班等。仅需要补班时有该字段。 |          |
+| statutory        | char(1)      | 是否法定节假日:Y-是,N-否。如果是法定节假日则返回1,仅当是法定节假日时有该字段。 |          |
+| created_by       | bigint       | 创建人                                                       |          |
+| creation_time    | timestamp    | 创建时间                                                     |          |
+| last_updated_by  | bigint       | 最后更新人                                                   |          |
+| last_update_time | timestamp    | 最后更新时间                                                 |          |
+| version          | bigint       | 版本号                                                       |          |
+| delete_flag      | tinyint      | 逻辑删除标志(0-未删除,1-已删除)                           |          |
+
+
+
 ## 开发参考
 
 * [两种优雅的获取当前登录用户ID的方式](https://blog.csdn.net/tomorrow9813/article/details/131736382)

+ 3 - 3
src/main/java/com/punchsettle/server/atomic/entity/PunchInMultiTask.java

@@ -7,7 +7,7 @@ import java.math.BigDecimal;
 import com.punchsettle.server.common.pojo.BaseEntity;
 
 import com.punchsettle.server.constant.ArchiveStatusEnum;
-import com.punchsettle.server.constant.CommonStatusEnum;
+import com.punchsettle.server.common.constant.CommonEnableStatusEnum;
 import com.punchsettle.server.constant.ExtraMethodEnum;
 import com.punchsettle.server.constant.PunchInMethodMultiEnum;
 import jakarta.persistence.Column;
@@ -81,10 +81,10 @@ public class PunchInMultiTask extends BaseEntity implements Serializable {
 
     /**
      * 是否启用宽限期(ENABLED-启用,DISABLED-关闭)
-     * @see CommonStatusEnum
+     * @see CommonEnableStatusEnum
      */
     @Column(name = "grace_status")
-    private CommonStatusEnum graceStatus;
+    private CommonEnableStatusEnum graceStatus;
 
     /**
      * 宽限期(单位:天)

+ 9 - 10
src/main/java/com/punchsettle/server/atomic/entity/PunchInTask.java

@@ -4,11 +4,10 @@ import java.io.Serial;
 import java.io.Serializable;
 import java.time.LocalDate;
 import java.time.LocalTime;
-import java.util.Date;
 
 import com.punchsettle.server.common.pojo.BaseEntity;
 import com.punchsettle.server.constant.ArchiveStatusEnum;
-import com.punchsettle.server.constant.CommonStatusEnum;
+import com.punchsettle.server.common.constant.CommonEnableStatusEnum;
 import com.punchsettle.server.constant.CompareRuleEnum;
 import com.punchsettle.server.constant.FullAttendancePeriodEnum;
 import com.punchsettle.server.constant.PunchInMethodEnum;
@@ -122,10 +121,10 @@ public class PunchInTask extends BaseEntity implements Serializable {
 
     /**
      * 是否启用节假日奖励(ENABLED-启用,DISABLED-关闭)
-     * @see CommonStatusEnum
+     * @see CommonEnableStatusEnum
      */
     @Column(name = "holiday_status")
-    private CommonStatusEnum holidayStatus;
+    private CommonEnableStatusEnum holidayStatus;
 
     /**
      * 次数记录(节假日用)
@@ -141,10 +140,10 @@ public class PunchInTask extends BaseEntity implements Serializable {
 
     /**
      * 是否启用全勤奖励(ENABLED-启用,DISABLED-关闭)
-     * @see CommonStatusEnum
+     * @see CommonEnableStatusEnum
      */
     @Column(name = "full_attendance_status")
-    private CommonStatusEnum fullAttendanceStatus;
+    private CommonEnableStatusEnum fullAttendanceStatus;
 
     /**
      * 全勤周期(周-WEEK,月-MONTH)
@@ -186,10 +185,10 @@ public class PunchInTask extends BaseEntity implements Serializable {
 
     /**
      * 是否启用宽限期(ENABLED-启用,DISABLED-关闭)
-     * @see CommonStatusEnum
+     * @see CommonEnableStatusEnum
      */
     @Column(name = "grace_status")
-    private CommonStatusEnum graceStatus;
+    private CommonEnableStatusEnum graceStatus;
 
     /**
      * 宽限期(单位:天)
@@ -211,9 +210,9 @@ public class PunchInTask extends BaseEntity implements Serializable {
 
     /**
      * 是否启用自动打卡(ENABLED-启用,DISABLED-关闭)
-     * @see CommonStatusEnum
+     * @see CommonEnableStatusEnum
      */
     @Column(name = "auto_status")
-    private CommonStatusEnum autoStatus;
+    private CommonEnableStatusEnum autoStatus;
 
 }

+ 72 - 0
src/main/java/com/punchsettle/server/atomic/entity/SysCalendar.java

@@ -0,0 +1,72 @@
+package com.punchsettle.server.atomic.entity;
+
+import com.punchsettle.server.common.constant.CommonYesNoEnum;
+import com.punchsettle.server.common.pojo.BaseEntity;
+import com.punchsettle.server.constant.CalendarStatusEnum;
+import jakarta.persistence.Column;
+import jakarta.persistence.Table;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+
+/**
+ * @author 
+ * 系统日历表
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@Table(name = "sys_calendar")
+public class SysCalendar extends BaseEntity implements Serializable {
+
+    /**
+     * 公历日期,格式:yyyy-MM-dd
+     */
+    @Column(name = "gregorian_date")
+    private String gregorianDate;
+
+    /**
+     * 农历日期,格式:yyyy-MM-dd
+     */
+    @Column(name = "lunar_date")
+    private String lunarDate;
+
+    /**
+     * 周内天数(1-7),周一为1,周日为7
+     */
+    @Column(name = "week_day")
+    private Integer weekDay;
+
+    /**
+     * 状态:WORKDAY-上班, HOLIDAY-放假;上班:含正常工作日及补班;放假:含周末及节假日。
+     * @see CalendarStatusEnum
+     */
+    @Column(name = "status")
+    private CalendarStatusEnum status;
+
+    /**
+     * 国家法定节日:元旦节, 春节, 清明节, 劳动节, 端午节, 中秋节, 国庆节。
+     */
+    @Column(name = "festival")
+    private String festival;
+
+    /**
+     * 是否补班:Y-是,N-否;需要补班,真是难受的一天!仅当需要补班时有该字段。
+     * @see CommonYesNoEnum
+     */
+    @Column(name = "bad_day")
+    private CommonYesNoEnum badDay;
+
+    /**
+     * 描述,表示什么时候补班,例如劳动节前补班、国庆节后补班等。仅需要补班时有该字段。
+     */
+    @Column(name = "description")
+    private String description;
+
+    /**
+     * 是否法定节假日:Y-是,N-否;如果是法定节假日则返回1,仅当是法定节假日时有该字段。
+     * @see CommonYesNoEnum
+     */
+    @Column(name = "statutory")
+    private CommonYesNoEnum statutory;
+}

+ 3 - 3
src/main/java/com/punchsettle/server/atomic/entity/SysDict.java

@@ -5,7 +5,7 @@ import java.io.Serializable;
 
 import com.punchsettle.server.common.pojo.BaseEntity;
 
-import com.punchsettle.server.constant.CommonStatusEnum;
+import com.punchsettle.server.common.constant.CommonEnableStatusEnum;
 import jakarta.persistence.Column;
 import jakarta.persistence.Table;
 import lombok.Data;
@@ -45,8 +45,8 @@ public class SysDict extends BaseEntity implements Serializable {
 
     /**
      * 状态(ENABLED-启用,DISABLED-失效)
-     * @see CommonStatusEnum
+     * @see CommonEnableStatusEnum
      */
     @Column(name = "status")
-    private CommonStatusEnum status;
+    private CommonEnableStatusEnum status;
 }

+ 3 - 3
src/main/java/com/punchsettle/server/atomic/entity/SysDictItem.java

@@ -4,7 +4,7 @@ import java.io.Serial;
 import java.io.Serializable;
 
 import com.punchsettle.server.common.pojo.BaseEntity;
-import com.punchsettle.server.constant.CommonStatusEnum;
+import com.punchsettle.server.common.constant.CommonEnableStatusEnum;
 import com.punchsettle.server.constant.DictDataTypeEnum;
 
 import jakarta.persistence.Column;
@@ -58,8 +58,8 @@ public class SysDictItem extends BaseEntity implements Serializable {
 
     /**
      * 状态(ENABLED-启用,DISABLED-失效)
-     * @see CommonStatusEnum
+     * @see CommonEnableStatusEnum
      */
     @Column(name = "status")
-    private CommonStatusEnum status;
+    private CommonEnableStatusEnum status;
 }

+ 15 - 0
src/main/java/com/punchsettle/server/atomic/mapper/SysCalendarMapper.java

@@ -0,0 +1,15 @@
+package com.punchsettle.server.atomic.mapper;
+
+import com.punchsettle.server.atomic.entity.SysCalendar;
+import tk.mybatis.mapper.common.Mapper;
+import tk.mybatis.mapper.common.special.InsertListMapper;
+
+/**
+ * @author tyuio
+ * @version 1.0.0
+ * @description 系统日历表 mapper
+ * @date 2024/12/12 19:07
+ */
+public interface SysCalendarMapper extends Mapper<SysCalendar>, InsertListMapper<SysCalendar> {
+
+}

+ 33 - 0
src/main/java/com/punchsettle/server/atomic/service/ISysCalendarService.java

@@ -0,0 +1,33 @@
+package com.punchsettle.server.atomic.service;
+
+import com.punchsettle.server.atomic.entity.SysCalendar;
+
+import java.util.List;
+
+/**
+ * @author tyuio
+ * @version 1.0.0
+ * @date 2025/4/14 12:44
+ * @description 系统日历表 service
+ */
+public interface ISysCalendarService {
+
+    /**
+     * 根据公历日期有模糊匹配删除数据
+     * @param gregorianDate 公历日期
+     */
+    void deleteByGregorianDateLike(String gregorianDate);
+
+    /**
+     * 批量插入数据
+     * @param sysCalendarList
+     */
+    void batchInsert(List<SysCalendar> sysCalendarList);
+
+    /**
+     * 根据公历日期查询数据
+     * @param gregorianDate 公历日期
+     * @return
+     */
+    SysCalendar getByGregorianDate(String gregorianDate);
+}

+ 3 - 3
src/main/java/com/punchsettle/server/constant/CommonStatusEnum.java → src/main/java/com/punchsettle/server/common/constant/CommonEnableStatusEnum.java

@@ -1,4 +1,4 @@
-package com.punchsettle.server.constant;
+package com.punchsettle.server.common.constant;
 
 import lombok.AllArgsConstructor;
 import lombok.Getter;
@@ -7,11 +7,11 @@ import lombok.Getter;
  * @author tyuio
  * @version 1.0.0
  * @date 2025/4/8 20:44
- * @description 通用状态枚举(ENABLED-启用,DISABLED-禁用)
+ * @description 通用启用/禁用状态枚举(ENABLED-启用,DISABLED-禁用)
  */
 @Getter
 @AllArgsConstructor
-public enum CommonStatusEnum {
+public enum CommonEnableStatusEnum {
 
     ENABLED("启用"),
     DISABLED("禁用");

+ 23 - 0
src/main/java/com/punchsettle/server/common/constant/CommonYesNoEnum.java

@@ -0,0 +1,23 @@
+package com.punchsettle.server.common.constant;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * @author tyuio
+ * @version 1.0.0
+ * @date 2025/4/14 15:11
+ * @description 通用是否枚举(Y-是,N-否)
+ */
+@Getter
+@AllArgsConstructor
+public enum CommonYesNoEnum {
+
+    Y("是"),
+    N("否");
+
+    /**
+     * 名称
+     */
+    private String name;
+}

+ 5 - 0
src/main/java/com/punchsettle/server/constant/CacheNameConstant.java

@@ -22,4 +22,9 @@ public class CacheNameConstant {
      * 字典项
      */
     public static final String DICT_ITEM_VO_LIST = "dictItemVoList";
+
+    /**
+     * 日期信息
+     */
+    public static final String CALENDAR = "calendar";
 }

+ 23 - 0
src/main/java/com/punchsettle/server/constant/CalendarStatusEnum.java

@@ -0,0 +1,23 @@
+package com.punchsettle.server.constant;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * @author tyuio
+ * @version 1.0.0
+ * @date 2025/4/14 15:04
+ * @description 日历状态枚举:WORKDAY-上班, HOLIDAY-放假;上班:含正常工作日及补班;放假:含周末及节假日。
+ */
+@Getter
+@AllArgsConstructor
+public enum CalendarStatusEnum {
+
+    WORKDAY("上班"),
+    HOLIDAY("放假");
+
+    /**
+     * 名称
+     */
+    private String name;
+}

+ 7 - 1
src/main/java/com/punchsettle/server/feign/OneApiFeign.java

@@ -1,8 +1,13 @@
 package com.punchsettle.server.feign;
 
+import com.punchsettle.server.feign.dto.HolidayData;
 import com.punchsettle.server.feign.dto.HolidayQuery;
 import com.punchsettle.server.feign.dto.OneApiResponse;
 import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.cloud.openfeign.SpringQueryMap;
+import org.springframework.web.bind.annotation.GetMapping;
+
+import java.util.List;
 
 /**
  * @author myou
@@ -18,5 +23,6 @@ public interface OneApiFeign {
      * @param query
      * @return
      */
-    OneApiResponse queryHoliday(HolidayQuery query);
+    @GetMapping("/public/holiday")
+    OneApiResponse<List<HolidayData>> queryHoliday(@SpringQueryMap HolidayQuery query);
 }

+ 1 - 1
src/main/java/com/punchsettle/server/feign/dto/OneApiResponse.java

@@ -14,7 +14,7 @@ import java.io.Serializable;
 public class OneApiResponse<T> implements Serializable {
 
     /**
-     * 响应码
+     * 响应码,0-成功
      */
     private Integer code;
 

+ 3 - 3
src/main/java/com/punchsettle/server/pojo/dict/DictItemQuery.java

@@ -1,6 +1,6 @@
 package com.punchsettle.server.pojo.dict;
 
-import com.punchsettle.server.constant.CommonStatusEnum;
+import com.punchsettle.server.common.constant.CommonEnableStatusEnum;
 import lombok.Data;
 
 /**
@@ -19,7 +19,7 @@ public class DictItemQuery {
 
     /**
      * 状态
-     * @see CommonStatusEnum
+     * @see CommonEnableStatusEnum
      */
-    private CommonStatusEnum status;
+    private CommonEnableStatusEnum status;
 }

+ 3 - 3
src/main/java/com/punchsettle/server/pojo/dict/DictQuery.java

@@ -1,6 +1,6 @@
 package com.punchsettle.server.pojo.dict;
 
-import com.punchsettle.server.constant.CommonStatusEnum;
+import com.punchsettle.server.common.constant.CommonEnableStatusEnum;
 import jakarta.validation.constraints.NotBlank;
 import lombok.Data;
 
@@ -21,7 +21,7 @@ public class DictQuery {
 
     /**
      * 状态(ENABLED-启用,DISABLED-失效)
-     * @see CommonStatusEnum
+     * @see CommonEnableStatusEnum
      */
-    private CommonStatusEnum status;
+    private CommonEnableStatusEnum status;
 }

+ 16 - 0
src/main/java/com/punchsettle/server/service/controller/OpController.java

@@ -30,4 +30,20 @@ public class OpController {
     public void clearCache(@RequestParam @NotBlank(message = "cacheName不能为空") String cacheName) {
         opManager.clearCache(cacheName);
     }
+
+    /**
+     * 调用日历定时任务
+     */
+    @GetMapping("invokeCalendarTask")
+    public void invokeCalendarTask() {
+        opManager.invokeCalendarTask();
+    }
+
+    /**
+     * 根据公历日期刷新指定日历数据
+     */
+    @GetMapping("refreshCalendar")
+    public void refreshCalendar(String gregorianDate) {
+        opManager.refreshCalendar(gregorianDate);
+    }
 }

+ 31 - 0
src/main/java/com/punchsettle/server/service/manager/ICalendarManager.java

@@ -0,0 +1,31 @@
+package com.punchsettle.server.service.manager;
+
+import com.punchsettle.server.atomic.entity.SysCalendar;
+
+/**
+ * @author tyuio
+ * @version 1.0.0
+ * @date 2025/4/14 11:16
+ * @description 日历 服务类
+ */
+public interface ICalendarManager {
+
+    /**
+     * 根据公历日期刷新指定日历数据
+     */
+    void refreshCalendar(String gregorianDate);
+
+    /**
+     * 根据公历日期获取指定日历数据
+     * @param gregorianDate
+     * @return
+     */
+    SysCalendar getCalendarByGregorianDate(String gregorianDate);
+
+    /**
+     * 判断指定日期是否节假日
+     * @param dateStr
+     * @return
+     */
+    boolean judgeHoliday(String dateStr);
+}

+ 11 - 0
src/main/java/com/punchsettle/server/service/manager/IOpManager.java

@@ -13,4 +13,15 @@ public interface IOpManager {
      * @param cacheName 缓存名称
      */
     void clearCache(String cacheName);
+
+    /**
+     * 调用日历定时任务
+     */
+    void invokeCalendarTask();
+
+    /**
+     * 根据公历日期刷新指定日历数据
+     * @param gregorianDate
+     */
+    void refreshCalendar(String gregorianDate);
 }

+ 0 - 2
src/main/java/com/punchsettle/server/service/manager/IPunchInManager.java

@@ -3,11 +3,9 @@ package com.punchsettle.server.service.manager;
 import java.util.List;
 
 import com.punchsettle.server.atomic.entity.PunchInMultiTask;
-import com.punchsettle.server.atomic.entity.PunchInMultiTaskHistory;
 import com.punchsettle.server.atomic.entity.PunchInTask;
 import com.punchsettle.server.atomic.entity.PunchInTaskExt;
 import com.punchsettle.server.atomic.entity.PunchInTaskHistory;
-import com.punchsettle.server.constant.CommonStatusEnum;
 import com.punchsettle.server.constant.PunchInStatusEnum;
 import com.punchsettle.server.pojo.punchin.PunchInDataQuery;
 import com.punchsettle.server.pojo.punchin.PunchInDataVO;

+ 108 - 0
src/main/java/com/punchsettle/server/service/manager/impl/CalendarManagerImpl.java

@@ -0,0 +1,108 @@
+package com.punchsettle.server.service.manager.impl;
+
+import com.punchsettle.server.atomic.entity.SysCalendar;
+import com.punchsettle.server.atomic.service.ISysCalendarService;
+import com.punchsettle.server.common.constant.CommonYesNoEnum;
+import com.punchsettle.server.common.utils.Assert;
+import com.punchsettle.server.constant.CacheNameConstant;
+import com.punchsettle.server.constant.CalendarStatusEnum;
+import com.punchsettle.server.feign.OneApiFeign;
+import com.punchsettle.server.feign.dto.HolidayData;
+import com.punchsettle.server.feign.dto.HolidayQuery;
+import com.punchsettle.server.feign.dto.OneApiResponse;
+import com.punchsettle.server.service.manager.ICalendarManager;
+import com.punchsettle.server.utiis.SpringUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.CacheManager;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+
+import javax.swing.*;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * @author tyuio
+ * @version 1.0.0
+ * @date 2025/4/14 15:56
+ * @description 日历 服务类
+ */
+@Slf4j
+@Component
+public class CalendarManagerImpl implements ICalendarManager {
+
+    @Autowired
+    private OneApiFeign oneApiFeign;
+
+    @Autowired
+    private ISysCalendarService sysCalendarService;
+
+    @Autowired
+    private CacheManager cacheManager;
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void refreshCalendar(String gregorianDate) {
+        Assert.isNullInBusiness(gregorianDate, "公历日期不能为空");
+        // 获取日历数据
+        HolidayQuery holidayQuery = new HolidayQuery();
+        holidayQuery.setQueryType(2);
+        holidayQuery.setDate(gregorianDate);
+        OneApiResponse<List<HolidayData>> oneApiResponse = oneApiFeign.queryHoliday(holidayQuery);
+        if (oneApiResponse.getCode() != 0) {
+            log.error("获取日历数据失败,查询日期:{},查询类型:{},错误信息:{}", holidayQuery.getQueryType(), holidayQuery.getDate(), oneApiResponse.getMsg());
+            return;
+        }
+
+        List<HolidayData> holidayDataList = oneApiResponse.getData();
+        if (CollectionUtils.isEmpty(holidayDataList)) {
+            log.info("获取日历数据为空,查询日期:{},查询类型:{},错误信息:{}", holidayQuery.getQueryType(), holidayQuery.getDate());
+            return;
+        }
+
+        List<SysCalendar> addCalendarList = holidayDataList.stream().map(holidayData -> {
+            SysCalendar sysCalendar = new SysCalendar();
+            BeanUtils.copyProperties(holidayData, sysCalendar);
+            sysCalendar.setGregorianDate(holidayData.getDate());
+            if (holidayData.getStatus() == 1) {
+                sysCalendar.setStatus(CalendarStatusEnum.WORKDAY);
+            }
+            if (holidayData.getStatus() == 2) {
+                sysCalendar.setStatus(CalendarStatusEnum.HOLIDAY);
+            }
+            sysCalendar.setBadDay(Objects.nonNull(holidayData.getBadDay()) && holidayData.getBadDay() == 1 ? CommonYesNoEnum.Y : CommonYesNoEnum.N);
+            sysCalendar.setStatutory(Objects.nonNull(holidayData.getStatutory()) && holidayData.getStatutory() == 1 ? CommonYesNoEnum.Y : CommonYesNoEnum.N);
+            return sysCalendar;
+        }).collect(Collectors.toList());
+
+        // 删除历史数据
+        sysCalendarService.deleteByGregorianDateLike(gregorianDate);
+
+        // 数据入库
+        sysCalendarService.batchInsert(addCalendarList);
+    }
+
+    @Override
+    @Cacheable(value = CacheNameConstant.CALENDAR, key = "#gregorianDate", unless = "#result == null")
+    public SysCalendar getCalendarByGregorianDate(String gregorianDate) {
+        Assert.isNullInBusiness(gregorianDate, "公历日期不能为空");
+        // 先尝试从数据库中获取,没有再拉取数据
+        SysCalendar sysCalendar = sysCalendarService.getByGregorianDate(gregorianDate);
+        if (Objects.isNull(sysCalendar)) {
+            SpringUtils.getBean(CalendarManagerImpl.class).refreshCalendar(gregorianDate);
+        }
+        return sysCalendarService.getByGregorianDate(gregorianDate);
+    }
+
+    @Override
+    public boolean judgeHoliday(String gregorianDate) {
+        Assert.isNullInBusiness(gregorianDate, "公历日期不能为空");
+        SysCalendar sysCalendar = SpringUtils.getBean(CalendarManagerImpl.class).getCalendarByGregorianDate(gregorianDate);
+        return CalendarStatusEnum.HOLIDAY.equals(sysCalendar);
+    }
+}

+ 18 - 0
src/main/java/com/punchsettle/server/service/manager/impl/OpManagerImpl.java

@@ -1,7 +1,9 @@
 package com.punchsettle.server.service.manager.impl;
 
 import com.punchsettle.server.common.exception.BusinessException;
+import com.punchsettle.server.service.manager.ICalendarManager;
 import com.punchsettle.server.service.manager.IOpManager;
+import com.punchsettle.server.task.CalendarTask;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.cache.Cache;
@@ -23,6 +25,12 @@ public class OpManagerImpl implements IOpManager {
     @Autowired
     private CacheManager cacheManager;
 
+    @Autowired
+    private CalendarTask calendarTask;
+
+    @Autowired
+    private ICalendarManager calendarManager;
+
     @Override
     public void clearCache(String cacheName) {
         Cache cache = cacheManager.getCache(cacheName);
@@ -31,4 +39,14 @@ public class OpManagerImpl implements IOpManager {
         }
         cache.clear();
     }
+
+    @Override
+    public void invokeCalendarTask() {
+        calendarTask.execute();
+    }
+
+    @Override
+    public void refreshCalendar(String gregorianDate) {
+        calendarManager.refreshCalendar(gregorianDate);
+    }
 }

+ 5 - 7
src/main/java/com/punchsettle/server/service/manager/impl/PunchInManagerImpl.java

@@ -3,7 +3,6 @@ package com.punchsettle.server.service.manager.impl;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.text.SimpleDateFormat;
-import java.time.DayOfWeek;
 import java.time.LocalDate;
 import java.time.LocalTime;
 import java.time.YearMonth;
@@ -35,11 +34,10 @@ import com.punchsettle.server.atomic.service.IPunchInRecordService;
 import com.punchsettle.server.atomic.service.IPunchInService;
 import com.punchsettle.server.common.exception.BusinessException;
 import com.punchsettle.server.common.utils.Assert;
-import com.punchsettle.server.constant.CommonStatusEnum;
+import com.punchsettle.server.common.constant.CommonEnableStatusEnum;
 import com.punchsettle.server.constant.CompareRuleEnum;
 import com.punchsettle.server.constant.PunchInCategoryEnum;
 import com.punchsettle.server.constant.PunchInMethodEnum;
-import com.punchsettle.server.constant.PunchInRuleEnum;
 import com.punchsettle.server.constant.PunchInSettleTypeEnum;
 import com.punchsettle.server.constant.PunchInStatusEnum;
 import com.punchsettle.server.constant.PunchInStatusV1Enum;
@@ -497,8 +495,8 @@ public class PunchInManagerImpl implements IPunchInManager {
         }
 
         // 打卡任务的节假日启用配置
-        CommonStatusEnum holidayStatus = Optional.ofNullable(punchInTask.getHolidayStatus()).orElse(CommonStatusEnum.DISABLED);
-        boolean enableHolidayFlag = CommonStatusEnum.ENABLED.equals(holidayStatus) && holidayFlag;
+        CommonEnableStatusEnum holidayStatus = Optional.ofNullable(punchInTask.getHolidayStatus()).orElse(CommonEnableStatusEnum.DISABLED);
+        boolean enableHolidayFlag = CommonEnableStatusEnum.ENABLED.equals(holidayStatus) && holidayFlag;
 
         // 计数打卡,要区分是否节假日使用不同的判断标准
         if (PunchInMethodEnum.COUNT.equals(punchInTask.getPunchInMethod())) {
@@ -574,12 +572,12 @@ public class PunchInManagerImpl implements IPunchInManager {
         int points = Optional.ofNullable(punchInTask.getPoints()).orElse(0);
 
         // 启用了全勤奖励
-        if (CommonStatusEnum.ENABLED.equals(punchInTask.getFullAttendanceStatus())) {
+        if (CommonEnableStatusEnum.ENABLED.equals(punchInTask.getFullAttendanceStatus())) {
 
         }
 
         // 启用了法定节假日(含周末)双倍奖励
-        if (CommonStatusEnum.ENABLED.equals(punchInTask.getHolidayStatus()) && judgeHoliday(punchInTaskHistory.getPunchInDate())) {
+        if (CommonEnableStatusEnum.ENABLED.equals(punchInTask.getHolidayStatus()) && judgeHoliday(punchInTaskHistory.getPunchInDate())) {
             points *= 2;
         }
 

+ 53 - 0
src/main/java/com/punchsettle/server/service/manager/impl/SysCalendarServiceImpl.java

@@ -0,0 +1,53 @@
+package com.punchsettle.server.service.manager.impl;
+
+import com.punchsettle.server.atomic.entity.SysCalendar;
+import com.punchsettle.server.atomic.mapper.SysCalendarMapper;
+import com.punchsettle.server.atomic.service.ISysCalendarService;
+import com.punchsettle.server.common.utils.Assert;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
+import tk.mybatis.mapper.weekend.Weekend;
+import tk.mybatis.mapper.weekend.WeekendCriteria;
+
+import java.util.List;
+
+/**
+ * @author tyuio
+ * @version 1.0.0
+ * @date 2025/4/14 12:44
+ * @description 系统日历表 service
+ */
+@Service
+public class SysCalendarServiceImpl implements ISysCalendarService {
+
+    @Autowired
+    private SysCalendarMapper sysCalendarMapper;
+
+    @Override
+    public void deleteByGregorianDateLike(String gregorianDate) {
+        Assert.isNull(gregorianDate);
+
+        Weekend<SysCalendar> weekend = Weekend.of(SysCalendar.class);
+        WeekendCriteria<SysCalendar, Object> criteria = weekend.weekendCriteria();
+        criteria.andLike(SysCalendar::getGregorianDate, String.format("%s%%", gregorianDate));
+        sysCalendarMapper.deleteByExample(weekend);
+    }
+
+    @Override
+    public void batchInsert(List<SysCalendar> sysCalendarList) {
+        Assert.notEmpty(sysCalendarList);
+        sysCalendarMapper.insertList(sysCalendarList);
+    }
+
+    @Override
+    public SysCalendar getByGregorianDate(String gregorianDate) {
+        if (StringUtils.hasText(gregorianDate)) {
+            return null;
+        }
+
+        SysCalendar calendarQuery = new SysCalendar();
+        calendarQuery.setGregorianDate(gregorianDate);
+        return sysCalendarMapper.selectOne(calendarQuery);
+    }
+}

+ 37 - 0
src/main/java/com/punchsettle/server/task/CalendarTask.java

@@ -0,0 +1,37 @@
+package com.punchsettle.server.task;
+
+import java.time.LocalDate;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import com.punchsettle.server.service.manager.ICalendarManager;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * @author tyuio
+ * @version 1.0.0
+ * @date 2025/4/14 12:57
+ * @description 日历定时任务,每年1月1日零点零一秒执行
+ */
+@Slf4j
+@Component
+public class CalendarTask {
+
+    @Autowired
+    private ICalendarManager calendarManager;
+
+    @Scheduled(cron = "1 0 0 1 1 ?")
+    public void execute() {
+        log.info("========== 日历定时任务 开始执行 ==========");
+
+        // 当前公历日期
+        int currentYear = LocalDate.now().getYear();
+        String gregorianDate = String.valueOf(currentYear);
+        calendarManager.refreshCalendar(gregorianDate);
+
+        log.info("========== 日历定时任务 结束执行 ==========");
+    }
+}

+ 1 - 1
src/main/resources/application.yaml

@@ -18,4 +18,4 @@ jasypt:
 
 # one-api接口平台
 one-api:
-  url: https://oneapi.coderbox.cn/openapi/public/holiday
+  url: https://oneapi.coderbox.cn/openapi