Pārlūkot izejas kodu

【feat】【v3】
1.完善打卡结算逻辑

ChenYL 11 mēneši atpakaļ
vecāks
revīzija
d255a96e72
25 mainītis faili ar 536 papildinājumiem un 264 dzēšanām
  1. 2 3
      doc/技术文档.md
  2. 3 4
      src/main/java/com/punchsettle/server/atomic/entity/PiMultiTaskHistory.java
  3. 6 4
      src/main/java/com/punchsettle/server/atomic/entity/PiStatus.java
  4. 3 4
      src/main/java/com/punchsettle/server/atomic/entity/PiStatusHistory.java
  5. 1 1
      src/main/java/com/punchsettle/server/atomic/entity/PiTask.java
  6. 12 8
      src/main/java/com/punchsettle/server/atomic/entity/PiTaskHistory.java
  7. 2 2
      src/main/java/com/punchsettle/server/atomic/service/impl/PiTaskServiceImpl.java
  8. 25 0
      src/main/java/com/punchsettle/server/constant/ContinueStageEnum.java
  9. 3 3
      src/main/java/com/punchsettle/server/constant/ContinueStatusEnum.java
  10. 2 2
      src/main/java/com/punchsettle/server/constant/PunchInResultEnum.java
  11. 23 0
      src/main/java/com/punchsettle/server/constant/SettleResultEnum.java
  12. 0 3
      src/main/java/com/punchsettle/server/constant/SettleStatusEnum.java
  13. 1 13
      src/main/java/com/punchsettle/server/pojo/punchIn/PiTaskData.java
  14. 2 2
      src/main/java/com/punchsettle/server/pojo/punchIn/PiTaskQuery.java
  15. 2 2
      src/main/java/com/punchsettle/server/pojo/punchIn/PunchInSettleData.java
  16. 17 0
      src/main/java/com/punchsettle/server/service/manager/ICalendarManager.java
  17. 34 5
      src/main/java/com/punchsettle/server/service/manager/IPunchInManager.java
  18. 3 3
      src/main/java/com/punchsettle/server/service/manager/IPunchInManagerV1.java
  19. 1 12
      src/main/java/com/punchsettle/server/service/manager/ISettleManager.java
  20. 21 0
      src/main/java/com/punchsettle/server/service/manager/impl/CalendarManagerImpl.java
  21. 139 15
      src/main/java/com/punchsettle/server/service/manager/impl/PunchInManagerImpl.java
  22. 21 21
      src/main/java/com/punchsettle/server/service/manager/impl/PunchInManagerV1Impl.java
  23. 25 72
      src/main/java/com/punchsettle/server/service/manager/impl/SettleManagerImpl.java
  24. 149 77
      src/main/java/com/punchsettle/server/task/PunchInCoreTask.java
  25. 39 8
      src/main/java/com/punchsettle/server/utiis/DateUtils.java

+ 2 - 3
doc/技术文档.md

@@ -112,11 +112,10 @@ ui设计工具:即时设计
   3. 如果N天宽限期后一直没有完成打卡,则一直处于宽限期
 * 正常打卡期:
   1. 如果完成打卡,允许结算积分和计算连续打卡天数
-  2. 如果没有完成打卡(连续打卡中断),则进入惩罚期
+  2. 如果没有完成打卡(连续打卡中断),则进入惩罚期,且接下来**Y天是惩罚时间且连续打卡天数重置(归零)**,如果**连续进入惩罚期的次数**等于中断X次,则重新进入宽限期
 * 惩罚期:
-  1. 如果没有完成打卡,则接下来**Y天是惩罚时间且连续打卡天数重置(归零)**,期间完成打卡也不结算积分、不计算连续打卡天数
+  1. 在Y天的惩罚时间内完成打卡也不结算积分、不计算连续打卡天数
   2. Y天的惩罚时间结束后,自动返回正常打卡期
-  3. 如果**连续进入惩罚期的次数**等于中断X次,则重新进入宽限期
 
 
 

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

@@ -6,12 +6,11 @@ import java.time.LocalDate;
 
 import com.punchsettle.server.common.pojo.BaseEntity;
 
-import com.punchsettle.server.constant.PunchInStatusEnum;
+import com.punchsettle.server.constant.PunchInResultEnum;
 import jakarta.persistence.Column;
 import jakarta.persistence.Table;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
-import org.springframework.beans.factory.annotation.Autowired;
 
 /**
  * @author tyuio
@@ -96,10 +95,10 @@ public class PiMultiTaskHistory extends BaseEntity implements Serializable {
 
     /**
      * 打卡结果(DONE-完成,UNDONE-未完成)
-     * @see PunchInStatusEnum
+     * @see PunchInResultEnum
      */
     @Column(name = "punch_in_result")
-    private PunchInStatusEnum punchInResult;
+    private PunchInResultEnum punchInResult;
 
     /**
      * 结算结果(未结算-UNSETTLED,已结算-SETTLED)

+ 6 - 4
src/main/java/com/punchsettle/server/atomic/entity/PiStatus.java

@@ -6,7 +6,8 @@ import java.math.BigDecimal;
 import java.time.LocalDate;
 
 import com.punchsettle.server.common.pojo.BaseEntity;
-import com.punchsettle.server.constant.ConsecutiveStatusEnum;
+import com.punchsettle.server.constant.ContinueStageEnum;
+import com.punchsettle.server.constant.ContinueStatusEnum;
 import jakarta.persistence.Column;
 import jakarta.persistence.Table;
 import lombok.Data;
@@ -52,10 +53,10 @@ public class PiStatus extends BaseEntity implements Serializable {
 
     /**
      * 任务连续打卡状态(连续打卡-CONTINUE、中断-INTERRUPTED)
-     * @see ConsecutiveStatusEnum
+     * @see ContinueStatusEnum
      */
     @Column(name = "task_continue_status")
-    private ConsecutiveStatusEnum taskContinueStatus;
+    private ContinueStatusEnum taskContinueStatus;
 
     /**
      * 任务连续天数,第一天开始就等于1
@@ -65,9 +66,10 @@ public class PiStatus extends BaseEntity implements Serializable {
 
     /**
      * 连续阶段(宽限期-GRACE_STAGE,正常打卡期-NORMAL_STAGE,惩罚期-PENALTY_STAGE)
+     * @see ContinueStageEnum
      */
     @Column(name = "continue_stage")
-    private String continueStage;
+    private ContinueStageEnum continueStage;
 
     /**
      * 阶段开始日期

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

@@ -4,10 +4,9 @@ import java.io.Serial;
 import java.io.Serializable;
 import java.math.BigDecimal;
 import java.time.LocalDate;
-import java.util.Date;
 
 import com.punchsettle.server.common.pojo.BaseEntity;
-import com.punchsettle.server.constant.ConsecutiveStatusEnum;
+import com.punchsettle.server.constant.ContinueStatusEnum;
 import jakarta.persistence.Column;
 import jakarta.persistence.Table;
 import lombok.Data;
@@ -53,10 +52,10 @@ public class PiStatusHistory extends BaseEntity implements Serializable {
 
     /**
      * 任务连续打卡状态(连续打卡-CONTINUE、中断-INTERRUPTED)
-     * @see ConsecutiveStatusEnum
+     * @see ContinueStatusEnum
      */
     @Column(name = "task_continue_status")
-    private ConsecutiveStatusEnum taskContinueStatus;
+    private ContinueStatusEnum taskContinueStatus;
 
     /**
      * 任务连续天数,第一天开始就等于1

+ 1 - 1
src/main/java/com/punchsettle/server/atomic/entity/PiTask.java

@@ -208,7 +208,7 @@ public class PiTask extends BaseEntity implements Serializable {
      * 连续中断次数
      */
     @Column(name = "continue_interrupted_count")
-    private Integer continueInterruptedDay;
+    private Integer continueInterruptedCount;
 
     /**
      * 惩罚天数(单位:天)

+ 12 - 8
src/main/java/com/punchsettle/server/atomic/entity/PiTaskHistory.java

@@ -6,10 +6,11 @@ import java.time.LocalDate;
 import java.time.LocalTime;
 
 import com.punchsettle.server.common.pojo.BaseEntity;
-import com.punchsettle.server.constant.ConsecutiveStatusEnum;
-import com.punchsettle.server.constant.PunchInStatusEnum;
-import com.punchsettle.server.constant.SettleStatusEnum;
+import com.punchsettle.server.constant.ContinueStageEnum;
+import com.punchsettle.server.constant.ContinueStatusEnum;
+import com.punchsettle.server.constant.PunchInResultEnum;
 
+import com.punchsettle.server.constant.SettleResultEnum;
 import jakarta.persistence.Column;
 import jakarta.persistence.Table;
 import lombok.Data;
@@ -62,9 +63,10 @@ public class PiTaskHistory extends BaseEntity implements Serializable {
 
     /**
      * 任务连续打卡状态(连续打卡-CONTINUE、中断-INTERRUPTED)
+     * @see ContinueStatusEnum
      */
     @Column(name = "task_continue_status")
-    private String taskContinueStatus;
+    private ContinueStatusEnum taskContinueStatus;
 
     /**
      * 任务连续天数,第一天开始就等于1
@@ -74,9 +76,10 @@ public class PiTaskHistory extends BaseEntity implements Serializable {
 
     /**
      * 连续阶段(宽限期-GRACE_STAGE,正常打卡期-NORMAL_STAGE,惩罚期-PENALTY_STAGE)
+     * @see ContinueStageEnum
      */
     @Column(name = "continue_stage")
-    private String continueStage;
+    private ContinueStageEnum continueStage;
 
     /**
      * 阶段开始日期
@@ -98,16 +101,17 @@ public class PiTaskHistory extends BaseEntity implements Serializable {
 
     /**
      * 打卡结果(DONE-完成,UNDONE-未完成)
-     * @see PunchInStatusEnum
+     * @see PunchInResultEnum
      */
     @Column(name = "punch_in_result")
-    private PunchInStatusEnum punchInResult;
+    private PunchInResultEnum punchInResult;
 
     /**
      * 结算结果(未结算-UNSETTLED,已结算-SETTLED)
+     * @see SettleResultEnum
      */
     @Column(name = "settle_result")
-    private String settleResult;
+    private SettleResultEnum settleResult;
 
     /**
      * 结算任务执行ID

+ 2 - 2
src/main/java/com/punchsettle/server/atomic/service/impl/PiTaskServiceImpl.java

@@ -33,8 +33,8 @@ public class PiTaskServiceImpl implements IPiTaskService {
 
         Weekend<PiTask> weekend = WeekendUtils.createExcludeAuditFields(PiTask.class);
         WeekendCriteria<PiTask, Object> criteria = weekend.weekendCriteria();
-        if (!CollectionUtils.isEmpty(piTaskQuery.getTaskUniqueIds())) {
-            criteria.andIn(PiTask::getUniqueId, piTaskQuery.getTaskUniqueIds());
+        if (!CollectionUtils.isEmpty(piTaskQuery.getUserIds())) {
+            criteria.andIn(PiTask::getCreatedBy, piTaskQuery.getUserIds());
         }
         if (Objects.nonNull(piTaskQuery.getTaskStatus())) {
             criteria.andEqualTo(PiTask::getTaskStatus, piTaskQuery.getTaskStatus());

+ 25 - 0
src/main/java/com/punchsettle/server/constant/ContinueStageEnum.java

@@ -0,0 +1,25 @@
+package com.punchsettle.server.constant;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * @author tyuio
+ * @version 1.0.0
+ * @date 2025/4/17 20:30
+ * @description 连续阶段枚举(无启用-NONE,宽限期-GRACE_STAGE,正常打卡期-NORMAL_STAGE,惩罚期-PENALTY_STAGE
+ */
+@Getter
+@AllArgsConstructor
+public enum ContinueStageEnum {
+
+    NONE("无启用"),
+    GRACE_STAGE("宽限期"),
+    NORMAL_STAGE("正常打卡期"),
+    PENALTY_STAGE("惩罚期");
+
+    /**
+     * 名称
+     */
+    private String name;
+}

+ 3 - 3
src/main/java/com/punchsettle/server/constant/ConsecutiveStatusEnum.java → src/main/java/com/punchsettle/server/constant/ContinueStatusEnum.java

@@ -7,13 +7,13 @@ import lombok.Getter;
  * @author tyuio
  * @version 1.0.0
  * @date 2025/4/9 12:24
- * @description 连续打卡状态枚举(连续打卡-NORMAL、中断--INTERRUPTED)
+ * @description 连续打卡状态枚举(连续打卡-CONTINUE、中断--INTERRUPTED)
  */
 @Getter
 @AllArgsConstructor
-public enum ConsecutiveStatusEnum {
+public enum ContinueStatusEnum {
 
-    CONSECUTIVE("连续打卡"),
+    CONTINUE("连续打卡"),
     INTERRUPTED("中断打卡");
 
     /**

+ 2 - 2
src/main/java/com/punchsettle/server/constant/PunchInStatusEnum.java → src/main/java/com/punchsettle/server/constant/PunchInResultEnum.java

@@ -7,11 +7,11 @@ import lombok.Getter;
  * @author tyuio
  * @version 1.0.0
  * @date 2025/4/9 12:22
- * @description 打卡状态枚举(DONE-完成,UNDONE-未完成)
+ * @description 打卡结果枚举(DONE-完成,UNDONE-未完成)
  */
 @Getter
 @AllArgsConstructor
-public enum PunchInStatusEnum {
+public enum PunchInResultEnum {
 
     DONE("完成"),
     UNDONE("未完成");

+ 23 - 0
src/main/java/com/punchsettle/server/constant/SettleResultEnum.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/17 22:26
+ * @description 结算结果枚举(未结算-UNSETTLED,已结算-SETTLED)
+ */
+@Getter
+@AllArgsConstructor
+public enum SettleResultEnum {
+
+    UNSETTLED("未结算"),
+    SETTLED("已结算");
+
+    /**
+     * 名称
+     */
+    private String name;
+}

+ 0 - 3
src/main/java/com/punchsettle/server/constant/SettleStatusEnum.java

@@ -14,9 +14,6 @@ import lombok.Getter;
 public enum SettleStatusEnum {
 
     UNSETTLED("未结算"),
-    GRACE_SKIP("宽限期跳过"),
-    PENALTY_SKIP("惩罚跳过"),
-    UNDONE_SKIP("未完成打卡跳过"),
     SETTLED("已结算");
 
     /**

+ 1 - 13
src/main/java/com/punchsettle/server/pojo/punchIn/PiTaskDto.java → src/main/java/com/punchsettle/server/pojo/punchIn/PiTaskData.java

@@ -2,8 +2,6 @@ package com.punchsettle.server.pojo.punchIn;
 
 import java.util.List;
 
-import com.punchsettle.server.atomic.entity.StatPiTaskMonth;
-import com.punchsettle.server.atomic.entity.StatPiTaskWeek;
 import com.punchsettle.server.atomic.entity.PiStatus;
 import com.punchsettle.server.atomic.entity.PiTask;
 import com.punchsettle.server.atomic.entity.PiTaskExt;
@@ -18,7 +16,7 @@ import lombok.Data;
  * @description 打卡结算 DTO
  */
 @Data
-public class PiTaskDto {
+public class PiTaskData {
 
     /**
      * 打卡任务
@@ -35,16 +33,6 @@ public class PiTaskDto {
      */
     private PiTaskHistory piTaskHistory;
 
-    /**
-     * 打卡周数据据统计
-     */
-    private StatPiTaskWeek statPiTaskWeek;
-
-    /**
-     * 打卡月数据据统计
-     */
-    private StatPiTaskMonth statPiTaskMonth;
-
     /**
      * 打卡状态
      */

+ 2 - 2
src/main/java/com/punchsettle/server/pojo/punchIn/PiTaskQuery.java

@@ -15,9 +15,9 @@ import lombok.Data;
 public class PiTaskQuery {
 
     /**
-     * 打卡任务唯一ID列表
+     * 用户ID列表
      */
-    private Collection<Long> taskUniqueIds;
+    private Collection<Long> userIds;
 
     /**
      * 任务状态(活跃-ACTIVE,归档-ARCHIVE)

+ 2 - 2
src/main/java/com/punchsettle/server/pojo/punchIn/PunchInSettleDto.java → src/main/java/com/punchsettle/server/pojo/punchIn/PunchInSettleData.java

@@ -16,7 +16,7 @@ import java.util.List;
  * @description 打卡结算 DTO
  */
 @Data
-public class PunchInSettleDto {
+public class PunchInSettleData {
 
     /**
      * 用户ID
@@ -51,5 +51,5 @@ public class PunchInSettleDto {
     /**
      * 打卡任务列表
      */
-    private List<PiTaskDto> piTaskDtoList;
+    private List<PiTaskData> piTaskDataList;
 }

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

@@ -2,6 +2,8 @@ package com.punchsettle.server.service.manager;
 
 import com.punchsettle.server.atomic.entity.SysCalendar;
 
+import java.util.List;
+
 /**
  * @author tyuio
  * @version 1.0.0
@@ -22,10 +24,25 @@ public interface ICalendarManager {
      */
     SysCalendar getCalendarByGregorianDate(String gregorianDate);
 
+    /**
+     * 根据日期范围获取指定日历数据
+     * @param gregorianStartDate 公历开始日期(格式:yyyy-MM-dd)
+     * @param gregorianStartDate 公历结束日期(格式:yyyy-MM-dd)
+     * @return
+     */
+    List<SysCalendar> getCalendarByRangeDate(String gregorianStartDate, String gregorianEndDate);
+
     /**
      * 判断指定日期是否节假日
      * @param gregorianDate 日期格式:yyyy-MM-dd
      * @return
      */
     boolean judgeHoliday(String gregorianDate);
+
+    /**
+     * 判断指定日期是否工作日
+     * @param gregorianDate 日期格式:yyyy-MM-dd
+     * @return
+     */
+    boolean judgeWorkday(String gregorianDate);
 }

+ 34 - 5
src/main/java/com/punchsettle/server/service/manager/IPunchInManager.java

@@ -1,10 +1,13 @@
 package com.punchsettle.server.service.manager;
 
 import com.punchsettle.server.atomic.entity.PiMultiTask;
+import com.punchsettle.server.atomic.entity.PiStatus;
 import com.punchsettle.server.atomic.entity.PiTask;
 import com.punchsettle.server.atomic.entity.PiTaskHistory;
-import com.punchsettle.server.constant.PunchInStatusEnum;
+import com.punchsettle.server.constant.ContinueStageEnum;
+import com.punchsettle.server.constant.PunchInResultEnum;
 
+import java.time.LocalDate;
 import java.util.List;
 
 /**
@@ -24,18 +27,44 @@ public interface IPunchInManager {
     boolean judgeRepeat(PiTask piTask, String repeatDateStr);
 
     /**
-     * 判断打卡状态
+     * 判断打卡结果
      * @param piTask 当前打卡任务
      * @param piTaskHistory 打卡记录
      * @return
      */
-    PunchInStatusEnum judgePunchInStatusInTask(PiTask piTask, PiTaskHistory piTaskHistory);
+    PunchInResultEnum judgePunchInResultInTask(PiTask piTask, PiTaskHistory piTaskHistory);
 
     /**
-     * 判断打卡状态(多任务)
+     * 判断打卡结果(多任务)
      * @param piMultiTask 打卡多任务任务
      * @param piTaskHistoryList 打卡记录
      * @return
      */
-    PunchInStatusEnum judgePunchInStatusInMultiTask(PiMultiTask piMultiTask, List<PiTaskHistory> piTaskHistoryList);
+    PunchInResultEnum judgePunchInResultInMultiTask(PiMultiTask piMultiTask, List<PiTaskHistory> piTaskHistoryList);
+
+    /**
+     * 根据打卡任务获取指定日期所在周需打卡总次数
+     * @param piTask 打卡任务
+     * @param specifiedDateStr 指定日期
+     * @return
+     */
+    int getPunchInTotalCountInWeek(PiTask piTask, String specifiedDateStr);
+
+    /**
+     * 根据打卡任务获取指定日期所在月需打卡总次数
+     * @param piTask 打卡任务
+     * @param specifiedDateStr 指定日期
+     * @return
+     */
+    int getPunchInTotalCountInMonth(PiTask piTask, String specifiedDateStr);
+
+    /**
+     * 判断打卡任务在指定日期的连续打卡阶段
+     * @param piTask
+     * @param piTaskHistory
+     * @param piStatus
+     * @param punchInDate
+     * @return
+     */
+    ContinueStageEnum judgeContinueStageInTask(PiTask piTask, PiTaskHistory piTaskHistory, PiStatus piStatus, LocalDate punchInDate);
 }

+ 3 - 3
src/main/java/com/punchsettle/server/service/manager/IPunchInManagerV1.java

@@ -11,7 +11,7 @@ import com.punchsettle.server.atomic.entity.PiStatus;
 import com.punchsettle.server.atomic.entity.PiTask;
 import com.punchsettle.server.atomic.entity.PiTaskExt;
 import com.punchsettle.server.atomic.entity.PiTaskHistory;
-import com.punchsettle.server.constant.PunchInStatusEnum;
+import com.punchsettle.server.constant.PunchInResultEnum;
 import com.punchsettle.server.pojo.punchinV1.PunchInDataQuery;
 import com.punchsettle.server.pojo.punchinV1.PunchInDataVO;
 import com.punchsettle.server.pojo.punchinV1.PunchInRecordRequest;
@@ -96,7 +96,7 @@ public interface IPunchInManagerV1 {
      * @param holidayFlag 是否是节假日(是-true,否-false)
      * @return
      */
-    PunchInStatusEnum judgePunchInStatusInTask(PiTask piTask, PiTaskHistory piTaskHistory, boolean holidayFlag);
+    PunchInResultEnum judgePunchInStatusInTask(PiTask piTask, PiTaskHistory piTaskHistory, boolean holidayFlag);
 
     /**
      * 判断打卡状态(多任务)
@@ -105,7 +105,7 @@ public interface IPunchInManagerV1 {
      * @param multiTaskNum 参与多任务计算数量
      * @return
      */
-    PunchInStatusEnum judgePunchInStatusInMultiTask(PiMultiTask piMultiTask, List<PiTaskHistory> piTaskHistoryList, int multiTaskNum);
+    PunchInResultEnum judgePunchInStatusInMultiTask(PiMultiTask piMultiTask, List<PiTaskHistory> piTaskHistoryList, int multiTaskNum);
 
     /**
      * 计算任务积分

+ 1 - 12
src/main/java/com/punchsettle/server/service/manager/ISettleManager.java

@@ -21,26 +21,15 @@ import java.util.List;
  */
 public interface ISettleManager {
 
-    /**
-     * 判断打卡任务结算状态
-     * @param piTask 打卡任务
-     * @param piTaskHistory 打卡记录
-     * @param piStatus 打卡状态
-     * @return 结算状态
-     */
-    SettleStatusEnum judgeSettleStatusInTask(PiTask piTask, PiTaskHistory piTaskHistory, PiStatus piStatus);
-
     /**
      * 计算任务积分
      * @param piTask 打卡任务
      * @param piTaskExtList 打卡任务拓展信息列表
      * @param piTaskHistory 打卡记录
-     * @param statPiTaskWeek 打卡周统计
-     * @param statPiTaskMonth 打卡月统计
      * @param piStatus 打卡统计
      * @return 积分
      */
-    int calculatePointsInTask(PiTask piTask, List<PiTaskExt> piTaskExtList, PiTaskHistory piTaskHistory, StatPiTaskWeek statPiTaskWeek, StatPiTaskMonth statPiTaskMonth, PiStatus piStatus);
+    int calculatePointsInTask(PiTask piTask, List<PiTaskExt> piTaskExtList, PiTaskHistory piTaskHistory, PiStatus piStatus);
 
 
     /**

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

@@ -11,6 +11,7 @@ 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.DateUtils;
 import com.punchsettle.server.utiis.SpringUtils;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.BeanUtils;
@@ -22,6 +23,8 @@ import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.CollectionUtils;
 
 import javax.swing.*;
+import java.time.LocalDate;
+import java.time.temporal.ChronoUnit;
 import java.util.List;
 import java.util.Objects;
 import java.util.stream.Collectors;
@@ -99,10 +102,28 @@ public class CalendarManagerImpl implements ICalendarManager {
         return sysCalendarService.getByGregorianDate(gregorianDate);
     }
 
+    @Override
+    public List<SysCalendar> getCalendarByRangeDate(String gregorianStartDate, String gregorianEndDate) {
+        LocalDate startDate = LocalDate.parse(gregorianStartDate);
+        LocalDate endDate = LocalDate.parse(gregorianEndDate);
+        // 计算两个日期之间的天数差
+        long daysBetween = ChronoUnit.DAYS.between(startDate, endDate);
+
+//        SysCalendar sysCalendar = SpringUtils.getBean(CalendarManagerImpl.class).getCalendarByGregorianDate(gregorianDate);
+        return List.of();
+    }
+
     @Override
     public boolean judgeHoliday(String gregorianDate) {
         Assert.isNullInBusiness(gregorianDate, "公历日期不能为空");
         SysCalendar sysCalendar = SpringUtils.getBean(CalendarManagerImpl.class).getCalendarByGregorianDate(gregorianDate);
         return CalendarStatusEnum.HOLIDAY.equals(sysCalendar);
     }
+
+    @Override
+    public boolean judgeWorkday(String gregorianDate) {
+        Assert.isNullInBusiness(gregorianDate, "公历日期不能为空");
+        SysCalendar sysCalendar = SpringUtils.getBean(CalendarManagerImpl.class).getCalendarByGregorianDate(gregorianDate);
+        return CalendarStatusEnum.WORKDAY.equals(sysCalendar);
+    }
 }

+ 139 - 15
src/main/java/com/punchsettle/server/service/manager/impl/PunchInManagerImpl.java

@@ -2,10 +2,16 @@ package com.punchsettle.server.service.manager.impl;
 
 import java.time.LocalDate;
 import java.time.LocalTime;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Objects;
 import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
 
+import com.punchsettle.server.atomic.entity.PiStatus;
+import com.punchsettle.server.constant.ContinueStageEnum;
+import com.punchsettle.server.utiis.DateUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 import org.springframework.util.CollectionUtils;
@@ -19,7 +25,7 @@ import com.punchsettle.server.common.exception.BusinessException;
 import com.punchsettle.server.common.utils.Assert;
 import com.punchsettle.server.constant.CompareRuleEnum;
 import com.punchsettle.server.constant.PunchInMethodEnum;
-import com.punchsettle.server.constant.PunchInStatusEnum;
+import com.punchsettle.server.constant.PunchInResultEnum;
 import com.punchsettle.server.constant.RepeatCategoryEnum;
 import com.punchsettle.server.service.manager.ICalendarManager;
 import com.punchsettle.server.service.manager.IPunchInManager;
@@ -71,18 +77,18 @@ public class PunchInManagerImpl implements IPunchInManager {
     }
 
     @Override
-    public PunchInStatusEnum judgePunchInStatusInTask(PiTask piTask, PiTaskHistory piTaskHistory) {
+    public PunchInResultEnum judgePunchInResultInTask(PiTask piTask, PiTaskHistory piTaskHistory) {
         Assert.isNullInBusiness(piTask, "打卡任务不能为空 ");
 
         // 没有打卡记录,直接没完成
         if (Objects.isNull(piTaskHistory)) {
-            return PunchInStatusEnum.UNDONE;
+            return PunchInResultEnum.UNDONE;
         }
 
         // 单次打卡,不区分是否节假日
         if (PunchInMethodEnum.SINGLE.equals(piTask.getPunchInMethod())) {
             int countTrack = Optional.ofNullable(piTask.getCountTrack()).orElse(0);
-            return countTrack > 0 ? PunchInStatusEnum.DONE : PunchInStatusEnum.UNDONE;
+            return countTrack > 0 ? PunchInResultEnum.DONE : PunchInResultEnum.UNDONE;
         }
 
         // 打卡任务的节假日启用配置
@@ -94,12 +100,12 @@ public class PunchInManagerImpl implements IPunchInManager {
             int countTrack = enableHolidayFlag ? piTask.getHolidayCountTrack() : piTask.getCountTrack();
             int punchInCountTrack = Optional.ofNullable(piTaskHistory.getCountTrack()).orElse(0);
             if (CompareRuleEnum.GTE.equals(piTask.getCompareRule()) && punchInCountTrack >= countTrack) {
-                return PunchInStatusEnum.DONE;
+                return PunchInResultEnum.DONE;
             }
             if (CompareRuleEnum.LTE.equals(piTask.getCompareRule()) && punchInCountTrack <= countTrack) {
-                return PunchInStatusEnum.DONE;
+                return PunchInResultEnum.DONE;
             }
-            return PunchInStatusEnum.UNDONE;
+            return PunchInResultEnum.UNDONE;
         }
 
         // 计时打卡,要区分是否节假日使用不同的判断标准
@@ -107,30 +113,148 @@ public class PunchInManagerImpl implements IPunchInManager {
             LocalTime timeTrack = enableHolidayFlag ? piTask.getHolidayTimeTrack() : piTask.getTimeTrack();
             LocalTime punchInTimeTrack = Optional.ofNullable(piTaskHistory.getTimeTrack()).orElse(LocalTime.parse("00:00:00.000"));
             if (CompareRuleEnum.GTE.equals(piTask.getCompareRule()) && punchInTimeTrack.compareTo(timeTrack) > -1) {
-                return PunchInStatusEnum.DONE;
+                return PunchInResultEnum.DONE;
             }
             if (CompareRuleEnum.LTE.equals(piTask.getCompareRule()) && punchInTimeTrack.compareTo(timeTrack) < 1) {
-                return PunchInStatusEnum.DONE;
+                return PunchInResultEnum.DONE;
             }
 
-            return PunchInStatusEnum.UNDONE;
+            return PunchInResultEnum.UNDONE;
         }
 
-        return PunchInStatusEnum.UNDONE;
+        return PunchInResultEnum.UNDONE;
     }
 
     @Override
-    public PunchInStatusEnum judgePunchInStatusInMultiTask(PiMultiTask piMultiTask, List<PiTaskHistory> piTaskHistoryList) {
+    public PunchInResultEnum judgePunchInResultInMultiTask(PiMultiTask piMultiTask, List<PiTaskHistory> piTaskHistoryList) {
         if (CollectionUtils.isEmpty(piTaskHistoryList)) {
-            return PunchInStatusEnum.UNDONE;
+            return PunchInResultEnum.UNDONE;
         }
 
         // 完成的打卡数量
-        long punchInDoneCount = piTaskHistoryList.stream().filter(v -> PunchInStatusEnum.DONE.equals(v.getPunchInStatus())).count();
+        long punchInDoneCount = piTaskHistoryList.stream().filter(v -> PunchInResultEnum.DONE.equals(v.getPunchInResult())).count();
 
         // 当天打卡次数大于等于设置的次数,则完成打卡
         // 没有设置时默认设置一个较大的数,避免出现打卡次数为0的情况
         Integer doneCount = Optional.ofNullable(piMultiTask.getPunchInDoneCount()).orElse(piTaskHistoryList.size() + 1);
-        return punchInDoneCount >= doneCount ? PunchInStatusEnum.DONE : PunchInStatusEnum.UNDONE;
+        return punchInDoneCount >= doneCount ? PunchInResultEnum.DONE : PunchInResultEnum.UNDONE;
+    }
+
+    @Override
+    public int getPunchInTotalCountInWeek(PiTask piTask, String specifiedDateStr) {
+        Assert.isNullInBusiness(piTask, "打卡任务不能为空 ");
+        Assert.isNull(specifiedDateStr, "指定日期不能为空 ");
+
+        if (RepeatCategoryEnum.EVERYDAY.equals(piTask.getRepeatCategory())) {
+            return 7;
+        }
+
+        if (RepeatCategoryEnum.CUSTOM.equals(piTask.getRepeatCategory())) {
+            return piTask.getRepeatCustomDay().split(",").length;
+        }
+
+        // 指定日期
+        LocalDate specifiedDate = LocalDate.parse(specifiedDateStr);
+
+        if (RepeatCategoryEnum.WORKDAY.equals(piTask.getRepeatCategory())) {
+            List<LocalDate> dateRange = DateUtils.getDateRangeInWeek(specifiedDate);
+            return (int) dateRange.stream().map(v -> DateUtils.YYYY_MM_DD_FORMATTER.format(v))
+                    .filter(v -> calendarManager.judgeWorkday(v)).count();
+        }
+
+        if (RepeatCategoryEnum.HOLIDAY.equals(piTask.getRepeatCategory())) {
+            List<LocalDate> dateRange = DateUtils.getDateRangeInWeek(specifiedDate);
+            return (int) dateRange.stream().map(v -> DateUtils.YYYY_MM_DD_FORMATTER.format(v))
+                    .filter(v -> calendarManager.judgeHoliday(v)).count();
+        }
+
+        return 0;
+    }
+
+    @Override
+    public int getPunchInTotalCountInMonth(PiTask piTask, String specifiedDateStr) {
+        Assert.isNullInBusiness(piTask, "打卡任务不能为空 ");
+        Assert.isNull(specifiedDateStr, "指定日期不能为空 ");
+
+        // 指定日期
+        LocalDate specifiedDate = LocalDate.parse(specifiedDateStr);
+
+        if (RepeatCategoryEnum.EVERYDAY.equals(piTask.getRepeatCategory())) {
+            return specifiedDate.lengthOfMonth();
+        }
+
+        // 日期列表
+        List<LocalDate> dateRange = DateUtils.getDateRangeInMonth(specifiedDate);
+
+        if (RepeatCategoryEnum.CUSTOM.equals(piTask.getRepeatCategory())) {
+            String[] split = piTask.getRepeatCustomDay().split(",");
+            Set<Integer> customDays = Arrays.stream(split).map(v -> Integer.valueOf(v)).collect(Collectors.toSet());
+            return (int) dateRange.stream().map(v -> v.getDayOfWeek().getValue()).filter(customDays::contains).count();
+        }
+
+        if (RepeatCategoryEnum.WORKDAY.equals(piTask.getRepeatCategory())) {
+            return (int) dateRange.stream().map(v -> DateUtils.YYYY_MM_DD_FORMATTER.format(v))
+                    .filter(v -> calendarManager.judgeWorkday(v)).count();
+        }
+
+        if (RepeatCategoryEnum.HOLIDAY.equals(piTask.getRepeatCategory())) {
+            return (int) dateRange.stream().map(v -> DateUtils.YYYY_MM_DD_FORMATTER.format(v))
+                    .filter(v -> calendarManager.judgeHoliday(v)).count();
+        }
+
+        return 0;
+    }
+
+    @Override
+    public ContinueStageEnum judgeContinueStageInTask(PiTask piTask, PiTaskHistory piTaskHistory, PiStatus piStatus, LocalDate punchInDate) {
+        if (CommonEnableStatusEnum.DISABLED.equals(piTask.getContinueStatus())) {
+            return ContinueStageEnum.NONE;
+        }
+
+        // TODO 启用/关闭连续打卡规则时要对状态表进行数据初始化
+
+        // 宽限期
+        if (ContinueStageEnum.GRACE_STAGE.equals(piStatus.getContinueStage())) {
+            LocalDate graceDay = piStatus.getStageStartDate().plusDays(piTask.getGraceDay());
+            // 仍处于宽限期限内
+            if (punchInDate.compareTo(graceDay) <= 0) {
+                return ContinueStageEnum.GRACE_STAGE;
+            }
+
+            // 已超过宽限期限,但是未完成打卡
+            if (PunchInResultEnum.UNDONE.equals(piTaskHistory.getPunchInResult())) {
+                return ContinueStageEnum.GRACE_STAGE;
+            }
+
+            // 已超过宽限期限,且已完成打卡,进入正常打卡期
+            return ContinueStageEnum.NORMAL_STAGE;
+        }
+
+        // 正常打卡期
+        if (ContinueStageEnum.NORMAL_STAGE.equals(piStatus.getContinueStage())) {
+            // 完成打卡则继续是正常打卡期,否则是惩罚期
+            if (PunchInResultEnum.DONE.equals(piTaskHistory.getPunchInResult())) {
+                return ContinueStageEnum.NORMAL_STAGE;
+            }
+
+            // 连续中断次数大于等于设置的中断次数,重新进入宽限期
+            if (piStatus.getContinueInterruptedCount() + 1 > piTask.getContinueInterruptedCount()) {
+                return ContinueStageEnum.GRACE_STAGE;
+            }
+
+            return ContinueStageEnum.PENALTY_STAGE;
+        }
+
+        // 惩罚期
+        if (ContinueStageEnum.PENALTY_STAGE.equals(piStatus.getContinueStage())) {
+            // 仍处于惩罚期
+            if (punchInDate.compareTo(piStatus.getStageEndDate()) <= 0) {
+                return ContinueStageEnum.GRACE_STAGE;
+            }
+
+            return ContinueStageEnum.NORMAL_STAGE;
+        }
+
+        return ContinueStageEnum.NONE;
     }
 }

+ 21 - 21
src/main/java/com/punchsettle/server/service/manager/impl/PunchInManagerV1Impl.java

@@ -24,7 +24,7 @@ import com.punchsettle.server.atomic.entity.StatPiTaskMonth;
 import com.punchsettle.server.atomic.entity.StatPiTaskWeek;
 import com.punchsettle.server.atomic.entity.PiStatus;
 import com.punchsettle.server.atomic.entity.PiTaskExt;
-import com.punchsettle.server.constant.ConsecutiveStatusEnum;
+import com.punchsettle.server.constant.ContinueStatusEnum;
 import com.punchsettle.server.constant.FullAttendancePeriodEnum;
 import com.punchsettle.server.constant.PunchInDimensionEnum;
 import com.punchsettle.server.constant.PunchInExtraMethodEnum;
@@ -49,7 +49,7 @@ import com.punchsettle.server.constant.CompareRuleEnum;
 import com.punchsettle.server.constant.PunchInCategoryEnum;
 import com.punchsettle.server.constant.PunchInMethodEnum;
 import com.punchsettle.server.constant.PunchInSettleTypeEnum;
-import com.punchsettle.server.constant.PunchInStatusEnum;
+import com.punchsettle.server.constant.PunchInResultEnum;
 import com.punchsettle.server.constant.PunchInStatusV1Enum;
 import com.punchsettle.server.constant.PunchInStatusViewEnum;
 import com.punchsettle.server.pojo.punchinV1.PunchInCalendarDataVO;
@@ -112,7 +112,7 @@ public class PunchInManagerV1Impl implements IPunchInManagerV1 {
         }
 
         // 获取一周的起始日期范围
-        List<LocalDate> weeklyDateRange = DateUtils.getWeeklyDateRange();
+        List<LocalDate> weeklyDateRange = DateUtils.getDateRangeInWeek();
         // 获取打卡任务ID
         List<Long> punchInIds = punchIns.stream().map(PunchIn::getId).collect(Collectors.toList());
         // 找出范围内的打卡记录
@@ -490,17 +490,17 @@ public class PunchInManagerV1Impl implements IPunchInManagerV1 {
     }
 
     @Override
-    public PunchInStatusEnum judgePunchInStatusInTask(PiTask piTask, PiTaskHistory piTaskHistory, boolean holidayFlag) {
+    public PunchInResultEnum judgePunchInStatusInTask(PiTask piTask, PiTaskHistory piTaskHistory, boolean holidayFlag) {
         Assert.isNullInBusiness(piTask, "打卡任务不能为空 ");
         // 没有打卡记录,直接没完成
         if (Objects.isNull(piTaskHistory)) {
-            return PunchInStatusEnum.UNDONE;
+            return PunchInResultEnum.UNDONE;
         }
 
         // 单次打卡,不区分是否节假日
         if (PunchInMethodEnum.SINGLE.equals(piTask.getPunchInMethod())) {
             int countTrack = Optional.ofNullable(piTask.getCountTrack()).orElse(0);
-            return countTrack > 0 ? PunchInStatusEnum.DONE : PunchInStatusEnum.UNDONE;
+            return countTrack > 0 ? PunchInResultEnum.DONE : PunchInResultEnum.UNDONE;
         }
 
         // 打卡任务的节假日启用配置
@@ -512,12 +512,12 @@ public class PunchInManagerV1Impl implements IPunchInManagerV1 {
             int countTrack = enableHolidayFlag ? piTask.getHolidayCountTrack() : piTask.getCountTrack();
             int punchInCountTrack = Optional.ofNullable(piTaskHistory.getCountTrack()).orElse(0);
             if (CompareRuleEnum.GTE.equals(piTask.getCompareRule()) && punchInCountTrack >= countTrack) {
-                return PunchInStatusEnum.DONE;
+                return PunchInResultEnum.DONE;
             }
             if (CompareRuleEnum.LTE.equals(piTask.getCompareRule()) && punchInCountTrack <= countTrack) {
-                return PunchInStatusEnum.DONE;
+                return PunchInResultEnum.DONE;
             }
-            return PunchInStatusEnum.UNDONE;
+            return PunchInResultEnum.UNDONE;
         }
 
         // 计时打卡,要区分是否节假日使用不同的判断标准
@@ -525,26 +525,26 @@ public class PunchInManagerV1Impl implements IPunchInManagerV1 {
             LocalTime timeTrack = enableHolidayFlag ? piTask.getHolidayTimeTrack() : piTask.getTimeTrack();
             LocalTime punchInTimeTrack = Optional.ofNullable(piTaskHistory.getTimeTrack()).orElse(LocalTime.parse("00:00:00.000"));
             if (CompareRuleEnum.GTE.equals(piTask.getCompareRule()) && punchInTimeTrack.compareTo(timeTrack) > -1) {
-                return PunchInStatusEnum.DONE;
+                return PunchInResultEnum.DONE;
             }
             if (CompareRuleEnum.LTE.equals(piTask.getCompareRule()) && punchInTimeTrack.compareTo(timeTrack) < 1) {
-                return PunchInStatusEnum.DONE;
+                return PunchInResultEnum.DONE;
             }
 
-            return PunchInStatusEnum.UNDONE;
+            return PunchInResultEnum.UNDONE;
         }
 
-        return PunchInStatusEnum.UNDONE;
+        return PunchInResultEnum.UNDONE;
     }
 
     @Override
-    public PunchInStatusEnum judgePunchInStatusInMultiTask(PiMultiTask piMultiTask, List<PiTaskHistory> piTaskHistoryList, int multiTaskNum) {
+    public PunchInResultEnum judgePunchInStatusInMultiTask(PiMultiTask piMultiTask, List<PiTaskHistory> piTaskHistoryList, int multiTaskNum) {
         if (CollectionUtils.isEmpty(piTaskHistoryList) || multiTaskNum == 0) {
-            return PunchInStatusEnum.UNDONE;
+            return PunchInResultEnum.UNDONE;
         }
 
         // 完成的打卡数量
-        long punchInDoneCount = piTaskHistoryList.stream().filter(v -> PunchInStatusEnum.DONE.equals(v.getPunchInStatus())).count();
+        long punchInDoneCount = piTaskHistoryList.stream().filter(v -> PunchInResultEnum.DONE.equals(v.getPunchInStatus())).count();
 
 //        // 次数,当天打卡次数大于等于设置的次数,则完成打卡
 //        if (PunchInMethodMultiEnum.COUNT.equals(punchInMultiTask.getPunchInMethod())) {
@@ -562,13 +562,13 @@ public class PunchInManagerV1Impl implements IPunchInManagerV1 {
 //            return punchInDoneRate.compareTo(doneRate) > -1 ? PunchInStatusEnum.DONE : PunchInStatusEnum.UNDONE;
 //        }
 
-        return PunchInStatusEnum.UNDONE;
+        return PunchInResultEnum.UNDONE;
     }
 
     @Override
     public int calculatePointsInTask(PiTask piTask, List<PiTaskExt> piTaskExts, PiTaskHistory piTaskHistory, StatPiTaskWeek statPiTaskWeek, StatPiTaskMonth statPiTaskMonth, PiStatus piStatus) {
         // 未完成打卡,积分为0
-        if (PunchInStatusEnum.UNDONE.equals(piTaskHistory.getPunchInStatus())) {
+        if (PunchInResultEnum.UNDONE.equals(piTaskHistory.getPunchInStatus())) {
             return 0;
         }
 
@@ -613,7 +613,7 @@ public class PunchInManagerV1Impl implements IPunchInManagerV1 {
 
         // 连续完成额外积分
         int taskPoints = 0;
-        if (CommonEnableStatusEnum.ENABLED.equals(piTask.getTaskPointsStatus()) && ConsecutiveStatusEnum.CONSECUTIVE.equals(piStatus.getTaskContinueStatus())) {
+        if (CommonEnableStatusEnum.ENABLED.equals(piTask.getTaskPointsStatus()) && ContinueStatusEnum.CONTINUE.equals(piStatus.getTaskContinueStatus())) {
             // punchInTaskExtList 根据InitialValue倒序排列
             piTaskExtList.sort(Comparator.comparing(PiTaskExt::getInitialValue).reversed());
             // 第二轮标志
@@ -710,7 +710,7 @@ public class PunchInManagerV1Impl implements IPunchInManagerV1 {
     @Override
     public int calculatePointsInMultiTask(PiMultiTask piMultiTask, List<PiMultiTaskExt> piMultiTaskExts, PiMultiTaskHistory piMultiTaskHistory, PiStatus piStatus) {
         // 未完成打卡或没有启用多任务积分计算,积分为0
-        if (PunchInStatusEnum.UNDONE.equals(piMultiTaskHistory.getPunchInStatus())
+        if (PunchInResultEnum.UNDONE.equals(piMultiTaskHistory.getPunchInStatus())
             || CommonEnableStatusEnum.ENABLED.equals(piMultiTask.getTaskPointsStatus())) {
             return 0;
         }
@@ -763,7 +763,7 @@ public class PunchInManagerV1Impl implements IPunchInManagerV1 {
 
         // 连续完成额外积分
         int taskPoints = 0;
-        if (CommonEnableStatusEnum.ENABLED.equals(piMultiTask.getTaskPointsStatus()) && ConsecutiveStatusEnum.CONSECUTIVE.equals(piStatus.getTaskContinueStatus())) {
+        if (CommonEnableStatusEnum.ENABLED.equals(piMultiTask.getTaskPointsStatus()) && ContinueStatusEnum.CONTINUE.equals(piStatus.getTaskContinueStatus())) {
             // punchInTaskExtList 根据InitialValue倒序排列
             punchInTaskExtList.sort(Comparator.comparing(PiMultiTaskExt::getInitialValue).reversed());
             // 第二轮标志

+ 25 - 72
src/main/java/com/punchsettle/server/service/manager/impl/SettleManagerImpl.java

@@ -1,37 +1,36 @@
 package com.punchsettle.server.service.manager.impl;
 
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.time.LocalDate;
+import java.time.temporal.ChronoUnit;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
 import com.punchsettle.server.atomic.entity.PiMultiTask;
 import com.punchsettle.server.atomic.entity.PiMultiTaskExt;
 import com.punchsettle.server.atomic.entity.PiMultiTaskHistory;
-import com.punchsettle.server.atomic.entity.StatPiTaskMonth;
-import com.punchsettle.server.atomic.entity.StatPiTaskWeek;
 import com.punchsettle.server.atomic.entity.PiStatus;
 import com.punchsettle.server.atomic.entity.PiTask;
 import com.punchsettle.server.atomic.entity.PiTaskExt;
 import com.punchsettle.server.atomic.entity.PiTaskHistory;
 import com.punchsettle.server.common.constant.CommonEnableStatusEnum;
-import com.punchsettle.server.constant.ConsecutiveStatusEnum;
+import com.punchsettle.server.constant.ContinueStatusEnum;
 import com.punchsettle.server.constant.FullAttendancePeriodEnum;
 import com.punchsettle.server.constant.PunchInDimensionEnum;
 import com.punchsettle.server.constant.PunchInExtraMethodEnum;
 import com.punchsettle.server.constant.PunchInMethodEnum;
-import com.punchsettle.server.constant.PunchInStatusEnum;
-import com.punchsettle.server.constant.SettleStatusEnum;
+import com.punchsettle.server.constant.PunchInResultEnum;
 import com.punchsettle.server.service.manager.ICalendarManager;
 import com.punchsettle.server.service.manager.ISettleManager;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-import org.springframework.util.CollectionUtils;
 
-import java.math.BigDecimal;
-import java.math.RoundingMode;
-import java.time.LocalDate;
-import java.time.temporal.ChronoUnit;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Optional;
-import java.util.stream.Collectors;
+import lombok.extern.slf4j.Slf4j;
 
 /**
  * @author tyuio
@@ -47,54 +46,9 @@ public class SettleManagerImpl implements ISettleManager {
     private ICalendarManager calendarManager;
 
     @Override
-    public SettleStatusEnum judgeSettleStatusInTask(PiTask piTask, PiTaskHistory piTaskHistory, PiStatus piStatus) {
-        // 未完成打卡则跳过
-        if (PunchInStatusEnum.UNDONE.equals(piTaskHistory.getPunchInStatus())) {
-            return SettleStatusEnum.UNDONE_SKIP;
-        }
-
-        // 不启用宽限期,则进行跳过
-        if (CommonEnableStatusEnum.DISABLED.equals(piTask.getContinueStatus())) {
-            return SettleStatusEnum.SETTLED;
-        }
-
-        // 宽限期部分,
-        if ("GRACE_STAGE".equals(piStatus.getTaskStage())) {
-            // 计算宽限期结束日,减1是因为开始当日也算在范围内
-            LocalDate graceEndDate = piStatus.getStageStartDate().plusDays(piTask.getGraceDay() - 1);
-            LocalDate punchInDate = LocalDate.parse(piTaskHistory.getPunchInDate());
-            // 如果打卡日期在宽限期范围内,则跳过,否则正常跳过,且进入正常打卡期
-            if (punchInDate.compareTo(graceEndDate) <= 0) {
-                return SettleStatusEnum.GRACE_SKIP;
-            } else {
-                return SettleStatusEnum.SETTLED;
-            }
-        }
-
-        // 正常打卡期
-        if ("NORMAL_STAGE".equals(piStatus.getTaskStage())) {
-            // 如果完成打卡则进入结算,否则进入惩罚期
-            if (PunchInStatusEnum.DONE.equals(piTaskHistory.getPunchInStatus())) {
-                return SettleStatusEnum.SETTLED;
-            } else {
-                return SettleStatusEnum.PENALTY_SKIP;
-            }
-        }
-
-        return SettleStatusEnum.SETTLED;
-    }
-
-    public static void main(String[] args) {
-        LocalDate minSettleDate = LocalDate.now().plusDays(7);
-        System.out.println(minSettleDate);
-    }
-
-    @Override
-    public int calculatePointsInTask(PiTask piTask, List<PiTaskExt> piTaskExtList,
-                                     PiTaskHistory piTaskHistory, StatPiTaskWeek statPiTaskWeek, StatPiTaskMonth statPiTaskMonth,
-                                     PiStatus piStatus) {
+    public int calculatePointsInTask(PiTask piTask, List<PiTaskExt> piTaskExtList, PiTaskHistory piTaskHistory, PiStatus piStatus) {
         // 未完成打卡,积分为0
-        if (PunchInStatusEnum.UNDONE.equals(piTaskHistory.getPunchInStatus())) {
+        if (PunchInResultEnum.UNDONE.equals(piTaskHistory.getPunchInResult())) {
             return 0;
         }
 
@@ -112,7 +66,7 @@ public class SettleManagerImpl implements ISettleManager {
 
         // 全勤积分,全勤则双倍奖励
         int fullAttendancePoints = 0;
-        if (judgeFullAttendanceStatusInTask(piTask, piTaskHistory, statPiTaskWeek, statPiTaskMonth)) {
+        if (judgeFullAttendanceStatusInTask(piTask, piTaskHistory, piStatus)) {
             fullAttendancePoints = basicPoints;
         }
 
@@ -233,8 +187,7 @@ public class SettleManagerImpl implements ISettleManager {
      * 
      * @return true-是全勤,false-不是全勤
      */
-    private boolean judgeFullAttendanceStatusInTask(PiTask piTask, PiTaskHistory piTaskHistory,
-                                                    StatPiTaskWeek statPiTaskWeek, StatPiTaskMonth statPiTaskMonth) {
+    private boolean judgeFullAttendanceStatusInTask(PiTask piTask, PiTaskHistory piTaskHistory, PiStatus piStatus) {
         // 没有启用全勤 则直接返回
         if (CommonEnableStatusEnum.DISABLED.equals(piTask.getFullAttendanceStatus())) {
             return false;
@@ -249,10 +202,10 @@ public class SettleManagerImpl implements ISettleManager {
         // 结算周期:周,并且结算日是周末;结算周期:月,结算日是当月最后一天;
         if (FullAttendancePeriodEnum.WEEK.equals(piTask.getFullAttendancePeriod())
             && punchInDate.getDayOfWeek().getValue() == 7) {
-            undoneCount = statPiTaskWeek.getPunchInTotalCount() - statPiTaskWeek.getPunchInDoneCount();
+            undoneCount = piStatus.getPunchInTotalCountInWeek() - piStatus.getPunchInDoneCountInWeek();
         } else if (FullAttendancePeriodEnum.MONTH.equals(piTask.getFullAttendancePeriod())
             && punchInDate.lengthOfMonth() == punchInDate.getDayOfMonth()) {
-            undoneCount = statPiTaskMonth.getPunchInTotalCount() - statPiTaskMonth.getPunchInDoneCount();
+            undoneCount = piStatus.getPunchInTotalCountInMonth() - piStatus.getPunchInDoneCountInMonth();
         }
 
         // 未完成数在容错范围内,则是全勤
@@ -271,7 +224,7 @@ public class SettleManagerImpl implements ISettleManager {
                                                  PiStatus piStatus) {
         // 没有启用任务积分计算、或是连续打卡状态为中断、或是没有拓展信息 则不进行计算
         if (CommonEnableStatusEnum.DISABLED.equals(piTask.getTaskPointsStatus())
-            || ConsecutiveStatusEnum.INTERRUPTED.equals(piStatus.getTaskContinueStatus())
+            || ContinueStatusEnum.INTERRUPTED.equals(piStatus.getTaskContinueStatus())
             || CollectionUtils.isEmpty(piTaskExtList)) {
             return 0;
         }
@@ -315,7 +268,7 @@ public class SettleManagerImpl implements ISettleManager {
                                           List<PiMultiTaskExt> piMultiTaskExtList, PiMultiTaskHistory piMultiTaskHistory,
                                           PiStatus piStatus) {
         // 未完成打卡或没有启用多任务积分计算,积分为0
-        if (PunchInStatusEnum.UNDONE.equals(piMultiTaskHistory.getPunchInStatus())
+        if (PunchInResultEnum.UNDONE.equals(piMultiTaskHistory.getPunchInStatus())
             || CommonEnableStatusEnum.DISABLED.equals(piMultiTask.getTaskPointsStatus())) {
             return 0;
         }
@@ -408,7 +361,7 @@ public class SettleManagerImpl implements ISettleManager {
                                                       List<PiMultiTaskExt> piMultiTaskExtList, PiStatus piStatus) {
         // 没有启用多任务积分计算、或是连续打卡状态为中断、或是没有拓展信息 则不进行计算
         if (CommonEnableStatusEnum.DISABLED.equals(piMultiTask.getTaskPointsStatus())
-            || ConsecutiveStatusEnum.INTERRUPTED.equals(piStatus.getTaskContinueStatus())
+            || ContinueStatusEnum.INTERRUPTED.equals(piStatus.getTaskContinueStatus())
             || CollectionUtils.isEmpty(piMultiTaskExtList)) {
             return 0;
         }

+ 149 - 77
src/main/java/com/punchsettle/server/task/PunchInCoreTask.java

@@ -4,8 +4,6 @@ import com.punchsettle.server.atomic.entity.PiMultiTask;
 import com.punchsettle.server.atomic.entity.PiMultiTaskExt;
 import com.punchsettle.server.atomic.entity.PiMultiTaskHistory;
 import com.punchsettle.server.atomic.entity.PiMultiTaskRela;
-import com.punchsettle.server.atomic.entity.StatPiTaskMonth;
-import com.punchsettle.server.atomic.entity.StatPiTaskWeek;
 import com.punchsettle.server.atomic.entity.PiStatus;
 import com.punchsettle.server.atomic.entity.PiTask;
 import com.punchsettle.server.atomic.entity.PiTaskExt;
@@ -21,15 +19,16 @@ import com.punchsettle.server.atomic.service.IPiTaskExtService;
 import com.punchsettle.server.atomic.service.IPiTaskHistoryService;
 import com.punchsettle.server.atomic.service.IPiTaskService;
 import com.punchsettle.server.constant.ArchiveStatusEnum;
-import com.punchsettle.server.constant.PunchInStatusEnum;
+import com.punchsettle.server.constant.ContinueStageEnum;
+import com.punchsettle.server.constant.ContinueStatusEnum;
+import com.punchsettle.server.constant.PunchInResultEnum;
+import com.punchsettle.server.constant.SettleResultEnum;
 import com.punchsettle.server.pojo.punchIn.PiMultiTaskExtQuery;
 import com.punchsettle.server.pojo.punchIn.PiMultiTaskHistoryQuery;
 import com.punchsettle.server.pojo.punchIn.PiMultiTaskQuery;
-import com.punchsettle.server.pojo.punchIn.PunchInSettleDto;
-import com.punchsettle.server.pojo.punchIn.PiStatsMonthQuery;
-import com.punchsettle.server.pojo.punchIn.StatPiTaskWeekQuery;
+import com.punchsettle.server.pojo.punchIn.PunchInSettleData;
 import com.punchsettle.server.pojo.punchIn.PiStatusQuery;
-import com.punchsettle.server.pojo.punchIn.PiTaskDto;
+import com.punchsettle.server.pojo.punchIn.PiTaskData;
 import com.punchsettle.server.pojo.punchIn.PiTaskExtQuery;
 import com.punchsettle.server.pojo.punchIn.PiTaskHistoryQuery;
 import com.punchsettle.server.pojo.punchIn.PiTaskQuery;
@@ -41,11 +40,14 @@ import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
+import javax.swing.text.html.Option;
+import java.time.DayOfWeek;
 import java.time.LocalDate;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.Set;
 import java.util.function.Function;
 import java.util.stream.Collectors;
@@ -131,33 +133,127 @@ public class PunchInCoreTask {
     private ICalendarManager calendarManager;
 
     public void manual(List<Long> userIds, String punchInDateStr) {
-        List<PunchInSettleDto> punchInSettleData = getPunchInSettleData(userIds, punchInDateStr);
+        List<PunchInSettleData> punchInSettleData = getPunchInSettleData(userIds, punchInDateStr);
+
+        // 打卡日期
+        LocalDate punchInDate = LocalDate.parse(punchInDateStr);
+        // 是否周一
+        boolean isMonday = DayOfWeek.MONDAY.equals(punchInDate.getDayOfWeek());
+        // 是否周日
+        boolean isSunday = DayOfWeek.SUNDAY.equals(punchInDate.getDayOfWeek());
+        // 是否打卡所在月第一天
+        boolean isFirstDayOfMonth = punchInDate.getDayOfMonth() == 1;
+        // 是否打卡所在月最后一天
+        boolean isLastDayOfMonth = punchInDate.getDayOfMonth() == punchInDate.lengthOfMonth();
 
         List<PiTaskHistory> updatePunchInTaskHistories = new ArrayList<>(punchInSettleData.size());
         List<PiMultiTaskHistory> updatePunchInMultiTaskHistories = new ArrayList<>(punchInSettleData.size());
-        for (PunchInSettleDto punchInSettle : punchInSettleData) {
+        for (PunchInSettleData punchInSettle : punchInSettleData) {
             // 单任务处理部分
-            for (PiTaskDto piTaskDto : punchInSettle.getPiTaskDtoList()) {
+            for (PiTaskData piTaskData : punchInSettle.getPiTaskDataList()) {
+                PiTask piTask = piTaskData.getPiTask();
+                PiTaskHistory piTaskHistory = piTaskData.getPiTaskHistory();
+                PiStatus piStatus = piTaskData.getPiStatus();
+                List<PiTaskExt> piTaskExtList = piTaskData.getPiTaskExtList();
+
                 PiTaskHistory updatePiTaskHistory = new PiTaskHistory();
-                updatePiTaskHistory.setId(piTaskDto.getPiTaskHistory().getId());
-                updatePiTaskHistory.setPunchInStatus(PunchInStatusEnum.UNDONE);
+                updatePiTaskHistory.setId(piTaskHistory.getId());
+
+                // 记录当前状态数据
+                updatePiTaskHistory.setTaskContinueStatus(piStatus.getTaskContinueStatus());
+                updatePiTaskHistory.setTaskContinueDay(piStatus.getTaskContinueDay());
+                updatePiTaskHistory.setContinueStage(piStatus.getContinueStage());
+                updatePiTaskHistory.setStageStartDate(piStatus.getStageStartDate());
+                updatePiTaskHistory.setStageEndDate(piStatus.getStageEndDate());
+                updatePiTaskHistory.setContinueInterruptedCount(piStatus.getContinueInterruptedCount());
+
+                // 判断打卡结果
+                PunchInResultEnum punchInResult = punchInManager.judgePunchInResultInTask(piTask, piTaskHistory);
+                punchInSettle.getPiMultiTaskHistory().setPunchInResult(punchInResult);
+                updatePiTaskHistory.setPunchInResult(punchInResult);
+
+                // 更新状态表数据
+                piStatus.setStatusDate(punchInDateStr);
+
+                // 设置任务连续状态
+                ContinueStatusEnum oldTaskContinueStatus = piStatus.getTaskContinueStatus();
+                piStatus.setTaskContinueStatus(punchInResult.equals(PunchInResultEnum.DONE) ? ContinueStatusEnum.CONTINUE : ContinueStatusEnum.INTERRUPTED);
+                piStatus.setTaskContinueDay(oldTaskContinueStatus.equals(piStatus.getTaskContinueStatus()) ? piStatus.getTaskContinueDay() + 1 : 1);
+
+                // 旧的连续阶段
+                ContinueStageEnum oldContinueStage = piStatus.getContinueStage();
+                // 判断当前处于的连续阶段
+                ContinueStageEnum continueStageResult = punchInManager.judgeContinueStageInTask(piTask, piTaskHistory, piStatus, punchInDate);
+                piStatus.setContinueStage(continueStageResult);
+                // 下面3种情况不处理:宽限期 变 宽限期;正常打卡期 变 正常打卡期;惩罚期 变 惩罚期;
+                // 宽限期 变 正常打卡期,则设置阶段开始时间,重置中断次数
+                if (ContinueStageEnum.GRACE_STAGE.equals(oldContinueStage) && ContinueStageEnum.NORMAL_STAGE.equals(continueStageResult)) {
+                    piStatus.setStageStartDate(punchInDate);
+                    piStatus.setContinueInterruptedCount(0);
+                }
+                // 如果正常打卡期 变 惩罚期,则设置阶段开始时间和阶段结束时间,增加中断次数
+                if (ContinueStageEnum.NORMAL_STAGE.equals(oldContinueStage) && ContinueStageEnum.PENALTY_STAGE.equals(continueStageResult)) {
+                    piStatus.setStageStartDate(punchInDate);
+                    piStatus.setStageEndDate(punchInDate.plusDays(piTask.getPenaltyDay()));
+                    piStatus.setContinueInterruptedCount(piStatus.getContinueInterruptedCount() + 1);
+                }
+                // 如果惩罚期 变 正常打卡期,则设置阶段开始时间
+                if (ContinueStageEnum.PENALTY_STAGE.equals(oldContinueStage) && ContinueStageEnum.NORMAL_STAGE.equals(continueStageResult)) {
+                    piStatus.setStageStartDate(punchInDate);
+                }
+
+                // 周一
+                if (isMonday) {
+                    String yearWeek = DateUtils.getYearWeek(punchInDate);
+                    piStatus.setStatTimeInWeek(yearWeek);
+
+                    // TODO 需要考虑中途变换了重复频率的问题,增加一个记录实际值的字段,容错率也会跟着有影响,影响结算
+                    int PunchInTotalCountInWeek = punchInManager.getPunchInTotalCountInWeek(piTask, punchInDateStr);
+                    piStatus.setPunchInTotalCountInWeek(PunchInTotalCountInWeek);
+
+                    piStatus.setPunchInCountInWeek(0);
+                    piStatus.setPunchInDoneCountInWeek(0);
+                }
+
+                // 打卡日所在月的第一天
+                if (isFirstDayOfMonth) {
+                    String yearMonth = DateUtils.getYearMonth(punchInDate);
+                    piStatus.setStatTimeInMonth(yearMonth);
+
+                    // TODO 需要考虑中途变换了重复频率的问题
+                    int PunchInTotalCountInMonth = punchInManager.getPunchInTotalCountInMonth(piTask, punchInDateStr);
+                    piStatus.setPunchInTotalCountInMonth(PunchInTotalCountInMonth);
+
+                    piStatus.setPunchInCountInMonth(0);
+                    piStatus.setPunchInDoneCountInMonth(0);
+                }
 
-                // 判断打卡状态
-                PunchInStatusEnum punchInStatusResult = punchInManager.judgePunchInStatusInTask(piTaskDto.getPiTask(), piTaskDto.getPiTaskHistory());
-                punchInSettle.getPiMultiTaskHistory().setPunchInStatus(punchInStatusResult);
-                updatePiTaskHistory.setPunchInStatus(punchInStatusResult);
+                // 存在打卡记录则已打卡数加1
+                if (Objects.nonNull(piTaskHistory)) {
+                    piStatus.setPunchInCountInWeek(piStatus.getPunchInCountInWeek() + 1);
+                    piStatus.setPunchInCountInMonth(piStatus.getPunchInCountInMonth() + 1);
+                }
+
+                // 完成打卡则完成打卡数记录加一
+                if (PunchInResultEnum.DONE.equals(punchInResult)) {
+                    piStatus.setPunchInDoneCountInWeek(piStatus.getPunchInDoneCountInWeek() + 1);
+                    piStatus.setPunchInDoneCountInMonth(piStatus.getPunchInDoneCountInMonth() + 1);
+                }
+
+                // TODO 可以考虑把年数据一起进行统计
+                // TODO 可以考虑把统计数据一起落表
 
-                // TODO 要判断并设置结算状态
                 // 计算积分
-                int taskPoints = settleManager.calculatePointsInTask(piTaskDto.getPiTask(), piTaskDto.getPiTaskExtList(),
-                        piTaskDto.getPiTaskHistory(), piTaskDto.getStatPiTaskWeek(),
-                        piTaskDto.getStatPiTaskMonth(), piTaskDto.getPiStatus());
-                updatePiTaskHistory.setSettlePoints(taskPoints);
+                int taskPoints = settleManager.calculatePointsInTask(piTask, piTaskExtList, piTaskHistory, piStatus);
+                piStatus.setPointsInWeek(piStatus.getPointsInWeek() + taskPoints);
+                piStatus.setPointsInMonth(piStatus.getPointsInMonth() + taskPoints);
 
                 // TODO 要设置结算任务执行ID
 
-                // 还有其他的要设置
-                updatePiTaskHistory.setSettleTaskHistoryId(piTaskDto.getPiTask().getId());
+                // 打卡记录 更新
+                updatePiTaskHistory.setSettlePoints(taskPoints);
+                updatePiTaskHistory.setSettleResult(SettleResultEnum.SETTLED);
+                updatePiTaskHistory.setSettleTaskHistoryId(piTaskData.getPiTask().getId());
                 updatePunchInTaskHistories.add(updatePiTaskHistory);
             }
 
@@ -165,10 +261,10 @@ public class PunchInCoreTask {
             PiMultiTaskHistory updatePiMultiTaskHistory = new PiMultiTaskHistory();
 
             // 判断多任务打卡状态并设置
-            PunchInStatusEnum punchInStatusEnumResult = punchInManager.judgePunchInStatusInMultiTask(punchInSettle.getPiMultiTask(),
+            PunchInResultEnum punchInResultEnumResult = punchInManager.judgePunchInResultInMultiTask(punchInSettle.getPiMultiTask(),
                     punchInSettle.getRelaPunchInTaskHistories());
-            punchInSettle.getPiMultiTaskHistory().setPunchInStatus(punchInStatusEnumResult);
-            updatePiMultiTaskHistory.setPunchInStatus(punchInStatusEnumResult);
+            punchInSettle.getPiMultiTaskHistory().setPunchInStatus(punchInResultEnumResult);
+            updatePiMultiTaskHistory.setPunchInStatus(punchInResultEnumResult);
 
             int multiTaskPoints = settleManager.calculatePointsInMultiTask(punchInSettle.getPiMultiTask(),
                     punchInSettle.getPiMultiTaskExtList(), punchInSettle.getPiMultiTaskHistory(),
@@ -190,7 +286,7 @@ public class PunchInCoreTask {
      * @param punchInDateStr 打卡日期
      * @return
      */
-    private List<PunchInSettleDto> getPunchInSettleData(List<Long> userIds, String punchInDateStr) {
+    private List<PunchInSettleData> getPunchInSettleData(List<Long> userIds, String punchInDateStr) {
         // 打卡日期
         LocalDate punchInDate = LocalDate.parse(punchInDateStr);
 
@@ -229,6 +325,13 @@ public class PunchInCoreTask {
         List<PiMultiTaskRela> piMultiTaskRelaList = punchInMultiTaskRelaService.queryByMultiTaskId(multiTaskIds);
         Map<Long, List<PiMultiTaskRela>> punchInMultiTaskRelaMap = piMultiTaskRelaList.stream().collect(Collectors.groupingBy(PiMultiTaskRela::getPunchInMultiTaskId));
 
+        // 获取打卡任务信息,打卡任务唯一ID-打卡任务关联
+        PiTaskQuery piTaskQuery = new PiTaskQuery();
+        piTaskQuery.setTaskStatus(ArchiveStatusEnum.ACTIVE);
+        piTaskQuery.setUserIds(userIds);
+        List<PiTask> piTasks = punchInTaskService.queryByCondition(piTaskQuery);
+        Map<Long, PiTask> punchInTaskMap = piTasks.stream().collect(Collectors.toMap(PiTask::getUniqueId, Function.identity(), (key1, key2) -> key1));
+
         // 获取打卡记录,用户ID-打卡记录关联
         PiTaskHistoryQuery piTaskHistoryQuery = new PiTaskHistoryQuery();
         piTaskHistoryQuery.setPunchInDate(punchInDateStr);
@@ -236,16 +339,6 @@ public class PunchInCoreTask {
         List<PiTaskHistory> punchInTaskHistories = punchInTaskHistoryService.queryByCondition(piTaskHistoryQuery);
         Map<Long, List<PiTaskHistory>> punchInTaskHistoryMap = punchInTaskHistories.stream().collect(Collectors.groupingBy(PiTaskHistory::getUserId));
 
-        // 打卡任务唯一ID
-        Set<Long> punchInTaskUniqueIdList = punchInTaskHistories.stream().map(PiTaskHistory::getPunchInTaskUniqueId).collect(Collectors.toSet());
-
-        // 获取打卡任务信息,打卡任务唯一ID-打卡任务关联
-        PiTaskQuery piTaskQuery = new PiTaskQuery();
-        piTaskQuery.setTaskStatus(ArchiveStatusEnum.ACTIVE);
-        piTaskQuery.setTaskUniqueIds(punchInTaskUniqueIdList);
-        List<PiTask> piTasks = punchInTaskService.queryByCondition(piTaskQuery);
-        Map<Long, PiTask> punchInTaskMap = piTasks.stream().collect(Collectors.toMap(PiTask::getUniqueId, Function.identity(), (key1, key2) -> key1));
-
         // 打卡任务ID
         Set<Long> punchInTaskIds = piTasks.stream().map(PiTask::getId).collect(Collectors.toSet());
 
@@ -255,75 +348,54 @@ public class PunchInCoreTask {
         List<PiTaskExt> piTaskExtList = punchInTaskExtService.queryByCondition(piTaskExtQuery);
         Map<Long, List<PiTaskExt>> punchInTaskExtGroupList = piTaskExtList.stream().collect(Collectors.groupingBy(PiTaskExt::getPunchInTaskId));
 
-        // 获取打卡任务周数据统计,打卡任务唯一ID-打卡任务周数据统计关联
-        StatPiTaskWeekQuery statPiTaskWeekQuery = new StatPiTaskWeekQuery();
-        statPiTaskWeekQuery.setTaskUniqueIds(punchInTaskUniqueIdList);
-        statPiTaskWeekQuery.setStatsTime(DateUtils.getYearWeek(punchInDate));
-        List<StatPiTaskWeek> statPiTaskWeekList = punchInStatsWeekService.queryByCondition(statPiTaskWeekQuery);
-        Map<Long, StatPiTaskWeek> punchInStatsWeekMap = statPiTaskWeekList.stream().collect(Collectors.toMap(StatPiTaskWeek::getTaskUniqueId, Function.identity(), (key1, key2)->key1));
-
-        // 获取打卡任务月数据统计,打卡任务唯一ID-打卡任务月数据统计关联
-        PiStatsMonthQuery piStatsMonthQuery = new PiStatsMonthQuery();
-        piStatsMonthQuery.setTaskUniqueIds(punchInTaskUniqueIdList);
-        piStatsMonthQuery.setStatsTime(DateUtils.getYearMonth(punchInDate));
-        List<StatPiTaskMonth> statPiTaskMonthList = punchInStatsMonthService.queryByCondition(piStatsMonthQuery);
-        Map<Long, StatPiTaskMonth> punchInStatsMonthMap = statPiTaskMonthList.stream().collect(Collectors.toMap(StatPiTaskMonth::getTaskUniqueId, Function.identity(), (key1, key2)->key1));
-
         return userIds.stream().map(userId -> {
-            PunchInSettleDto punchInSettleDto = new PunchInSettleDto();
-            punchInSettleDto.setUserId(userId);
+            PunchInSettleData punchInSettleData = new PunchInSettleData();
+            punchInSettleData.setUserId(userId);
 
             PiMultiTask piMultiTask = punchInMultiTaskMap.get(userId);
-            punchInSettleDto.setPiMultiTask(piMultiTask);
+            punchInSettleData.setPiMultiTask(piMultiTask);
 
             List<PiMultiTaskExt> tempPiMultiTaskExtList = punchInMultiTaskExtMap.get(piMultiTask.getId());
-            punchInSettleDto.setPiMultiTaskExtList(tempPiMultiTaskExtList);
+            punchInSettleData.setPiMultiTaskExtList(tempPiMultiTaskExtList);
 
             PiMultiTaskHistory piMultiTaskHistory = punchInMultiTaskHistoryMap.get(piMultiTask.getUniqueId());
-            punchInSettleDto.setPiMultiTaskHistory(piMultiTaskHistory);
+            punchInSettleData.setPiMultiTaskHistory(piMultiTaskHistory);
 
             List<PiStatus> tempPiStatusList = punchInStatusMap.get(userId);
-            PiStatus punchInStatusInMultiTask = tempPiStatusList.stream().filter(v -> Objects.nonNull(v.getPunchInMultiTaskUniqueId())).findFirst().get();
-            punchInSettleDto.setPiMultiTask(punchInStatusInMultiTask);
+            PiStatus piStatusInMultiTask = tempPiStatusList.stream().filter(v -> Objects.nonNull(v.getMultiTaskUniqueId())).findFirst().get();
+            punchInSettleData.setPiStatus(piStatusInMultiTask);
 
             List<PiMultiTaskRela> tempPiMultiTaskRelaList = punchInMultiTaskRelaMap.get(piMultiTask.getId());
-            Set<Long> relaContainTaskIdList = tempPiMultiTaskRelaList.stream().map(PiMultiTaskRela::getPunchInTaskId).collect(Collectors.toSet());
+            Set<Long> relaContainTaskIdList = tempPiMultiTaskRelaList.stream().map(PiMultiTaskRela::getTaskId).collect(Collectors.toSet());
 
-            Map<Long, PiStatus> punchInStatusInTaskMap = tempPiStatusList.stream().filter(v -> Objects.nonNull(v.getPunchInTaskUniqueId())).collect(Collectors.toMap(PiStatus::getPunchInTaskUniqueId, Function.identity(), (key1, key2) -> key1));
+            Map<Long, PiStatus> punchInStatusInTaskMap = tempPiStatusList.stream().filter(v -> Objects.nonNull(v.getTaskUniqueId())).collect(Collectors.toMap(PiStatus::getTaskUniqueId, Function.identity(), (key1, key2) -> key1));
 
             List<PiTaskHistory> tempPunchInTaskHistories = punchInTaskHistoryMap.get(userId);
-            List<PiTaskDto> piTaskDtoList = new ArrayList<>(tempPunchInTaskHistories.size());
+            List<PiTaskData> piTaskDataList = new ArrayList<>(tempPunchInTaskHistories.size());
             List<PiTaskHistory> relaPunchInTaskHistories = new ArrayList<>(relaContainTaskIdList.size());
             for (PiTaskHistory piTaskHistory : tempPunchInTaskHistories) {
-                PiTaskDto piTaskDto = new PiTaskDto();
-                piTaskDto.setPiTaskHistory(piTaskHistory);
+                PiTaskData piTaskData = new PiTaskData();
+                piTaskData.setPiTaskHistory(piTaskHistory);
 
                 PiTask piTask = punchInTaskMap.get(piTaskHistory.getPunchInTaskUniqueId());
-                piTaskDto.setPiTask(piTask);
+                piTaskData.setPiTask(piTask);
                 if (relaContainTaskIdList.contains(piTask.getId())) {
                     relaPunchInTaskHistories.add(piTaskHistory);
                 }
 
                 List<PiTaskExt> tempPiTaskExtList = punchInTaskExtGroupList.get(piTask.getId());
-                piTaskDto.setPiTaskExtList(tempPiTaskExtList);
-
-                StatPiTaskWeek statPiTaskWeek = punchInStatsWeekMap.get(piTask.getUniqueId());
-                piTaskDto.setStatPiTaskWeek(statPiTaskWeek);
-
-                StatPiTaskMonth statPiTaskMonth = punchInStatsMonthMap.get(piTask.getUniqueId());
-                piTaskDto.setStatPiTaskMonth(statPiTaskMonth);
+                piTaskData.setPiTaskExtList(tempPiTaskExtList);
 
                 PiStatus piStatus = punchInStatusInTaskMap.get(piTaskHistory.getPunchInTaskUniqueId());
-                piTaskDto.setPiStatus(piStatus);
+                piTaskData.setPiStatus(piStatus);
 
-                piTaskDtoList.add(piTaskDto);
+                piTaskDataList.add(piTaskData);
             }
 
-            punchInSettleDto.setPiTaskDtoList(piTaskDtoList);
-            punchInSettleDto.setRelaPunchInTaskHistories(relaPunchInTaskHistories);
+            punchInSettleData.setPiTaskDataList(piTaskDataList);
+            punchInSettleData.setRelaPunchInTaskHistories(relaPunchInTaskHistories);
 
-            return punchInSettleDto;
+            return punchInSettleData;
         }).collect(Collectors.toList());
-
     }
 }

+ 39 - 8
src/main/java/com/punchsettle/server/utiis/DateUtils.java

@@ -1,9 +1,9 @@
 package com.punchsettle.server.utiis;
 
-import java.sql.Timestamp;
 import java.text.SimpleDateFormat;
 import java.time.DayOfWeek;
 import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
 import java.time.temporal.TemporalAdjusters;
 import java.time.temporal.WeekFields;
 import java.util.ArrayList;
@@ -25,7 +25,9 @@ public class DateUtils {
     /**
      * 日期格式(yyyy-MM-dd)
      */
-    public static final String DATE_FORMAT = "yyyy-MM-dd";
+    public static final String YYYY_MM_DD_FORMAT = "yyyy-MM-dd";
+
+    public static final DateTimeFormatter YYYY_MM_DD_FORMATTER = DateTimeFormatter.ofPattern(YYYY_MM_DD_FORMAT);
 
     /**
      * 创建完整的日期时间格式化器(yyyy-MM-dd HH:mm:ss)
@@ -40,24 +42,52 @@ public class DateUtils {
      * @return
      */
     public static SimpleDateFormat buildDateFormat() {
-        return new SimpleDateFormat(DATE_FORMAT);
+        return new SimpleDateFormat(YYYY_MM_DD_FORMAT);
     }
 
     /**
-     * 获取一周的时间范围
+     * 获取当前周的日期列表(周一~周日)
      * @return 返回日期字符串列表
      */
-    public static List<LocalDate> getWeeklyDateRange() {
+    public static List<LocalDate> getDateRangeInWeek() {
         LocalDate today = LocalDate.now();
+        return getDateRangeInWeek(today);
+    }
 
+    /**
+     * 获取日期所在月的日期列表(周一~周日)
+     * @param date 指定日期
+     * @return
+     */
+    public static List<LocalDate> getDateRangeInWeek(LocalDate date) {
         // 获取本周的第一天(假设周一为一周的第一天)
-        LocalDate firstDayOfWeek = today.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
+        LocalDate firstDayOfWeek = date.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
 
         // 打印本周的所有日期
         List<LocalDate> list = new ArrayList<>(7);
         for (int i = 0; i < 7; i++) {
-            LocalDate date = firstDayOfWeek.plusDays(i);
-            list.add(date);
+            LocalDate tempDate = firstDayOfWeek.plusDays(i);
+            list.add(tempDate);
+        }
+        return list;
+    }
+
+    /**
+     * 获取日期所在月的日期列表(1号~30号/31号)
+     * @param date 指定日期
+     * @return
+     */
+    public static List<LocalDate> getDateRangeInMonth(LocalDate date) {
+        // 获取本月的第一天
+        LocalDate firstDayOfMonth = date.with(TemporalAdjusters.firstDayOfMonth());
+        // 本月长度
+        int lengthOfMonth = date.lengthOfMonth();
+
+        // 打印本月的所有日期
+        List<LocalDate> list = new ArrayList<>(lengthOfMonth);
+        for (int i = 0; i < lengthOfMonth; i++) {
+            LocalDate tempDate = firstDayOfMonth.plusDays(i);
+            list.add(tempDate);
         }
         return list;
     }
@@ -113,4 +143,5 @@ public class DateUtils {
         // 组合年份和周数
         return String.format("%d-%02d", year, month);
     }
+
 }