瀏覽代碼

【feat】【第二版开发】
1.完善批量插入和更新的配置
2.完善脚本
3.完善技术文档
4.完善结算功能
5.完善记录查询功能

ChenYL 1 年之前
父節點
當前提交
e40e2ffa97
共有 30 個文件被更改,包括 460 次插入153 次删除
  1. 38 0
      doc/sql/update-v2.sql
  2. 30 28
      doc/技术文档.md
  3. 1 1
      src/main/java/com/punchsettle/server/atomic/entity/PunchIn.java
  4. 36 0
      src/main/java/com/punchsettle/server/atomic/entity/PunchInRecord.java
  5. 0 22
      src/main/java/com/punchsettle/server/atomic/entity/PunchInRecordSettlementRela.java
  6. 1 1
      src/main/java/com/punchsettle/server/atomic/mapper/PunchInRecordMapper.java
  7. 1 2
      src/main/java/com/punchsettle/server/atomic/mapper/PunchInRecordSettlementRelaMapper.java
  8. 1 1
      src/main/java/com/punchsettle/server/atomic/mapper/PunchInSettlementMapper.java
  9. 1 0
      src/main/java/com/punchsettle/server/atomic/service/impl/LotteryScratchRecordServiceImpl.java
  10. 4 0
      src/main/java/com/punchsettle/server/atomic/service/impl/PunchInRecordServiceImpl.java
  11. 2 0
      src/main/java/com/punchsettle/server/atomic/service/impl/PunchInServiceImpl.java
  12. 1 0
      src/main/java/com/punchsettle/server/atomic/service/impl/PunchInSettlementServiceImpl.java
  13. 1 1
      src/main/java/com/punchsettle/server/atomic/service/impl/UserClaimRewardRecordServiceImpl.java
  14. 1 0
      src/main/java/com/punchsettle/server/constant/PunchInStatusViewEnum.java
  15. 50 0
      src/main/java/com/punchsettle/server/dto/punchin/PunchInCalendarDataResult.java
  16. 8 4
      src/main/java/com/punchsettle/server/dto/punchin/PunchInDataResult.java
  17. 23 5
      src/main/java/com/punchsettle/server/dto/punchin/PunchInRecordDataResult.java
  18. 6 3
      src/main/java/com/punchsettle/server/dto/reward/ClaimRewardRecordDto.java
  19. 5 0
      src/main/java/com/punchsettle/server/dto/scratch/ScratchDto.java
  20. 1 1
      src/main/java/com/punchsettle/server/dto/settle/SettleDto.java
  21. 4 9
      src/main/java/com/punchsettle/server/dto/settle/SettleResultDto.java
  22. 7 11
      src/main/java/com/punchsettle/server/service/controller/PunchInController.java
  23. 6 4
      src/main/java/com/punchsettle/server/service/controller/SettleController.java
  24. 9 0
      src/main/java/com/punchsettle/server/service/manager/IPunchInManager.java
  25. 89 1
      src/main/java/com/punchsettle/server/service/manager/impl/PunchInManagerImpl.java
  26. 4 0
      src/main/java/com/punchsettle/server/service/manager/impl/RewardManagerImpl.java
  27. 4 0
      src/main/java/com/punchsettle/server/service/manager/impl/ScratchManagerImpl.java
  28. 124 57
      src/main/java/com/punchsettle/server/service/manager/impl/SettleManagerImpl.java
  29. 1 1
      src/main/java/com/punchsettle/server/utiis/DateUtils.java
  30. 1 1
      src/main/resources/application-dev.yaml

+ 38 - 0
doc/sql/update-v2.sql

@@ -167,3 +167,41 @@ ALTER TABLE punch_settle.lottery_scratch_record CHANGE win_amount amount decimal
 ALTER TABLE punch_settle.punch_in_record ADD punch_in_status int DEFAULT 0 NOT NULL COMMENT '打卡状态(0-进行中,1-完成,2-未完成) ,结算后修改状态,单次打卡除外';
 ALTER TABLE punch_settle.punch_in_record CHANGE punch_in_status punch_in_status int DEFAULT 0 NOT NULL COMMENT '打卡状态(0-进行中,1-完成,2-未完成) ,结算后修改状态,单次打卡除外' AFTER time_track;
 
+update punch_settle.punch_in_record
+set punch_in_status = 1;
+
+update punch_settle.punch_in_record record,
+punch_settle.punch_in_record_settlement_rela rela,
+punch_settle.punch_in pi
+set rela.reward_num = pi.reward_num
+where rela.record_id = record.id
+and record.punch_in_id = pi.id;
+
+
+ALTER TABLE punch_settle.punch_in_record MODIFY COLUMN count_track int DEFAULT 0 NULL COMMENT '次数记录';
+ALTER TABLE punch_settle.punch_in_record MODIFY COLUMN time_track time DEFAULT '00:00:00.000' NULL COMMENT '时间记录';
+
+ALTER TABLE punch_settle.punch_in_record_settlement_rela DROP COLUMN reward_num;
+ALTER TABLE punch_settle.punch_in_record_settlement_rela DROP COLUMN category;
+ALTER TABLE punch_settle.punch_in_record_settlement_rela DROP COLUMN rule;
+
+ALTER TABLE punch_settle.punch_in_record ADD settle_reward_num int DEFAULT 0 NULL COMMENT '结算时的奖励倍数';
+ALTER TABLE punch_settle.punch_in_record ADD settle_category int DEFAULT 0 NULL COMMENT '结算时的打卡类型(0-单次打卡,1-计数、2计时)';
+ALTER TABLE punch_settle.punch_in_record ADD settle_rule int DEFAULT 1 NULL COMMENT '结算时的比较规则(0-大于,1-大于等于,2-小于,3-小于等于)';
+ALTER TABLE punch_settle.punch_in_record ADD settle_count_track int DEFAULT 0 NULL COMMENT '结算时的次数记录';
+
+ALTER TABLE punch_settle.punch_in_record ADD settle_time_track TIMESTAMP NULL COMMENT '结算时的时间记录';
+ALTER TABLE punch_settle.punch_in_record MODIFY COLUMN settle_time_track time DEFAULT '00:00:00.000' NULL COMMENT '结算时的时间记录';
+
+ALTER TABLE punch_settle.punch_in_record CHANGE settle_reward_num settle_reward_num int DEFAULT 0 NULL COMMENT '结算时的奖励倍数' AFTER punch_in_status;
+ALTER TABLE punch_settle.punch_in_record CHANGE settle_category settle_category int DEFAULT 0 NULL COMMENT '结算时的打卡类型(0-单次打卡,1-计数、2计时)' AFTER settle_reward_num;
+ALTER TABLE punch_settle.punch_in_record CHANGE settle_rule settle_rule int DEFAULT 1 NULL COMMENT '结算时的比较规则(0-大于,1-大于等于,2-小于,3-小于等于)' AFTER settle_category;
+ALTER TABLE punch_settle.punch_in_record CHANGE settle_count_track settle_count_track int DEFAULT 0 NULL COMMENT '结算时的次数记录' AFTER settle_rule;
+ALTER TABLE punch_settle.punch_in_record CHANGE settle_time_track settle_time_track time DEFAULT '00:00:00' NULL COMMENT '结算时的时间记录' AFTER settle_count_track;
+
+ALTER TABLE punch_settle.punch_in_record MODIFY COLUMN settle_reward_num int DEFAULT 0 NULL COMMENT '结算时任务上的奖励倍数';
+ALTER TABLE punch_settle.punch_in_record MODIFY COLUMN settle_category int DEFAULT 0 NULL COMMENT '结算时任务上的打卡类型(0-单次打卡,1-计数、2计时)';
+ALTER TABLE punch_settle.punch_in_record MODIFY COLUMN settle_rule int DEFAULT 1 NULL COMMENT '结算时任务上的比较规则(0-大于,1-大于等于,2-小于,3-小于等于)';
+ALTER TABLE punch_settle.punch_in_record MODIFY COLUMN settle_count_track int DEFAULT 0 NULL COMMENT '结算时任务上的次数记录';
+ALTER TABLE punch_settle.punch_in_record MODIFY COLUMN settle_time_track time DEFAULT '00:00:00' NULL COMMENT '结算时任务上的时间记录';
+

+ 30 - 28
doc/技术文档.md

@@ -227,20 +227,25 @@ ui设计工具:即时设计
 
 表名:punch_in_record
 
-| 字段             | 类型        | 描述                                                         |
-| ---------------- | ----------- | ------------------------------------------------------------ |
-| id               | bigint      | 主键                                                         |
-| punch_in_id      | bigint      | 打卡任务表主键                                               |
-| punch_in_date    | varchar(10) | 打卡日期                                                     |
-| count_track      | int         | 次数记录                                                     |
-| time_track       | time        | 时间记录                                                     |
-| punch_in_status  | int         | 打卡状态(0-进行中,1-完成,2-未完成) ,结算后修改状态,单次打卡除外 |
-| created_by       | bigint      | 创建人                                                       |
-| creation_time    | timestamp   | 创建时间                                                     |
-| last_updated_by  | bigint      | 最后更信人                                                   |
-| last_update_time | timestamp   | 最后更新时间                                                 |
-| version          | bigint      | 版本号                                                       |
-| delete_flag      | tinyint     | 逻辑删除标志(0-未删除,1-已删除)                           |
+| 字段               | 类型        | 描述                                                         |
+| ------------------ | ----------- | ------------------------------------------------------------ |
+| id                 | bigint      | 主键                                                         |
+| punch_in_id        | bigint      | 打卡任务表主键                                               |
+| punch_in_date      | varchar(10) | 打卡日期                                                     |
+| count_track        | int         | 次数记录                                                     |
+| time_track         | time        | 时间记录                                                     |
+| settle_reward_num  | int         | 结算时任务上的奖励倍数                                       |
+| settle_category    | int         | 结算时任务上的打卡类型(0-单次打卡,1-计数、2计时)            |
+| settle_rule        | int         | 结算时任务上的比较规则(0-大于,1-大于等于,2-小于,3-小于等于) |
+| settle_count_track | int         | 结算时任务上的次数记录                                       |
+| settle_time_track  | time        | 结算时任务上的时间记录                                       |
+| punch_in_status    | int         | 打卡状态(0-进行中,1-完成,2-未完成) ,结算后修改状态,单次打卡除外 |
+| created_by         | bigint      | 创建人                                                       |
+| creation_time      | timestamp   | 创建时间                                                     |
+| last_updated_by    | bigint      | 最后更信人                                                   |
+| last_update_time   | timestamp   | 最后更新时间                                                 |
+| version            | bigint      | 版本号                                                       |
+| delete_flag        | tinyint     | 逻辑删除标志(0-未删除,1-已删除)                           |
 
 
 
@@ -273,20 +278,17 @@ ui设计工具:即时设计
 
 表名:punch_in_record_settlement_rela
 
-| 字段             | 类型      | 描述                                                     |
-| ---------------- | --------- | -------------------------------------------------------- |
-| id               | bigint    | 主键                                                     |
-| record_id        | bigint    | 打卡任务记录表ID                                         |
-| settlement_id    | bigint    | 打卡任务结算表ID                                         |
-| reward_num       | int       | 奖励倍数                                                 |
-| category         | int       | 打卡类型(0-单次打卡,1-计数、2计时)打卡类型              |
-| rule             | int       | 比较规则(0-大于,1-大于等于,2-小于,3-小于等于)比较规则 |
-| created_by       | bigint    | 创建人                                                   |
-| creation_time    | timestamp | 创建时间                                                 |
-| last_updated_by  | bigint    | 最后更信人                                               |
-| last_update_time | timestamp | 最后更新时间                                             |
-| version          | bigint    | 版本号                                                   |
-| delete_flag      | tinyint   | 逻辑删除标志(0-未删除,1-已删除)                       |
+| 字段             | 类型      | 描述                               |
+| ---------------- | --------- | ---------------------------------- |
+| id               | bigint    | 主键                               |
+| record_id        | bigint    | 打卡任务记录表ID                   |
+| settlement_id    | bigint    | 打卡任务结算表ID                   |
+| created_by       | bigint    | 创建人                             |
+| creation_time    | timestamp | 创建时间                           |
+| last_updated_by  | bigint    | 最后更信人                         |
+| last_update_time | timestamp | 最后更新时间                       |
+| version          | bigint    | 版本号                             |
+| delete_flag      | tinyint   | 逻辑删除标志(0-未删除,1-已删除) |
 
 
 

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

@@ -4,8 +4,8 @@ import java.io.Serial;
 import java.io.Serializable;
 import java.time.LocalTime;
 
-import com.punchsettle.server.common.typehandler.EnumValueTypeHandler;
 import com.punchsettle.server.common.entity.BaseEntity;
+import com.punchsettle.server.common.typehandler.EnumValueTypeHandler;
 import com.punchsettle.server.constant.PunchInCategoryEnum;
 import com.punchsettle.server.constant.PunchInRuleEnum;
 

+ 36 - 0
src/main/java/com/punchsettle/server/atomic/entity/PunchInRecord.java

@@ -7,6 +7,8 @@ import java.time.LocalTime;
 import com.punchsettle.server.common.entity.BaseEntity;
 
 import com.punchsettle.server.common.typehandler.EnumValueTypeHandler;
+import com.punchsettle.server.constant.PunchInCategoryEnum;
+import com.punchsettle.server.constant.PunchInRuleEnum;
 import com.punchsettle.server.constant.PunchInStatusEnum;
 import jakarta.persistence.Column;
 import jakarta.persistence.Table;
@@ -58,4 +60,38 @@ public class PunchInRecord extends BaseEntity implements Serializable {
     @ColumnType(typeHandler = EnumValueTypeHandler.class)
     @Column(name = "punch_in_status")
     private PunchInStatusEnum punchInStatus;
+
+    /**
+     * 结算时的结算奖励数
+     */
+    @Column(name = "settle_reward_num")
+    private Integer settleRewardNum;
+
+    /**
+     * 结算时的打卡类型(0-单次打卡,1-计数、2计时)
+     * @see PunchInCategoryEnum
+     */
+    @ColumnType(typeHandler = EnumValueTypeHandler.class)
+    @Column(name = "settle_category")
+    private PunchInCategoryEnum settleCategory;
+
+    /**
+     * 结算时的比较规则(0-大于,1-大于等于,2-小于,3-小于等于)
+     * @see PunchInRuleEnum
+     */
+    @ColumnType(typeHandler = EnumValueTypeHandler.class)
+    @Column(name = "settle_rule")
+    private PunchInRuleEnum settleRule;
+
+    /**
+     * 结算时的次数记录
+     */
+    @Column(name = "settle_count_track")
+    private Integer settleCountTrack;
+
+    /**
+     * 结算时的时间记录
+     */
+    @Column(name = "settle_time_track")
+    private LocalTime settleTimeTrack;
 }

+ 0 - 22
src/main/java/com/punchsettle/server/atomic/entity/PunchInRecordSettlementRela.java

@@ -39,26 +39,4 @@ public class PunchInRecordSettlementRela extends BaseEntity implements Serializa
      */
     @Column(name = "settlement_id")
     private Long settlementId;
-
-    /**
-     * 结算奖励数
-     */
-    @Column(name = "reward_num")
-    private Integer rewardNum;
-
-    /**
-     * 打卡类型(0-单次打卡,1-计数、2计时)
-     * @see PunchInCategoryEnum
-     */
-    @ColumnType(typeHandler = EnumValueTypeHandler.class)
-    @Column(name = "category")
-    private PunchInCategoryEnum category;
-
-    /**
-     * 比较规则(0-大于,1-大于等于,2-小于,3-小于等于)
-     * @see PunchInRuleEnum
-     */
-    @ColumnType(typeHandler = EnumValueTypeHandler.class)
-    @Column(name = "rule")
-    private PunchInRuleEnum rule;
 }

+ 1 - 1
src/main/java/com/punchsettle/server/atomic/mapper/PunchInRecordMapper.java

@@ -2,9 +2,9 @@ package com.punchsettle.server.atomic.mapper;
 
 import com.punchsettle.server.atomic.entity.PunchInRecord;
 
-import tk.mybatis.mapper.additional.insert.InsertListMapper;
 import tk.mybatis.mapper.additional.update.batch.BatchUpdateSelectiveMapper;
 import tk.mybatis.mapper.common.Mapper;
+import tk.mybatis.mapper.common.special.InsertListMapper;
 
 /**
  * @description 打卡任务记录表 mapper

+ 1 - 2
src/main/java/com/punchsettle/server/atomic/mapper/PunchInRecordSettlementRelaMapper.java

@@ -1,8 +1,7 @@
 package com.punchsettle.server.atomic.mapper;
 
 import com.punchsettle.server.atomic.entity.PunchInRecordSettlementRela;
-
-import tk.mybatis.mapper.additional.insert.InsertListMapper;
+import tk.mybatis.mapper.common.special.InsertListMapper;
 
 /**
  * @description 打卡任务记录与结算关联表 mapper

+ 1 - 1
src/main/java/com/punchsettle/server/atomic/mapper/PunchInSettlementMapper.java

@@ -2,8 +2,8 @@ package com.punchsettle.server.atomic.mapper;
 
 import com.punchsettle.server.atomic.entity.PunchInSettlement;
 
-import tk.mybatis.mapper.additional.insert.InsertListMapper;
 import tk.mybatis.mapper.common.Mapper;
+import tk.mybatis.mapper.common.special.InsertListMapper;
 
 /**
  * @description 打卡任务结算表 mapper

+ 1 - 0
src/main/java/com/punchsettle/server/atomic/service/impl/LotteryScratchRecordServiceImpl.java

@@ -59,6 +59,7 @@ public class LotteryScratchRecordServiceImpl implements ILotteryScratchRecordSer
         if (!Objects.isNull(query.getUserId())) {
             criteria.andEqualTo(LotteryScratchRecord::getUserId, query.getUserId());
         }
+        weekend.orderBy(LotteryScratchRecord::getCreationTime).desc();
         return scratchRecordMapper.selectByExample(weekend);
     }
 }

+ 4 - 0
src/main/java/com/punchsettle/server/atomic/service/impl/PunchInRecordServiceImpl.java

@@ -82,6 +82,10 @@ public class PunchInRecordServiceImpl implements IPunchInRecordService {
         if (!CollectionUtils.isEmpty(query.getPunchInIds())) {
             criteria.andIn(PunchInRecord::getPunchInId, query.getPunchInIds());
         }
+        if (!Objects.isNull(query.getPunchInId())) {
+            criteria.andEqualTo(PunchInRecord::getPunchInId, query.getPunchInId());
+        }
+        weekend.orderBy(PunchInRecord::getPunchInDate).desc();
         return punchInRecordMapper.selectByExample(weekend);
     }
 

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

@@ -54,6 +54,8 @@ public class PunchInServiceImpl implements IPunchInService {
         if (!Objects.isNull(query.getArchiveFlag())) {
             criteria.andEqualTo(PunchIn::getArchiveFlag, query.getArchiveFlag());
         }
+        punchInWeekend.orderBy(PunchIn::getRewardNum).desc();
+        punchInWeekend.orderBy(PunchIn::getCreationTime).desc();
         return punchInMapper.selectByExample(punchInWeekend);
     }
 

+ 1 - 0
src/main/java/com/punchsettle/server/atomic/service/impl/PunchInSettlementServiceImpl.java

@@ -46,6 +46,7 @@ public class PunchInSettlementServiceImpl implements IPunchInSettlementService {
         if (!Objects.isNull(query.getUserId())) {
             criteria.andEqualTo(PunchInSettlement::getUserId, query.getUserId());
         }
+        weekend.orderBy(PunchInSettlement::getSettlementTime).desc();
         return punchInSettlementMapper.selectByExample(weekend);
     }
 }

+ 1 - 1
src/main/java/com/punchsettle/server/atomic/service/impl/UserClaimRewardRecordServiceImpl.java

@@ -45,7 +45,7 @@ public class UserClaimRewardRecordServiceImpl implements IUserClaimRewardRecordS
         if (StringUtils.hasText(query.getStartDate()) && StringUtils.hasText(query.getEndDate())) {
             criteria.andBetween(UserClaimRewardRecord::getClaimRewardTime, query.getStartDate(), query.getEndDate());
         }
-
+        weekend.orderBy(UserClaimRewardRecord::getClaimRewardTime).desc();
         return userClaimRewardRecordMapper.selectByExample(weekend);
     }
 }

+ 1 - 0
src/main/java/com/punchsettle/server/constant/PunchInStatusViewEnum.java

@@ -17,6 +17,7 @@ public enum PunchInStatusViewEnum {
     UNCREATED("未创建打卡任务", "uncreated"),
     PUNCH_IN("已打卡", "punchIn"),
     UN_PUNCH_IN("没打卡", "unPunchIn"),
+    TODAY_UNKNOWN("当天打卡状态未知", "todayUnknown"),
     FUTURE_TIME("未到打卡时间", "futureTime");
 
     /**

+ 50 - 0
src/main/java/com/punchsettle/server/dto/punchin/PunchInCalendarDataResult.java

@@ -0,0 +1,50 @@
+package com.punchsettle.server.dto.punchin;
+
+import java.time.LocalTime;
+
+import com.punchsettle.server.constant.PunchInStatusEnum;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * @author tyuio
+ * @version 1.0.0
+ * @description 打卡数据查询结果
+ * @date 2024/12/16 20:09
+ */
+@Data
+@EqualsAndHashCode
+public class PunchInCalendarDataResult {
+
+    /**
+     * 打卡日期
+     */
+    private String date;
+
+    /**
+     * 信息
+     */
+    private String info;
+
+    /**
+     * 打卡日期
+     */
+    private String punchInDate;
+
+    /**
+     * 次数记录
+     */
+    private Integer countTrack;
+
+    /**
+     * 时间记录
+     */
+    private LocalTime timeTrack;
+
+    /**
+     * 打卡状态(0-进行中,1-完成,2-未完成) ,结算后修改状态,单次打卡除外
+     * @see PunchInStatusEnum
+     */
+    private PunchInStatusEnum punchInStatus;
+}

+ 8 - 4
src/main/java/com/punchsettle/server/dto/punchin/PunchInDataResult.java

@@ -1,12 +1,11 @@
 package com.punchsettle.server.dto.punchin;
 
-import jakarta.validation.constraints.NotNull;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
 import java.math.BigDecimal;
 import java.util.List;
 
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
 /**
  * @author tyuio
  * @version 1.0.0
@@ -37,6 +36,11 @@ public class PunchInDataResult {
      */
     private BigDecimal punchInRate;
 
+    /**
+     * 打卡记录(日历)
+     */
+    private List<PunchInCalendarDataResult> calendarSelected;
+
     /**
      * 打卡记录
      */

+ 23 - 5
src/main/java/com/punchsettle/server/dto/punchin/PunchInRecordDataResult.java

@@ -1,6 +1,9 @@
 package com.punchsettle.server.dto.punchin;
 
-import java.math.BigDecimal;
+import java.time.LocalTime;
+
+import com.punchsettle.server.constant.PunchInCategoryEnum;
+import com.punchsettle.server.constant.PunchInStatusEnum;
 
 import lombok.Data;
 import lombok.EqualsAndHashCode;
@@ -18,12 +21,27 @@ public class PunchInRecordDataResult {
     /**
      * 打卡日期
      */
-    private String date;
+    private String punchInDate;
 
     /**
-     * 信息
+     * 次数记录
      */
-    private String info;
+    private Integer countTrack;
 
-    // TODO 这里加打卡日志信息
+    /**
+     * 时间记录
+     */
+    private LocalTime timeTrack;
+
+    /**
+     * 打卡状态(0-进行中,1-完成,2-未完成) ,结算后修改状态,单次打卡除外
+     * @see PunchInStatusEnum
+     */
+    private PunchInStatusEnum punchInStatus;
+
+    /**
+     * 结算时的打卡类型(0-单次打卡,1-计数、2计时)
+     * @see PunchInCategoryEnum
+     */
+    private PunchInCategoryEnum settleCategory;
 }

+ 6 - 3
src/main/java/com/punchsettle/server/dto/reward/ClaimRewardRecordDto.java

@@ -1,7 +1,5 @@
 package com.punchsettle.server.dto.reward;
 
-import java.sql.Timestamp;
-
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 
@@ -15,6 +13,11 @@ import lombok.EqualsAndHashCode;
 @EqualsAndHashCode
 public class ClaimRewardRecordDto {
 
+    /**
+     * 记录主键
+     */
+    private Long id;
+
     /**
      * 本次领取奖励数
      */
@@ -23,7 +26,7 @@ public class ClaimRewardRecordDto {
     /**
      * 领取奖励时间
      */
-    private Timestamp claimRewardTime;
+    private String claimRewardTime;
 
     /**
      * 领取前用户拥有的奖励数

+ 5 - 0
src/main/java/com/punchsettle/server/dto/scratch/ScratchDto.java

@@ -54,4 +54,9 @@ public class ScratchDto {
     @NotNull(message = "金额不能为空", groups = {Save.class})
     @Positive(message = "金额必须大于0", groups = {Save.class})
     private BigDecimal amount;
+
+    /**
+     * 创建时间
+     */
+    private String creationTime;
 }

+ 1 - 1
src/main/java/com/punchsettle/server/dto/settle/SettleDto.java

@@ -43,5 +43,5 @@ public class SettleDto {
     /**
      * 结算时间
      */
-    private Timestamp settlementTime;
+    private String settlementTime;
 }

+ 4 - 9
src/main/java/com/punchsettle/server/dto/settle/SettleResultDto.java

@@ -1,14 +1,14 @@
 package com.punchsettle.server.dto.settle;
 
+import java.util.List;
+
 import com.punchsettle.server.atomic.entity.PunchInRecord;
-import com.punchsettle.server.atomic.entity.PunchInRecordSettlementRela;
 import com.punchsettle.server.atomic.entity.PunchInSettlement;
 import com.punchsettle.server.atomic.entity.User;
+
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 
-import java.util.List;
-
 /**
  * @author tyuio
  * @version 1.0.0
@@ -37,10 +37,5 @@ public class SettleResultDto {
     /**
      * 待新增的结算记录
      */
-    private PunchInSettlement addPunchInSettlements;
-
-    /**
-     * 待新增的打卡结算关联记录
-     */
-    private List<PunchInRecordSettlementRela> addRelas;
+    private PunchInSettlement addPunchInSettlement;
 }

+ 7 - 11
src/main/java/com/punchsettle/server/service/controller/PunchInController.java

@@ -44,6 +44,11 @@ public class PunchInController {
         return punchInManager.queryPunchInAndRecord();
     }
 
+    /**
+     * 查询指定打卡任务
+     * @param dto
+     * @return
+     */
     @PostMapping("queryPunchInById")
     public PunchInDto queryPunchInById(@RequestBody @Validated({Query.class}) PunchInDto dto) {
         return punchInManager.queryPunchInById(dto.getId());
@@ -112,16 +117,7 @@ public class PunchInController {
      * @param query
      */
     @PostMapping("/queryPunchInData")
-    public List<PunchInDataResult> queryPunchInData(@RequestBody @Validated PunchInDataQuery query) {
-
-    }
-
-    public static void main(String[] args) {
-        YearMonth yearMonth = YearMonth.of(2024, 12);
-        LocalDate localDate = yearMonth.atDay(1);
-        LocalDate localDate1 = yearMonth.atEndOfMonth();
-        System.out.println(localDate);
-        System.out.println(localDate1);
-        System.out.println(yearMonth.lengthOfMonth());
+    public PunchInDataResult queryPunchInData(@RequestBody @Validated PunchInDataQuery query) {
+        return punchInManager.queryPunchInData(query);
     }
 }

+ 6 - 4
src/main/java/com/punchsettle/server/service/controller/SettleController.java

@@ -1,13 +1,15 @@
 package com.punchsettle.server.service.controller;
 
+import java.util.List;
+
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
+import com.punchsettle.server.dto.settle.SettleDto;
 import com.punchsettle.server.dto.settle.SettleQuery;
 import com.punchsettle.server.dto.settle.SettleRequest;
 import com.punchsettle.server.service.manager.ISettleManager;
@@ -28,7 +30,7 @@ public class SettleController {
     /**
      * 手动调起结算定时任务
      */
-    @GetMapping("/manualSettle")
+    @PostMapping("/manualSettle")
     public void manualSettle(@RequestBody @Validated SettleRequest settleRequest) {
         settleManager.manualSettle(settleRequest);
     }
@@ -37,7 +39,7 @@ public class SettleController {
      * 手动调起结算定时任务
      */
     @PostMapping("/querySettle")
-    public void querySettle(@RequestBody @Validated SettleQuery query) {
-        settleManager.querySettle(query);
+    public List<SettleDto> querySettle(@RequestBody @Validated SettleQuery query) {
+        return settleManager.querySettle(query);
     }
 }

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

@@ -2,6 +2,8 @@ package com.punchsettle.server.service.manager;
 
 import java.util.List;
 
+import com.punchsettle.server.dto.punchin.PunchInDataQuery;
+import com.punchsettle.server.dto.punchin.PunchInDataResult;
 import com.punchsettle.server.dto.punchin.PunchInDto;
 import com.punchsettle.server.dto.punchin.PunchInRecordDto;
 import com.punchsettle.server.dto.punchin.PunchInWithRecordDto;
@@ -60,4 +62,11 @@ public interface IPunchInManager {
      * @param dto
      */
     void revokePunchIn(PunchInDto dto);
+
+    /**
+     * 查询打卡数据
+     * @param query
+     * @return
+     */
+    PunchInDataResult queryPunchInData(PunchInDataQuery query);
 }

+ 89 - 1
src/main/java/com/punchsettle/server/service/manager/impl/PunchInManagerImpl.java

@@ -1,8 +1,12 @@
 package com.punchsettle.server.service.manager.impl;
 
+import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.text.SimpleDateFormat;
 import java.time.LocalDate;
 import java.time.LocalTime;
+import java.time.YearMonth;
+import java.time.temporal.ChronoUnit;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -13,6 +17,10 @@ import java.util.function.Function;
 import java.util.stream.Collectors;
 
 import com.punchsettle.server.constant.PunchInStatusEnum;
+import com.punchsettle.server.dto.punchin.PunchInDataQuery;
+import com.punchsettle.server.dto.punchin.PunchInDataResult;
+import com.punchsettle.server.dto.punchin.PunchInCalendarDataResult;
+import com.punchsettle.server.dto.punchin.PunchInRecordDataResult;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -59,6 +67,11 @@ public class PunchInManagerImpl implements IPunchInManager {
     @Autowired
     private ISettleManager settleManager;
 
+    /**
+     * 数值100
+     */
+    private static final BigDecimal ONE_HUNDRED = new BigDecimal(100);
+
     @Override
     public List<PunchInWithRecordDto> queryPunchInAndRecord() {
         // 获取当前用户ID
@@ -139,6 +152,10 @@ public class PunchInManagerImpl implements IPunchInManager {
                 if (!Objects.isNull(punchInRecord) && today.isEqual(weeklyDate)) {
                     punchInWithRecordDto.setTimeTrack(punchInRecord.getTimeTrack());
                     punchInWithRecordDto.setCountTrack(punchInRecord.getCountTrack());
+                }
+
+                // 如果是今天设置状态控制页面显示
+                if (today.isEqual(weeklyDate)) {
                     punchInWithRecordDto.setPunchInStatus(punchInStatus);
                 }
             }
@@ -173,6 +190,13 @@ public class PunchInManagerImpl implements IPunchInManager {
                 || PunchInStatusEnum.REMAKE_FINISH.equals(punchInStatusEnum)) {
                 return PunchInStatusViewEnum.PUNCH_IN;
             }
+            // 当天存在打卡记录,但是还没满足打卡条件,则认为打卡状态未知
+            return PunchInStatusViewEnum.TODAY_UNKNOWN;
+        }
+
+        // 一周的某天是今天,且不存在打卡记录,则还没进行打卡
+        if (weeklyDate.isEqual(today) && Objects.isNull(punchInRecord)) {
+            return PunchInStatusViewEnum.TODAY_UNKNOWN;
         }
 
         // 不符合任何情况则是未打卡
@@ -325,7 +349,71 @@ public class PunchInManagerImpl implements IPunchInManager {
             PunchInRecord updateRecord = new PunchInRecord();
             updateRecord.setId(punchInRecord.getId());
             updateRecord.setCountTrack(punchInRecord.getCountTrack() - 1);
-            punchInRecordService.update(punchInRecord);
+            punchInRecordService.update(updateRecord);
+            if (updateRecord.getCountTrack() == 0) {
+                punchInRecordService.delete(punchInRecord.getId());
+            }
         }
     }
+
+    @Override
+    public PunchInDataResult queryPunchInData(PunchInDataQuery query) {
+        PunchIn punchIn = Optional.ofNullable(punchInService.getById(query.getId())).orElseThrow(() -> BusinessException.fail("找到指定的打卡任务"));
+
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+        YearMonth yearMonth = YearMonth.of(query.getYear(), query.getMonth());
+        // 本月第一日
+        LocalDate firstOfMonth = yearMonth.atDay(1);
+        // 本月最后以日
+        LocalDate endOfMonth = yearMonth.atEndOfMonth();
+        // 任务创建日期
+        LocalDate punchInCreationDate = punchIn.getCreationTime().toLocalDateTime().toLocalDate();
+
+        // 获取打卡记录
+        PunchInRecordQuery punchInRecordQuery = new PunchInRecordQuery();
+        punchInRecordQuery.setPunchInId(punchIn.getId());
+        punchInRecordQuery.setStartDate(String.format("%s 00:00:00.000", firstOfMonth));
+        punchInRecordQuery.setEndDate(String.format("%s 23:59:59.999", endOfMonth));
+        List<PunchInRecord> punchInRecords = punchInRecordService.listByCondition(punchInRecordQuery);
+
+        // 构造数据,日历部分的数据只需要已打卡的数据
+        List<PunchInCalendarDataResult> punchInCalendarDataResults = new ArrayList<>();
+        List<PunchInRecordDataResult> punchInRecordDtoList = new ArrayList<>();
+        for (PunchInRecord punchInRecord : punchInRecords) {
+            PunchInRecordDataResult punchInRecordDto = new PunchInRecordDataResult();
+            BeanUtils.copyProperties(punchInRecord, punchInRecordDto);
+            punchInRecordDtoList.add(punchInRecordDto);
+
+            if (PunchInStatusEnum.UN_FINISH.equals(punchInRecord.getPunchInStatus())
+                    || PunchInStatusEnum.DOING.equals(punchInRecord.getPunchInStatus())) {
+                continue;
+            }
+            PunchInCalendarDataResult punchInCalendarDataResult = new PunchInCalendarDataResult();
+            punchInCalendarDataResult.setPunchInDate(punchInRecord.getPunchInDate());
+            punchInCalendarDataResult.setInfo("打卡");
+            punchInCalendarDataResult.setDate(punchInRecord.getPunchInDate());
+            punchInCalendarDataResults.add(punchInCalendarDataResult);
+        }
+
+        // 计算全勤率
+        BigDecimal punchInRate = BigDecimal.ZERO;
+        // 要考虑任务刚创建的情况,任务较迟创建的话则使用任务创建时间
+        long dayLength = ChronoUnit.DAYS.between(firstOfMonth.isBefore(punchInCreationDate) ? punchInCreationDate : firstOfMonth, LocalDate.now());
+        if (dayLength != 0) {
+            punchInRate = BigDecimal.valueOf(punchInCalendarDataResults.size())
+                    .divide(BigDecimal.valueOf(dayLength), 4, RoundingMode.HALF_DOWN)
+                    .multiply(ONE_HUNDRED);
+        }
+
+        // 构造返回结果
+        PunchInDataResult punchInDataResult = new PunchInDataResult();
+        punchInDataResult.setStartDate(sdf.format(punchIn.getCreationTime()));
+        punchInDataResult.setEndDate(LocalDate.now().toString());
+        punchInDataResult.setPunchInNum(punchInCalendarDataResults.size());
+        punchInDataResult.setCalendarSelected(punchInCalendarDataResults);
+        punchInDataResult.setPunchInRecords(punchInRecordDtoList);
+        punchInDataResult.setPunchInRate(punchInRate);
+
+        return punchInDataResult;
+    }
 }

+ 4 - 0
src/main/java/com/punchsettle/server/service/manager/impl/RewardManagerImpl.java

@@ -1,6 +1,7 @@
 package com.punchsettle.server.service.manager.impl;
 
 import java.sql.Timestamp;
+import java.text.SimpleDateFormat;
 import java.util.List;
 import java.util.Objects;
 import java.util.Optional;
@@ -83,10 +84,13 @@ public class RewardManagerImpl implements IRewardManager {
         query.setStartDate(String.format("%s 00:00:00.000", query.getStartDate()));
         query.setEndDate(String.format("%s 23:59:59.999", query.getEndDate()));
 
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
         List<UserClaimRewardRecord> userClaimRewardRecords = userClaimRewardRecordService.listByCondition(query);
         return userClaimRewardRecords.stream().map(record -> {
             ClaimRewardRecordDto dto = new ClaimRewardRecordDto();
             BeanUtils.copyProperties(record, dto);
+            dto.setClaimRewardTime(sdf.format(record.getClaimRewardTime()));
             return dto;
         }).toList();
     }

+ 4 - 0
src/main/java/com/punchsettle/server/service/manager/impl/ScratchManagerImpl.java

@@ -17,6 +17,7 @@ import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.CollectionUtils;
 import org.springframework.util.StringUtils;
 
+import java.text.SimpleDateFormat;
 import java.util.List;
 import java.util.Objects;
 import java.util.Optional;
@@ -124,9 +125,12 @@ public class ScratchManagerImpl implements IScratchManager {
             return List.of();
         }
 
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
         return scratchRecords.stream().map(record -> {
             ScratchDto dto = new ScratchDto();
             BeanUtils.copyProperties(record, dto);
+            dto.setCreationTime(sdf.format(record.getCreationTime()));
             return dto;
         }).toList();
     }

+ 124 - 57
src/main/java/com/punchsettle/server/service/manager/impl/SettleManagerImpl.java

@@ -1,8 +1,9 @@
 package com.punchsettle.server.service.manager.impl;
 
 import java.sql.Timestamp;
-import java.time.DayOfWeek;
+import java.text.SimpleDateFormat;
 import java.time.LocalDate;
+import java.time.LocalTime;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
@@ -11,23 +12,12 @@ import java.util.Optional;
 import java.util.function.Function;
 import java.util.stream.Collectors;
 
-import com.punchsettle.server.common.exception.BusinessException;
-import com.punchsettle.server.common.utils.Assert;
-import com.punchsettle.server.constant.PunchInCategoryEnum;
-import com.punchsettle.server.constant.PunchInRuleEnum;
-import com.punchsettle.server.constant.PunchInSettleTypeEnum;
-import com.punchsettle.server.constant.PunchInStatusEnum;
-import com.punchsettle.server.dto.settle.SettleDto;
-import com.punchsettle.server.dto.settle.SettleInfoDto;
-import com.punchsettle.server.dto.settle.SettleQuery;
-import com.punchsettle.server.dto.settle.SettleRequest;
-import com.punchsettle.server.dto.settle.SettleResultDto;
-import com.punchsettle.server.utiis.SpringUtils;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
 
 import com.punchsettle.server.atomic.entity.PunchIn;
 import com.punchsettle.server.atomic.entity.PunchInRecord;
@@ -41,14 +31,24 @@ import com.punchsettle.server.atomic.service.IPunchInService;
 import com.punchsettle.server.atomic.service.IPunchInSettlementService;
 import com.punchsettle.server.atomic.service.ISettlementTaskService;
 import com.punchsettle.server.atomic.service.IUserService;
+import com.punchsettle.server.common.exception.BusinessException;
+import com.punchsettle.server.common.utils.Assert;
+import com.punchsettle.server.constant.PunchInCategoryEnum;
+import com.punchsettle.server.constant.PunchInRuleEnum;
+import com.punchsettle.server.constant.PunchInSettleTypeEnum;
+import com.punchsettle.server.constant.PunchInStatusEnum;
 import com.punchsettle.server.dto.punchin.PunchInQuery;
 import com.punchsettle.server.dto.punchin.PunchInRecordQuery;
-import com.punchsettle.server.dto.task.SettleRewardTaskDto;
+import com.punchsettle.server.dto.settle.SettleDto;
+import com.punchsettle.server.dto.settle.SettleInfoDto;
+import com.punchsettle.server.dto.settle.SettleQuery;
+import com.punchsettle.server.dto.settle.SettleRequest;
+import com.punchsettle.server.dto.settle.SettleResultDto;
 import com.punchsettle.server.service.manager.ISettleManager;
 import com.punchsettle.server.utiis.DateUtils;
+import com.punchsettle.server.utiis.SpringUtils;
 
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.util.StringUtils;
 
 /**
  * @author tyuio
@@ -117,7 +117,9 @@ public class SettleManagerImpl implements ISettleManager {
         // 读取用户的打卡任务,如果punchIds为空则结算用户所有的打卡任务
         PunchInQuery punchInQuery = new PunchInQuery();
         punchInQuery.setUserIds(userIds);
-        punchInQuery.setPunchInIds(punchInIds);
+        if (!CollectionUtils.isEmpty(punchInIds)) {
+            punchInQuery.setPunchInIds(punchInIds);
+        }
         List<PunchIn> punchIns = punchInService.listByCondition(punchInQuery);
         if (CollectionUtils.isEmpty(punchIns)) {
             log.info("结算任务结束,原因:没有找到打卡任务");
@@ -132,7 +134,7 @@ public class SettleManagerImpl implements ISettleManager {
         recordQuery.setEndDate(settleInfo.getSettleDateStr());
         recordQuery.setPunchInIds(punchInIds);
         List<PunchInRecord> punchInRecords = punchInRecordService.listByCondition(recordQuery);
-        if (CollectionUtils.isEmpty(punchInRecords)) {
+        if (CollectionUtils.isEmpty(punchInRecords) && !PunchInSettleTypeEnum.REMAKE.equals(settleInfo.getSettleType())) {
             log.info("结算任务结束,原因:没有打卡记录");
             return;
         }
@@ -155,17 +157,6 @@ public class SettleManagerImpl implements ISettleManager {
         // 打卡任务-打卡记录 map
         Map<Long, PunchInRecord> punchInRecordMap = punchInRecords.stream().collect(Collectors.toMap(PunchInRecord::getPunchInId, Function.identity(), (key1, key2) -> key1));
 
-        // 待更新的用户
-        List<User> updateUsers = new ArrayList<>();
-        // 新增的打卡结算关联关系
-        List<PunchInRecordSettlementRela> addRelas = new ArrayList<>();
-        // 待更新的打卡记录
-        List<PunchInRecord> updatePunchInRecords = new ArrayList<>();
-        // 待新增的打卡记录
-        List<PunchInRecord> addPunchInRecords = new ArrayList<>();
-        // 待新增的打卡结算信息
-        List<PunchInSettlement> addPunchInSettlements = new ArrayList<>();
-
         // 先创建结算任务执行记录
         SettlementTask settlementTask = new SettlementTask();
         settlementTask.setSettleDate(settleDate.toString());
@@ -174,13 +165,27 @@ public class SettleManagerImpl implements ISettleManager {
         settlementTaskService.insert(settlementTask);
 
         // 结算
+        List<SettleResultDto> settleResultDtoList = new ArrayList<>();
         for (User user : users) {
             SettleResultDto settleResult = settle(settleInfo, user, userPunchInMap.get(user.getId()), punchInRecordMap, weeklyPunchInRecords);
+            settleResultDtoList.add(settleResult);
+        }
+
+        // 更新数据
+        // 待更新的用户
+        List<User> updateUsers = new ArrayList<>();
+        // 待更新的打卡记录
+        List<PunchInRecord> updatePunchInRecords = new ArrayList<>();
+        // 待新增的打卡记录
+        List<PunchInRecord> addPunchInRecords = new ArrayList<>();
+        // 待新增的打卡结算信息
+        List<PunchInSettlement> addPunchInSettlements = new ArrayList<>();
+
+        for (SettleResultDto settleResult : settleResultDtoList) {
             updateUsers.add(settleResult.getUpdateUser());
-            addRelas.addAll(settleResult.getAddRelas());
             addPunchInRecords.addAll(settleResult.getAddPunchInRecords());
             updatePunchInRecords.addAll(settleResult.getUpdatePunchInRecords());
-            addPunchInSettlements.add(settleResult.getAddPunchInSettlements());
+            addPunchInSettlements.add(settleResult.getAddPunchInSettlement());
         }
 
         // 更新用户奖励信息
@@ -193,18 +198,24 @@ public class SettleManagerImpl implements ISettleManager {
             punchInRecordService.batchInsert(addPunchInRecords);
         }
 
+        // 更新已有的打卡记录
         if (!CollectionUtils.isEmpty(updatePunchInRecords)) {
             punchInRecordService.batchUpdate(updatePunchInRecords);
         }
 
         // 新增结算信息
         if (!CollectionUtils.isEmpty(addPunchInSettlements)) {
+            // 补充本次的计算任务ID
+            addPunchInSettlements.stream().forEach(v -> v.setSettlementTaskId(settlementTask.getId()));
             punchInSettlementService.batchInsert(addPunchInSettlements);
         }
 
         // 新增关联信息
-        if (!CollectionUtils.isEmpty(addRelas)) {
-            punchInRecordSettlementRelaService.batchInsert(addRelas);
+        if (!CollectionUtils.isEmpty(settleResultDtoList)) {
+            List<PunchInRecordSettlementRela> relaList = buildPunchInRecordSettlementRelaList(settleResultDtoList);
+            if (!CollectionUtils.isEmpty(relaList)) {
+                punchInRecordSettlementRelaService.batchInsert(relaList);
+            }
         }
 
         // 构造并新增结算任务信息
@@ -228,8 +239,6 @@ public class SettleManagerImpl implements ISettleManager {
     private SettleResultDto settle(SettleInfoDto settleInfo, User user, List<PunchIn> punchIns, Map<Long, PunchInRecord> punchInRecordMap, Map<Long, List<PunchInRecord>> weeklyPunchInRecordMap) {
         // 结算奖励数
         int settleRewardNum = 0;
-        // 新增的打卡结算关联关系
-        List<PunchInRecordSettlementRela> addRelas = new ArrayList<>();
         // 待更新的打卡记录
         List<PunchInRecord> updatePunchInRecords = new ArrayList<>();
         // 待新增的打卡记录
@@ -238,43 +247,49 @@ public class SettleManagerImpl implements ISettleManager {
         for (PunchIn punchIn : punchIns) {
             // 获取打卡记录
             PunchInRecord punchInRecord = punchInRecordMap.get(punchIn.getId());
+            // 不是补打卡且不存在打卡记录直接跳过,无须结算和更新记录状态
+            if (!PunchInSettleTypeEnum.REMAKE.equals(settleInfo.getSettleType()) && Objects.isNull(punchInRecord)) {
+                continue;
+            }
             // 判断是否满足打卡规则
             PunchInStatusEnum punchInStatus = judgePunchInStatus(punchIn, punchInRecord);
-            //不满足则跳过无需接续,如果是补卡则直接完成继续计算
+            // 不是补卡或打卡任务未完成,则跳过
             if (!PunchInSettleTypeEnum.REMAKE.equals(settleInfo.getSettleType()) && PunchInStatusEnum.UN_FINISH.equals(punchInStatus)) {
-                punchInRecord.setPunchInStatus(punchInStatus);
-                updatePunchInRecords.add(punchInRecord);
+                PunchInRecord updatePunchInRecord = buildPunchInRecordForSettle(punchIn);
+                updatePunchInRecord.setId(punchInRecord.getId());
+                updatePunchInRecord.setPunchInStatus(punchInStatus);
+                updatePunchInRecords.add(updatePunchInRecord);
                 continue;
             }
 
             // 补打卡,完全没有打卡记录则需要补充打卡记录
             if (PunchInSettleTypeEnum.REMAKE.equals(settleInfo.getSettleType()) && Objects.isNull(punchInRecord)) {
-                punchInRecord = new PunchInRecord();
+                punchInRecord = buildPunchInRecordForSettle(punchIn);
                 punchInRecord.setPunchInId(punchIn.getId());
                 punchInRecord.setPunchInDate(settleInfo.getSettleDateStr());
+                punchInRecord.setPunchInStatus(PunchInStatusEnum.REMAKE_FINISH);
                 addPunchInRecords.add(punchInRecord);
             }
 
             // 补打卡,已有打卡记录但是不满足打卡规则,则需要对打卡记录做准备
             if (PunchInSettleTypeEnum.REMAKE.equals(settleInfo.getSettleType()) && PunchInStatusEnum.UN_FINISH.equals(punchInStatus)) {
-                punchInRecord.setPunchInStatus(PunchInStatusEnum.REMAKE_FINISH);
                 fillTrack(punchIn, punchInRecord);
             }
 
+            // 不是补卡,且打卡状态为完成,需要更新打卡状态为完成
+            if (Objects.isNull(punchInRecord.getPunchInStatus()) || PunchInStatusEnum.DOING.equals(punchInRecord.getPunchInStatus())) {
+                PunchInRecord updatePunchInRecord = buildPunchInRecordForSettle(punchIn);
+                updatePunchInRecord.setId(punchInRecord.getId());
+                updatePunchInRecord.setPunchInStatus(punchInStatus);
+                updatePunchInRecords.add(updatePunchInRecord);
+            }
+
             // 周末双倍奖励,否则计算普通奖励
             settleRewardNum += settleInfo.getWeekendFlag() ? punchIn.getRewardNum() * 2 : punchIn.getRewardNum();
             // 计算全勤双倍奖励
             if (judgeFullAttendance(settleInfo, punchIn, weeklyPunchInRecordMap)) {
                 settleRewardNum += punchIn.getRewardNum() * 2;
             }
-
-            // 构建结算任务与记录关联信息
-            PunchInRecordSettlementRela rela = new PunchInRecordSettlementRela();
-            rela.setRecordId(punchInRecord.getId());
-            rela.setRewardNum(punchIn.getRewardNum());
-            rela.setCategory(punchIn.getCategory());
-            rela.setRule(punchIn.getRule());
-            addRelas.add(rela);
         }
 
         // 计算结算前后,用户奖励数的变化
@@ -297,11 +312,10 @@ public class SettleManagerImpl implements ISettleManager {
         updateUser.setUnclaimedRewardNum(afterSettleRewardNum);
 
         SettleResultDto settleResultDto = new SettleResultDto();
-        settleResultDto.setAddRelas(addRelas);
         settleResultDto.setUpdateUser(updateUser);
         settleResultDto.setAddPunchInRecords(addPunchInRecords);
         settleResultDto.setUpdatePunchInRecords(updatePunchInRecords);
-        settleResultDto.setAddPunchInSettlements(addPunchInSettlement);
+        settleResultDto.setAddPunchInSettlement(addPunchInSettlement);
         return settleResultDto;
     }
 
@@ -319,16 +333,17 @@ public class SettleManagerImpl implements ISettleManager {
 
         // 计数打卡
         if (PunchInCategoryEnum.COUNT.equals(punchIn.getCategory())) {
-            if (PunchInRuleEnum.GREATER.equals(punchIn.getRule()) && punchInRecord.getCountTrack().compareTo(punchIn.getCountTrack()) < 1) {
+            Integer recordCountTrack = Optional.ofNullable(punchInRecord.getCountTrack()).orElse(0);
+            if (PunchInRuleEnum.GREATER.equals(punchIn.getRule()) && recordCountTrack.compareTo(punchIn.getCountTrack()) < 1) {
                 return PunchInStatusEnum.UN_FINISH;
             }
-            if (PunchInRuleEnum.GREATER_OR_EQUAL.equals(punchIn.getRule()) && punchInRecord.getCountTrack().compareTo(punchIn.getCountTrack()) == -1) {
+            if (PunchInRuleEnum.GREATER_OR_EQUAL.equals(punchIn.getRule()) && recordCountTrack.compareTo(punchIn.getCountTrack()) == -1) {
                 return PunchInStatusEnum.UN_FINISH;
             }
-            if (PunchInRuleEnum.LESS.equals(punchIn.getRule()) && punchInRecord.getCountTrack().compareTo(punchIn.getCountTrack()) > -1) {
+            if (PunchInRuleEnum.LESS.equals(punchIn.getRule()) && recordCountTrack.compareTo(punchIn.getCountTrack()) > -1) {
                 return PunchInStatusEnum.UN_FINISH;
             }
-            if (PunchInRuleEnum.LESS_OR_EQUAL.equals(punchIn.getRule()) && punchInRecord.getCountTrack().compareTo(punchIn.getCountTrack()) == 1) {
+            if (PunchInRuleEnum.LESS_OR_EQUAL.equals(punchIn.getRule()) && recordCountTrack.compareTo(punchIn.getCountTrack()) == 1) {
                 return PunchInStatusEnum.UN_FINISH;
             }
 
@@ -337,16 +352,17 @@ public class SettleManagerImpl implements ISettleManager {
 
         // 计时打卡
         if (PunchInCategoryEnum.TIME.equals(punchIn.getCategory())) {
-            if (PunchInRuleEnum.GREATER.equals(punchIn.getRule()) && punchInRecord.getTimeTrack().compareTo(punchIn.getTimeTrack()) < 1) {
+            LocalTime recordTimeTrack = Optional.ofNullable(punchInRecord.getTimeTrack()).orElse(LocalTime.parse("00:00:00.000"));
+            if (PunchInRuleEnum.GREATER.equals(punchIn.getRule()) && recordTimeTrack.compareTo(punchIn.getTimeTrack()) < 1) {
                 return PunchInStatusEnum.UN_FINISH;
             }
-            if (PunchInRuleEnum.GREATER_OR_EQUAL.equals(punchIn.getRule()) && punchInRecord.getTimeTrack().compareTo(punchIn.getTimeTrack()) == -1) {
+            if (PunchInRuleEnum.GREATER_OR_EQUAL.equals(punchIn.getRule()) && recordTimeTrack.compareTo(punchIn.getTimeTrack()) == -1) {
                 return PunchInStatusEnum.UN_FINISH;
             }
-            if (PunchInRuleEnum.LESS.equals(punchIn.getRule()) && punchInRecord.getTimeTrack().compareTo(punchIn.getTimeTrack()) > -1) {
+            if (PunchInRuleEnum.LESS.equals(punchIn.getRule()) && recordTimeTrack.compareTo(punchIn.getTimeTrack()) > -1) {
                 return PunchInStatusEnum.UN_FINISH;
             }
-            if (PunchInRuleEnum.LESS_OR_EQUAL.equals(punchIn.getRule()) && punchInRecord.getTimeTrack().compareTo(punchIn.getTimeTrack()) == 1) {
+            if (PunchInRuleEnum.LESS_OR_EQUAL.equals(punchIn.getRule()) && recordTimeTrack.compareTo(punchIn.getTimeTrack()) == 1) {
                 return PunchInStatusEnum.UN_FINISH;
             }
 
@@ -410,9 +426,57 @@ public class SettleManagerImpl implements ISettleManager {
         return weeklyFinishRecord.size() >= 5;
     }
 
+    /**
+     * 构建待更新结算数据的打卡记录
+     * @return
+     */
+    private PunchInRecord buildPunchInRecordForSettle(PunchIn punchIn) {
+        PunchInRecord updatePunchInRecord = new PunchInRecord();
+        updatePunchInRecord.setSettleRewardNum(punchIn.getRewardNum());
+        updatePunchInRecord.setSettleCategory(punchIn.getCategory());
+        updatePunchInRecord.setSettleRule(punchIn.getRule());
+        updatePunchInRecord.setSettleCountTrack(punchIn.getCountTrack());
+        updatePunchInRecord.setSettleTimeTrack(punchIn.getTimeTrack());
+        return updatePunchInRecord;
+    }
+
+    /**
+     * 构造打卡记录与结算记录的关联关系
+     * @param settleResultDtos
+     * @return
+     */
+    private static List<PunchInRecordSettlementRela> buildPunchInRecordSettlementRelaList(List<SettleResultDto> settleResultDtos) {
+        if (CollectionUtils.isEmpty(settleResultDtos)) {
+            return List.of();
+        }
+
+        List<PunchInRecordSettlementRela> relaList = new ArrayList();
+        // 补充关联关系ID(结算记录ID、打卡记录ID)
+        for (SettleResultDto settleResultDto : settleResultDtos) {
+            for (PunchInRecord punchInRecord : settleResultDto.getAddPunchInRecords()) {
+                PunchInRecordSettlementRela rela = new PunchInRecordSettlementRela();
+                rela.setRecordId(punchInRecord.getId());
+                rela.setSettlementId(settleResultDto.getAddPunchInSettlement().getId());
+                relaList.add(rela);
+            }
+
+            for (PunchInRecord punchInRecord : settleResultDto.getUpdatePunchInRecords()) {
+                PunchInRecordSettlementRela rela = new PunchInRecordSettlementRela();
+                rela.setRecordId(punchInRecord.getId());
+                rela.setSettlementId(settleResultDto.getAddPunchInSettlement().getId());
+                relaList.add(rela);
+            }
+        }
+        return relaList;
+    }
+
     @Override
     public void manualSettle(SettleRequest settleRequest) {
+        // TODO 这里考虑加判断条件防止重复手动结算
         Assert.isNullInBusiness(settleRequest, "结算请求不能为空");
+        if (!PunchInSettleTypeEnum.OPS.equals(settleRequest.getSettleType())) {
+            BusinessException.throwFail("非运维结算,禁止执行");
+        }
         SpringUtils.getBean(ISettleManager.class).settleHandler(settleRequest.getSettleType(), LocalDate.parse(settleRequest.getSettleDate()), settleRequest.getUserIds(), settleRequest.getPunchInIds());
     }
 
@@ -425,10 +489,13 @@ public class SettleManagerImpl implements ISettleManager {
         query.setStartDate(String.format("%s 00:00:00.000", query.getStartDate()));
         query.setEndDate(String.format("%s 23:59:59.999", query.getEndDate()));
 
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
         List<PunchInSettlement> punchInSettlements = punchInSettlementService.listByCondition(query);
         return punchInSettlements.stream().map(settlement -> {
             SettleDto dto = new SettleDto();
             BeanUtils.copyProperties(settlement, dto);
+            dto.setSettlementTime(sdf.format(settlement.getSettlementTime()));
             return dto;
         }).toList();
     }

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

@@ -50,7 +50,7 @@ public class DateUtils {
      */
     public static LocalDate getLastWeekMonday(LocalDate date) {
         // 获取上周的周一日期
-        return date.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)).minusWeeks(1);
+        return date.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
     }
 
     /**

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

@@ -1,7 +1,7 @@
 spring:
   datasource:
     username: root
-    url: jdbc:mysql://localhost:3306/punch_settle?useSSL=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
+    url: jdbc:mysql://localhost:3306/punch_settle?useSSL=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&allowMultiQueries=true
 
 logging:
   level: