Browse Source

【feat】【v3】
1.修复发现的问题
2.优化代码逻辑
3.修改sql脚本

ChenYL 10 tháng trước cách đây
mục cha
commit
0bcb3a8d86
34 tập tin đã thay đổi với 534 bổ sung319 xóa
  1. 58 20
      doc/sql/update-v3.sql
  2. 3 27
      src/main/java/com/punchsettle/server/atomic/entity/PiStatus.java
  3. 3 27
      src/main/java/com/punchsettle/server/atomic/entity/PiStatusHistory.java
  4. 9 1
      src/main/java/com/punchsettle/server/atomic/entity/SettleUserHistory.java
  5. 2 1
      src/main/java/com/punchsettle/server/atomic/mapper/SettleUserHistoryMapper.java
  6. 6 0
      src/main/java/com/punchsettle/server/atomic/service/IPiStatusService.java
  7. 6 0
      src/main/java/com/punchsettle/server/atomic/service/ISettleUserHistoryService.java
  8. 6 0
      src/main/java/com/punchsettle/server/atomic/service/impl/PiStatusServiceImpl.java
  9. 9 0
      src/main/java/com/punchsettle/server/atomic/service/impl/SettleUserHistoryServiceImpl.java
  10. 29 0
      src/main/java/com/punchsettle/server/pojo/op/SettleRequest.java
  11. 7 0
      src/main/java/com/punchsettle/server/pojo/settle/SettleUserHistoryQuery.java
  12. 1 1
      src/main/java/com/punchsettle/server/pojo/ucharts/LineSeriesVO.java
  13. 1 1
      src/main/java/com/punchsettle/server/pojo/ucharts/LineVO.java
  14. 35 0
      src/main/java/com/punchsettle/server/service/controller/OpController.java
  15. 3 3
      src/main/java/com/punchsettle/server/service/controller/UserController.java
  16. 6 0
      src/main/java/com/punchsettle/server/service/manager/IAccountManager.java
  17. 2 2
      src/main/java/com/punchsettle/server/service/manager/IPunchInCoreManager.java
  18. 7 0
      src/main/java/com/punchsettle/server/service/manager/ISettleManager.java
  19. 5 0
      src/main/java/com/punchsettle/server/service/manager/IStatManager.java
  20. 11 0
      src/main/java/com/punchsettle/server/service/manager/impl/AccountManagerImpl.java
  21. 11 4
      src/main/java/com/punchsettle/server/service/manager/impl/PunchInCoreManagerImpl.java
  22. 28 11
      src/main/java/com/punchsettle/server/service/manager/impl/PunchInManagerImpl.java
  23. 7 1
      src/main/java/com/punchsettle/server/service/manager/impl/SettleCoreManagerImpl.java
  24. 158 30
      src/main/java/com/punchsettle/server/service/manager/impl/SettleManagerImpl.java
  25. 29 6
      src/main/java/com/punchsettle/server/service/manager/impl/StatManagerImpl.java
  26. 11 0
      src/main/java/com/punchsettle/server/service/manager/impl/UserManagerImpl.java
  27. 0 149
      src/main/java/com/punchsettle/server/task/PointsDistributeTask.java
  28. 32 0
      src/main/java/com/punchsettle/server/task/SettleDistributeTask.java
  29. 18 8
      src/main/java/com/punchsettle/server/task/SettlePointsTask.java
  30. 7 21
      src/main/java/com/punchsettle/server/task/StatNewUserTask.java
  31. 5 0
      src/main/java/com/punchsettle/server/utiis/DateUtils.java
  32. 1 1
      src/main/resources/application.yaml
  33. 9 5
      src/test/java/com/punchsettle/server/service/manager/impl/PunchInManagerImplTest.java
  34. 9 0
      src/test/java/com/punchsettle/server/service/manager/impl/SettleManagerImplTest.java

+ 58 - 20
doc/sql/update-v3.sql

@@ -646,9 +646,9 @@ ALTER TABLE punch_settle.sys_dict_item MODIFY COLUMN data_type varchar(10) DEFAU
 UPDATE punch_settle.sys_dict_item SET data_type = 'INTEGER' WHERE data_type = '1';
 UPDATE punch_settle.sys_dict_item SET data_type = 'STRING' WHERE data_type = '0';
 
-INSERT INTO item_consume_win_history(id, user_id, action, source, category, amount, created_by, creation_time, last_updated_by, last_update_time, version, delete_flag)
-SELECT id, created_by, action_type, source, category, amount, created_by, creation_time, last_updated_by, last_update_time, version, delete_flag
-FROM lottery_scratch_record;
+-- INSERT INTO item_consume_win_history(id, user_id, action, source, category, amount, created_by, creation_time, last_updated_by, last_update_time, version, delete_flag)
+-- SELECT id, created_by, action_type, source, category, amount, created_by, creation_time, last_updated_by, last_update_time, version, delete_flag
+-- FROM lottery_scratch_record;
 UPDATE punch_settle.item_consume_win_history SET action = 'CONSUME' WHERE action = '0';
 UPDATE punch_settle.item_consume_win_history SET action = 'WIN' WHERE action = '1';
 UPDATE punch_settle.item_consume_win_history SET action = 'REVERSE_CONSUME' WHERE action = '2';
@@ -673,13 +673,13 @@ ALTER TABLE punch_settle.settle_task_history MODIFY COLUMN processed_total_num i
 -- 删除无效的用户数据
 delete from user where id not in (select created_by from pi_task group by created_by);
 -- 初始化账户数据,account数从user导入
-insert into account(user_id, account_name, account_category, points, created_by, creation_time, last_updated_by, last_update_time, version, delete_flag)
-select id, '基本户', 'BASIC', unused_points, id, CURRENT_TIMESTAMP(), id, CURRENT_TIMESTAMP(), 1, 0
-from user;
+-- insert into account(user_id, account_name, account_category, points, created_by, creation_time, last_updated_by, last_update_time, version, delete_flag)
+-- select id, '基本户', 'BASIC', unused_points, id, CURRENT_TIMESTAMP(), id, CURRENT_TIMESTAMP(), 1, 0
+-- from user;
 -- 初始化基本奖励数据
-insert into reward(user_id, reward_name, exchange_points, auto_status, created_by, creation_time, last_updated_by, last_update_time, version, delete_flag)
-select id, '刮一次刮刮乐', 1, 'DISABLED', id, CURRENT_TIMESTAMP(), id, CURRENT_TIMESTAMP(), 1, 0
-from user;
+-- insert into reward(user_id, reward_name, exchange_points, auto_status, created_by, creation_time, last_updated_by, last_update_time, version, delete_flag)
+-- select id, '刮一次刮刮乐', 1, 'DISABLED', id, CURRENT_TIMESTAMP(), id, CURRENT_TIMESTAMP(), 1, 0
+-- from user;
 update reward
 set reward_unique_id = id,
 reward_version = 1,
@@ -689,16 +689,16 @@ ALTER TABLE punch_settle.reward MODIFY COLUMN reward_status varchar(10) CHARACTE
 ALTER TABLE punch_settle.reward MODIFY COLUMN reward_version int NOT NULL COMMENT '奖励修改版本';
 
 ALTER TABLE punch_settle.reward_history DROP COLUMN account_name;
-insert into reward_history(user_id, reward_id, exchange_method, exchange_count, exchange_total_points, account_id, account_points_before_exchange, account_points_after_exchange,
-unused_points_before_exchange, unused_points_after_exchange, used_points_before_exchange, used_points_after_exchange,
-created_by, creation_time, last_updated_by, last_update_time, version, delete_flag)
-select created_by,
-(select id from reward r where r.user_id = rr.created_by and r.reward_name = '刮一次刮刮乐'),
-'MANUAL', claim_reward_num, claim_reward_num,
-(SELECT ID FROM account a where a.user_id = rr.created_by and a.account_category = 'BASIC'),
-rr.before_claim_reward_num , rr.after_claim_reward_num , rr.before_claim_reward_num , rr.after_claim_reward_num , rr.before_claim_reward_num , rr.after_claim_reward_num ,
-created_by, creation_time, last_updated_by, last_update_time, version, delete_flag
-from user_claim_reward_record rr;
+-- insert into reward_history(user_id, reward_id, exchange_method, exchange_count, exchange_total_points, account_id, account_points_before_exchange, account_points_after_exchange,
+-- unused_points_before_exchange, unused_points_after_exchange, used_points_before_exchange, used_points_after_exchange,
+-- created_by, creation_time, last_updated_by, last_update_time, version, delete_flag)
+-- select created_by,
+-- (select id from reward r where r.user_id = rr.created_by and r.reward_name = '刮一次刮刮乐'),
+-- 'MANUAL', claim_reward_num, claim_reward_num,
+-- (SELECT ID FROM account a where a.user_id = rr.created_by and a.account_category = 'BASIC'),
+-- rr.before_claim_reward_num , rr.after_claim_reward_num , rr.before_claim_reward_num , rr.after_claim_reward_num , rr.before_claim_reward_num , rr.after_claim_reward_num ,
+-- created_by, creation_time, last_updated_by, last_update_time, version, delete_flag
+-- from user_claim_reward_record rr;
 DROP TABLE IF EXISTS user_claim_reward_record;
 
 -- insert into pi_task_history(id, user_id, task_unique_id,
@@ -753,4 +753,42 @@ ALTER TABLE punch_settle.`user` ADD user_category varchar(10) DEFAULT 'NORMAL' N
 ALTER TABLE punch_settle.`user` CHANGE user_category user_category varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT 'NORMAL' NOT NULL COMMENT '用户类型(普通-NORMAL,管理员-ADMIN)' AFTER open_id;
 
 
-
+delete from pi_task;
+delete from settle_task_history;
+delete from sys_dict;
+delete from sys_dict_item;
+delete from user;
+
+ALTER TABLE punch_settle.pi_task MODIFY COLUMN unique_id bigint NULL COMMENT '任务唯一ID';
+
+ALTER TABLE punch_settle.pi_status_history MODIFY COLUMN points_in_month int NULL COMMENT '本月获取积分数';
+ALTER TABLE punch_settle.pi_status_history MODIFY COLUMN punch_in_done_count_in_month int NULL COMMENT '本月完成打卡数';
+ALTER TABLE punch_settle.pi_status_history MODIFY COLUMN punch_in_count_in_month int NULL COMMENT '本月已打卡数';
+ALTER TABLE punch_settle.pi_status_history MODIFY COLUMN punch_in_total_count_in_month int NULL COMMENT '本月需打卡数';
+ALTER TABLE punch_settle.pi_status_history MODIFY COLUMN stat_time_in_month char(7) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '统计月份(格式:yyyy-MM)';
+ALTER TABLE punch_settle.pi_status_history MODIFY COLUMN points_in_week int NULL COMMENT '本周获取积分数';
+ALTER TABLE punch_settle.pi_status_history MODIFY COLUMN punch_in_done_count_in_week int NULL COMMENT '本周完成打卡数';
+ALTER TABLE punch_settle.pi_status_history MODIFY COLUMN punch_in_count_in_week int NULL COMMENT '本周已打卡数';
+ALTER TABLE punch_settle.pi_status_history MODIFY COLUMN punch_in_total_count_in_week int NULL COMMENT '本周需打卡数';
+ALTER TABLE punch_settle.pi_status_history MODIFY COLUMN stat_time_in_week char(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '统计周数(格式:yyyy-周数)';
+ALTER TABLE punch_settle.pi_status_history MODIFY COLUMN repeat_prev_total_count_in_month int NULL COMMENT '本月需打卡数(变更重复类型前)';
+ALTER TABLE punch_settle.pi_status_history MODIFY COLUMN repeat_prev_total_count_in_week int NULL COMMENT '本周需打卡数(变更重复类型前)';
+
+ALTER TABLE punch_settle.pi_status MODIFY COLUMN repeat_prev_total_count_in_week int NULL COMMENT '本周需打卡数(变更重复类型前)';
+ALTER TABLE punch_settle.pi_status MODIFY COLUMN repeat_prev_total_count_in_month int NULL COMMENT '本月需打卡数(变更重复类型前)';
+ALTER TABLE punch_settle.pi_status MODIFY COLUMN stat_time_in_week char(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '统计周数(格式:yyyy-周数)';
+ALTER TABLE punch_settle.pi_status MODIFY COLUMN punch_in_total_count_in_week int NULL COMMENT '本周需打卡数';
+ALTER TABLE punch_settle.pi_status MODIFY COLUMN punch_in_count_in_week int NULL COMMENT '本周已打卡数';
+ALTER TABLE punch_settle.pi_status MODIFY COLUMN punch_in_done_count_in_week int NULL COMMENT '本周完成打卡数';
+ALTER TABLE punch_settle.pi_status MODIFY COLUMN points_in_week int NULL COMMENT '本周获取积分数';
+ALTER TABLE punch_settle.pi_status MODIFY COLUMN stat_time_in_month char(7) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '统计月份(格式:yyyy-MM)';
+ALTER TABLE punch_settle.pi_status MODIFY COLUMN punch_in_total_count_in_month int NULL COMMENT '本月需打卡数';
+ALTER TABLE punch_settle.pi_status MODIFY COLUMN punch_in_count_in_month int NULL COMMENT '本月已打卡数';
+ALTER TABLE punch_settle.pi_status MODIFY COLUMN punch_in_done_count_in_month int NULL COMMENT '本月完成打卡数';
+ALTER TABLE punch_settle.pi_status MODIFY COLUMN points_in_month int NULL COMMENT '本月获取积分数';
+
+ALTER TABLE punch_settle.settle_task_rela_history MODIFY COLUMN pi_task_history_id bigint NULL COMMENT '单任务打卡记录ID';
+
+ALTER TABLE punch_settle.account_transfer_history MODIFY COLUMN sender_account_id bigint NULL COMMENT '转出账户id';
+ALTER TABLE punch_settle.account_transfer_history MODIFY COLUMN sa_points_before_transfer int NULL COMMENT '转出账户转出前积分';
+ALTER TABLE punch_settle.account_transfer_history MODIFY COLUMN sa_points_after_transfer int NULL COMMENT '转出账户转出后积分';

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

@@ -87,7 +87,7 @@ public class PiStatus extends BaseEntity implements Serializable {
     /**
      * 连续中断次数
      */
-    @Column(name = "连续中断次数")
+    @Column(name = "continue_interrupted_count")
     private Integer continueInterruptedCount;
 
     /**
@@ -130,7 +130,7 @@ public class PiStatus extends BaseEntity implements Serializable {
     /**
      * 统计时间(格式:yyyy-W周数)
      */
-    @Column(name = "stats_time_in_week")
+    @Column(name = "stat_time_in_week")
     private String statTimeInWeek;
 
     /**
@@ -151,18 +151,6 @@ public class PiStatus extends BaseEntity implements Serializable {
     @Column(name = "punch_in_done_count_in_week")
     private Integer punchInDoneCountInWeek;
 
-    /**
-     * 本周打卡率
-     */
-    @Column(name = "punch_in_rate_in_week")
-    private BigDecimal punchInRateInWeek;
-
-    /**
-     * 本周打卡完成率
-     */
-    @Column(name = "punch_in_done_rate_in_week")
-    private BigDecimal punchInDoneRateInWeek;
-
     /**
      * 本周获取积分数
      */
@@ -172,7 +160,7 @@ public class PiStatus extends BaseEntity implements Serializable {
     /**
      * 统计时间(格式:yyyy-W周数)
      */
-    @Column(name = "stats_time_in_month")
+    @Column(name = "stat_time_in_month")
     private String statTimeInMonth;
 
     /**
@@ -193,18 +181,6 @@ public class PiStatus extends BaseEntity implements Serializable {
     @Column(name = "punch_in_done_count_in_month")
     private Integer punchInDoneCountInMonth;
 
-    /**
-     * 本周打卡率
-     */
-    @Column(name = "punch_in_rate_in_month")
-    private BigDecimal punchInRateInMonth;
-
-    /**
-     * 本周打卡完成率
-     */
-    @Column(name = "punch_in_done_rate_in_month")
-    private BigDecimal punchInDoneRateInMonth;
-
     /**
      * 本周获取积分数
      */

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

@@ -85,7 +85,7 @@ public class PiStatusHistory extends BaseEntity implements Serializable {
     /**
      * 连续中断次数
      */
-    @Column(name = "连续中断次数")
+    @Column(name = "continue_interrupted_count")
     private Integer continueInterruptedCount;
 
     /**
@@ -134,7 +134,7 @@ public class PiStatusHistory extends BaseEntity implements Serializable {
     /**
      * 统计时间(格式:yyyy-W周数)
      */
-    @Column(name = "stats_time_in_week")
+    @Column(name = "stat_time_in_week")
     private String statTimeInWeek;
 
     /**
@@ -155,18 +155,6 @@ public class PiStatusHistory extends BaseEntity implements Serializable {
     @Column(name = "punch_in_done_count_in_week")
     private Integer punchInDoneCountInWeek;
 
-    /**
-     * 本周打卡率
-     */
-    @Column(name = "punch_in_rate_in_week")
-    private BigDecimal punchInRateInWeek;
-
-    /**
-     * 本周打卡完成率
-     */
-    @Column(name = "punch_in_done_rate_in_week")
-    private BigDecimal punchInDoneRateInWeek;
-
     /**
      * 本周获取积分数
      */
@@ -176,7 +164,7 @@ public class PiStatusHistory extends BaseEntity implements Serializable {
     /**
      * 统计时间(格式:yyyy-W周数)
      */
-    @Column(name = "stats_time_in_month")
+    @Column(name = "stat_time_in_month")
     private String statTimeInMonth;
 
     /**
@@ -197,18 +185,6 @@ public class PiStatusHistory extends BaseEntity implements Serializable {
     @Column(name = "punch_in_done_count_in_month")
     private Integer punchInDoneCountInMonth;
 
-    /**
-     * 本周打卡率
-     */
-    @Column(name = "punch_in_rate_in_month")
-    private BigDecimal punchInRateInMonth;
-
-    /**
-     * 本周打卡完成率
-     */
-    @Column(name = "punch_in_done_rate_in_month")
-    private BigDecimal punchInDoneRateInMonth;
-
     /**
      * 本周获取积分数
      */

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

@@ -6,6 +6,7 @@ import java.io.Serializable;
 import com.punchsettle.server.common.pojo.BaseEntity;
 
 import com.punchsettle.server.constant.PointsDistributeStatusEnum;
+import com.punchsettle.server.constant.SettleResultEnum;
 import jakarta.persistence.Column;
 import jakarta.persistence.Table;
 import lombok.Data;
@@ -47,6 +48,13 @@ public class SettleUserHistory extends BaseEntity implements Serializable {
     @Column(name = "settle_date")
     private String settleDate;
 
+    /**
+     * 结算结果(已结算-SETTLED,无需结算-NOT_SETTLED)
+     * @see SettleResultEnum
+     */
+    @Column(name = "settle_result")
+    private SettleResultEnum settleResult;
+
     /**
      * 结算积分
      */
@@ -70,6 +78,6 @@ public class SettleUserHistory extends BaseEntity implements Serializable {
      * @see PointsDistributeStatusEnum
      */
     @Column(name="distribute_status")
-    private PointsDistributeStatusEnum distributeStatusEnum;
+    private PointsDistributeStatusEnum distributeStatus;
 
 }

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

@@ -1,6 +1,7 @@
 package com.punchsettle.server.atomic.mapper;
 
 import com.punchsettle.server.atomic.entity.SettleUserHistory;
+import tk.mybatis.mapper.additional.update.batch.BatchUpdateSelectiveMapper;
 import tk.mybatis.mapper.common.Mapper;
 import tk.mybatis.mapper.common.special.InsertListMapper;
 
@@ -10,6 +11,6 @@ import tk.mybatis.mapper.common.special.InsertListMapper;
  * @description 结算用户记录表 Mapper
  * @date 2025/04/08 10:30
  */
-public interface SettleUserHistoryMapper extends Mapper<SettleUserHistory>, InsertListMapper<SettleUserHistory> {
+public interface SettleUserHistoryMapper extends Mapper<SettleUserHistory>, InsertListMapper<SettleUserHistory>, BatchUpdateSelectiveMapper<SettleUserHistory> {
 
 }

+ 6 - 0
src/main/java/com/punchsettle/server/atomic/service/IPiStatusService.java

@@ -25,4 +25,10 @@ public interface IPiStatusService {
      * @param piStatusList
      */
     void batchUpdate(List<PiStatus> piStatusList);
+
+    /**
+     * 新增
+     * @param piStatus
+     */
+    void insert(PiStatus piStatus);
 }

+ 6 - 0
src/main/java/com/punchsettle/server/atomic/service/ISettleUserHistoryService.java

@@ -25,4 +25,10 @@ public interface ISettleUserHistoryService {
      * @return
      */
     List<SettleUserHistory> querySettleUserHistory(SettleUserHistoryQuery query);
+
+    /**
+     * 批量更新
+     * @param settleUserHistories
+     */
+    void batchUpdate(List<SettleUserHistory> settleUserHistories);
 }

+ 6 - 0
src/main/java/com/punchsettle/server/atomic/service/impl/PiStatusServiceImpl.java

@@ -46,4 +46,10 @@ public class PiStatusServiceImpl implements IPiStatusService {
         Assert.notEmpty(piStatusList);
         piStatusMapper.batchUpdateSelective(piStatusList);
     }
+
+    @Override
+    public void insert(PiStatus piStatus) {
+        Assert.isNull(piStatus);
+        piStatusMapper.insertSelective(piStatus);
+    }
 }

+ 9 - 0
src/main/java/com/punchsettle/server/atomic/service/impl/SettleUserHistoryServiceImpl.java

@@ -47,6 +47,15 @@ public class SettleUserHistoryServiceImpl implements ISettleUserHistoryService {
         if (StringUtils.hasText(query.getSettleDateLike())) {
             criteria.andLike(SettleUserHistory::getSettleDate, String.format("%s%%", query.getSettleDateLike()));
         }
+        if (Objects.nonNull(query.getDistributeStatus())) {
+            criteria.andEqualTo(SettleUserHistory::getDistributeStatus, query.getDistributeStatus());
+        }
         return settleUserHistoryMapper.selectByExample(weekend);
     }
+
+    @Override
+    public void batchUpdate(List<SettleUserHistory> settleUserHistories) {
+        Assert.notEmpty(settleUserHistories);
+        settleUserHistoryMapper.batchUpdateSelective(settleUserHistories);
+    }
 }

+ 29 - 0
src/main/java/com/punchsettle/server/pojo/op/SettleRequest.java

@@ -0,0 +1,29 @@
+package com.punchsettle.server.pojo.op;
+
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotEmpty;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author tyuio
+ * @version 1.0.0
+ * @date 2025/5/7 18:27
+ * @description 结算请求
+ */
+@Data
+public class SettleRequest {
+
+    /**
+     * 待结算的用户ID列表
+     */
+    @NotEmpty(message = "待结算的用户ID列表不能为空")
+    private List<Long> userIds;
+
+    /**
+     * 待结算的打卡日期
+     */
+    @NotBlank(message = "待结算的打卡日期不能为空")
+    private String punchInDate;
+}

+ 7 - 0
src/main/java/com/punchsettle/server/pojo/settle/SettleUserHistoryQuery.java

@@ -1,5 +1,6 @@
 package com.punchsettle.server.pojo.settle;
 
+import com.punchsettle.server.constant.PointsDistributeStatusEnum;
 import lombok.Data;
 
 /**
@@ -25,4 +26,10 @@ public class SettleUserHistoryQuery {
      * 结算日期
      */
     private String settleDate;
+
+    /**
+     * 积分下发状态
+     * @see PointsDistributeStatusEnum
+     */
+    private PointsDistributeStatusEnum distributeStatus;
 }

+ 1 - 1
src/main/java/com/punchsettle/server/pojo/ucharts/LineSeriesVO.java

@@ -6,7 +6,7 @@ import lombok.Data;
  * @author myou
  * @version 1.0.0
  * @date 2025/5/1 9:57
- * @description uCharts图表 折线图具体数据
+ * @description uCharts图表 折线图数据
  */
 @Data
 public class LineSeriesVO {

+ 1 - 1
src/main/java/com/punchsettle/server/pojo/ucharts/LineVO.java

@@ -19,7 +19,7 @@ public class LineVO {
     private String[] categories;
 
     /**
-     * 折线图数据
+     * 数据
      */
     private List<LineSeriesVO> series;
 }

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

@@ -1,14 +1,23 @@
 package com.punchsettle.server.service.controller;
 
+import com.punchsettle.server.pojo.op.SettleRequest;
 import com.punchsettle.server.service.manager.IOpManager;
+import com.punchsettle.server.service.manager.ISettleManager;
+import com.punchsettle.server.service.manager.IStatManager;
+import com.punchsettle.server.task.SettlePointsTask;
+import com.punchsettle.server.utiis.SpringUtils;
 import jakarta.validation.constraints.NotBlank;
 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.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
+import java.time.LocalDate;
+
 /**
  * @author tyuio
  * @version 1.0.0
@@ -54,4 +63,30 @@ public class OpController {
     public void refreshCalendar(String gregorianDate) {
         opManager.refreshCalendar(gregorianDate);
     }
+
+    /**
+     * 调用统计新用户数定时任务
+     */
+    @GetMapping("/statNewUser")
+    public void statNewUser(@NotBlank(message = "统计日期不能为空") String statTime) {
+        SpringUtils.getBean(IStatManager.class).statNewUser(statTime);
+    }
+
+    /**
+     * 手动结算
+     * @param settleRequest
+     */
+    @PostMapping("/settle")
+    public void settle(@RequestBody @Validated SettleRequest settleRequest) {
+        SpringUtils.getBean(SettlePointsTask.class).settle(settleRequest.getUserIds(), settleRequest.getPunchInDate());
+    }
+
+    /**
+     * 积分下发
+     * @param settleDate 结算日期
+     */
+    @GetMapping("/distributePoints")
+    public void distributePoints(@NotBlank(message = "结算日期不能为空") String settleDate) {
+        SpringUtils.getBean(ISettleManager.class).distributePoints(LocalDate.parse(settleDate));
+    }
 }

+ 3 - 3
src/main/java/com/punchsettle/server/service/controller/UserController.java

@@ -1,8 +1,5 @@
 package com.punchsettle.server.service.controller;
 
-import com.punchsettle.server.pojo.login.LoginRequest;
-import com.punchsettle.server.utiis.UserUtils;
-import me.chanjar.weixin.common.error.WxErrorException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -11,10 +8,13 @@ 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.pojo.login.LoginRequest;
 import com.punchsettle.server.pojo.user.NicknameRequest;
 import com.punchsettle.server.pojo.user.UserInfoVO;
 import com.punchsettle.server.service.manager.IUserManager;
 
+import me.chanjar.weixin.common.error.WxErrorException;
+
 /**
  * @author tyuio
  * @version 1.0.0

+ 6 - 0
src/main/java/com/punchsettle/server/service/manager/IAccountManager.java

@@ -56,4 +56,10 @@ public interface IAccountManager {
      * @param transferMonth 转账月份
      */
     List<TransferHistoryVO> queryTransferHistory(String transferMonth);
+
+    /**
+     * 创建基本账户
+     * @param userId
+     */
+    void createBasicAccount(Long userId);
 }

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

@@ -23,10 +23,10 @@ public interface IPunchInCoreManager {
     /**
      * 判断指定日期是否在打卡任务的重复周期内
      * @param piTask 打卡任务
-     * @param repeatDateStr 指定日期
+     * @param repeatDate 指定日期
      * @return true-在周期内,false-不在周期内
      */
-    boolean judgeRepeat(PiTask piTask, String repeatDateStr);
+    boolean judgeRepeat(PiTask piTask, LocalDate repeatDate);
 
     /**
      * 判断打卡结果

+ 7 - 0
src/main/java/com/punchsettle/server/service/manager/ISettleManager.java

@@ -1,5 +1,6 @@
 package com.punchsettle.server.service.manager;
 
+import java.time.LocalDate;
 import java.util.List;
 
 import com.punchsettle.server.pojo.settle.SettlePointsHistoryVO;
@@ -27,4 +28,10 @@ public interface ISettleManager {
      * @param settleTaskHistoryId 结算任务ID
      */
     void settle(List<Long> userIds, String punchInDateStr, Long settleTaskHistoryId);
+
+    /**
+     * 结算后下发积分
+     * @param settleDate 结算日期
+     */
+    void distributePoints(LocalDate settleDate);
 }

+ 5 - 0
src/main/java/com/punchsettle/server/service/manager/IStatManager.java

@@ -44,4 +44,9 @@ public interface IStatManager {
      */
     void statPiTaskData(IStatPiTaskService statPiTaskService, StatPeriodEnum statPeriod, List<Long> userIds, LocalDate statTime, LocalDate statFirstDay, LocalDate statLastDay);
 
+    /**
+     * 统计新用户
+     * @param statTime
+     */
+    void statNewUser(String statTime);
 }

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

@@ -256,4 +256,15 @@ public class AccountManagerImpl implements IAccountManager {
             return transferHistoryVO;
         }).collect(Collectors.toList());
     }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void createBasicAccount(Long userId) {
+        Account account = new Account();
+        account.setUserId(userId);
+        account.setPoints(0);
+        account.setAccountName("基本账户");
+        account.setAccountCategory(AccountCategoryEnum.BASIC);
+        accountService.insert(account);
+    }
 }

+ 11 - 4
src/main/java/com/punchsettle/server/service/manager/impl/PunchInCoreManagerImpl.java

@@ -48,7 +48,15 @@ public class PunchInCoreManagerImpl implements IPunchInCoreManager {
     private ICalendarManager calendarManager;
 
     @Override
-    public boolean judgeRepeat(PiTask piTask, String repeatDateStr) {
+    public boolean judgeRepeat(PiTask piTask, LocalDate repeatDate) {
+        // 存在结束日期,判断当前日期是否已归档
+        if (Objects.nonNull(piTask.getEndDate())) {
+            // 重复日期在归档日期之后
+            if (repeatDate.isAfter(piTask.getEndDate())) {
+                return false;
+            }
+        }
+
         // 每天
         if (RepeatCategoryEnum.EVERYDAY.equals(piTask.getRepeatCategory())) {
             return true;
@@ -56,12 +64,12 @@ public class PunchInCoreManagerImpl implements IPunchInCoreManager {
 
         // 法定工作日
         if (RepeatCategoryEnum.WORKDAY.equals(piTask.getRepeatCategory())) {
-            return calendarManager.judgeWorkday(repeatDateStr);
+            return calendarManager.judgeWorkday(repeatDate.toString());
         }
 
         // 法定节假日(含周末)
         if (RepeatCategoryEnum.HOLIDAY.equals(piTask.getRepeatCategory())) {
-            return calendarManager.judgeHoliday(repeatDateStr);
+            return calendarManager.judgeHoliday(repeatDate.toString());
         }
 
         // 自定义
@@ -70,7 +78,6 @@ public class PunchInCoreManagerImpl implements IPunchInCoreManager {
                 BusinessException.throwFail(String.format("打卡任务ID:%s, 重复周期类型:自定义重复,没有设定自定义重复日期"));
             }
 
-            LocalDate repeatDate = LocalDate.parse(repeatDateStr);
             int dayOfWeekValue = repeatDate.getDayOfWeek().getValue();
             return piTask.getRepeatCustomDay().contains(String.valueOf(dayOfWeekValue));
         }

+ 28 - 11
src/main/java/com/punchsettle/server/service/manager/impl/PunchInManagerImpl.java

@@ -13,7 +13,10 @@ import java.util.Set;
 import java.util.function.Function;
 import java.util.stream.Collectors;
 
+import com.punchsettle.server.atomic.entity.PiStatus;
+import com.punchsettle.server.atomic.service.IPiStatusService;
 import com.punchsettle.server.constant.CacheNameConstant;
+import com.punchsettle.server.constant.ContinueStatusEnum;
 import com.punchsettle.server.utiis.SpringUtils;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -100,6 +103,9 @@ public class PunchInManagerImpl implements IPunchInManager {
     @Autowired
     private CacheManager cacheManager;
 
+    @Autowired
+    private IPiStatusService piStatusService;
+
     /**
      * 默认显示时间00:00:00.000
      */
@@ -130,7 +136,7 @@ public class PunchInManagerImpl implements IPunchInManager {
         // 1.判断重复频率,只显示今天待打卡的任务
         // 2.判断显示时间,还没到点显示的暂时不显示
         // 3.根据displayOrder进行排序,按自然顺序排列
-        return piTasks.stream().filter(piTask -> punchInCoreManager.judgeRepeat(piTask, todayStr))
+        return piTasks.stream().filter(piTask -> punchInCoreManager.judgeRepeat(piTask, today))
                 .filter(piTask -> {
                     LocalTime displayTime = Optional.ofNullable(piTask.getDisplayTime()).orElse(DEFAULT_DISPLAY_TIME);
                     return nowTime.compareTo(displayTime) > -1;
@@ -144,6 +150,7 @@ public class PunchInManagerImpl implements IPunchInManager {
                     // 获取并设置已打卡记录
                     PiTaskHistory piTaskHistory = piTaskHistoryMap.get(piTask.getUniqueId());
                     if (Objects.nonNull(piTaskHistory)) {
+                        piTaskToDoVO.setPunchInResult(piTaskHistory.getPunchInResult());
                         piTaskToDoVO.setCurrentCountTrack(piTaskHistory.getCountTrack());
                         piTaskToDoVO.setCurrentTimeTrack(piTaskHistory.getTimeTrack());
                     }
@@ -243,14 +250,14 @@ public class PunchInManagerImpl implements IPunchInManager {
         // TODO 这里应该要有打卡任务的每天记录才能精准判断,现在先简化一下用当前任务的重复频率进行判断
         if (punchInDate.isBefore(today) && Objects.isNull(piTaskHistory)) {
             // 判断是否需要打卡
-            boolean repeatResult = punchInCoreManager.judgeRepeat(piTask, today.toString());
+            boolean repeatResult = punchInCoreManager.judgeRepeat(piTask, today);
             return repeatResult ? PunchInResultViewEnum.UNDONE : PunchInResultViewEnum.NOT_NEED;
         }
 
         // 打卡日期是今天,且不存在打卡记录,则有两种情况:1.今天不用打卡;2.今天需要打卡但是还没打卡
         if (punchInDate.isEqual(today)) {
             // 判断是否需要打卡
-            boolean repeatResult = punchInCoreManager.judgeRepeat(piTask, today.toString());
+            boolean repeatResult = punchInCoreManager.judgeRepeat(piTask, today);
             // 今天不用无须打卡
             if (!repeatResult) {
                 return PunchInResultViewEnum.NOT_NEED;
@@ -343,6 +350,11 @@ public class PunchInManagerImpl implements IPunchInManager {
             piTaskService.update(updatePiTask);
         }
 
+        // 今天
+        LocalDate today = LocalDate.now();
+        // 当前用户ID
+        Long currentUserId = UserUtils.getCurrentUserId();
+
         // 保存数据
         piTaskService.insert(addPiTask);
         // 如果首次保存,需要设置唯一ID
@@ -351,15 +363,22 @@ public class PunchInManagerImpl implements IPunchInManager {
             updatePiTask.setId(addPiTask.getId());
             updatePiTask.setUniqueId(addPiTask.getId());
             piTaskService.update(updatePiTask);
-        }
 
-        // 今天
-        String today = LocalDate.now().toString();
+            PiStatus addPiStatus = new PiStatus();
+            addPiStatus.setUserId(currentUserId);
+            addPiStatus.setTaskUniqueId(addPiTask.getId());
+            addPiStatus.setStatusDate(today.toString());
+            addPiStatus.setTaskContinueStatus(ContinueStatusEnum.INTERRUPTED);
+            addPiStatus.setTaskContinueDay(0);
+            addPiStatus.setRepeatCategory(addPiTask.getRepeatCategory());
+            addPiStatus.setRepeatCustomDay(addPiTask.getRepeatCustomDay());
+            piStatusService.insert(addPiStatus);
+        }
 
         // 不是新增打卡任务 更新打卡记录
         if (Objects.nonNull(addPiTask.getUniqueId())) {
             // 查询今天的打卡记录
-            PiTaskHistory oldPiTaskHistory = piTaskHistoryService.getByTaskUniqueIdAndPunchInDate(addPiTask.getUniqueId(), today);
+            PiTaskHistory oldPiTaskHistory = piTaskHistoryService.getByTaskUniqueIdAndPunchInDate(addPiTask.getUniqueId(), today.toString());
             // 已打卡则重新判断打卡状态
             if (Objects.nonNull(oldPiTaskHistory)) {
                 // 新编辑的打卡任务+旧的打卡记录判断打卡结果
@@ -373,15 +392,13 @@ public class PunchInManagerImpl implements IPunchInManager {
             }
         }
 
-
         // 清除缓存
-        Long currentUserId = UserUtils.getCurrentUserId();
         cacheManager.getCache(CacheNameConstant.TASK_LIST_FOR_USER).evict(currentUserId);
         cacheManager.getCache(CacheNameConstant.TASK_LIST_VO).evict(currentUserId);
         cacheManager.getCache(CacheNameConstant.TASK_PUNCH_IN_HISTORY).evict(String.format("%s_%s", currentUserId, today));
         cacheManager.getCache(CacheNameConstant.TASK_HISTORY_LIST_FOR_USER).evict(String.format("%s_%s", currentUserId, today));
-        cacheManager.getCache(CacheNameConstant.TASK_STAT).evict(String.format("%s_%s", currentUserId, today.substring(0, 7)));
-        cacheManager.getCache(CacheNameConstant.TASK_STAT).evict(String.format("%s_%s", currentUserId, today.substring(0, 4)));
+        cacheManager.getCache(CacheNameConstant.TASK_STAT).evict(String.format("%s_%s", currentUserId, today.toString().substring(0, 7)));
+        cacheManager.getCache(CacheNameConstant.TASK_STAT).evict(String.format("%s_%s", currentUserId, today.toString().substring(0, 4)));
     }
 
     @Override

+ 7 - 1
src/main/java/com/punchsettle/server/service/manager/impl/SettleCoreManagerImpl.java

@@ -6,6 +6,7 @@ import java.time.LocalDate;
 import java.time.temporal.ChronoUnit;
 import java.util.Comparator;
 import java.util.List;
+import java.util.Objects;
 import java.util.Optional;
 import java.util.stream.Collectors;
 
@@ -50,6 +51,11 @@ public class SettleCoreManagerImpl implements ISettleCoreManager {
     @Override
     public int calculatePointsInTask(PiTask piTask, List<PiTaskExt> piTaskExtList, PiTaskHistory piTaskHistory,
         PiStatus piStatus) {
+        // 未打卡,积分为0
+        if (Objects.isNull(piTaskHistory)) {
+            return 0;
+        }
+
         // 未完成打卡,积分为0
         if (PunchInResultEnum.UNDONE.equals(piTaskHistory.getPunchInResult())) {
             return 0;
@@ -91,7 +97,7 @@ public class SettleCoreManagerImpl implements ISettleCoreManager {
         }
 
         // 打卡任务使用的拓展信息
-        List<TaskExt> punchInMultiExtList = piTaskExtList.stream()
+        List<TaskExt> punchInMultiExtList = Optional.ofNullable(piTaskExtList).orElse(List.of()).stream()
             .filter(v -> PunchInDimensionEnum.MULTI_DAY.equals(v.getDimension())).collect(Collectors.toList());
         // 连续完成额外积分
         int taskPoints = calculateContinuePoints(piTask, punchInMultiExtList, piStatus);

+ 158 - 30
src/main/java/com/punchsettle/server/service/manager/impl/SettleManagerImpl.java

@@ -12,6 +12,16 @@ import java.util.Set;
 import java.util.function.Function;
 import java.util.stream.Collectors;
 
+import com.punchsettle.server.atomic.entity.Account;
+import com.punchsettle.server.atomic.entity.AccountTransferHistory;
+import com.punchsettle.server.atomic.entity.User;
+import com.punchsettle.server.atomic.service.IAccountService;
+import com.punchsettle.server.atomic.service.IAccountTransferHistoryService;
+import com.punchsettle.server.atomic.service.IUserService;
+import com.punchsettle.server.constant.AccountCategoryEnum;
+import com.punchsettle.server.constant.PointsDistributeStatusEnum;
+import com.punchsettle.server.constant.TransferCategoryEnum;
+import com.punchsettle.server.pojo.account.AccountQuery;
 import com.punchsettle.server.pojo.settle.SettleUserHistoryQuery;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -112,6 +122,15 @@ public class SettleManagerImpl implements ISettleManager {
     @Autowired
     private ISettleTaskRelaHistoryService settleTaskRelaHistoryService;
 
+    @Autowired
+    private IUserService userService;
+
+    @Autowired
+    private IAccountService accountService;
+
+    @Autowired
+    private IAccountTransferHistoryService accountTransferHistoryService;
+
     @Override
     @Cacheable(cacheNames = CacheNameConstant.SETTLE_POINTS_HISTORY, key = "#userId+'_'+settleMonth", condition = "#userId != null && settleMont != null && !settleMonth.isBlank()")
     public List<SettlePointsHistoryVO> querySettlePointsHistory(Long userId, String settleMonth) {
@@ -163,6 +182,10 @@ public class SettleManagerImpl implements ISettleManager {
             addSettleUserHistory.setUserId(settleData.getUserId());
             addSettleUserHistory.setSettleDate(punchInDateStr);
             addSettleUserHistory.setSettleTaskHistoryId(settleTaskHistoryId);
+            addSettleUserHistory.setBeforeSettlePoints(0);
+            addSettleUserHistory.setAfterSettlePoints(0);
+            addSettleUserHistory.setSettleResult(SettleResultEnum.SETTLE);
+            addSettleUserHistory.setDistributeStatus(PointsDistributeStatusEnum.NOT_DISTRIBUTE);
             addSettleUserHistories.add(addSettleUserHistory);
 
             // 不存在打卡任务则跳过
@@ -192,7 +215,7 @@ public class SettleManagerImpl implements ISettleManager {
                 addSettleTaskRelaHistory.setPiTaskUniqueId(piTask.getUniqueId());
 
                 // 有打卡任务,但是今天无需结算
-                boolean repeatResult = punchInCoreManager.judgeRepeat(piTask, punchInDateStr);
+                boolean repeatResult = punchInCoreManager.judgeRepeat(piTask, punchInDate);
                 if (!repeatResult) {
                     addSettleTaskRelaHistory.setSettleResult(SettleResultEnum.NOT_SETTLED);
                     addSettleTaskRelaHistory.setSettlePoints(0);
@@ -218,7 +241,13 @@ public class SettleManagerImpl implements ISettleManager {
 
                 // 计算积分,要先刷新打卡状态
                 int settlePoints = settleCoreManager.calculatePointsInTask(piTask, piTaskExtList, piTaskHistory, oldPiStatus);
+                // 计算总积分
+                totalSettlePoints += settlePoints;
 
+                // 没有打过卡时,没有打卡记录
+                if (Objects.nonNull(piTaskHistory)) {
+                    addSettleTaskRelaHistory.setPiTaskHistoryId(piTaskHistory.getId());
+                }
                 addSettleTaskRelaHistory.setSettleResult(SettleResultEnum.SETTLE);
                 addSettleTaskRelaHistory.setSettlePoints(settlePoints);
                 addSettleTaskRelaHistories.add(addSettleTaskRelaHistory);
@@ -330,39 +359,39 @@ public class SettleManagerImpl implements ISettleManager {
         Map<Long, List<PiTaskExt>> piTaskExtGroupList =
                 piTaskExtList.stream().collect(Collectors.groupingBy(PiTaskExt::getTaskId));
 
-        return userIds.stream().map(userId -> {
+        return userIds.stream().filter(userId -> piTaskMap.containsKey(userId)).map(userId -> {
             SettleData settleData = new SettleData();
 
             // 设置用户ID
             settleData.setUserId(userId);
 
             // TODO 获取并设置多任务打卡信息,这个不可能为空,为空则用户初始注册时创建时有问题
-            PiMultiTask piMultiTask = piMultiTaskMap.get(userId);
-            settleData.setPiMultiTask(piMultiTask);
-
-            // 获取并设置对应的拓展信息
-            List<PiMultiTaskExt> tempPiMultiTaskExtList = piMultiTaskExtMap.get(piMultiTask.getId());
-            settleData.setPiMultiTaskExtList(tempPiMultiTaskExtList);
+//            PiMultiTask piMultiTask = piMultiTaskMap.get(userId);
+//            settleData.setPiMultiTask(piMultiTask);
+//
+//            // 获取并设置对应的拓展信息
+//            List<PiMultiTaskExt> tempPiMultiTaskExtList = piMultiTaskExtMap.get(piMultiTask.getId());
+//            settleData.setPiMultiTaskExtList(tempPiMultiTaskExtList);
 
             // 获取并设置对应的多任务打卡记录
-            PiMultiTaskHistory piMultiTaskHistory = piMultiTaskHistoryMap.get(piMultiTask.getUniqueId());
-            settleData.setPiMultiTaskHistory(piMultiTaskHistory);
-
-            // 获取多任务与打卡任务的关联信息
-            List<PiMultiTaskRela> tempPiMultiTaskRelaList = piMultiTaskRelaMap.get(piMultiTask.getId());
-            Set<Long> relaContainTaskIdList =
-                    tempPiMultiTaskRelaList.stream().map(PiMultiTaskRela::getTaskId).collect(Collectors.toSet());
-
-            // 获取并设置多任务的状态信息
-            PiStatus piStatusInMultiTask = piStatusMapInMultiTask.get(piMultiTask.getUniqueId());
-            settleData.setPiStatus(piStatusInMultiTask);
+//            PiMultiTaskHistory piMultiTaskHistory = piMultiTaskHistoryMap.get(piMultiTask.getUniqueId());
+//            settleData.setPiMultiTaskHistory(piMultiTaskHistory);
+//
+//            // 获取多任务与打卡任务的关联信息
+//            List<PiMultiTaskRela> tempPiMultiTaskRelaList = piMultiTaskRelaMap.get(piMultiTask.getId());
+//            Set<Long> relaContainTaskIdList =
+//                    tempPiMultiTaskRelaList.stream().map(PiMultiTaskRela::getTaskId).collect(Collectors.toSet());
+//
+//            // 获取并设置多任务的状态信息
+//            PiStatus piStatusInMultiTask = piStatusMapInMultiTask.get(piMultiTask.getUniqueId());
+//            settleData.setPiStatus(piStatusInMultiTask);
 
             // 获取任务列表
             List<PiTask> piTasksList = piTaskMap.get(userId);
             // 打卡任务数据
             List<PiTaskData> piTaskDataList = new ArrayList<>(piTasksList.size());
             // 关联的打卡任务记录
-            List<PiTaskHistory> relaPunchInTaskHistories = new ArrayList<>(relaContainTaskIdList.size());
+//            List<PiTaskHistory> relaPunchInTaskHistories = new ArrayList<>(relaContainTaskIdList.size());
 
             for (PiTask piTask : piTasksList) {
                 PiTaskData piTaskData = new PiTaskData();
@@ -373,9 +402,9 @@ public class SettleManagerImpl implements ISettleManager {
                 piTaskData.setPiTaskHistory(piTaskHistory);
 
                 //设置多任务与打卡记录的关联信息
-                if (relaContainTaskIdList.contains(piTask.getId())) {
-                    relaPunchInTaskHistories.add(piTaskHistory);
-                }
+//                if (relaContainTaskIdList.contains(piTask.getId())) {
+//                    relaPunchInTaskHistories.add(piTaskHistory);
+//                }
 
                 // 获取并设置拓展信息
                 List<PiTaskExt> tempPiTaskExtList = piTaskExtGroupList.get(piTask.getId());
@@ -389,7 +418,7 @@ public class SettleManagerImpl implements ISettleManager {
             }
 
             settleData.setPiTaskDataList(piTaskDataList);
-            settleData.setRelaPunchInTaskHistories(relaPunchInTaskHistories);
+//            settleData.setRelaPunchInTaskHistories(relaPunchInTaskHistories);
 
             return settleData;
         }).collect(Collectors.toList());
@@ -475,21 +504,21 @@ public class SettleManagerImpl implements ISettleManager {
 
             // 设置实时数据
             piStatus.setRepeatPrevTotalCountInWeek(prevTotalCountInWeek + oldPrevTotalCountInWeek);
-            piStatus.setPunchInTotalCountInWeek(piStatus.getRepeatPrevTotalCountInWeek() + punchInTotalCountInWeek);
+            piStatus.setPunchInTotalCountInWeek(Optional.ofNullable(piStatus.getRepeatPrevTotalCountInWeek()).orElse(0) + punchInTotalCountInWeek);
             piStatus.setRepeatPrevTotalCountInMonth(prevTotalCountInMonth + oldPrevTotalCountInMonth);
-            piStatus.setPunchInTotalCountInMonth(piStatus.getRepeatPrevTotalCountInMonth() + punchInTotalCountInMonth);
+            piStatus.setPunchInTotalCountInMonth(Optional.ofNullable(piStatus.getRepeatPrevTotalCountInMonth()).orElse(0) + punchInTotalCountInMonth);
         }
 
         // 存在打卡记录则已打卡数加1
         if (Objects.nonNull(piTaskHistory)) {
-            piStatus.setPunchInCountInWeek(piStatus.getPunchInCountInWeek() + 1);
-            piStatus.setPunchInCountInMonth(piStatus.getPunchInCountInMonth() + 1);
+            piStatus.setPunchInCountInWeek(Optional.ofNullable(piStatus.getPunchInCountInWeek()).orElse(0) + 1);
+            piStatus.setPunchInCountInMonth(Optional.ofNullable(piStatus.getPunchInCountInMonth()).orElse(0) + 1);
         }
 
         // 完成打卡则完成打卡数记录加一
         if (PunchInResultEnum.DONE.equals(punchInResult)) {
-            piStatus.setPunchInDoneCountInWeek(piStatus.getPunchInDoneCountInWeek() + 1);
-            piStatus.setPunchInDoneCountInMonth(piStatus.getPunchInDoneCountInMonth() + 1);
+            piStatus.setPunchInDoneCountInWeek(Optional.ofNullable(piStatus.getPunchInDoneCountInWeek()).orElse(0) + 1);
+            piStatus.setPunchInDoneCountInMonth(Optional.ofNullable(piStatus.getPunchInDoneCountInMonth()).orElse(0) + 1);
         }
     }
 
@@ -534,4 +563,103 @@ public class SettleManagerImpl implements ISettleManager {
             piStatus.setStageStartDate(punchInDate);
         }
     }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void distributePoints(LocalDate settleDate) {
+        // 查询结算记录
+        SettleUserHistoryQuery settleUserHistoryQuery = new SettleUserHistoryQuery();
+        settleUserHistoryQuery.setSettleDate(settleDate.toString());
+        settleUserHistoryQuery.setDistributeStatus(PointsDistributeStatusEnum.NOT_DISTRIBUTE);
+        List<SettleUserHistory> settleUserHistories = settleUserHistoryService.querySettleUserHistory(settleUserHistoryQuery);
+
+        if (CollectionUtils.isEmpty(settleUserHistories)) {
+            log.info("========== 积分分发定时任务,没有可分发的积分 结束执行 ==========");
+            return;
+        }
+
+        // 用户ID-用户结算记录关联
+        Map<Long, SettleUserHistory> settleUserHistoryMap = settleUserHistories.stream().collect(Collectors.toMap(SettleUserHistory::getUserId, Function.identity(), (key1, key2) -> key1));
+        // 用户ID列表
+        Set<Long> userIds = settleUserHistories.stream().map(SettleUserHistory::getUserId).collect(Collectors.toSet());
+
+        // 用户信息, 用户ID-用户信息关联
+        List<User> users = userService.listByIds(userIds);
+        Map<Long, User> userMap = users.stream().collect(Collectors.toMap(User::getId, Function.identity(), (key1, key2) -> key1));
+
+        // 获取账户信息,用户ID-账户信息关联
+        AccountQuery accountQuery = new AccountQuery();
+        accountQuery.setAccountCategory(AccountCategoryEnum.BASIC);
+        accountQuery.setUserIds(userIds);
+        List<Account> accounts = accountService.getAccountByCondition(accountQuery);
+        Map<Long, Account> accountMap = accounts.stream().collect(Collectors.toMap(Account::getUserId, Function.identity(), (key1, key2) -> key1));
+
+        // 用户信息 更新列表
+        List<User> updateUserList = new ArrayList<>();
+        // 账户信息 更新列表
+        List<Account> updateAccountList = new ArrayList<>();
+        // 转账记录 新增列表
+        List<AccountTransferHistory> addAccountTransferHistories = new ArrayList<>();
+        // 结算用户信息 更新列表
+        List<SettleUserHistory> updateSettleUserHistories = new ArrayList<>();
+
+        for (Long userId : userIds) {
+            // 用户信息
+            User user = userMap.get(userId);
+            // 账户信息
+            Account account = accountMap.get(userId);
+            // 结算信息
+            SettleUserHistory oldSettleUserHistory = settleUserHistoryMap.get(userId);
+            // 结算积分
+            Integer settlePoints = Optional.ofNullable(oldSettleUserHistory.getSettlePoints()).orElse(0);
+
+            // 获取并设置用户信息
+            Integer beforeTotalPoints = Optional.ofNullable(user.getTotalPoints()).orElse(0);
+            Integer beforeUnusedPoints = Optional.ofNullable(user.getUnusedPoints()).orElse(0);
+            User updateUser = new User();
+            updateUser.setId(user.getId());
+            updateUser.setTotalPoints(beforeTotalPoints + settlePoints);
+            updateUser.setUnusedPoints(beforeUnusedPoints + settlePoints);
+            updateUserList.add(user);
+
+            // 更新账户信息
+            Integer beforeAccountPoints = Optional.ofNullable(account.getPoints()).orElse(0);
+            account.setPoints(beforeAccountPoints + settlePoints);
+            updateAccountList.add(account);
+
+            // 增加账户转账记录
+            AccountTransferHistory accountTransferHistory = new AccountTransferHistory();
+            accountTransferHistory.setUserId(userId);
+            accountTransferHistory.setTransferPoints(settlePoints);
+            accountTransferHistory.setTransferCategory(TransferCategoryEnum.SETTLE);
+            accountTransferHistory.setRecipientAccountId(account.getId());
+            accountTransferHistory.setRaPointsBeforeTransfer(beforeAccountPoints);
+            accountTransferHistory.setRaPointsAfterTransfer(account.getPoints());
+            addAccountTransferHistories.add(accountTransferHistory);
+
+            // 设置结算积分记录
+            SettleUserHistory updateSettleUserHistory = new SettleUserHistory();
+            updateSettleUserHistory.setId(oldSettleUserHistory.getId());
+            updateSettleUserHistory.setBeforeSettlePoints(beforeTotalPoints);
+            updateSettleUserHistory.setAfterSettlePoints(beforeTotalPoints + settlePoints);
+            updateSettleUserHistory.setDistributeStatus(PointsDistributeStatusEnum.DISTRIBUTE);
+            updateSettleUserHistories.add(updateSettleUserHistory);
+        }
+
+        if (!CollectionUtils.isEmpty(updateUserList)) {
+            userService.batchUpdate(updateUserList);
+        }
+
+        if (!CollectionUtils.isEmpty(updateAccountList)) {
+            accountService.batchUpdate(updateAccountList);
+        }
+
+        if (!CollectionUtils.isEmpty(addAccountTransferHistories)) {
+            accountTransferHistoryService.insertList(addAccountTransferHistories);
+        }
+
+        if (!CollectionUtils.isEmpty(updateSettleUserHistories)) {
+            settleUserHistoryService.batchUpdate(updateSettleUserHistories);
+        }
+    }
 }

+ 29 - 6
src/main/java/com/punchsettle/server/service/manager/impl/StatManagerImpl.java

@@ -13,6 +13,8 @@ import java.util.function.Function;
 import java.util.stream.Collectors;
 
 import com.punchsettle.server.atomic.entity.User;
+import com.punchsettle.server.atomic.service.IUserService;
+import com.punchsettle.server.common.utils.Assert;
 import com.punchsettle.server.constant.UserCategoryEnum;
 import com.punchsettle.server.service.manager.IUserManager;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -91,6 +93,9 @@ public class StatManagerImpl implements IStatManager {
     @Autowired
     private IUserManager userManager;
 
+    @Autowired
+    private IUserService userService;
+
     @Override
     @Cacheable(cacheNames = CacheNameConstant.STAT_POINTS_LINE, key = "T(com.punchsettle.server.utiis.UserUtils).getCurrentUserId()")
     public LineVO queryStatPointsLine() {
@@ -101,14 +106,14 @@ public class StatManagerImpl implements IStatManager {
 
         // 获取折线图时间范围
         List<LocalDate> dateRange = DateUtils.getDateRange(startDate, endDate);
-        String[] lineCategories = dateRange.stream().map(LocalDate::toString).toArray(String[]::new);
+        String[] lineCategories = dateRange.stream().map(v -> DateUtils.MM_DD_FORMATTER.format(v)).toArray(String[]::new);
 
         StatPointsQuery statPointsQuery = new StatPointsQuery();
         statPointsQuery.setUserId(currentUserId);
         statPointsQuery.setStatStartTime(startDate.toString());
         statPointsQuery.setStatEndTime(endDate.toString());
         List<StatPoints> statPointsList = statPointsService.queryByCondition(statPointsQuery);
-        Map<String, StatPoints> statPointsMap = statPointsList.stream().collect(Collectors.toMap(StatPoints::getStatTime, Function.identity(), (v1, v2) -> v1));
+        Map<String, StatPoints> statPointsMap = statPointsList.stream().collect(Collectors.toMap(v -> v.getStatTime().substring(5), Function.identity(), (v1, v2) -> v1));
 
         List<Integer> settlePointsList = new ArrayList<>(lineCategories.length);
         List<Integer> consumePointsList = new ArrayList<>(lineCategories.length);
@@ -157,13 +162,13 @@ public class StatManagerImpl implements IStatManager {
 
         // 获取折线图时间范围
         List<LocalDate> dateRange = DateUtils.getDateRange(startDate, endDate);
-        String[] lineCategories = dateRange.stream().map(LocalDate::toString).toArray(String[]::new);
+        String[] lineCategories = dateRange.stream().map(v -> DateUtils.MM_DD_FORMATTER.format(v)).toArray(String[]::new);
 
         StatNewUserQuery statNewUserQuery = new StatNewUserQuery();
         statNewUserQuery.setStatStartTime(startDate.toString());
         statNewUserQuery.setStatEndTime(endDate.toString());
         List<StatNewUser> statNewUserList = statNewUserService.queryByCondition(statNewUserQuery);
-        Map<String, Integer> statNewUserMap = statNewUserList.stream().collect(Collectors.toMap(StatNewUser::getStatTime, StatNewUser::getNewUserCount, (v1, v2) -> v1));
+        Map<String, Integer> statNewUserMap = statNewUserList.stream().collect(Collectors.toMap(v -> v.getStatTime().substring(5), StatNewUser::getNewUserCount, (v1, v2) -> v1));
 
         List<Integer> newUserCountList = new ArrayList<>(lineCategories.length);
         for (String lineCategory : lineCategories) {
@@ -191,14 +196,14 @@ public class StatManagerImpl implements IStatManager {
 
         // 获取折线图时间范围
         List<LocalDate> dateRange = DateUtils.getDateRange(startDate, endDate);
-        String[] lineCategories = dateRange.stream().map(LocalDate::toString).toArray(String[]::new);
+        String[] lineCategories = dateRange.stream().map(v -> DateUtils.MM_DD_FORMATTER.format(v)).toArray(String[]::new);
 
         PiTaskHistoryQuery piTaskHistoryQuery = new PiTaskHistoryQuery();
         piTaskHistoryQuery.setUserIds(Arrays.asList(currentUserId));
         piTaskHistoryQuery.setPunchInDateFrom(startDate.toString());
         piTaskHistoryQuery.setPunchInDateTo(endDate.toString());
         List<PiTaskHistory> piTaskHistoryList = piTaskHistoryService.queryByCondition(piTaskHistoryQuery);
-        Map<String, List<PiTaskHistory>> piTaskHistoryMap = piTaskHistoryList.stream().collect(Collectors.groupingBy(PiTaskHistory::getPunchInDate));
+        Map<String, List<PiTaskHistory>> piTaskHistoryMap = piTaskHistoryList.stream().collect(Collectors.groupingBy(v -> v.getPunchInDate().substring(5)));
 
         // 总任务数
         List<Integer> totalTaskCountList = new ArrayList<>(lineCategories.length);
@@ -346,4 +351,22 @@ public class StatManagerImpl implements IStatManager {
         return statPiTask;
     }
 
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void statNewUser(String statTime) {
+        Assert.isNullInBusiness(statTime, "统计日期不能为空");
+
+        // 构建查询的时间范围
+        String creationTimeFrom = String.format("%s 00:00:00.000", statTime);
+        String creationTimeTo = String.format("%s 23:59:59.999", statTime);
+
+        // 统计
+        int newUserCount = userService.countByCondition(creationTimeFrom, creationTimeTo);
+
+        // 数据入库
+        StatNewUser addStatNewUser = new StatNewUser();
+        addStatNewUser.setStatTime(statTime.toString());
+        addStatNewUser.setNewUserCount(newUserCount);
+        statNewUserService.insert(addStatNewUser);
+    }
 }

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

@@ -1,8 +1,10 @@
 package com.punchsettle.server.service.manager.impl;
 
+import java.math.BigDecimal;
 import java.util.Objects;
 
 import com.punchsettle.server.constant.UserCategoryEnum;
+import com.punchsettle.server.service.manager.IAccountManager;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.cache.CacheManager;
@@ -46,6 +48,9 @@ public class UserManagerImpl implements IUserManager {
     @Autowired
     private ITokenManager tokenManager;
 
+    @Autowired
+    private IAccountManager accountManager;
+
     @Override
     public String login(LoginRequest request) throws WxErrorException {
         // 微信登录
@@ -60,7 +65,13 @@ public class UserManagerImpl implements IUserManager {
             user.setOpenId(wxMaJscode2SessionResult.getOpenid());
             user.setNickname(request.getNickname());
             user.setUserCategory(UserCategoryEnum.NORMAL);
+            user.setUnusedPoints(0);
+            user.setTotalPoints(0);
+            user.setUsedPoints(0);
+            user.setTotalConsumeAmount(BigDecimal.ZERO);
+            user.setTotalWinAmount(BigDecimal.ZERO);
             userService.insert(user);
+            accountManager.createBasicAccount(user.getId());
         } else {
             User updateUser = new User();
             updateUser.setId(user.getId());

+ 0 - 149
src/main/java/com/punchsettle/server/task/PointsDistributeTask.java

@@ -1,149 +0,0 @@
-package com.punchsettle.server.task;
-
-import com.punchsettle.server.atomic.entity.Account;
-import com.punchsettle.server.atomic.entity.AccountTransferHistory;
-import com.punchsettle.server.atomic.entity.SettleUserHistory;
-import com.punchsettle.server.atomic.entity.User;
-import com.punchsettle.server.atomic.service.IAccountService;
-import com.punchsettle.server.atomic.service.IAccountTransferHistoryService;
-import com.punchsettle.server.atomic.service.ISettleUserHistoryService;
-import com.punchsettle.server.atomic.service.IUserService;
-import com.punchsettle.server.constant.AccountCategoryEnum;
-import com.punchsettle.server.constant.TransferCategoryEnum;
-import com.punchsettle.server.pojo.account.AccountQuery;
-import com.punchsettle.server.pojo.settle.SettleUserHistoryQuery;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-import org.springframework.util.CollectionUtils;
-
-import java.time.LocalDate;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-
-/**
- * @author tyuio
- * @version 1.0.0
- * @date 2025/5/6 19:31
- * @description 积分分发 定时任务
- */
-@Slf4j
-@Component
-public class PointsDistributeTask {
-
-    @Autowired
-    private ISettleUserHistoryService settleUserHistoryService;
-
-    @Autowired
-    private IUserService userService;
-
-    @Autowired
-    private IAccountService accountService;
-
-    @Autowired
-    private IAccountTransferHistoryService accountTransferHistoryService;
-
-    public void execute() {
-        log.info("========== 积分分发定时任务 开始执行 ==========");
-        // 结算日期
-        LocalDate settleDate = LocalDate.now().minusDays(1);
-
-        // 查询结算记录
-        SettleUserHistoryQuery settleUserHistoryQuery = new SettleUserHistoryQuery();
-        settleUserHistoryQuery.setSettleDate(settleDate.toString());
-        List<SettleUserHistory> settleUserHistories = settleUserHistoryService.querySettleUserHistory(settleUserHistoryQuery);
-
-        if (CollectionUtils.isEmpty(settleUserHistories)) {
-            log.info("========== 积分分发定时任务,没有可分发的积分 结束执行 ==========");
-            return;
-        }
-
-        // 用户ID-用户结算记录关联
-        Map<Long, SettleUserHistory> settleUserHistoryMap = settleUserHistories.stream().collect(Collectors.toMap(SettleUserHistory::getUserId, Function.identity(), (key1, key2) -> key1));
-        // 用户ID列表
-        Set<Long> userIds = settleUserHistories.stream().map(SettleUserHistory::getUserId).collect(Collectors.toSet());
-
-        // 用户信息, 用户ID-用户信息关联
-        List<User> users = userService.listByIds(userIds);
-        Map<Long, User> userMap = users.stream().collect(Collectors.toMap(User::getId, Function.identity(), (key1, key2) -> key1));
-
-        // 获取账户信息,用户ID-账户信息关联
-        AccountQuery accountQuery = new AccountQuery();
-        accountQuery.setAccountCategory(AccountCategoryEnum.BASIC);
-        accountQuery.setUserIds(userIds);
-        List<Account> accounts = accountService.getAccountByCondition(accountQuery);
-        Map<Long, Account> accountMap = accounts.stream().collect(Collectors.toMap(Account::getUserId, Function.identity(), (key1, key2) -> key1));
-
-        // 用户信息 更新列表
-        List<User> updateUserList = new ArrayList<>();
-        // 账户信息 更新列表
-        List<Account> updateAccountList = new ArrayList<>();
-        // 转账记录 新增列表
-        List<AccountTransferHistory> addAccountTransferHistories = new ArrayList<>();
-        // 结算用户信息 更新列表
-        List<SettleUserHistory> updateSettleUserHistories = new ArrayList<>();
-
-        for (Long userId : userIds) {
-            // 用户信息
-            User user = userMap.get(userId);
-            // 账户信息
-            Account account = accountMap.get(userId);
-            // 结算信息
-            SettleUserHistory settleUserHistory = settleUserHistoryMap.get(userId);
-            // 结算积分
-            Integer settlePoints = Optional.ofNullable(settleUserHistory.getSettlePoints()).orElse(0);
-
-            // 获取并设置用户信息
-            Integer beforeTotalPoints = Optional.ofNullable(user.getTotalPoints()).orElse(0);
-            Integer beforeUnusedPoints = Optional.ofNullable(user.getUnusedPoints()).orElse(0);
-            User updateUser = new User();
-            updateUser.setId(user.getId());
-            updateUser.setTotalPoints(beforeTotalPoints + settlePoints);
-            updateUser.setUnusedPoints(beforeUnusedPoints + settlePoints);
-            updateUserList.add(user);
-
-            // 更新账户信息
-            Integer beforeAccountPoints = Optional.ofNullable(account.getPoints()).orElse(0);
-            account.setPoints(beforeAccountPoints + settlePoints);
-            updateAccountList.add(account);
-
-            // 增加账户转账记录
-            AccountTransferHistory accountTransferHistory = new AccountTransferHistory();
-            accountTransferHistory.setTransferPoints(settlePoints);
-            accountTransferHistory.setTransferCategory(TransferCategoryEnum.SETTLE);
-            accountTransferHistory.setRecipientAccountId(account.getId());
-            accountTransferHistory.setRaPointsAfterTransfer(beforeAccountPoints);
-            accountTransferHistory.setRaPointsAfterTransfer(account.getPoints());
-            addAccountTransferHistories.add(accountTransferHistory);
-
-            // 设置结算积分记录
-            SettleUserHistory updateSettleUserHistory = new SettleUserHistory();
-            updateSettleUserHistory.setBeforeSettlePoints(beforeTotalPoints);
-            updateSettleUserHistory.setAfterSettlePoints(beforeTotalPoints + settlePoints);
-            updateSettleUserHistories.add(updateSettleUserHistory);
-        }
-
-        if (!CollectionUtils.isEmpty(updateUserList)) {
-            userService.batchUpdate(updateUserList);
-        }
-
-        if (!CollectionUtils.isEmpty(updateAccountList)) {
-            accountService.batchUpdate(updateAccountList);
-        }
-
-        if (!CollectionUtils.isEmpty(addAccountTransferHistories)) {
-            accountTransferHistoryService.insertList(addAccountTransferHistories);
-        }
-
-        if (!CollectionUtils.isEmpty(updateSettleUserHistories)) {
-            settleUserHistoryService.insertList(updateSettleUserHistories);
-        }
-
-        log.info("========== 积分分发定时任务 结束执行 ==========");
-    }
-}

+ 32 - 0
src/main/java/com/punchsettle/server/task/SettleDistributeTask.java

@@ -0,0 +1,32 @@
+package com.punchsettle.server.task;
+
+import com.punchsettle.server.service.manager.ISettleManager;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.time.LocalDate;
+
+/**
+ * @author tyuio
+ * @version 1.0.0
+ * @date 2025/5/6 19:31
+ * @description 结算后积分分发 定时任务
+ */
+@Slf4j
+@Component
+public class SettleDistributeTask {
+
+    @Autowired
+    private ISettleManager settleManager;
+
+    public void execute() {
+        log.info("========== 积分分发定时任务 开始执行 ==========");
+        // 结算日期
+        LocalDate settleDate = LocalDate.now().minusDays(1);
+        // 下发积分
+        settleManager.distributePoints(settleDate);
+
+        log.info("========== 积分分发定时任务 结束执行 ==========");
+    }
+}

+ 18 - 8
src/main/java/com/punchsettle/server/task/PointsSettleTask.java → src/main/java/com/punchsettle/server/task/SettlePointsTask.java

@@ -17,11 +17,11 @@ import java.util.List;
  * @author tyuio
  * @version 1.0.0
  * @date 2025/4/15 16:24
- * @description 结算定时任务
+ * @description 结算积分 定时任务
  */
 @Slf4j
 @Component
-public class PointsSettleTask {
+public class SettlePointsTask {
 
     @Autowired
     private IUserService userService;
@@ -44,9 +44,21 @@ public class PointsSettleTask {
         // 打卡日期
         LocalDate punchInDate = LocalDate.now().minusDays(1);
 
+        // 结算
+        settle(userIds, punchInDate.toString());
+
+        log.info("========== 打卡结算定时任务 结束执行 ==========");
+    }
+
+    /**
+     * 结算
+     * @param userIds 待结算的用户
+     * @param punchInDate 结算的打卡打卡日期
+     */
+    public void settle(List<Long> userIds, String punchInDate) {
         // 数据入库
         SettleTaskHistory addSettleTaskHistory = new SettleTaskHistory();
-        addSettleTaskHistory.setSettleDate(punchInDate.toString());
+        addSettleTaskHistory.setSettleDate(punchInDate);
         addSettleTaskHistory.setProcessedTotalNum(userIds.size());
         addSettleTaskHistory.setProcessedUnsettleNum(userIds.size());
         addSettleTaskHistory.setProcessedSettleNum(0);
@@ -63,11 +75,11 @@ public class PointsSettleTask {
         for (List<Long> tempUserIds : Lists.partition(userIds, batchNum)) {
             try {
                 // 结算
-                settleManager.settle(tempUserIds, punchInDate.toString(), addSettleTaskHistory.getId());
+                settleManager.settle(tempUserIds, punchInDate, addSettleTaskHistory.getId());
 
                 // 更新结算数量
-                unsettleNum -= batchNum;
-                settleNum += batchNum;
+                unsettleNum -= tempUserIds.size();
+                settleNum += tempUserIds.size();
 
                 // 更新数据记录
                 SettleTaskHistory updateSettleTaskHistory = new SettleTaskHistory();
@@ -79,7 +91,5 @@ public class PointsSettleTask {
                 log.error("结算异常", e);
             }
         }
-
-        log.info("========== 打卡结算定时任务 结束执行 ==========");
     }
 }

+ 7 - 21
src/main/java/com/punchsettle/server/task/StatNewUserTask.java

@@ -1,13 +1,13 @@
 package com.punchsettle.server.task;
 
-import com.punchsettle.server.atomic.entity.StatNewUser;
-import com.punchsettle.server.atomic.service.IStatNewUserService;
-import com.punchsettle.server.atomic.service.IUserService;
-import lombok.extern.slf4j.Slf4j;
+import java.time.LocalDate;
+
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
-import java.time.LocalDate;
+import com.punchsettle.server.service.manager.IStatManager;
+
+import lombok.extern.slf4j.Slf4j;
 
 /**
  * @author tyuio
@@ -20,27 +20,13 @@ import java.time.LocalDate;
 public class StatNewUserTask {
 
     @Autowired
-    private IStatNewUserService statNewUserService;
-
-    @Autowired
-    private IUserService userService;
+    private IStatManager statManager;
 
     public void execute() {
         log.info("========== 新用户数据统计定时任务 结束执行 ==========");
 
-        // 构建查询的时间范围
         LocalDate statTime = LocalDate.now().minusDays(1);
-        String creationTimeFrom = String.format("%s 00:00:00.000", statTime.toString());
-        String creationTimeTo = String.format("%s 23:59:59.999", statTime.toString());
-
-        // 统计
-        int newUserCount = userService.countByCondition(creationTimeFrom, creationTimeTo);
-
-        // 数据入库
-        StatNewUser addStatNewUser = new StatNewUser();
-        addStatNewUser.setStatTime(statTime.toString());
-        addStatNewUser.setNewUserCount(newUserCount);
-        statNewUserService.insert(addStatNewUser);
+        statManager.statNewUser(statTime.toString());
 
         log.info("========== 新用户数据统计定时任务 结束执行 ==========");
     }

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

@@ -33,6 +33,11 @@ public class DateUtils {
      */
     public static final DateTimeFormatter YYYY_MM_DD_FORMATTER = DateTimeFormatter.ofPattern(YYYY_MM_DD_FORMAT);
 
+    /**
+     * 日期格式(MM-dd)的格式化器
+     */
+    public static final DateTimeFormatter MM_DD_FORMATTER = DateTimeFormatter.ofPattern("MM-dd");
+
     /**
      * 创建完整的日期时间格式化器(yyyy-MM-dd HH:mm:ss)
      * @return

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

@@ -23,6 +23,6 @@ one-api:
 # 系统相关配置
 biz:
   # 折线图数据数量
-  lineItemCount: 30
+  lineItemCount: 15
   # Json Token过期时间,单位:天
   tokenExpire: 30

+ 9 - 5
src/test/java/com/punchsettle/server/service/manager/impl/PunchInManagerImplTest.java

@@ -41,23 +41,27 @@ class PunchInManagerImplTest {
     void judgeRepeat() {
         PiTask piTask1 = new PiTask();
         piTask1.setRepeatCategory(RepeatCategoryEnum.EVERYDAY);
-        Assertions.assertTrue(punchInManager.judgeRepeat(piTask1, "2025-04-23"));
+        Assertions.assertTrue(punchInManager.judgeRepeat(piTask1, LocalDate.parse("2025-04-23")));
 
         PiTask piTask2 = new PiTask();
         piTask2.setRepeatCategory(RepeatCategoryEnum.WORKDAY);
-        Assertions.assertTrue(punchInManager.judgeRepeat(piTask2, "2025-04-23"));
+        Assertions.assertTrue(punchInManager.judgeRepeat(piTask2, LocalDate.parse("2025-04-23")));
 
         PiTask piTask3 = new PiTask();
         piTask3.setRepeatCategory(RepeatCategoryEnum.WORKDAY);
-        Assertions.assertFalse(punchInManager.judgeRepeat(piTask3, "2025-04-26"));
+        Assertions.assertFalse(punchInManager.judgeRepeat(piTask3, LocalDate.parse("2025-04-26")));
 
         PiTask piTask4 = new PiTask();
         piTask4.setRepeatCategory(RepeatCategoryEnum.HOLIDAY);
-        Assertions.assertFalse(punchInManager.judgeRepeat(piTask4, "2025-04-23"));
+        Assertions.assertFalse(punchInManager.judgeRepeat(piTask4, LocalDate.parse("2025-04-23")));
 
         PiTask piTask5 = new PiTask();
         piTask5.setRepeatCategory(RepeatCategoryEnum.HOLIDAY);
-        Assertions.assertTrue(punchInManager.judgeRepeat(piTask5, "2025-04-26"));
+        Assertions.assertTrue(punchInManager.judgeRepeat(piTask5, LocalDate.parse("2025-04-26")));
+
+        PiTask piTask6 = new PiTask();
+        piTask6.setEndDate(LocalDate.parse("2025-04-25"));
+        Assertions.assertFalse(punchInManager.judgeRepeat(piTask6, LocalDate.parse("2025-04-26")));
     }
 
     @Test

+ 9 - 0
src/test/java/com/punchsettle/server/service/manager/impl/SettleManagerImplTest.java

@@ -302,6 +302,15 @@ class SettleManagerImplTest {
         Assertions.assertEquals(10, points2);
     }
 
+    /**
+     * 测试 没有打卡
+     */
+    @Test
+    void calculatePointsInTask9() {
+        int points1 = settleManager.calculatePointsInTask(null, null, null, null);
+        Assertions.assertEquals(0, points1);
+    }
+
     /**
      * 测试未完成打卡、未启用任务积分计算
      */