فهرست منبع

【feat】【第一版开发】
1.完善技术文档
2.第一版功能开发完成

ChenYL 1 سال پیش
والد
کامیت
5fe58b8fe5
72فایلهای تغییر یافته به همراه1269 افزوده شده و 318 حذف شده
  1. 5 6
      doc/sql/punch_settle-ddl.sql
  2. 42 44
      doc/技术文档.md
  3. 4 3
      src/main/java/com/punchsettle/server/atomic/entity/PunchIn.java
  4. 7 13
      src/main/java/com/punchsettle/server/atomic/entity/PunchInRecord.java
  5. 4 3
      src/main/java/com/punchsettle/server/atomic/entity/PunchInRecordSettlementRela.java
  6. 7 6
      src/main/java/com/punchsettle/server/atomic/entity/PunchInSettlement.java
  7. 5 4
      src/main/java/com/punchsettle/server/atomic/entity/SettlementNotifyTask.java
  8. 18 17
      src/main/java/com/punchsettle/server/atomic/entity/SettlementTask.java
  9. 4 3
      src/main/java/com/punchsettle/server/atomic/entity/User.java
  10. 6 5
      src/main/java/com/punchsettle/server/atomic/entity/UserClaimRewardRecord.java
  11. 13 19
      src/main/java/com/punchsettle/server/atomic/entity/UserReward.java
  12. 1 0
      src/main/java/com/punchsettle/server/atomic/mapper/PunchInMapper.java
  13. 1 0
      src/main/java/com/punchsettle/server/atomic/mapper/PunchInRecordMapper.java
  14. 3 2
      src/main/java/com/punchsettle/server/atomic/mapper/PunchInRecordSettlementRelaMapper.java
  15. 3 1
      src/main/java/com/punchsettle/server/atomic/mapper/PunchInSettlementMapper.java
  16. 1 0
      src/main/java/com/punchsettle/server/atomic/mapper/SettlementNotifyTaskMapper.java
  17. 1 0
      src/main/java/com/punchsettle/server/atomic/mapper/SettlementTaskMapper.java
  18. 1 0
      src/main/java/com/punchsettle/server/atomic/mapper/UserClaimRewardRecordMapper.java
  19. 1 0
      src/main/java/com/punchsettle/server/atomic/mapper/UserMapper.java
  20. 3 1
      src/main/java/com/punchsettle/server/atomic/mapper/UserRewardMapper.java
  21. 2 2
      src/main/java/com/punchsettle/server/atomic/service/IPunchInRecordService.java
  22. 20 0
      src/main/java/com/punchsettle/server/atomic/service/IPunchInRecordSettlementRelaService.java
  23. 9 2
      src/main/java/com/punchsettle/server/atomic/service/IPunchInService.java
  24. 20 0
      src/main/java/com/punchsettle/server/atomic/service/IPunchInSettlementService.java
  25. 24 0
      src/main/java/com/punchsettle/server/atomic/service/ISettlementTaskService.java
  26. 15 0
      src/main/java/com/punchsettle/server/atomic/service/IUserRewardService.java
  27. 8 0
      src/main/java/com/punchsettle/server/atomic/service/IUserService.java
  28. 11 11
      src/main/java/com/punchsettle/server/atomic/service/impl/PunchInRecordServiceImpl.java
  29. 33 0
      src/main/java/com/punchsettle/server/atomic/service/impl/PunchInRecordSettlementRelaServiceImpl.java
  30. 27 11
      src/main/java/com/punchsettle/server/atomic/service/impl/PunchInServiceImpl.java
  31. 30 0
      src/main/java/com/punchsettle/server/atomic/service/impl/PunchInSettlementServiceImpl.java
  32. 34 0
      src/main/java/com/punchsettle/server/atomic/service/impl/SettlementTaskServiceImpl.java
  33. 5 8
      src/main/java/com/punchsettle/server/atomic/service/impl/UserClaimRewardRecordServiceImpl.java
  34. 37 7
      src/main/java/com/punchsettle/server/atomic/service/impl/UserRewardServiceImpl.java
  35. 12 4
      src/main/java/com/punchsettle/server/atomic/service/impl/UserServiceImpl.java
  36. 2 2
      src/main/java/com/punchsettle/server/common/converter/enums/IntegerToEnumConverter.java
  37. 3 3
      src/main/java/com/punchsettle/server/common/converter/enums/IntegerToEnumConverterFactory.java
  38. 5 4
      src/main/java/com/punchsettle/server/common/dto/JsonResponse.java
  39. 4 4
      src/main/java/com/punchsettle/server/common/entity/BaseEntity.java
  40. 72 0
      src/main/java/com/punchsettle/server/common/utils/Assert.java
  41. 10 0
      src/main/java/com/punchsettle/server/common/valid/Delete.java
  42. 10 0
      src/main/java/com/punchsettle/server/common/valid/DoSomething.java
  43. 10 0
      src/main/java/com/punchsettle/server/common/valid/Query.java
  44. 10 0
      src/main/java/com/punchsettle/server/common/valid/Save.java
  45. 10 0
      src/main/java/com/punchsettle/server/common/valid/Update.java
  46. 32 0
      src/main/java/com/punchsettle/server/constant/PunchInStatusEnum.java
  47. 39 5
      src/main/java/com/punchsettle/server/core/aop/GlobalExceptionHandler.java
  48. 5 4
      src/main/java/com/punchsettle/server/core/aop/ResponseControllerAdvice.java
  49. 4 3
      src/main/java/com/punchsettle/server/core/aop/WebOperateLogAspect.java
  50. 2 1
      src/main/java/com/punchsettle/server/core/config/BizConfig.java
  51. 6 5
      src/main/java/com/punchsettle/server/core/config/FeignConfig.java
  52. 3 1
      src/main/java/com/punchsettle/server/core/config/MyBatisConfig.java
  53. 5 3
      src/main/java/com/punchsettle/server/core/config/WebMvcConfig.java
  54. 2 5
      src/main/java/com/punchsettle/server/core/interceptor/AuthInterceptor.java
  55. 9 7
      src/main/java/com/punchsettle/server/core/interceptor/MybatisAuditDataInterceptor.java
  56. 19 5
      src/main/java/com/punchsettle/server/dto/PunchInDto.java
  57. 4 4
      src/main/java/com/punchsettle/server/dto/PunchInRecordQuery.java
  58. 1 0
      src/main/java/com/punchsettle/server/dto/wechat/Code2SessionResponse.java
  59. 3 2
      src/main/java/com/punchsettle/server/feign/WechatMiniProgramFeign.java
  60. 10 9
      src/main/java/com/punchsettle/server/service/controller/LoginController.java
  61. 55 8
      src/main/java/com/punchsettle/server/service/controller/PunchInController.java
  62. 44 0
      src/main/java/com/punchsettle/server/service/controller/RewardController.java
  63. 30 0
      src/main/java/com/punchsettle/server/service/controller/TaskController.java
  64. 3 3
      src/main/java/com/punchsettle/server/service/manager/ILoginManager.java
  65. 2 2
      src/main/java/com/punchsettle/server/service/manager/IPunchInManager.java
  66. 15 0
      src/main/java/com/punchsettle/server/service/manager/ITaskManager.java
  67. 13 13
      src/main/java/com/punchsettle/server/service/manager/impl/LoginManagerImpl.java
  68. 75 46
      src/main/java/com/punchsettle/server/service/manager/impl/PunchInManagerImpl.java
  69. 58 1
      src/main/java/com/punchsettle/server/service/manager/impl/RewardManagerImpl.java
  70. 224 0
      src/main/java/com/punchsettle/server/service/manager/impl/TaskManagerImpl.java
  71. 50 3
      src/main/java/com/punchsettle/server/utiis/DateUtils.java
  72. 3 3
      src/main/java/com/punchsettle/server/utiis/TokenUtils.java

+ 5 - 6
doc/sql/punch_settle-ddl.sql

@@ -23,8 +23,7 @@ CREATE TABLE `punch_in` (
 CREATE TABLE `punch_in_record` (
   `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
   `punch_in_id` bigint NOT NULL COMMENT '打卡任务表主键',
-  `punch_in_time` timestamp NOT NULL COMMENT '打卡时间',
-  `punch_in_status` tinyint NOT NULL DEFAULT '1' COMMENT '打卡状态(1-待打卡,2-完成、3-未完成)',
+  `punch_in_date` varchar(10) NOT NULL COMMENT '打卡日期',
   `created_by` bigint NOT NULL COMMENT '创建人',
   `creation_time` timestamp NOT NULL COMMENT '创建时间',
   `last_updated_by` bigint NOT NULL COMMENT '最后更新人',
@@ -98,12 +97,12 @@ CREATE TABLE `settlement_notify_task` (
 
 CREATE TABLE `settlement_task` (
   `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
+  `settle_date` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '结算日期',
   `start_time` timestamp NULL DEFAULT NULL COMMENT '任务开始时间',
   `end_time` timestamp NULL DEFAULT NULL COMMENT '任务结束时间',
-  `task_status` varchar(20) NOT NULL DEFAULT 'processing' COMMENT '任务状态(success-成功,fail-失败,processing-处理中)',
-  `processed_num` int NOT NULL DEFAULT '0' COMMENT '处理数量',
-  `processed_success_num` int NOT NULL DEFAULT '0' COMMENT '处理成功数量',
-  `processed_fail_num` int NOT NULL DEFAULT '0' COMMENT '处理失败数量',
+  `processed_num` int NOT NULL DEFAULT '0' COMMENT '待处理结算数量',
+  `processed_settle_num` int NOT NULL DEFAULT '0' COMMENT '处理已结算数量',
+  `processed_unsettle_num` int NOT NULL DEFAULT '0' COMMENT '处理没结算数量',
   `error_message` text COMMENT '失败异常信息',
   `created_by` bigint NOT NULL COMMENT '创建人',
   `creation_time` timestamp NOT NULL COMMENT '创建时间',

+ 42 - 44
doc/技术文档.md

@@ -99,18 +99,17 @@ ui设计工具:即时设计
 
 表名:punch_in_record
 
-| 字段             | 类型      | 描述                                   |
-| ---------------- | --------- | -------------------------------------- |
-| id               | bigint    | 主键                                   |
-| punch_in_id      | bigint    | 打卡任务表主键                         |
-| punch_in_time    | timestamp | 打卡时间                               |
-| punch_in_status  | tinyint   | 打卡状态(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      | 主键                               |
+| punch_in_id      | bigint      | 打卡任务表主键                     |
+| punch_in_date    | varchar(10) | 打卡日期                           |
+| created_by       | bigint      | 创建人                             |
+| creation_time    | timestamp   | 创建时间                           |
+| last_updated_by  | bigint      | 最后更信人                         |
+| last_update_time | timestamp   | 最后更新时间                       |
+| version          | bigint      | 版本号                             |
+| delete_flag      | tinyint     | 逻辑删除标志(0-未删除,1-已删除) |
 
 
 
@@ -202,22 +201,22 @@ ui设计工具:即时设计
 
 表名:settlement_task
 
-| 字段                  | 类型        | 描述                                                 |
-| --------------------- | ----------- | ---------------------------------------------------- |
-| id                    | bigint      | 主键                                                 |
-| start_time            | timestamp   | 任务开始时间                                         |
-| end_time              | timestamp   | 任务结束时间                                         |
-| task_status           | varchar(20) | 任务状态(success-成功,fail-失败,processing-处理中) |
-| processed_num         | int         | 处理数量                                             |
-| processed_success_num | int         | 处理成功数量                                         |
-| processed_fail_num    | int         | 处理失败数量                                         |
-| error_message         | text        | 失败异常信息                                         |
-| created_by            | bigint      | 创建人                                               |
-| creation_time         | timestamp   | 创建时间                                             |
-| last_updated_by       | bigint      | 最后更信人                                           |
-| last_update_time      | timestamp   | 最后更新时间                                         |
-| version               | bigint      | 版本号                                               |
-| delete_flag           | tinyint     | 逻辑删除标志(0-未删除,1-已删除)                   |
+| 字段                   | 类型        | 描述                               |
+| ---------------------- | ----------- | ---------------------------------- |
+| id                     | bigint      | 主键                               |
+| settle_date            | varchar(10) | 结算日期                           |
+| start_time             | timestamp   | 任务开始时间                       |
+| end_time               | timestamp   | 任务结束时间                       |
+| processed_num          | int         | 处理结算数量                     |
+| processed_settle_num   | int         | 处理已结算数量                     |
+| processed_unsettle_num | int         | 处理没结算数量                     |
+| error_message          | text        | 失败异常信息                       |
+| created_by             | bigint      | 创建人                             |
+| creation_time          | timestamp   | 创建时间                           |
+| last_updated_by        | bigint      | 最后更信人                         |
+| last_update_time       | timestamp   | 最后更新时间                       |
+| version                | bigint      | 版本号                             |
+| delete_flag            | tinyint     | 逻辑删除标志(0-未删除,1-已删除) |
 
 
 
@@ -225,22 +224,21 @@ ui设计工具:即时设计
 
 表名:settlement_notify_task
 
-| 字段               | 类型        | 描述                                                 |
-| ------------------ | ----------- | ---------------------------------------------------- |
-| id                 | bigint      | 主键                                                 |
-| start_time         | timestamp   | 任务开始时间                                         |
-| end_time           | timestamp   | 任务结束时间                                         |
-| task_status        | varchar(20) | 任务状态(success-成功,fail-失败,processing-处理中) |
-| notify_num         | int         | 通知数量                                             |
-| notify_success_num | int         | 通知成功数量                                         |
-| notify_fail_num    | int         | 通知失败数量                                         |
-| error_message      | text        | 失败异常信息                                         |
-| created_by         | bigint      | 创建人                                               |
-| creation_time      | timestamp   | 创建时间                                             |
-| last_updated_by    | bigint      | 最后更信人                                           |
-| last_update_time   | timestamp   | 最后更新时间                                         |
-| version            | bigint      | 版本号                                               |
-| delete_flag        | tinyint     | 逻辑删除标志(0-未删除,1-已删除)                   |
+| 字段               | 类型      | 描述                               |
+| ------------------ | --------- | ---------------------------------- |
+| id                 | bigint    | 主键                               |
+| start_time         | timestamp | 任务开始时间                       |
+| end_time           | timestamp | 任务结束时间                       |
+| notify_num         | int       | 通知数量                           |
+| notify_success_num | int       | 通知成功数量                       |
+| notify_fail_num    | int       | 通知失败数量                       |
+| error_message      | text      | 失败异常信息                       |
+| created_by         | bigint    | 创建人                             |
+| creation_time      | timestamp | 创建时间                           |
+| last_updated_by    | bigint    | 最后更信人                         |
+| last_update_time   | timestamp | 最后更新时间                       |
+| version            | bigint    | 版本号                             |
+| delete_flag        | tinyint   | 逻辑删除标志(0-未删除,1-已删除) |
 
 
 

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

@@ -1,14 +1,15 @@
 package com.punchsettle.server.atomic.entity;
 
+import java.io.Serial;
+import java.io.Serializable;
+
 import com.punchsettle.server.common.entity.BaseEntity;
+
 import jakarta.persistence.Column;
 import jakarta.persistence.Table;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 
-import java.io.Serial;
-import java.io.Serializable;
-
 /**
  * @description 打卡任务表 实体
  * @version 1.0.0

+ 7 - 13
src/main/java/com/punchsettle/server/atomic/entity/PunchInRecord.java

@@ -1,15 +1,15 @@
 package com.punchsettle.server.atomic.entity;
 
+import java.io.Serial;
+import java.io.Serializable;
+
 import com.punchsettle.server.common.entity.BaseEntity;
+
 import jakarta.persistence.Column;
 import jakarta.persistence.Table;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 
-import java.io.Serial;
-import java.io.Serializable;
-import java.sql.Timestamp;
-
 /**
  * @description 打卡任务记录表 实体
  * @version 1.0.0
@@ -31,14 +31,8 @@ public class PunchInRecord extends BaseEntity implements Serializable {
     private Long punchInId;
 
     /**
-     * 打卡任务表主键
-     */
-    @Column(name = "punch_in_id")
-    private Timestamp punchInTime;
-
-    /**
-     * 打卡状态(1-待打卡,2-完成、3-未完成)
+     * 打卡日期
      */
-    @Column(name = "punch_in_status")
-    private Integer punchInStatus;
+    @Column(name = "punch_in_date")
+    private String punchInDate;
 }

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

@@ -1,14 +1,15 @@
 package com.punchsettle.server.atomic.entity;
 
+import java.io.Serial;
+import java.io.Serializable;
+
 import com.punchsettle.server.common.entity.BaseEntity;
+
 import jakarta.persistence.Column;
 import jakarta.persistence.Table;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 
-import java.io.Serial;
-import java.io.Serializable;
-
 /**
  * @description 打卡任务记录与结算关联表 实体
  * @version 1.0.0

+ 7 - 6
src/main/java/com/punchsettle/server/atomic/entity/PunchInSettlement.java

@@ -1,15 +1,16 @@
 package com.punchsettle.server.atomic.entity;
 
+import java.io.Serial;
+import java.io.Serializable;
+import java.sql.Timestamp;
+
 import com.punchsettle.server.common.entity.BaseEntity;
+
 import jakarta.persistence.Column;
 import jakarta.persistence.Table;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 
-import java.io.Serial;
-import java.io.Serializable;
-import java.sql.Timestamp;
-
 /**
  * @description 打卡任务结算表 实体
  * @version 1.0.0
@@ -52,13 +53,13 @@ public class PunchInSettlement extends BaseEntity implements Serializable {
      * 结算任务表id
      */
     @Column(name = "settlement_task_id")
-    private Timestamp settlementTaskId;
+    private Long settlementTaskId;
 
     /**
      * 结算时间
      */
     @Column(name = "settlement_time")
-    private Timestamp settlement_time;
+    private Timestamp settlementTime;
 
     /**
      * 通知表ID

+ 5 - 4
src/main/java/com/punchsettle/server/atomic/entity/SettlementNotifyTask.java

@@ -1,15 +1,16 @@
 package com.punchsettle.server.atomic.entity;
 
+import java.io.Serial;
+import java.io.Serializable;
+import java.sql.Timestamp;
+
 import com.punchsettle.server.common.entity.BaseEntity;
+
 import jakarta.persistence.Column;
 import jakarta.persistence.Table;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 
-import java.io.Serial;
-import java.io.Serializable;
-import java.sql.Timestamp;
-
 /**
  * 通知定时任务执行记录表
  * @author tyuio

+ 18 - 17
src/main/java/com/punchsettle/server/atomic/entity/SettlementTask.java

@@ -1,15 +1,16 @@
 package com.punchsettle.server.atomic.entity;
 
+import java.io.Serial;
+import java.io.Serializable;
+import java.sql.Timestamp;
+
 import com.punchsettle.server.common.entity.BaseEntity;
+
 import jakarta.persistence.Column;
 import jakarta.persistence.Table;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 
-import java.io.Serial;
-import java.io.Serializable;
-import java.sql.Timestamp;
-
 /**
  * @description 奖励结算定时任务执行记录表 实体
  * @version 1.0.0
@@ -24,6 +25,12 @@ public class SettlementTask extends BaseEntity implements Serializable {
     @Serial
     private static final long serialVersionUID = 4359906154365259984L;
 
+    /**
+     * 结算日期
+     */
+    @Column(name = "settle_date")
+    private String settleDate;
+
     /**
      * 任务开始时间
      */
@@ -37,26 +44,20 @@ public class SettlementTask extends BaseEntity implements Serializable {
     private Timestamp endTime;
 
     /**
-     * 任务状态(success-成功,fail-失败,processing-处理中)
-     */
-    @Column(name = "task_status")
-    private String taskStatus;
-
-    /**
-     * 处理数量
+     * 待处理结算数量
      */
     @Column(name = "processed_num")
     private Integer processedNum;
 
     /**
-     * 处理成功数量
+     * 处理已结算数量
      */
-    @Column(name = "processed_success_num")
-    private Integer processedSuccessNum;
+    @Column(name = "processed_settle_num")
+    private Integer processedSettleNum;
 
     /**
-     * 处理失败数量
+     * 处理没结算数量
      */
-    @Column(name = "processed_fail_num")
-    private Integer processedFailNum;
+    @Column(name = "processed_unsettle_num")
+    private Integer processedUnsettleNum;
 }

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

@@ -1,14 +1,15 @@
 package com.punchsettle.server.atomic.entity;
 
+import java.io.Serial;
+import java.io.Serializable;
+
 import com.punchsettle.server.common.entity.BaseEntity;
+
 import jakarta.persistence.Column;
 import jakarta.persistence.Table;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 
-import java.io.Serial;
-import java.io.Serializable;
-
 /**
  * @description 用户表 实体
  * @version 1.0.0

+ 6 - 5
src/main/java/com/punchsettle/server/atomic/entity/UserClaimRewardRecord.java

@@ -1,15 +1,16 @@
 package com.punchsettle.server.atomic.entity;
 
+import java.io.Serial;
+import java.io.Serializable;
+import java.sql.Timestamp;
+
 import com.punchsettle.server.common.entity.BaseEntity;
+
 import jakarta.persistence.Column;
 import jakarta.persistence.Table;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 
-import java.io.Serial;
-import java.io.Serializable;
-import java.sql.Timestamp;
-
 /**
  * @author tyuio
  * @version 1.0.0
@@ -46,7 +47,7 @@ public class UserClaimRewardRecord extends BaseEntity implements Serializable {
      * 领取前用户拥有的奖励数
      */
     @Column(name = "before_claim_reward_num")
-    private Integer beforeClaimRewardTime;
+    private Integer beforeClaimRewardNum;
 
     /**
      * 领取后用户拥有的奖励数

+ 13 - 19
src/main/java/com/punchsettle/server/atomic/entity/UserReward.java

@@ -1,15 +1,15 @@
 package com.punchsettle.server.atomic.entity;
 
+import java.io.Serial;
+import java.io.Serializable;
+
 import com.punchsettle.server.common.entity.BaseEntity;
+
 import jakarta.persistence.Column;
 import jakarta.persistence.Table;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 
-import java.io.Serial;
-import java.io.Serializable;
-import java.sql.Timestamp;
-
 /**
  * @author tyuio
  * @version 1.0.0
@@ -31,26 +31,20 @@ public class UserReward extends BaseEntity implements Serializable {
     private Long userId;
 
     /**
-     * 本次领取奖励数
-     */
-    @Column(name = "claim_reward_num")
-    private Integer claimRewardNum;
-
-    /**
-     * 领取奖励时间
+     * 总奖励数
      */
-    @Column(name = "claim_reward_time")
-    private Timestamp claimRewardTime;
+    @Column(name = "total_reward_num")
+    private Integer totalRewardNum;
 
     /**
-     * 领取前用户拥有的奖励数
+     * 未领取奖励数
      */
-    @Column(name = "before_claim_reward_num")
-    private Integer beforeClaimRewardNum;
+    @Column(name = "unclaimed_reward_num")
+    private Integer unclaimedRewardNum;
 
     /**
-     * 领取后用户拥有的奖励数
+     * 领取奖励数
      */
-    @Column(name = "after_claim_reward_num")
-    private Integer afterClaimRewardNum;
+    @Column(name = "claimed_reward_num")
+    private Integer claimedRewardNum;
 }

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

@@ -1,6 +1,7 @@
 package com.punchsettle.server.atomic.mapper;
 
 import com.punchsettle.server.atomic.entity.PunchIn;
+
 import tk.mybatis.mapper.common.Mapper;
 
 /**

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

@@ -1,6 +1,7 @@
 package com.punchsettle.server.atomic.mapper;
 
 import com.punchsettle.server.atomic.entity.PunchInRecord;
+
 import tk.mybatis.mapper.common.Mapper;
 
 /**

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

@@ -1,7 +1,8 @@
 package com.punchsettle.server.atomic.mapper;
 
 import com.punchsettle.server.atomic.entity.PunchInRecordSettlementRela;
-import tk.mybatis.mapper.common.Mapper;
+
+import tk.mybatis.mapper.additional.insert.InsertListMapper;
 
 /**
  * @description 打卡任务记录与结算关联表 mapper
@@ -9,5 +10,5 @@ import tk.mybatis.mapper.common.Mapper;
  * @date 2024/11/25 10:57
  * @author tyuio
  */
-public interface PunchInRecordSettlementRelaMapper extends Mapper<PunchInRecordSettlementRela> {
+public interface PunchInRecordSettlementRelaMapper extends InsertListMapper<PunchInRecordSettlementRela> {
 }

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

@@ -1,6 +1,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;
 
 /**
@@ -9,5 +11,5 @@ import tk.mybatis.mapper.common.Mapper;
  * @date 2024/11/25 10:57
  * @author tyuio
  */
-public interface PunchInSettlementMapper extends Mapper<PunchInSettlement> {
+public interface PunchInSettlementMapper extends Mapper<PunchInSettlement>, InsertListMapper<PunchInSettlement> {
 }

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

@@ -1,6 +1,7 @@
 package com.punchsettle.server.atomic.mapper;
 
 import com.punchsettle.server.atomic.entity.SettlementNotifyTask;
+
 import tk.mybatis.mapper.common.Mapper;
 
 /**

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

@@ -1,6 +1,7 @@
 package com.punchsettle.server.atomic.mapper;
 
 import com.punchsettle.server.atomic.entity.SettlementTask;
+
 import tk.mybatis.mapper.common.Mapper;
 
 /**

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

@@ -1,6 +1,7 @@
 package com.punchsettle.server.atomic.mapper;
 
 import com.punchsettle.server.atomic.entity.UserClaimRewardRecord;
+
 import tk.mybatis.mapper.common.Mapper;
 
 /**

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

@@ -1,6 +1,7 @@
 package com.punchsettle.server.atomic.mapper;
 
 import com.punchsettle.server.atomic.entity.User;
+
 import tk.mybatis.mapper.common.Mapper;
 
 /**

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

@@ -1,6 +1,8 @@
 package com.punchsettle.server.atomic.mapper;
 
 import com.punchsettle.server.atomic.entity.UserReward;
+
+import tk.mybatis.mapper.additional.update.batch.BatchUpdateSelectiveMapper;
 import tk.mybatis.mapper.common.Mapper;
 
 /**
@@ -9,5 +11,5 @@ import tk.mybatis.mapper.common.Mapper;
  * @description 用户奖励数据表 mapper
  * @date 2024/11/25 20:49
  */
-public interface UserRewardMapper extends Mapper<UserReward> {
+public interface UserRewardMapper extends Mapper<UserReward>, BatchUpdateSelectiveMapper<UserReward> {
 }

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

@@ -1,10 +1,10 @@
 package com.punchsettle.server.atomic.service;
 
+import java.util.List;
+
 import com.punchsettle.server.atomic.entity.PunchInRecord;
 import com.punchsettle.server.dto.PunchInRecordQuery;
 
-import java.util.List;
-
 /**
  * @author tyuio
  * @version 1.0.0

+ 20 - 0
src/main/java/com/punchsettle/server/atomic/service/IPunchInRecordSettlementRelaService.java

@@ -0,0 +1,20 @@
+package com.punchsettle.server.atomic.service;
+
+import java.util.List;
+
+import com.punchsettle.server.atomic.entity.PunchInRecordSettlementRela;
+
+/**
+ * @author tyuio
+ * @version 1.0.0
+ * @description 打卡任务记录与结算关联表
+ * @date 2024/11/26 12:53
+ */
+public interface IPunchInRecordSettlementRelaService {
+
+    /**
+     * 批量新增
+     * @param punchInRecordSettlementRelas
+     */
+    void batchInsert(List<PunchInRecordSettlementRela> punchInRecordSettlementRelas);
+}

+ 9 - 2
src/main/java/com/punchsettle/server/atomic/service/IPunchInService.java

@@ -1,9 +1,9 @@
 package com.punchsettle.server.atomic.service;
 
-import com.punchsettle.server.atomic.entity.PunchIn;
-
 import java.util.List;
 
+import com.punchsettle.server.atomic.entity.PunchIn;
+
 /**
  * @author tyuio
  * @version 1.0.0
@@ -19,6 +19,13 @@ public interface IPunchInService {
      */
     List<PunchIn> listByCreatedBy(Long createdBy);
 
+    /**
+     * 根据创建人查询所有的打卡结算任务数据
+     * @param userIds 创建人id
+     * @return
+     */
+    List<PunchIn> listByCreatedBy(List<Long> userIds);
+
     /**
      * 新增或更新打卡结算任务
      * @param punchIn

+ 20 - 0
src/main/java/com/punchsettle/server/atomic/service/IPunchInSettlementService.java

@@ -0,0 +1,20 @@
+package com.punchsettle.server.atomic.service;
+
+import java.util.List;
+
+import com.punchsettle.server.atomic.entity.PunchInSettlement;
+
+/**
+ * @author tyuio
+ * @version 1.0.0
+ * @description 打卡任务结算表
+ * @date 2024/11/26 12:35
+ */
+public interface IPunchInSettlementService {
+
+    /**
+     * 批量新增
+     * @param punchInSettlements
+     */
+    void batchInsert(List<PunchInSettlement> punchInSettlements);
+}

+ 24 - 0
src/main/java/com/punchsettle/server/atomic/service/ISettlementTaskService.java

@@ -0,0 +1,24 @@
+package com.punchsettle.server.atomic.service;
+
+import com.punchsettle.server.atomic.entity.SettlementTask;
+
+/**
+ * @author tyuio
+ * @version 1.0.0
+ * @description 奖励结算定时任务执行记录表
+ * @date 2024/11/26 11:53
+ */
+public interface ISettlementTaskService {
+
+    /**
+     * 新增
+     * @param task
+     */
+    void insert(SettlementTask task);
+
+    /**
+     * 更新
+     * @param task
+     */
+    void update(SettlementTask task);
+}

+ 15 - 0
src/main/java/com/punchsettle/server/atomic/service/IUserRewardService.java

@@ -1,5 +1,7 @@
 package com.punchsettle.server.atomic.service;
 
+import java.util.List;
+
 import com.punchsettle.server.atomic.entity.UserReward;
 
 /**
@@ -22,4 +24,17 @@ public interface IUserRewardService {
      * @param userReward
      */
     void updateReward(UserReward userReward);
+
+    /**
+     * 根据用户id列表查询用户奖励列表
+     * @param userIds
+     * @return
+     */
+    List<UserReward> listByUserIds(List<Long> userIds);
+
+    /**
+     * 批量更新用户奖励数
+     * @param userRewards
+     */
+    void batchUpdateUserReward(List<UserReward> userRewards);
 }

+ 8 - 0
src/main/java/com/punchsettle/server/atomic/service/IUserService.java

@@ -1,5 +1,7 @@
 package com.punchsettle.server.atomic.service;
 
+import java.util.List;
+
 import com.punchsettle.server.atomic.entity.User;
 
 /**
@@ -23,4 +25,10 @@ public interface IUserService {
      * @return
      */
     User getAndAdd(String openId);
+
+    /**
+     * 查询所有用户
+     * @return
+     */
+    List<User> list();
 }

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

@@ -1,19 +1,22 @@
 package com.punchsettle.server.atomic.service.impl;
 
+import java.util.List;
+import java.util.Objects;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
 import com.punchsettle.server.atomic.entity.PunchInRecord;
 import com.punchsettle.server.atomic.mapper.PunchInRecordMapper;
 import com.punchsettle.server.atomic.service.IPunchInRecordService;
+import com.punchsettle.server.common.utils.Assert;
 import com.punchsettle.server.dto.PunchInRecordQuery;
+
 import io.micrometer.common.util.StringUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-import org.springframework.util.CollectionUtils;
 import tk.mybatis.mapper.weekend.Weekend;
 import tk.mybatis.mapper.weekend.WeekendCriteria;
 
-import java.util.List;
-import java.util.Objects;
-
 /**
  * @author tyuio
  * @version 1.0.0
@@ -28,10 +31,7 @@ public class PunchInRecordServiceImpl implements IPunchInRecordService {
 
     @Override
     public void insert(PunchInRecord record) {
-        if (Objects.isNull(record)) {
-            return;
-        }
-
+        Assert.isNull(record);
         punchInRecordMapper.insertSelective(record);
     }
 
@@ -44,7 +44,7 @@ public class PunchInRecordServiceImpl implements IPunchInRecordService {
         Weekend<PunchInRecord> weekend = Weekend.of(PunchInRecord.class);
         WeekendCriteria<PunchInRecord, Object> criteria = weekend.weekendCriteria();
         if (StringUtils.isNotBlank(query.getStartDate()) && StringUtils.isNotBlank(query.getEndDate())) {
-            criteria.andBetween(PunchInRecord::getPunchInTime, query.getStartDate(), query.getEndDate());
+            criteria.andBetween(PunchInRecord::getPunchInDate, query.getStartDate(), query.getEndDate());
         }
         if (!CollectionUtils.isEmpty(query.getPunchInIds())) {
             criteria.andIn(PunchInRecord::getPunchInId, query.getPunchInIds());

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

@@ -0,0 +1,33 @@
+package com.punchsettle.server.atomic.service.impl;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import com.punchsettle.server.atomic.entity.PunchInRecordSettlementRela;
+import com.punchsettle.server.atomic.mapper.PunchInRecordSettlementRelaMapper;
+import com.punchsettle.server.atomic.service.IPunchInRecordSettlementRelaService;
+
+/**
+ * @author tyuio
+ * @version 1.0.0
+ * @description 打卡任务记录与结算关联表
+ * @date 2024/11/26 12:54
+ */
+@Service
+public class PunchInRecordSettlementRelaServiceImpl implements IPunchInRecordSettlementRelaService {
+
+    @Autowired
+    private PunchInRecordSettlementRelaMapper punchInRecordSettlementRelaMapper;
+
+    @Override
+    public void batchInsert(List<PunchInRecordSettlementRela> punchInRecordSettlementRelas) {
+        if (CollectionUtils.isEmpty(punchInRecordSettlementRelas)) {
+            return;
+        }
+
+        punchInRecordSettlementRelaMapper.insertList(punchInRecordSettlementRelas);
+    }
+}

+ 27 - 11
src/main/java/com/punchsettle/server/atomic/service/impl/PunchInServiceImpl.java

@@ -1,13 +1,19 @@
 package com.punchsettle.server.atomic.service.impl;
 
+import java.util.List;
+import java.util.Objects;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
 import com.punchsettle.server.atomic.entity.PunchIn;
 import com.punchsettle.server.atomic.mapper.PunchInMapper;
 import com.punchsettle.server.atomic.service.IPunchInService;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
+import com.punchsettle.server.common.utils.Assert;
 
-import java.util.List;
-import java.util.Objects;
+import tk.mybatis.mapper.weekend.Weekend;
+import tk.mybatis.mapper.weekend.WeekendCriteria;
 
 /**
  * @author tyuio
@@ -33,20 +39,30 @@ public class PunchInServiceImpl implements IPunchInService {
     }
 
     @Override
-    public void insertOrUpdate(PunchIn punchIn) {
-        if (Objects.isNull(punchIn)) {
-            return;
+    public List<PunchIn> listByCreatedBy(List<Long> userIds) {
+        if (CollectionUtils.isEmpty(userIds)) {
+            return List.of();
         }
 
-        punchInMapper.save(punchIn);
+        Weekend<PunchIn> punchInWeekend = Weekend.of(PunchIn.class);
+        WeekendCriteria<PunchIn, Object> criteria = punchInWeekend.weekendCriteria();
+        criteria.andIn(PunchIn::getCreatedBy, userIds);
+        return punchInMapper.selectByExample(punchInWeekend);
     }
 
     @Override
-    public void delete(Long punchInId) {
-        if (Objects.isNull(punchInId)) {
-            return;
+    public void insertOrUpdate(PunchIn punchIn) {
+        Assert.isNull(punchIn);
+        if (Objects.isNull(punchIn.getId())) {
+            punchInMapper.insertSelective(punchIn);
+        } else {
+            punchInMapper.updateByPrimaryKeySelective(punchIn);
         }
+    }
 
+    @Override
+    public void delete(Long punchInId) {
+        Assert.isNull(punchInId);
         punchInMapper.deleteByPrimaryKey(punchInId);
     }
 }

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

@@ -0,0 +1,30 @@
+package com.punchsettle.server.atomic.service.impl;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.punchsettle.server.atomic.entity.PunchInSettlement;
+import com.punchsettle.server.atomic.mapper.PunchInSettlementMapper;
+import com.punchsettle.server.atomic.service.IPunchInSettlementService;
+import com.punchsettle.server.common.utils.Assert;
+
+/**
+ * @author tyuio
+ * @version 1.0.0
+ * @description 打卡任务结算表
+ * @date 2024/11/26 12:39
+ */
+@Service
+public class PunchInSettlementServiceImpl implements IPunchInSettlementService {
+
+    @Autowired
+    private PunchInSettlementMapper punchInSettlementMapper;
+
+    @Override
+    public void batchInsert(List<PunchInSettlement> punchInSettlements) {
+        Assert.notEmpty(punchInSettlements);
+        punchInSettlementMapper.insertList(punchInSettlements);
+    }
+}

+ 34 - 0
src/main/java/com/punchsettle/server/atomic/service/impl/SettlementTaskServiceImpl.java

@@ -0,0 +1,34 @@
+package com.punchsettle.server.atomic.service.impl;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.punchsettle.server.atomic.entity.SettlementTask;
+import com.punchsettle.server.atomic.mapper.SettlementTaskMapper;
+import com.punchsettle.server.atomic.service.ISettlementTaskService;
+import com.punchsettle.server.common.utils.Assert;
+
+/**
+ * @author tyuio
+ * @version 1.0.0
+ * @description 奖励结算定时任务执行记录表
+ * @date 2024/11/26 11:55
+ */
+@Service
+public class SettlementTaskServiceImpl implements ISettlementTaskService {
+
+    @Autowired
+    private SettlementTaskMapper settlementTaskMapper;
+
+    @Override
+    public void insert(SettlementTask task) {
+        Assert.isNull(task);
+        settlementTaskMapper.insertSelective(task);
+    }
+
+    @Override
+    public void update(SettlementTask task) {
+        Assert.isNull(task);
+        settlementTaskMapper.updateByPrimaryKeySelective(task);
+    }
+}

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

@@ -1,12 +1,12 @@
 package com.punchsettle.server.atomic.service.impl;
 
-import com.punchsettle.server.atomic.entity.UserClaimRewardRecord;
-import com.punchsettle.server.atomic.mapper.UserClaimRewardRecordMapper;
-import com.punchsettle.server.atomic.service.IUserClaimRewardRecordService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import java.util.Objects;
+import com.punchsettle.server.atomic.entity.UserClaimRewardRecord;
+import com.punchsettle.server.atomic.mapper.UserClaimRewardRecordMapper;
+import com.punchsettle.server.atomic.service.IUserClaimRewardRecordService;
+import com.punchsettle.server.common.utils.Assert;
 
 /**
  * @author tyuio
@@ -22,10 +22,7 @@ public class UserClaimRewardRecordServiceImpl implements IUserClaimRewardRecordS
 
     @Override
     public void insert(UserClaimRewardRecord record) {
-        if (Objects.isNull(record)) {
-            return;
-        }
-
+        Assert.isNull(record);
         userClaimRewardRecordMapper.insertSelective(record);
     }
 }

+ 37 - 7
src/main/java/com/punchsettle/server/atomic/service/impl/UserRewardServiceImpl.java

@@ -1,12 +1,19 @@
 package com.punchsettle.server.atomic.service.impl;
 
+import java.util.List;
+import java.util.Objects;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
 import com.punchsettle.server.atomic.entity.UserReward;
 import com.punchsettle.server.atomic.mapper.UserRewardMapper;
 import com.punchsettle.server.atomic.service.IUserRewardService;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
+import com.punchsettle.server.common.utils.Assert;
 
-import java.util.Objects;
+import tk.mybatis.mapper.weekend.Weekend;
+import tk.mybatis.mapper.weekend.WeekendCriteria;
 
 /**
  * @author tyuio
@@ -25,15 +32,38 @@ public class UserRewardServiceImpl implements IUserRewardService {
         if (Objects.isNull(currentUserId)) {
             return null;
         }
-        return userRewardMapper.selectByPrimaryKey(currentUserId);
+
+        UserReward userReward = new UserReward();
+        userReward.setUserId(currentUserId);
+        return userRewardMapper.selectOne(userReward);
     }
 
     @Override
     public void updateReward(UserReward userReward) {
-        if(Objects.isNull(userReward)) {
-            return;
+        Assert.isNull(userReward);
+
+        if (Objects.isNull(userReward)) {
+            userRewardMapper.insertSelective(userReward);
+        } else {
+            userRewardMapper.updateByPrimaryKeySelective(userReward);
+        }
+    }
+
+    @Override
+    public List<UserReward> listByUserIds(List<Long> userIds) {
+        if(CollectionUtils.isEmpty(userIds)) {
+            return List.of();
         }
 
-        userRewardMapper.save(userReward);
+        Weekend<UserReward> weekend = Weekend.of(UserReward.class);
+        WeekendCriteria<UserReward, Object> criteria = weekend.weekendCriteria();
+        criteria.andIn(UserReward::getUserId, userIds);
+        return userRewardMapper.selectByExample(weekend);
+    }
+
+    @Override
+    public void batchUpdateUserReward(List<UserReward> userRewards) {
+        Assert.notEmpty(userRewards);
+        userRewardMapper.batchUpdateSelective(userRewards);
     }
 }

+ 12 - 4
src/main/java/com/punchsettle/server/atomic/service/impl/UserServiceImpl.java

@@ -1,13 +1,16 @@
 package com.punchsettle.server.atomic.service.impl;
 
+import java.util.List;
+import java.util.Objects;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
 import com.punchsettle.server.atomic.entity.User;
 import com.punchsettle.server.atomic.mapper.UserMapper;
 import com.punchsettle.server.atomic.service.IUserService;
-import io.micrometer.common.util.StringUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
 
-import java.util.Objects;
+import io.micrometer.common.util.StringUtils;
 
 /**
  * @author tyuio
@@ -39,4 +42,9 @@ public class UserServiceImpl implements IUserService {
         queryUser.setOpenId(openId);
         return userMapper.selectOne(queryUser);
     }
+
+    @Override
+    public List<User> list() {
+        return userMapper.selectAll();
+    }
 }

+ 2 - 2
src/main/java/com/punchsettle/server/common/converter/enums/IntegerToEnumConverter.java

@@ -1,10 +1,10 @@
 package com.punchsettle.server.common.converter.enums;
 
-import org.springframework.core.convert.converter.Converter;
-
 import java.util.HashMap;
 import java.util.Map;
 
+import org.springframework.core.convert.converter.Converter;
+
 /**
  * 转换器 数值转换为枚举
  *

+ 3 - 3
src/main/java/com/punchsettle/server/common/converter/enums/IntegerToEnumConverterFactory.java

@@ -1,11 +1,11 @@
 package com.punchsettle.server.common.converter.enums;
 
-import org.springframework.core.convert.converter.Converter;
-import org.springframework.core.convert.converter.ConverterFactory;
-
 import java.util.HashMap;
 import java.util.Map;
 
+import org.springframework.core.convert.converter.Converter;
+import org.springframework.core.convert.converter.ConverterFactory;
+
 public class IntegerToEnumConverterFactory implements ConverterFactory<Integer, IJsonEnum> {
 
     private static final Map<Class, Converter> CONVERTERS = new HashMap<>();

+ 5 - 4
src/main/java/com/punchsettle/server/common/dto/JsonResponse.java

@@ -1,14 +1,15 @@
 package com.punchsettle.server.common.dto;
 
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.punchsettle.server.common.constant.ResponseCodeEnum;
+
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 
-import java.io.Serial;
-import java.io.Serializable;
-import java.util.Date;
-
 /**
  * json 统一响应体
  *

+ 4 - 4
src/main/java/com/punchsettle/server/common/entity/BaseEntity.java

@@ -1,12 +1,12 @@
 package com.punchsettle.server.common.entity;
 
+import java.sql.Timestamp;
+
 import jakarta.persistence.Column;
 import jakarta.persistence.Id;
 import lombok.Data;
+import tk.mybatis.mapper.annotation.KeySql;
 import tk.mybatis.mapper.annotation.LogicDelete;
-import tk.mybatis.mapper.annotation.Version;
-
-import java.sql.Timestamp;
 
 /**
  * @description 实体类基类(6个通用审计字段)
@@ -21,6 +21,7 @@ public class BaseEntity {
      * 主键
      */
     @Id
+    @KeySql(useGeneratedKeys = true)
     @Column(name = "id")
     private Long id;
 
@@ -51,7 +52,6 @@ public class BaseEntity {
     /**
      * 版本号
      */
-    @Version
     @Column(name = "version")
     private Integer version;
 

+ 72 - 0
src/main/java/com/punchsettle/server/common/utils/Assert.java

@@ -0,0 +1,72 @@
+package com.punchsettle.server.common.utils;
+
+import java.util.Collection;
+import java.util.Objects;
+
+import com.punchsettle.server.common.exception.BusinessException;
+
+/**
+ * @author tyuio
+ * @version 1.0.0
+ * @description 断言工具类
+ * @date 2024/11/26 19:43
+ */
+public class Assert {
+
+    /**
+     * 判断对象是否为空
+     * @param object 待判断对象
+     * @param errorMsg 异常提示信息
+     * @throws IllegalArgumentException
+     */
+    public static void isNull(Object object, String errorMsg) throws IllegalArgumentException {
+        if (Objects.isNull(object)) {
+            throw new IllegalArgumentException(errorMsg);
+        }
+    }
+
+    /**
+     * 判断对象是否为空
+     * @param object 待判断对象
+     * @throws IllegalArgumentException
+     */
+    public static void isNull(Object object) throws IllegalArgumentException {
+        isNull(object, "传入的对象参数不能为空");
+    }
+
+    /**
+     * 判断对象是否为空
+     * @param object 待判断对象
+     * @param errorMsg 异常提示信息
+     * @throws BusinessException
+     */
+    public static void isNullInBusiness(Object object, String errorMsg) throws BusinessException {
+        if (Objects.isNull(object)) {
+            throw new BusinessException(errorMsg);
+        }
+    }
+
+    /**
+     * 判断集合是否为空
+     * @param collection 待判断对象
+     * @param errorMsg 异常提示信息
+     * @return
+     * @param <T>
+     * @throws IllegalArgumentException
+     */
+    public static <T> void notEmpty(Collection<T> collection, String errorMsg) throws IllegalArgumentException {
+        if (collection == null || collection.isEmpty()) {
+            throw new IllegalArgumentException(errorMsg);
+        }
+    }
+
+    /**
+     * 判断集合是否为空
+     * @param collection 待判断对象
+     * @param <T>
+     * @throws IllegalArgumentException
+     */
+    public static <T> void notEmpty(Collection<T> collection) throws IllegalArgumentException {
+        notEmpty(collection, "传入的集合参数不能为空");
+    }
+}

+ 10 - 0
src/main/java/com/punchsettle/server/common/valid/Delete.java

@@ -0,0 +1,10 @@
+package com.punchsettle.server.common.valid;
+
+/**
+ * @author tyuio
+ * @version 1.0.0
+ * @description 删除 校验器分组
+ * @date 2024/11/26 15:23
+ */
+public interface Delete {
+}

+ 10 - 0
src/main/java/com/punchsettle/server/common/valid/DoSomething.java

@@ -0,0 +1,10 @@
+package com.punchsettle.server.common.valid;
+
+/**
+ * @author tyuio
+ * @version 1.0.0
+ * @description 做某一操作 校验器分组
+ * @date 2024/11/26 15:47
+ */
+public interface DoSomething {
+}

+ 10 - 0
src/main/java/com/punchsettle/server/common/valid/Query.java

@@ -0,0 +1,10 @@
+package com.punchsettle.server.common.valid;
+
+/**
+ * @author tyuio
+ * @version 1.0.0
+ * @description 查询 校验器分组
+ * @date 2024/11/26 15:21
+ */
+public interface Query {
+}

+ 10 - 0
src/main/java/com/punchsettle/server/common/valid/Save.java

@@ -0,0 +1,10 @@
+package com.punchsettle.server.common.valid;
+
+/**
+ * @author tyuio
+ * @version 1.0.0
+ * @description 新增 校验器分组
+ * @date 2024/11/26 15:22
+ */
+public interface Save {
+}

+ 10 - 0
src/main/java/com/punchsettle/server/common/valid/Update.java

@@ -0,0 +1,10 @@
+package com.punchsettle.server.common.valid;
+
+/**
+ * @author tyuio
+ * @version 1.0.0
+ * @description 更新 校验器分组
+ * @date 2024/11/26 15:22
+ */
+public interface Update {
+}

+ 32 - 0
src/main/java/com/punchsettle/server/constant/PunchInStatusEnum.java

@@ -0,0 +1,32 @@
+package com.punchsettle.server.constant;
+
+import lombok.Getter;
+
+/**
+ * @author tyuio
+ * @version 1.0.0
+ * @description 打卡状态 枚举
+ * @date 2024/11/26 21:59
+ */
+@Getter
+public enum PunchInStatusEnum {
+
+    UNCREATED("未创建打卡任务", 0),
+    PUNCHIN("已打卡", 1),
+    UNPUNCHIN("没打卡", 2);
+
+    /**
+     * 名称
+     */
+    private String name;
+
+    /**
+     * 值
+     */
+    private Integer value;
+
+    PunchInStatusEnum(String name, Integer value) {
+        this.name = name;
+        this.value = value;
+    }
+}

+ 39 - 5
src/main/java/com/punchsettle/server/core/aop/GlobalExceptionHandler.java

@@ -1,14 +1,21 @@
 package com.punchsettle.server.core.aop;
 
-import com.punchsettle.server.common.dto.JsonResponse;
-import com.punchsettle.server.common.exception.BusinessException;
-import com.punchsettle.server.common.exception.LoginException;
-import lombok.extern.slf4j.Slf4j;
+import java.util.List;
+import java.util.stream.Collectors;
+
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
+import org.springframework.validation.ObjectError;
+import org.springframework.web.bind.MethodArgumentNotValidException;
 import org.springframework.web.bind.annotation.ExceptionHandler;
 import org.springframework.web.bind.annotation.RestControllerAdvice;
 
+import com.punchsettle.server.common.dto.JsonResponse;
+import com.punchsettle.server.common.exception.BusinessException;
+import com.punchsettle.server.common.exception.LoginException;
+
+import lombok.extern.slf4j.Slf4j;
+
 /**
  * 全局异常处理
  */
@@ -28,8 +35,35 @@ public class GlobalExceptionHandler {
         return JsonResponse.fail(e.getMessage());
     }
 
+    /**
+     * 登录异常处理
+     * @param e
+     * @return
+     */
     @ExceptionHandler(LoginException.class)
-    public ResponseEntity<Object> loginExceptionHandler(Exception e) {
+    public ResponseEntity<Object> loginExceptionHandler(LoginException e) {
         return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(JsonResponse.fail(e.getMessage()));
     }
+
+    /**
+     * 方法参数校验异常处理
+     * @param e
+     * @return
+     */
+    @ExceptionHandler(MethodArgumentNotValidException.class)
+    public JsonResponse methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
+        List<ObjectError> allErrors = e.getAllErrors();
+        String errorMsg = allErrors.stream().map(error -> error.getDefaultMessage())
+                .collect(Collectors.joining(";"));
+        return JsonResponse.fail(String.format("参数错误:%s", errorMsg));
+    }
+
+    /**
+     * 全局异常处理
+     */
+    @ExceptionHandler(Exception.class)
+    public JsonResponse exceptionHandler(Exception e) {
+        log.error(e.getMessage(), e);
+        return JsonResponse.fail("系统异常,请稍后再试");
+    }
 }

+ 5 - 4
src/main/java/com/punchsettle/server/core/aop/ResponseControllerAdvice.java

@@ -1,9 +1,5 @@
 package com.punchsettle.server.core.aop;
 
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.punchsettle.server.common.annotation.IgnoreResponseWrapper;
-import com.punchsettle.server.common.dto.JsonResponse;
 import org.springframework.core.MethodParameter;
 import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
@@ -13,6 +9,11 @@ import org.springframework.http.server.ServerHttpResponse;
 import org.springframework.web.bind.annotation.RestControllerAdvice;
 import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
 
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.punchsettle.server.common.annotation.IgnoreResponseWrapper;
+import com.punchsettle.server.common.dto.JsonResponse;
+
 /**
  * 接口返回统一处理
  */

+ 4 - 3
src/main/java/com/punchsettle/server/core/aop/WebOperateLogAspect.java

@@ -1,7 +1,7 @@
 package com.punchsettle.server.core.aop;
 
-import jakarta.servlet.http.HttpServletRequest;
-import lombok.extern.slf4j.Slf4j;
+import java.util.Arrays;
+
 import org.aspectj.lang.ProceedingJoinPoint;
 import org.aspectj.lang.annotation.Around;
 import org.aspectj.lang.annotation.Aspect;
@@ -11,7 +11,8 @@ import org.springframework.web.context.request.RequestContextHolder;
 import org.springframework.web.context.request.ServletRequestAttributes;
 import org.springframework.web.multipart.MultipartFile;
 
-import java.util.Arrays;
+import jakarta.servlet.http.HttpServletRequest;
+import lombok.extern.slf4j.Slf4j;
 
 @Slf4j
 @Aspect

+ 2 - 1
src/main/java/com/punchsettle/server/core/config/BizConfig.java

@@ -1,9 +1,10 @@
 package com.punchsettle.server.core.config;
 
-import lombok.Getter;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Configuration;
 
+import lombok.Getter;
+
 @Getter
 @Configuration
 public class BizConfig {

+ 6 - 5
src/main/java/com/punchsettle/server/core/config/FeignConfig.java

@@ -1,8 +1,8 @@
 package com.punchsettle.server.core.config;
 
-import feign.Logger;
-import feign.RequestInterceptor;
-import feign.codec.Decoder;
+import java.util.ArrayList;
+import java.util.List;
+
 import org.springframework.beans.factory.ObjectFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
@@ -12,8 +12,9 @@ import org.springframework.context.annotation.Configuration;
 import org.springframework.http.MediaType;
 import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
 
-import java.util.ArrayList;
-import java.util.List;
+import feign.Logger;
+import feign.RequestInterceptor;
+import feign.codec.Decoder;
 
 /**
  * @className FeignConfig

+ 3 - 1
src/main/java/com/punchsettle/server/core/config/MyBatisConfig.java

@@ -1,8 +1,10 @@
 package com.punchsettle.server.core.config;
 
-import com.punchsettle.server.core.interceptor.MybatisAuditDataInterceptor;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
+
+import com.punchsettle.server.core.interceptor.MybatisAuditDataInterceptor;
+
 import tk.mybatis.mapper.autoconfigure.ConfigurationCustomizer;
 import tk.mybatis.spring.annotation.MapperScan;
 

+ 5 - 3
src/main/java/com/punchsettle/server/core/config/WebMvcConfig.java

@@ -1,13 +1,14 @@
 package com.punchsettle.server.core.config;
 
-import com.punchsettle.server.common.converter.enums.IntegerToEnumConverterFactory;
-import com.punchsettle.server.core.interceptor.AuthInterceptor;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.format.FormatterRegistry;
 import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
 import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
 
+import com.punchsettle.server.common.converter.enums.IntegerToEnumConverterFactory;
+import com.punchsettle.server.core.interceptor.AuthInterceptor;
+
 @Configuration
 public class WebMvcConfig implements WebMvcConfigurer {
 
@@ -21,6 +22,7 @@ public class WebMvcConfig implements WebMvcConfigurer {
 
     @Override
     public void addInterceptors(InterceptorRegistry registry) {
-        registry.addInterceptor(authInterceptor).addPathPatterns("/watermark/**", "/oss/**");
+        registry.addInterceptor(authInterceptor)
+                .excludePathPatterns("/health/**", "/login/**");
     }
 }

+ 2 - 5
src/main/java/com/punchsettle/server/core/interceptor/AuthInterceptor.java

@@ -1,7 +1,6 @@
 package com.punchsettle.server.core.interceptor;
 
 import java.util.Map;
-import java.util.Objects;
 
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
@@ -11,8 +10,8 @@ import org.springframework.web.servlet.HandlerInterceptor;
 import com.auth0.jwt.interfaces.Claim;
 import com.punchsettle.server.atomic.entity.User;
 import com.punchsettle.server.atomic.service.IUserService;
-import com.punchsettle.server.common.exception.BusinessException;
 import com.punchsettle.server.common.exception.LoginException;
+import com.punchsettle.server.common.utils.Assert;
 import com.punchsettle.server.utiis.TokenUtils;
 import com.punchsettle.server.utiis.UserUtils;
 
@@ -56,9 +55,7 @@ public class AuthInterceptor implements HandlerInterceptor {
 
         // 校验系统中是否存在该用户
         User currentUser = userService.getById(currentUserId);
-        if (Objects.isNull(currentUser)) {
-            throw BusinessException.fail("不存在的用户");
-        }
+        Assert.isNullInBusiness(currentUser, "不存在的用户");
 
         // 把用户信息设置如入上下文
         UserUtils.setCurrentId(currentUser.getId());

+ 9 - 7
src/main/java/com/punchsettle/server/core/interceptor/MybatisAuditDataInterceptor.java

@@ -1,8 +1,10 @@
 package com.punchsettle.server.core.interceptor;
 
-import com.punchsettle.server.common.entity.BaseEntity;
-import com.punchsettle.server.utiis.UserUtils;
-import lombok.extern.slf4j.Slf4j;
+import java.sql.Timestamp;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
 import org.apache.ibatis.executor.Executor;
 import org.apache.ibatis.mapping.MappedStatement;
 import org.apache.ibatis.mapping.SqlCommandType;
@@ -11,10 +13,10 @@ import org.apache.ibatis.plugin.Intercepts;
 import org.apache.ibatis.plugin.Invocation;
 import org.apache.ibatis.plugin.Signature;
 
-import java.sql.Timestamp;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
+import com.punchsettle.server.common.entity.BaseEntity;
+import com.punchsettle.server.utiis.UserUtils;
+
+import lombok.extern.slf4j.Slf4j;
 
 /**
  * @author tyuio

+ 19 - 5
src/main/java/com/punchsettle/server/dto/PunchInDto.java

@@ -1,5 +1,15 @@
 package com.punchsettle.server.dto;
 
+import org.hibernate.validator.constraints.Length;
+
+import com.punchsettle.server.common.valid.Delete;
+import com.punchsettle.server.common.valid.DoSomething;
+import com.punchsettle.server.common.valid.Save;
+import com.punchsettle.server.common.valid.Update;
+
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Positive;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 
@@ -16,35 +26,39 @@ public class PunchInDto {
     /**
      * 打卡结算主键
      */
+    @NotNull(message = "打卡结算主键不能为空", groups = {Update.class, Delete.class, DoSomething.class})
     private Long id;
 
     /**
      * 版本号
      */
+    @NotNull(message = "版本号不能为空", groups = {Update.class})
+    @Positive(message = "版本号必须大于0", groups = {Update.class})
     private Integer version;
 
     /**
      * 任务名称
      */
+    @NotBlank(message = "任务名称不能为空", groups = {Save.class, Update.class})
+    @Length(max = 30, message = "任务名称不能超过30个字符", groups = {Save.class, Update.class})
     private String taskName;
 
     /**
      * 奖励倍数
      */
+    @NotNull(message = "奖励倍数不能为空", groups = {Save.class, Update.class})
+    @Positive(message = "奖励倍数必须大于0", groups = {Save.class, Update.class})
     private Integer rewardNum;
 
     /**
      * 是否启用周末双倍标志(0-不是,1-是)
      */
+    @NotNull(message = "是否启用周末双倍标志不能为空", groups = {Save.class, Update.class})
     private Boolean weekendDoubleFlag;
 
     /**
      * 是否启用全勤奖励标志(0-不是,1-是)
      */
+    @NotNull(message = "是否启用全勤奖励标志不能为空", groups = {Save.class, Update.class})
     private Boolean fullAttendanceFlag;
-
-    /**
-     * 是否归档标志(0-不是,1-是)
-     */
-    private Boolean archiveFlag;
 }

+ 4 - 4
src/main/java/com/punchsettle/server/dto/PunchInRecordQuery.java

@@ -1,10 +1,10 @@
 package com.punchsettle.server.dto;
 
+import java.util.List;
+
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 
-import java.util.List;
-
 /**
  * @author tyuio
  * @version 1.0.0
@@ -21,12 +21,12 @@ public class PunchInRecordQuery {
     private List<Long> punchInIds;
 
     /**
-     * 查询日期范围-开始日期
+     * 打卡日期范围-开始日期
      */
     private String startDate;
 
     /**
-     * 查询日期范围-结束日期
+     * 打卡日期范围-结束日期
      */
     private String endDate;
 }

+ 1 - 0
src/main/java/com/punchsettle/server/dto/wechat/Code2SessionResponse.java

@@ -1,6 +1,7 @@
 package com.punchsettle.server.dto.wechat;
 
 import com.fasterxml.jackson.annotation.JsonAlias;
+
 import lombok.Data;
 
 /**

+ 3 - 2
src/main/java/com/punchsettle/server/feign/WechatMiniProgramFeign.java

@@ -1,11 +1,12 @@
 package com.punchsettle.server.feign;
 
-import com.punchsettle.server.dto.wechat.Code2SessionRequest;
-import com.punchsettle.server.dto.wechat.Code2SessionResponse;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.cloud.openfeign.SpringQueryMap;
 import org.springframework.web.bind.annotation.GetMapping;
 
+import com.punchsettle.server.dto.wechat.Code2SessionRequest;
+import com.punchsettle.server.dto.wechat.Code2SessionResponse;
+
 /**
  * @interfaceNName WeChatMiniProgramFeign
  * @description 微信小程序服务接口

+ 10 - 9
src/main/java/com/punchsettle/server/service/controller/WechatMiniProgramController.java → src/main/java/com/punchsettle/server/service/controller/LoginController.java

@@ -1,26 +1,27 @@
 package com.punchsettle.server.service.controller;
 
-import com.punchsettle.server.dto.wechat.LoginRequest;
-import com.punchsettle.server.service.manager.IWechatMiniProgramManager;
 import org.springframework.beans.factory.annotation.Autowired;
 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.wechat.LoginRequest;
+import com.punchsettle.server.service.manager.ILoginManager;
+
 /**
- * @className WeChatMiniProgramController
- * @description 微信小程序
+ * @className LoginController
+ * @description 登录 controller
  * @author ChenYL
  * @date 2023/07/23 16:08
  * @version V1.0
  **/
 @RestController
 @RequestMapping("/wechat/miniprogram")
-public class WechatMiniProgramController {
+public class LoginController {
 
     @Autowired
-    private IWechatMiniProgramManager wechatMiniProgramManager;
+    private ILoginManager loginManager;
 
     /**
      * 微信小程序登录
@@ -28,8 +29,8 @@ public class WechatMiniProgramController {
      * @param request
      * @return 微信登陆后获得的session_key
      */
-    @PostMapping("/login")
-    public String login(@RequestBody LoginRequest request) {
-        return wechatMiniProgramManager.login(request);
+    @PostMapping("/wechat/miniprogram/login")
+    public String wechatMiniProgramLogin(@RequestBody LoginRequest request) {
+        return loginManager.wechatMiniProgramLogin(request);
     }
 }

+ 55 - 8
src/main/java/com/punchsettle/server/service/controller/PunchInController.java

@@ -1,26 +1,73 @@
 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.common.valid.Delete;
+import com.punchsettle.server.common.valid.DoSomething;
+import com.punchsettle.server.common.valid.Save;
+import com.punchsettle.server.common.valid.Update;
+import com.punchsettle.server.dto.PunchInDto;
+import com.punchsettle.server.dto.PunchInWithRecordDto;
+import com.punchsettle.server.service.manager.IPunchInManager;
+
 /**
  * @author tyuio
  * @version 1.0.0
- * @description 打卡结算任务
+ * @description 打卡任务 controller
  * @date 2024/11/25 14:48
  */
 @RestController
 @RequestMapping("/punchIn")
 public class PunchInController {
 
-    // 查询
+    @Autowired
+    private IPunchInManager punchInManager;
+
+    /**
+     * 查询打卡任务
+     */
     @GetMapping("/query")
-    public void query() {
-//        return null;
+    public List<PunchInWithRecordDto> query() {
+        return punchInManager.queryPunchInAndRecord();
+    }
+
+    /**
+     * 新增打卡任务
+     */
+    @PostMapping("/save")
+    public void save(@RequestBody @Validated({Save.class}) PunchInDto dto) {
+        punchInManager.saveOrUpdatePunchIn(dto);
+    }
+
+    /**
+     * 新增或更新打卡任务
+     */
+    @PostMapping("/update")
+    public void update(@RequestBody @Validated({Update.class}) PunchInDto dto) {
+        punchInManager.saveOrUpdatePunchIn(dto);
+    }
+
+    /**
+     * 删除打卡任务
+     */
+    @PostMapping("/delete")
+    public void delete(@RequestBody @Validated({Delete.class}) PunchInDto dto) {
+        punchInManager.deletePunchIn(dto.getId());
+    }
+
+    /**
+     * 打卡
+     */
+    @PostMapping("/doPunchIn")
+    public void doPunchIn(@RequestBody @Validated({DoSomething.class}) PunchInDto dto) {
+        punchInManager.doPunchIn(dto.getId());
     }
-//    新建任务
-//    编辑任务
-//    删除任务
-//    用户完成任务
 }

+ 44 - 0
src/main/java/com/punchsettle/server/service/controller/RewardController.java

@@ -0,0 +1,44 @@
+package com.punchsettle.server.service.controller;
+
+import org.springframework.beans.factory.annotation.Autowired;
+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.ClaimRewardDto;
+import com.punchsettle.server.dto.UserRewardDto;
+import com.punchsettle.server.service.manager.IRewardManager;
+
+/**
+ * @author tyuio
+ * @version 1.0.0
+ * @description 奖励 controller
+ * @date 2024/11/26 15:00
+ */
+@RestController
+@RequestMapping("/reward")
+public class RewardController {
+
+    @Autowired
+    private IRewardManager rewardManager;
+
+    /**
+     * 查询奖励
+     * @return
+     */
+    @GetMapping("/queryReward")
+    public UserRewardDto queryReward() {
+        return rewardManager.queryReward();
+    }
+
+    /**
+     * 领取奖励
+     * @param dto
+     */
+    @PostMapping("/claimReward")
+    public void claimReward(@RequestBody ClaimRewardDto dto) {
+        rewardManager.claimReward(dto);
+    }
+}

+ 30 - 0
src/main/java/com/punchsettle/server/service/controller/TaskController.java

@@ -0,0 +1,30 @@
+package com.punchsettle.server.service.controller;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.punchsettle.server.service.manager.ITaskManager;
+
+/**
+ * @author tyuio
+ * @version 1.0.0
+ * @description 结算定时任务 controller
+ * @date 2024/11/26 15:04
+ */
+@RestController
+@RequestMapping("/task")
+public class TaskController {
+
+    @Autowired
+    private ITaskManager taskManager;
+
+    /**
+     * 手动调起结算定时任务
+     */
+    @GetMapping("/manualSettle")
+    public void manualSettle() {
+        taskManager.autoSettle();
+    }
+}

+ 3 - 3
src/main/java/com/punchsettle/server/service/manager/IWechatMiniProgramManager.java → src/main/java/com/punchsettle/server/service/manager/ILoginManager.java

@@ -3,9 +3,9 @@ package com.punchsettle.server.service.manager;
 import com.punchsettle.server.dto.wechat.LoginRequest;
 
 /**
- * 微信小程序 服务类
+ * 登录 服务类
  */
-public interface IWechatMiniProgramManager {
+public interface ILoginManager {
 
     /**
      * 微信小程序登录
@@ -13,5 +13,5 @@ public interface IWechatMiniProgramManager {
      * @param request
      * @return 微信登陆后获得的session_key
      */
-    String login(LoginRequest request);
+    String wechatMiniProgramLogin(LoginRequest request);
 }

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

@@ -1,10 +1,10 @@
 package com.punchsettle.server.service.manager;
 
+import java.util.List;
+
 import com.punchsettle.server.dto.PunchInDto;
 import com.punchsettle.server.dto.PunchInWithRecordDto;
 
-import java.util.List;
-
 /**
  * @author tyuio
  * @version 1.0.0

+ 15 - 0
src/main/java/com/punchsettle/server/service/manager/ITaskManager.java

@@ -0,0 +1,15 @@
+package com.punchsettle.server.service.manager;
+
+/**
+ * @author tyuio
+ * @version 1.0.0
+ * @description 定时任务服务类
+ * @date 2024/11/26 9:19
+ */
+public interface ITaskManager {
+
+    /**
+     * 结算定时任务
+     */
+    void autoSettle();
+}

+ 13 - 13
src/main/java/com/punchsettle/server/service/manager/impl/WechatMiniProgramManagerImpl.java → src/main/java/com/punchsettle/server/service/manager/impl/LoginManagerImpl.java

@@ -1,31 +1,33 @@
 package com.punchsettle.server.service.manager.impl;
 
 
+import java.util.Calendar;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
 import com.punchsettle.server.atomic.entity.User;
 import com.punchsettle.server.atomic.service.IUserService;
 import com.punchsettle.server.common.exception.BusinessException;
-import com.punchsettle.server.core.config.BizConfig;
+import com.punchsettle.server.common.utils.Assert;
 import com.punchsettle.server.constant.CacheConstant;
+import com.punchsettle.server.core.config.BizConfig;
 import com.punchsettle.server.dto.wechat.Code2SessionRequest;
 import com.punchsettle.server.dto.wechat.Code2SessionResponse;
 import com.punchsettle.server.dto.wechat.LoginRequest;
 import com.punchsettle.server.feign.WechatMiniProgramFeign;
-import com.punchsettle.server.service.manager.IWechatMiniProgramManager;
+import com.punchsettle.server.service.manager.ILoginManager;
 import com.punchsettle.server.utiis.CacheUtils;
 import com.punchsettle.server.utiis.TokenUtils;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.cache.CacheManager;
-import org.springframework.stereotype.Service;
 
-import java.util.Calendar;
+import lombok.extern.slf4j.Slf4j;
 
 /**
- * 微信小程序服务类
+ * 登录服务类
  */
 @Slf4j
 @Service
-public class WechatMiniProgramManagerImpl implements IWechatMiniProgramManager {
+public class LoginManagerImpl implements ILoginManager {
 
     @Autowired
     private WechatMiniProgramFeign wechatMiniProgramFeign;
@@ -37,7 +39,7 @@ public class WechatMiniProgramManagerImpl implements IWechatMiniProgramManager {
     private BizConfig bizConfig;
 
     @Override
-    public String login(LoginRequest request) {
+    public String wechatMiniProgramLogin(LoginRequest request) {
         // 从微信获取session_key
         Code2SessionRequest code2SessionRequest = new Code2SessionRequest();
         code2SessionRequest.setGrantType("authorization_code");
@@ -49,9 +51,7 @@ public class WechatMiniProgramManagerImpl implements IWechatMiniProgramManager {
 
         // 获取用户记录
         User user = userService.getAndAdd(loginResponse.getOpenId());
-        if (user == null) {
-            throw BusinessException.fail(String.format("不存在的用户,且无法新增,openid: %s", loginResponse.getOpenId()));
-        }
+        Assert.isNullInBusiness(user, String.format("不存在的用户,且无法新增,openid: %s", loginResponse.getOpenId()));
 
         // 缓存微信用户对应的session_key
         CacheUtils.put(CacheConstant.WECHAT_MINI_PROGRAM_SESSION_KEY, user.getId().toString(),

+ 75 - 46
src/main/java/com/punchsettle/server/service/manager/impl/PunchInManagerImpl.java

@@ -1,15 +1,17 @@
 package com.punchsettle.server.service.manager.impl;
 
-import java.sql.Timestamp;
 import java.text.SimpleDateFormat;
+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.function.Function;
 import java.util.stream.Collectors;
 
 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;
 
@@ -18,6 +20,8 @@ import com.punchsettle.server.atomic.entity.PunchInRecord;
 import com.punchsettle.server.atomic.service.IPunchInRecordService;
 import com.punchsettle.server.atomic.service.IPunchInService;
 import com.punchsettle.server.common.exception.BusinessException;
+import com.punchsettle.server.common.utils.Assert;
+import com.punchsettle.server.constant.PunchInStatusEnum;
 import com.punchsettle.server.dto.PunchInDto;
 import com.punchsettle.server.dto.PunchInRecordDto;
 import com.punchsettle.server.dto.PunchInRecordQuery;
@@ -35,6 +39,7 @@ import lombok.extern.slf4j.Slf4j;
  * @date 2024/11/25 15:12
  */
 @Slf4j
+@Service
 public class PunchInManagerImpl implements IPunchInManager {
 
     @Autowired
@@ -45,10 +50,10 @@ public class PunchInManagerImpl implements IPunchInManager {
 
     @Override
     public List<PunchInWithRecordDto> queryPunchInAndRecord() {
-        Long currentUserId = UserUtils.getCurrentUserId();
-        if (Objects.isNull(currentUserId)) {
-            throw BusinessException.fail("无法获取当前用户信息,无法查询打卡任务");
-        }
+        // 获取当前用户ID
+        Long currentUserId = Optional.ofNullable(UserUtils.getCurrentUserId())
+            .orElseThrow(() -> BusinessException.fail("无法获取当前用户信息,无法查询打卡任务"));
+
         // 查询打卡任务
         List<PunchIn> punchIns = punchInService.listByCreatedBy(currentUserId);
         if (CollectionUtils.isEmpty(punchIns)) {
@@ -56,46 +61,75 @@ public class PunchInManagerImpl implements IPunchInManager {
             return List.of();
         }
 
-        List<PunchInWithRecordDto> punchInWithRecordDtos = punchIns.stream().map(v -> {
-            PunchInWithRecordDto dto = new PunchInWithRecordDto();
-            BeanUtils.copyProperties(v, dto);
-            dto.setPunchInId(v.getId());
-            return dto;
-        }).collect(Collectors.toList());
-
-        // 获取一周的起始日期范围,找出范围内的打卡记录
-        List<String> weeklyDateRange = DateUtils.getWeeklyDateRangeStr();
-        String startDate = weeklyDateRange.getFirst();
-        String endDate = weeklyDateRange.getLast();
+        // 获取一周的起始日期范围,
+        List<LocalDate> weeklyDateRange = DateUtils.getWeeklyDateRange();
         // 获取打卡任务ID
         List<Long> punchInIds = punchIns.stream().map(PunchIn::getId).collect(Collectors.toList());
-
+        // 找出范围内的打卡记录
         PunchInRecordQuery query = new PunchInRecordQuery();
         query.setPunchInIds(punchInIds);
-        query.setStartDate(startDate);
-        query.setEndDate(endDate);
+        query.setStartDate(weeklyDateRange.getFirst().toString());
+        query.setEndDate(weeklyDateRange.getLast().toString());
         List<PunchInRecord> punchInRecords = punchInRecordService.listByCondition(query);
 
         // 按打卡任务任务分组
         Map<Long, List<PunchInRecord>> recordMap =
             punchInRecords.stream().collect(Collectors.groupingBy(PunchInRecord::getPunchInId));
-        // 构建打卡记录
+
+        // 日期格式化
         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
-        for (PunchInWithRecordDto dto : punchInWithRecordDtos) {
-            List<PunchInRecord> records = Optional.ofNullable(recordMap.get(dto.getPunchInId())).orElse(List.of());
-            Map<Object, Integer> punchInDateMap =
-                records.stream().collect(Collectors.toMap(record -> sdf.format(record.getPunchInTime()),
-                    PunchInRecord::getPunchInStatus, (key1, key2) -> key1));
-            // 构建打卡记录
-            List<PunchInRecordDto> punchInRecordDtoList = weeklyDateRange.stream().map(punchInDate -> {
-                PunchInRecordDto punchInRecordDto = new PunchInRecordDto();
-                Integer punchInStatus = punchInDateMap.get(punchInDate);
-                punchInRecordDto.setPunchInDate(punchInDate);
-                punchInRecordDto.setPunchInStatus(punchInStatus);
-                return punchInRecordDto;
-            }).collect(Collectors.toList());
 
-            dto.setPunchInRecords(punchInRecordDtoList);
+        // 当前日期
+        LocalDate today = LocalDate.now();
+
+        // 构建打卡记录
+        List<PunchInWithRecordDto> punchInWithRecordDtos = new ArrayList<>();
+        for (PunchIn punchIn : punchIns) {
+            PunchInWithRecordDto punchInWithRecordDto = new PunchInWithRecordDto();
+            BeanUtils.copyProperties(punchIn, punchInWithRecordDto);
+            punchInWithRecordDto.setPunchInId(punchIn.getId());
+
+            // 打卡任务创建日期
+            LocalDate punchInCreationDate = LocalDate.parse(sdf.format(punchIn.getCreationTime()));
+
+            // 获取打卡任务对应的打卡记录,并按打卡日期转为map
+            List<PunchInRecord> records =
+                Optional.ofNullable(recordMap.get(punchInWithRecordDto.getPunchInId())).orElse(List.of());
+            Map<String, PunchInRecord> recordWeekMap = records.stream()
+                .collect(Collectors.toMap(PunchInRecord::getPunchInDate, Function.identity(), (key1, key2) -> key1));
+
+            // 设置打卡记录
+            List<PunchInRecordDto> recordDtos = new ArrayList<>();
+            punchInWithRecordDto.setPunchInRecords(recordDtos);
+
+            // 知道任务什么时候创建
+            // 在这之前(不包含)的记录的状态值都为0-任务未创建
+            // 在这之后如果打卡则状态为1-任务已创建已打卡
+            // 在这之后如果没打卡则状态为2-任务已创建但未打卡
+            // 如果当前日期超过一周中的某天则跳过
+            for (LocalDate currentDate : weeklyDateRange) {
+                String currentDateStr = currentDate.toString();
+                // 设置打卡记录
+                PunchInRecordDto punchInRecordDto = new PunchInRecordDto();
+                punchInRecordDto.setPunchInDate(currentDateStr);
+                recordDtos.add(punchInRecordDto);
+
+                // 还没到当前日期则跳过
+                if (currentDate.isAfter(today)) {
+                    continue;
+                }
+
+                // 根据过往打卡记录设置打卡状态
+                if (currentDate.isBefore(punchInCreationDate)) {
+                    punchInRecordDto.setPunchInStatus(PunchInStatusEnum.UNCREATED.getValue());
+                } else if (recordWeekMap.containsKey(currentDateStr)) {
+                    punchInRecordDto.setPunchInStatus(PunchInStatusEnum.PUNCHIN.getValue());
+                } else {
+                    punchInRecordDto.setPunchInStatus(PunchInStatusEnum.UNPUNCHIN.getValue());
+                }
+
+            }
+            punchInWithRecordDtos.add(punchInWithRecordDto);
         }
 
         return punchInWithRecordDtos;
@@ -103,33 +137,28 @@ public class PunchInManagerImpl implements IPunchInManager {
 
     @Override
     public void saveOrUpdatePunchIn(PunchInDto dto) {
-        if (Objects.isNull(dto)) {
-            throw BusinessException.fail("请传入任务信息");
-        }
+        Assert.isNullInBusiness(dto.getId(), "请传入任务信息");
+
         PunchIn punchIn = new PunchIn();
         BeanUtils.copyProperties(dto, punchIn);
+        punchIn.setArchiveFlag(false);
         punchInService.insertOrUpdate(punchIn);
     }
 
     @Override
     public void deletePunchIn(Long punchInId) {
-        if (Objects.isNull(punchInId)) {
-            throw BusinessException.fail("请传入待删除的任务");
-        }
+        Assert.isNullInBusiness(punchInId, "请传入待删除的任务");
         punchInService.delete(punchInId);
     }
 
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void doPunchIn(Long punchInId) {
-        if (Objects.isNull(punchInId)) {
-            throw BusinessException.fail("请传入待打卡的任务");
-        }
-
+        Assert.isNullInBusiness(punchInId, "请传入待打卡的任务");
         // 创建打卡记录
         PunchInRecord punchInRecord = new PunchInRecord();
         punchInRecord.setPunchInId(punchInId);
-        punchInRecord.setPunchInTime(new Timestamp(System.currentTimeMillis()));
+        punchInRecord.setPunchInDate(LocalDate.now().toString());
         punchInRecordService.insert(punchInRecord);
     }
 }

+ 58 - 1
src/main/java/com/punchsettle/server/service/manager/impl/RewardManagerImpl.java

@@ -1,8 +1,23 @@
 package com.punchsettle.server.service.manager.impl;
 
+import java.sql.Timestamp;
+import java.util.Objects;
+import java.util.Optional;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.punchsettle.server.atomic.entity.UserClaimRewardRecord;
+import com.punchsettle.server.atomic.entity.UserReward;
+import com.punchsettle.server.atomic.service.IUserClaimRewardRecordService;
+import com.punchsettle.server.atomic.service.IUserRewardService;
+import com.punchsettle.server.common.exception.BusinessException;
+import com.punchsettle.server.common.utils.Assert;
 import com.punchsettle.server.dto.ClaimRewardDto;
 import com.punchsettle.server.dto.UserRewardDto;
 import com.punchsettle.server.service.manager.IRewardManager;
+import com.punchsettle.server.utiis.UserUtils;
 
 /**
  * @author tyuio
@@ -10,15 +25,57 @@ import com.punchsettle.server.service.manager.IRewardManager;
  * @description 奖励 服务类
  * @date 2024/11/25 20:59
  */
+@Service
 public class RewardManagerImpl implements IRewardManager {
 
+    @Autowired
+    private IUserClaimRewardRecordService userClaimRewardRecordService;
+
+    @Autowired
+    private IUserRewardService userRewardService;
+
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public void claimReward(ClaimRewardDto dto) {
+        if (Objects.isNull(dto) || Objects.isNull(dto.getClaimRewardNum())) {
+            throw BusinessException.fail("待领取的奖励数不能为空");
+        }
 
+        // 获取用户信息
+        Long currentUserId =
+            Optional.ofNullable(UserUtils.getCurrentUserId()).orElseThrow(() -> BusinessException.fail("无法获取当前用户ID"));
+        UserReward userReward = Optional.ofNullable(userRewardService.getByUserId(currentUserId)).orElseThrow(() -> BusinessException.fail("无法获取当前用户的奖励信息"));
+
+        // 计算未领取奖励数、已领取奖励数
+        if (userReward.getUnclaimedRewardNum() < dto.getClaimRewardNum()) {
+            throw BusinessException.fail("当前用户奖励不足,无法领取");
+        }
+        int unclaimedRewardNum = userReward.getUnclaimedRewardNum() - dto.getClaimRewardNum();
+        int claimedRewardNum = userReward.getClaimedRewardNum() + dto.getClaimRewardNum();
+
+        // 构建打卡记录
+        UserClaimRewardRecord userClaimRewardRecord = new UserClaimRewardRecord();
+        userClaimRewardRecord.setUserId(currentUserId);
+        userClaimRewardRecord.setClaimRewardNum(dto.getClaimRewardNum());
+        userClaimRewardRecord.setClaimRewardTime(new Timestamp(System.currentTimeMillis()));
+        userClaimRewardRecord.setBeforeClaimRewardNum(userReward.getUnclaimedRewardNum());
+        userClaimRewardRecord.setAfterClaimRewardNum(unclaimedRewardNum);
+        userClaimRewardRecordService.insert(userClaimRewardRecord);
+
+        // 更新用户奖励信息
+        userReward.setUnclaimedRewardNum(unclaimedRewardNum);
+        userReward.setClaimedRewardNum(claimedRewardNum);
+        userRewardService.updateReward(userReward);
     }
 
     @Override
     public UserRewardDto queryReward() {
-        return null;
+        Long currentUserId = UserUtils.getCurrentUserId();
+        UserReward userReward = userRewardService.getByUserId(currentUserId);
+        Assert.isNullInBusiness(userReward, "用户没有奖励信息");
+
+        UserRewardDto userRewardDto = new UserRewardDto();
+        userRewardDto.setUnclaimedRewardNum(userReward.getUnclaimedRewardNum());
+        return userRewardDto;
     }
 }

+ 224 - 0
src/main/java/com/punchsettle/server/service/manager/impl/TaskManagerImpl.java

@@ -0,0 +1,224 @@
+package com.punchsettle.server.service.manager.impl;
+
+import java.sql.Timestamp;
+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.function.Function;
+import java.util.stream.Collectors;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+
+import com.punchsettle.server.atomic.entity.PunchIn;
+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.SettlementTask;
+import com.punchsettle.server.atomic.entity.UserReward;
+import com.punchsettle.server.atomic.service.IPunchInRecordService;
+import com.punchsettle.server.atomic.service.IPunchInRecordSettlementRelaService;
+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.IUserRewardService;
+import com.punchsettle.server.dto.PunchInRecordQuery;
+import com.punchsettle.server.service.manager.ITaskManager;
+import com.punchsettle.server.utiis.DateUtils;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * @author tyuio
+ * @version 1.0.0
+ * @description 打卡结算服务
+ * @date 2024/11/26 9:20
+ */
+@Service
+@Slf4j
+public class TaskManagerImpl implements ITaskManager {
+
+    @Autowired
+    private IPunchInService punchInService;
+
+    @Autowired
+    private IPunchInRecordService punchInRecordService;
+
+    @Autowired
+    private IUserRewardService userRewardService;
+
+    @Autowired
+    private IPunchInSettlementService punchInSettlementService;
+
+    @Autowired
+    private ISettlementTaskService settlementTaskService;
+
+    @Autowired
+    private IPunchInRecordSettlementRelaService punchInRecordSettlementRelaService;
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void autoSettle() {
+        log.info("结算任务开始");
+        Timestamp settleStartTime = new Timestamp(System.currentTimeMillis());
+
+        // 获取昨天的日期,
+        LocalDate yesterday = DateUtils.getYesterdayDate();
+        String yesterdayStr = DateUtils.getYesterdayDateStr();
+        // 判断是否是周末
+        boolean weekendFlag =
+            DayOfWeek.SATURDAY.equals(yesterday.getDayOfWeek()) || DayOfWeek.SUNDAY.equals(yesterday.getDayOfWeek());
+        boolean sundayFlag = DayOfWeek.SUNDAY.equals(yesterday.getDayOfWeek());
+
+        PunchInRecordQuery recordQuery = new PunchInRecordQuery();
+        recordQuery.setStartDate(yesterdayStr);
+        recordQuery.setEndDate(yesterdayStr);
+        List<PunchInRecord> punchInRecords = punchInRecordService.listByCondition(recordQuery);
+        if (CollectionUtils.isEmpty(punchInRecords)) {
+            log.info("结算任务结束,原因:没有打卡记录");
+            return;
+        }
+
+        List<Long> userIds = punchInRecords.stream().map(PunchInRecord::getCreatedBy).collect(Collectors.toList());
+
+        // 读取用户的打卡任务
+        List<PunchIn> punchIns = punchInService.listByCreatedBy(userIds);
+        if (CollectionUtils.isEmpty(punchIns)) {
+            log.info("结算任务结束,原因:根据打卡记录没有找到打卡任务");
+            return;
+        }
+
+        // 读取用户奖励数据
+        List<UserReward> userRewards = userRewardService.listByUserIds(userIds);
+        if (CollectionUtils.isEmpty(userRewards)) {
+            log.info("结算任务结束,原因:没有找到用户奖励信息");
+            return;
+        }
+
+        // 获取一周的打卡记录
+        Map<Long, List<PunchInRecord>> punchInRecordForWeek = Map.of();
+        if (sundayFlag) {
+            List<Long> punchInIds = punchIns.stream().map(PunchIn::getId).collect(Collectors.toList());
+            PunchInRecordQuery recordForWeekQuery = new PunchInRecordQuery();
+            recordForWeekQuery.setPunchInIds(punchInIds);
+            recordForWeekQuery.setStartDate(DateUtils.getLastWeekMondayStr());
+            recordForWeekQuery.setEndDate(DateUtils.getLastWeekSundayStr());
+            List<PunchInRecord> punchInRecordForWeeks = punchInRecordService.listByCondition(recordForWeekQuery);
+            if (!CollectionUtils.isEmpty(punchInRecordForWeeks)) {
+                punchInRecordForWeek =
+                    punchInRecordForWeeks.stream().collect(Collectors.groupingBy(PunchInRecord::getPunchInId));
+            }
+        }
+
+        // 打卡任务容器
+        Map<Long, PunchIn> punchInMap =
+            punchIns.stream().collect(Collectors.toMap(PunchIn::getId, Function.identity(), (key1, key2) -> key1));
+
+        // 用户-打卡记录分组
+        Map<Long, List<PunchInRecord>> userPunchInRecordMap =
+            punchInRecords.stream().collect(Collectors.groupingBy(PunchInRecord::getCreatedBy));
+
+        // 用户-奖励分组
+        Map<Long, UserReward> userRewardMap = userRewards.stream()
+            .collect(Collectors.toMap(UserReward::getUserId, Function.identity(), (key1, key2) -> key1));
+
+        // 先创建结算任务执行记录
+        SettlementTask settlementTask = new SettlementTask();
+        settlementTask.setSettleDate(yesterdayStr);
+        settlementTask.setStartTime(settleStartTime);
+        settlementTask.setProcessedNum(userPunchInRecordMap.size());
+        settlementTaskService.insert(settlementTask);
+
+        // 结算时间
+        Timestamp settlementTime = new Timestamp(System.currentTimeMillis());
+        List<PunchInSettlement> addPunchInSettlements = new ArrayList<>();
+        List<UserReward> updateUserRewards = new ArrayList<>();
+        List<PunchInRecordSettlementRela> punchInRecordSettlementRelas = new ArrayList<>();
+
+        // 有打卡记录的打卡任务则进行结算
+        for (Long userId : userPunchInRecordMap.keySet()) {
+            // 获取用户打卡记录
+            List<PunchInRecord> punchInRecordList = userPunchInRecordMap.get(userId);
+            if (CollectionUtils.isEmpty(punchInRecordList)) {
+                log.info("用户{}没有打卡记录,无须结算", userId);
+                continue;
+            }
+            // 获取用户打卡奖励
+            UserReward userReward = userRewardMap.get(userId);
+            if (Objects.isNull(userReward)) {
+                log.info("用户{}没有奖励信息,无法结算", userId);
+                continue;
+            }
+
+            // 根据打卡记录上的打卡任务ID获取具体的打卡任务信息进行结算
+            int settleRewardNum = 0;
+            for (PunchInRecord punchInRecord : punchInRecordList) {
+                PunchIn punchIn = punchInMap.get(punchInRecord.getPunchInId());
+                if (Objects.isNull(punchIn)) {
+                    continue;
+                }
+                // 周末双倍奖励,否则计算普通奖励
+                settleRewardNum += weekendFlag ? punchIn.getRewardNum() * 2 : punchIn.getRewardNum();
+                // 周日计算一次全勤双倍奖励
+                if (sundayFlag && punchIn.getFullAttendanceFlag()) {
+                    List<PunchInRecord> tempRecordList = punchInRecordForWeek.get(punchInRecord.getPunchInId());
+                    if (!CollectionUtils.isEmpty(tempRecordList) && tempRecordList.size() >= 6) {
+                        settleRewardNum += punchIn.getRewardNum() * 2;
+                    }
+                }
+
+                // 构建结算任务与记录关联信息
+                PunchInRecordSettlementRela rela = new PunchInRecordSettlementRela();
+                rela.setRecordId(punchInRecord.getId());
+                rela.setSettlementId(settlementTask.getId());
+                punchInRecordSettlementRelas.add(rela);
+            }
+
+            // 计算结算前后,用户奖励数的变化
+            int beforeSettleRewardNum = userReward.getUnclaimedRewardNum();
+            int afterSettleRewardNum = beforeSettleRewardNum + settleRewardNum;
+            int totalRewardNum = userReward.getTotalRewardNum() + settleRewardNum;
+
+            // 构造结算信息
+            PunchInSettlement addPunchInSettlement = new PunchInSettlement();
+            addPunchInSettlement.setSettlementTaskId(settlementTask.getId());
+            addPunchInSettlement.setUserId(userId);
+            addPunchInSettlement.setSettleRewardNum(settleRewardNum);
+            addPunchInSettlement.setSettlementTime(settlementTime);
+            addPunchInSettlement.setBeforeSettleRewardNum(beforeSettleRewardNum);
+            addPunchInSettlement.setAfterSettleRewardNum(afterSettleRewardNum);
+            addPunchInSettlements.add(addPunchInSettlement);
+
+            // 构造用户奖励信息
+            UserReward updateUserReward = new UserReward();
+            updateUserReward.setId(userReward.getId());
+            updateUserReward.setVersion(userReward.getVersion());
+            updateUserReward.setTotalRewardNum(totalRewardNum);
+            updateUserReward.setUnclaimedRewardNum(afterSettleRewardNum);
+            updateUserRewards.add(updateUserReward);
+        }
+
+        // 更新用户奖励信息
+        userRewardService.batchUpdateUserReward(updateUserRewards);
+
+        // 新增结算信息
+        punchInSettlementService.batchInsert(addPunchInSettlements);
+
+        // 构造并新增关联信息
+        punchInRecordSettlementRelaService.batchInsert(punchInRecordSettlementRelas);
+
+        // 构造并新增结算任务信息
+        settlementTask.setProcessedSettleNum(addPunchInSettlements.size());
+        settlementTask
+            .setProcessedUnsettleNum(settlementTask.getProcessedNum() - settlementTask.getProcessedSettleNum());
+        settlementTask.setEndTime(new Timestamp(System.currentTimeMillis()));
+        settlementTaskService.update(settlementTask);
+
+        log.info("结算任务结束");
+    }
+}

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

@@ -18,18 +18,65 @@ public class DateUtils {
      * 获取一周的时间范围
      * @return 返回日期字符串列表
      */
-    public static List<String> getWeeklyDateRangeStr() {
+    public static List<LocalDate> getWeeklyDateRange() {
         LocalDate today = LocalDate.now();
 
         // 获取本周的第一天(假设周一为一周的第一天)
         LocalDate firstDayOfWeek = today.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
 
         // 打印本周的所有日期
-        List<String> list = new ArrayList<>(7);
+        List<LocalDate> list = new ArrayList<>(7);
         for (int i = 0; i < 7; i++) {
             LocalDate date = firstDayOfWeek.plusDays(i);
-            list.add(date.toString());
+            list.add(date);
         }
         return list;
     }
+
+    /**
+     * 获取昨天的日期
+     * @return
+     */
+    public static LocalDate getYesterdayDate() {
+        LocalDate today = LocalDate.now();
+        return today.minusDays(1);
+    }
+
+    /**
+     * 获取昨天的日期(字符串)
+     * @return
+     */
+    public static String getYesterdayDateStr() {
+        return getYesterdayDate().toString();
+    }
+
+    /**
+     * 获取上周的周一日期
+     * @return
+     */
+    public static LocalDate getLastWeekMonday() {
+        // 获取当前日期
+        LocalDate today = LocalDate.now();
+        // 获取上周的周一日期
+        return today.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)).minusWeeks(1);
+    }
+
+    /**
+     * 获取上周的周一日期(字符串)
+     * @return
+     */
+    public static String getLastWeekMondayStr() {
+        // 获取当前日期
+        LocalDate today = LocalDate.now();
+        // 获取上周的周一日期
+        return today.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)).minusWeeks(1).toString();
+    }
+
+    /**
+     * 获取上周的周日日期(字符串)
+     * @return
+     */
+    public static String getLastWeekSundayStr() {
+        return getLastWeekMonday().plusDays(6).toString();
+    }
 }

+ 3 - 3
src/main/java/com/punchsettle/server/utiis/TokenUtils.java

@@ -1,14 +1,14 @@
 package com.punchsettle.server.utiis;
 
+import java.util.Date;
+import java.util.Map;
+
 import com.auth0.jwt.JWT;
 import com.auth0.jwt.JWTVerifier;
 import com.auth0.jwt.algorithms.Algorithm;
 import com.auth0.jwt.interfaces.Claim;
 import com.punchsettle.server.core.config.BizConfig;
 
-import java.util.Date;
-import java.util.Map;
-
 /**
  * @className JwtUtils
  * @description Token凭证工具