Browse Source

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

ChenYL 10 months ago
parent
commit
0bcb3a8d86
34 changed files with 534 additions and 319 deletions
  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);
+    }
+
     /**
      * 测试未完成打卡、未启用任务积分计算
      */