Pārlūkot izejas kodu

【feat】【v3】
1.增加积分统计定时任务
2.优化代码逻辑

ChenYL 10 mēneši atpakaļ
vecāks
revīzija
4000f8953b
21 mainītis faili ar 314 papildinājumiem un 60 dzēšanām
  1. 1 0
      doc/sql/update-v3.sql
  2. 0 1
      doc/技术文档.md
  3. 0 6
      src/main/java/com/punchsettle/server/atomic/entity/StatPoints.java
  4. 2 1
      src/main/java/com/punchsettle/server/atomic/mapper/StatPointsMapper.java
  5. 4 5
      src/main/java/com/punchsettle/server/atomic/service/IRewardExchangeHistoryService.java
  6. 6 0
      src/main/java/com/punchsettle/server/atomic/service/IStatPointsService.java
  7. 18 5
      src/main/java/com/punchsettle/server/atomic/service/impl/RewardExchangeHistoryServiceImpl.java
  8. 13 0
      src/main/java/com/punchsettle/server/atomic/service/impl/StatPointsServiceImpl.java
  9. 1 1
      src/main/java/com/punchsettle/server/constant/CacheNameConstant.java
  10. 30 0
      src/main/java/com/punchsettle/server/pojo/op/StatPointsRequest.java
  11. 35 0
      src/main/java/com/punchsettle/server/pojo/reward/RewardExchangeHistoryQuery.java
  12. 1 1
      src/main/java/com/punchsettle/server/pojo/settle/SettleUserHistoryVO.java
  13. 12 0
      src/main/java/com/punchsettle/server/pojo/stat/StatPointsQuery.java
  14. 9 0
      src/main/java/com/punchsettle/server/service/controller/OpController.java
  15. 3 3
      src/main/java/com/punchsettle/server/service/controller/SettleController.java
  16. 2 2
      src/main/java/com/punchsettle/server/service/manager/ISettleManager.java
  17. 7 0
      src/main/java/com/punchsettle/server/service/manager/IStatManager.java
  18. 14 1
      src/main/java/com/punchsettle/server/service/manager/impl/RewardManagerImpl.java
  19. 24 26
      src/main/java/com/punchsettle/server/service/manager/impl/SettleManagerImpl.java
  20. 83 8
      src/main/java/com/punchsettle/server/service/manager/impl/StatManagerImpl.java
  21. 49 0
      src/main/java/com/punchsettle/server/task/StatPointsTask.java

+ 1 - 0
doc/sql/update-v3.sql

@@ -799,3 +799,4 @@ ALTER TABLE punch_settle.pi_task ADD manual_archive_date date NULL COMMENT '手
 ALTER TABLE punch_settle.pi_task CHANGE manual_archive_date manual_archive_date date NULL COMMENT '手动归档日期' AFTER archive_status;
 ALTER TABLE punch_settle.pi_task CHANGE end_date auto_archive_date date NULL COMMENT '自动归档日期';
 ALTER TABLE punch_settle.pi_task MODIFY COLUMN auto_archive_date date NULL COMMENT '自动归档日期';
+ALTER TABLE punch_settle.stat_points DROP COLUMN total_points;

+ 0 - 1
doc/技术文档.md

@@ -1266,7 +1266,6 @@ ui设计工具:即时设计
 | stat_time        | char(10)  | 统计时间(格式:yyyy-MM-dd)       | 普通索引 |
 | settle_points    | int       | 每日积分的结算数                   |          |
 | consume_points   | int       | 每日积分的消耗数量                 |          |
-| total_points     | int       | 每日剩余总积分                     |          |
 | created_by       | bigint    | 创建人                             |          |
 | creation_time    | timestamp | 创建时间                           |          |
 | last_updated_by  | bigint    | 最后更新人                         |          |

+ 0 - 6
src/main/java/com/punchsettle/server/atomic/entity/StatPoints.java

@@ -47,10 +47,4 @@ public class StatPoints extends BaseEntity implements Serializable {
      */
     @Column(name = "consume_points")
     private Integer consumePoints;
-
-    /**
-     * 每日剩余总积分
-     */
-    @Column(name = "total_points")
-    private Integer totalPoints;
 }

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

@@ -2,6 +2,7 @@ package com.punchsettle.server.atomic.mapper;
 
 import com.punchsettle.server.atomic.entity.StatPoints;
 import tk.mybatis.mapper.common.Mapper;
+import tk.mybatis.mapper.common.special.InsertListMapper;
 
 /**
  * @author tyuio
@@ -9,5 +10,5 @@ import tk.mybatis.mapper.common.Mapper;
  * @description 积分数据统计 Mapper
  * @date 2025/04/08 10:30
  */
-public interface StatPointsMapper extends Mapper<StatPoints> {
+public interface StatPointsMapper extends Mapper<StatPoints>, InsertListMapper<StatPoints> {
 }

+ 4 - 5
src/main/java/com/punchsettle/server/atomic/service/IRewardExchangeHistoryService.java

@@ -1,6 +1,7 @@
 package com.punchsettle.server.atomic.service;
 
 import com.punchsettle.server.atomic.entity.RewardExchangeHistory;
+import com.punchsettle.server.pojo.reward.RewardExchangeHistoryQuery;
 
 import java.util.List;
 
@@ -17,14 +18,12 @@ public interface IRewardExchangeHistoryService {
      * @param rewardExchangeHistory
      */
     void insert(RewardExchangeHistory rewardExchangeHistory);
-
     /**
-     * 查询兑换记录
-     * @param userId 用户ID
-     * @param exchangeMonth 兑换月份
+     * 按条件查询
+     * @param query
      * @return
      */
-    List<RewardExchangeHistory> queryRewardExchangeHistory(Long userId, String exchangeMonth);
+    List<RewardExchangeHistory> queryByCondition(RewardExchangeHistoryQuery query);
 
     /**
      * 批量新增

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

@@ -19,4 +19,10 @@ public interface IStatPointsService {
      * @return
      */
     List<StatPoints> queryByCondition(StatPointsQuery query);
+
+    /**
+     * 批量新增
+     * @param statPointsList
+     */
+    void batchAdd(List<StatPoints> statPointsList);
 }

+ 18 - 5
src/main/java/com/punchsettle/server/atomic/service/impl/RewardExchangeHistoryServiceImpl.java

@@ -4,12 +4,16 @@ import com.punchsettle.server.atomic.entity.RewardExchangeHistory;
 import com.punchsettle.server.atomic.mapper.RewardExchangeHistoryMapper;
 import com.punchsettle.server.atomic.service.IRewardExchangeHistoryService;
 import com.punchsettle.server.common.utils.Assert;
+import com.punchsettle.server.pojo.reward.RewardExchangeHistoryQuery;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
 import tk.mybatis.mapper.weekend.Weekend;
 import tk.mybatis.mapper.weekend.WeekendCriteria;
 
 import java.util.List;
+import java.util.Objects;
 
 /**
  * @author tyuio
@@ -30,14 +34,23 @@ public class RewardExchangeHistoryServiceImpl implements IRewardExchangeHistoryS
     }
 
     @Override
-    public List<RewardExchangeHistory> queryRewardExchangeHistory(Long userId, String exchangeMonth) {
-        Assert.isNull(userId);
-        Assert.isNull(exchangeMonth);
+    public List<RewardExchangeHistory> queryByCondition(RewardExchangeHistoryQuery query) {
+        Assert.isNull(query);
 
         Weekend<RewardExchangeHistory> weekend = Weekend.of(RewardExchangeHistory.class);
         WeekendCriteria<RewardExchangeHistory, Object> criteria = weekend.weekendCriteria();
-        criteria.andEqualTo(RewardExchangeHistory::getUserId, userId);
-        criteria.andLike(RewardExchangeHistory::getCreationTime, String.format("%s%%", exchangeMonth));
+        if (Objects.nonNull(query.getUserId())) {
+            criteria.andEqualTo(RewardExchangeHistory::getUserId, query.getUserId());
+        }
+        if (!CollectionUtils.isEmpty(query.getUserIds())) {
+            criteria.andIn(RewardExchangeHistory::getUserId, query.getUserIds());
+        }
+        if (StringUtils.hasText(query.getExchangeTimeFrom())) {
+            criteria.andGreaterThanOrEqualTo(RewardExchangeHistory::getCreationTime, query.getExchangeTimeFrom());
+        }
+        if (StringUtils.hasText(query.getExchangeTimeTo())) {
+            criteria.andLessThanOrEqualTo(RewardExchangeHistory::getCreationTime, query.getExchangeTimeTo());
+        }
         return rewardExchangeHistoryMapper.selectByExample(weekend);
     }
 

+ 13 - 0
src/main/java/com/punchsettle/server/atomic/service/impl/StatPointsServiceImpl.java

@@ -8,6 +8,7 @@ import com.punchsettle.server.pojo.stat.StatPointsQuery;
 import com.punchsettle.server.utiis.WeekendUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
 import org.springframework.util.StringUtils;
 import tk.mybatis.mapper.weekend.Weekend;
 import tk.mybatis.mapper.weekend.WeekendCriteria;
@@ -42,6 +43,18 @@ public class StatPointsServiceImpl implements IStatPointsService {
         if (StringUtils.hasText(query.getStatEndTime())) {
             criteria.andLessThanOrEqualTo(StatPoints::getStatTime, query.getStatEndTime());
         }
+        if (!CollectionUtils.isEmpty(query.getUserIds())) {
+            criteria.andIn(StatPoints::getUserId, query.getUserIds());
+        }
+        if (StringUtils.hasText(query.getStatTime())) {
+            criteria.andEqualTo(StatPoints::getStatTime, query.getStatTime());
+        }
         return statPointsMapper.selectByExample(weekend);
     }
+
+    @Override
+    public void batchAdd(List<StatPoints> statPointsList) {
+        Assert.notEmpty(statPointsList);
+        statPointsMapper.insertList(statPointsList);
+    }
 }

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

@@ -46,7 +46,7 @@ public class CacheNameConstant {
     /**
      * 积分结算记录
      */
-    public static final String SETTLE_POINTS_HISTORY = "settlePointsHistory";
+    public static final String SETTLE_USER_HISTORY = "settlePointsHistory";
 
     /**
      * 奖励列表

+ 30 - 0
src/main/java/com/punchsettle/server/pojo/op/StatPointsRequest.java

@@ -0,0 +1,30 @@
+package com.punchsettle.server.pojo.op;
+
+import java.time.LocalDate;
+import java.util.List;
+
+import jakarta.validation.constraints.NotEmpty;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+/**
+ * @author tyuio
+ * @version 1.0.0
+ * @date 2025/5/8 20:04
+ * @description 积分统计 请求
+ */
+@Data
+public class StatPointsRequest {
+
+    /**
+     * 统计时间
+     */
+    @NotNull(message = "统计时间不能为空")
+    private LocalDate statTime;
+
+    /**
+     * 用户列表
+     */
+    @NotEmpty(message = "待统计用户不能为空")
+    private List<Long> userIds;
+}

+ 35 - 0
src/main/java/com/punchsettle/server/pojo/reward/RewardExchangeHistoryQuery.java

@@ -0,0 +1,35 @@
+package com.punchsettle.server.pojo.reward;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author tyuio
+ * @version 1.0.0
+ * @date 2025/5/8 19:33
+ * @description 奖励兑换记录 查询类
+ */
+@Data
+public class RewardExchangeHistoryQuery {
+
+    /**
+     * 用户ID
+     */
+    private Long userId;
+
+    /**
+     * 用户ID列表
+     */
+    private List<Long> userIds;
+
+    /**
+     * 兑换时间开始
+     */
+    private String exchangeTimeFrom;
+
+    /**
+     * 兑换时间(结束)
+     */
+    private String exchangeTimeTo;
+}

+ 1 - 1
src/main/java/com/punchsettle/server/pojo/settle/SettlePointsHistoryVO.java → src/main/java/com/punchsettle/server/pojo/settle/SettleUserHistoryVO.java

@@ -9,7 +9,7 @@ import lombok.Data;
  * @description 积分结算记录
  */
 @Data
-public class SettlePointsHistoryVO {
+public class SettleUserHistoryVO {
 
     /**
      * 结算日期

+ 12 - 0
src/main/java/com/punchsettle/server/pojo/stat/StatPointsQuery.java

@@ -2,6 +2,8 @@ package com.punchsettle.server.pojo.stat;
 
 import lombok.Data;
 
+import java.util.List;
+
 /**
  * @author myou
  * @version 1.0.0
@@ -25,4 +27,14 @@ public class StatPointsQuery {
      * 用户ID
      */
     private Long userId;
+
+    /**
+     * 用户ID列表
+     */
+    private List<Long> userIds;
+
+    /**
+     * 统计时间
+     */
+    private String statTime;
 }

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

@@ -2,6 +2,7 @@ package com.punchsettle.server.service.controller;
 
 import java.time.LocalDate;
 
+import com.punchsettle.server.pojo.op.StatPointsRequest;
 import com.punchsettle.server.task.StatPiTask;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
@@ -129,4 +130,12 @@ public class OpController {
     public void statTask() {
         SpringUtils.getBean(StatPiTask.class).execute();
     }
+
+    /**
+     * 统计积分
+     */
+    @PostMapping("statPoints")
+    public void statPoints(@RequestBody @Validated StatPointsRequest request) {
+        SpringUtils.getBean(IStatManager.class).statPoints(request.getUserIds(), request.getStatTime());
+    }
 }

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

@@ -9,7 +9,7 @@ import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
-import com.punchsettle.server.pojo.settle.SettlePointsHistoryVO;
+import com.punchsettle.server.pojo.settle.SettleUserHistoryVO;
 import com.punchsettle.server.service.manager.ISettleManager;
 
 import jakarta.validation.constraints.NotBlank;
@@ -34,7 +34,7 @@ public class SettleController {
      * @return
      */
     @GetMapping("/querySettlePointsHistory")
-    public List<SettlePointsHistoryVO> querySettlePointsHistory(@NotBlank(message = "结算月不能为空") String settleMonth) {
-    	return settleManager.querySettlePointsHistory(UserUtils.getCurrentUserId(), settleMonth);
+    public List<SettleUserHistoryVO> querySettlePointsHistory(@NotBlank(message = "结算月不能为空") String settleMonth) {
+    	return settleManager.querySettleUserHistory(UserUtils.getCurrentUserId(), settleMonth);
     }
 }

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

@@ -3,7 +3,7 @@ package com.punchsettle.server.service.manager;
 import java.time.LocalDate;
 import java.util.List;
 
-import com.punchsettle.server.pojo.settle.SettlePointsHistoryVO;
+import com.punchsettle.server.pojo.settle.SettleUserHistoryVO;
 
 /**
  * @author tyuio
@@ -19,7 +19,7 @@ public interface ISettleManager {
      * @param settleMonth 结算月
      * @return
      */
-    List<SettlePointsHistoryVO> querySettlePointsHistory(Long userId, String settleMonth);
+    List<SettleUserHistoryVO> querySettleUserHistory(Long userId, String settleMonth);
 
     /**
      * 结算

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

@@ -49,4 +49,11 @@ public interface IStatManager {
      * @param statTime
      */
     void statNewUser(String statTime);
+
+    /**
+     * 统计积分
+     * @param userIds
+     * @param statDate
+     */
+    void statPoints(List<Long> userIds, LocalDate statDate);
 }

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

@@ -1,6 +1,7 @@
 package com.punchsettle.server.service.manager.impl;
 
 import java.text.SimpleDateFormat;
+import java.time.LocalDate;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
@@ -32,6 +33,7 @@ import com.punchsettle.server.constant.CacheNameConstant;
 import com.punchsettle.server.constant.RewardExchangeMethodEnum;
 import com.punchsettle.server.constant.VersionStatusEnum;
 import com.punchsettle.server.pojo.account.AccountQuery;
+import com.punchsettle.server.pojo.reward.RewardExchangeHistoryQuery;
 import com.punchsettle.server.pojo.reward.RewardExchangeHistoryVO;
 import com.punchsettle.server.pojo.reward.RewardExchangeRequest;
 import com.punchsettle.server.pojo.reward.RewardQuery;
@@ -243,7 +245,18 @@ public class RewardManagerImpl implements IRewardManager {
     public List<RewardExchangeHistoryVO> queryRewardExchangeHistory(String exchangeMonth) {
         Assert.isNullInBusiness(exchangeMonth, "兑换月份不能为空");
 
-        List<RewardExchangeHistory> rewardExchangeHistories = rewardExchangeHistoryService.queryRewardExchangeHistory(UserUtils.getCurrentUserId(), exchangeMonth);
+        // 本月第一天
+        String firstDayOfMonth = String.format("%s-01 00:00.00.000", exchangeMonth);
+        // 本月最后一天
+        String[] split = exchangeMonth.split("-");
+        LocalDate tempFirstDayOfMonth = LocalDate.of(Integer.valueOf(split[0]), Integer.valueOf(split[1]), 1);
+        String lastDayOfMonth = String.format("%s-%s 23:59:59.000", exchangeMonth, tempFirstDayOfMonth.lengthOfMonth());
+
+        RewardExchangeHistoryQuery rewardExchangeHistoryQuery = new RewardExchangeHistoryQuery();
+        rewardExchangeHistoryQuery.setUserId(UserUtils.getCurrentUserId());
+        rewardExchangeHistoryQuery.setExchangeTimeFrom(firstDayOfMonth);
+        rewardExchangeHistoryQuery.setExchangeTimeTo(lastDayOfMonth);
+        List<RewardExchangeHistory> rewardExchangeHistories = rewardExchangeHistoryService.queryByCondition(rewardExchangeHistoryQuery);
         if (CollectionUtils.isEmpty(rewardExchangeHistories)) {
             return List.of();
         }

+ 24 - 26
src/main/java/com/punchsettle/server/service/manager/impl/SettleManagerImpl.java

@@ -3,6 +3,7 @@ package com.punchsettle.server.service.manager.impl;
 import java.time.DayOfWeek;
 import java.time.LocalDate;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -23,6 +24,8 @@ 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 com.punchsettle.server.service.manager.IAccountManager;
+import com.punchsettle.server.service.manager.ICacheManager;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.cache.annotation.Cacheable;
@@ -37,10 +40,6 @@ import com.punchsettle.server.atomic.entity.PiTaskExt;
 import com.punchsettle.server.atomic.entity.PiTaskHistory;
 import com.punchsettle.server.atomic.entity.SettleTaskRelaHistory;
 import com.punchsettle.server.atomic.entity.SettleUserHistory;
-import com.punchsettle.server.atomic.service.IPiMultiTaskExtService;
-import com.punchsettle.server.atomic.service.IPiMultiTaskHistoryService;
-import com.punchsettle.server.atomic.service.IPiMultiTaskRelaService;
-import com.punchsettle.server.atomic.service.IPiMultiTaskService;
 import com.punchsettle.server.atomic.service.IPiStatusService;
 import com.punchsettle.server.atomic.service.IPiTaskExtService;
 import com.punchsettle.server.atomic.service.IPiTaskHistoryService;
@@ -61,7 +60,7 @@ import com.punchsettle.server.pojo.punchIn.PiTaskExtQuery;
 import com.punchsettle.server.pojo.punchIn.PiTaskHistoryQuery;
 import com.punchsettle.server.pojo.punchIn.PiTaskQuery;
 import com.punchsettle.server.pojo.settle.SettleData;
-import com.punchsettle.server.pojo.settle.SettlePointsHistoryVO;
+import com.punchsettle.server.pojo.settle.SettleUserHistoryVO;
 import com.punchsettle.server.service.manager.IPunchInCoreManager;
 import com.punchsettle.server.service.manager.ISettleCoreManager;
 import com.punchsettle.server.service.manager.ISettleManager;
@@ -94,18 +93,6 @@ public class SettleManagerImpl implements ISettleManager {
     @Autowired
     private IPiStatusService piStatusService;
 
-    @Autowired
-    private IPiMultiTaskService piMultiTaskService;
-
-    @Autowired
-    private IPiMultiTaskExtService piMultiTaskExtService;
-
-    @Autowired
-    private IPiMultiTaskHistoryService piMultiTaskHistoryService;
-
-    @Autowired
-    private IPiMultiTaskRelaService piMultiTaskRelaService;
-
     @Autowired
     private IPunchInCoreManager punchInCoreManager;
 
@@ -124,24 +111,30 @@ public class SettleManagerImpl implements ISettleManager {
     @Autowired
     private IAccountTransferHistoryService accountTransferHistoryService;
 
+    @Autowired
+    private ICacheManager cacheManager;
+
+    @Autowired
+    private IAccountManager accountManager;
+
     @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) {
+    @Cacheable(cacheNames = CacheNameConstant.SETTLE_USER_HISTORY, key = "#userId+'_'+settleMonth", condition = "#userId != null && settleMont != null && !settleMonth.isBlank()")
+    public List<SettleUserHistoryVO> querySettleUserHistory(Long userId, String settleMonth) {
         Assert.isNullInBusiness(settleMonth, "结算月份不能为空");
         Assert.isNullInBusiness(userId, "用户ID不能为空");
 
         SettleUserHistoryQuery settleUserHistoryQuery = new SettleUserHistoryQuery();
         settleUserHistoryQuery.setUserId(userId);
         settleUserHistoryQuery.setSettleDateLike(settleMonth);
-        List<SettleUserHistory> settlePointsHistories = settleUserHistoryService.querySettleUserHistory(settleUserHistoryQuery);
-        if (CollectionUtils.isEmpty(settlePointsHistories)) {
+        List<SettleUserHistory> settleUserHistories = settleUserHistoryService.querySettleUserHistory(settleUserHistoryQuery);
+        if (CollectionUtils.isEmpty(settleUserHistories)) {
             return List.of();
         }
 
-        return settlePointsHistories.stream().map(settlePointsHistory -> {
-            SettlePointsHistoryVO settlePointsHistoryVO = new SettlePointsHistoryVO();
-            BeanUtils.copyProperties(settlePointsHistory, settlePointsHistoryVO);
-            return settlePointsHistoryVO;
+        return settleUserHistories.stream().map(settleUserHistory -> {
+            SettleUserHistoryVO settleUserHistoryVO = new SettleUserHistoryVO();
+            BeanUtils.copyProperties(settleUserHistory, settleUserHistoryVO);
+            return settleUserHistoryVO;
         }).collect(Collectors.toList());
     }
 
@@ -271,6 +264,8 @@ public class SettleManagerImpl implements ISettleManager {
         if (!CollectionUtils.isEmpty(addPiStatusList)) {
             piStatusService.batchUpdate(addPiStatusList);
         }
+
+        userIds.forEach(userId -> cacheManager.batchEvictLike(Arrays.asList(CacheNameConstant.SETTLE_USER_HISTORY), String.valueOf(userId)));
     }
 
     /**
@@ -688,6 +683,9 @@ public class SettleManagerImpl implements ISettleManager {
             settleUserHistoryService.batchUpdate(zeroSettleUserHistories);
         }
 
-        // TODO 差这里的缓存清理
+        userIds.forEach(userId -> {
+            cacheManager.batchEvict(Arrays.asList(CacheNameConstant.USER, CacheNameConstant.USER_VO), userId);
+            accountManager.clearCache(userId);
+        });
     }
 }

+ 83 - 8
src/main/java/com/punchsettle/server/service/manager/impl/StatManagerImpl.java

@@ -9,10 +9,19 @@ import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Optional;
+import java.util.Set;
 import java.util.function.Function;
 import java.util.stream.Collectors;
 
+import com.punchsettle.server.atomic.entity.RewardExchangeHistory;
+import com.punchsettle.server.atomic.entity.SettleUserHistory;
+import com.punchsettle.server.atomic.service.IRewardExchangeHistoryService;
+import com.punchsettle.server.atomic.service.ISettleUserHistoryService;
+import com.punchsettle.server.pojo.reward.RewardExchangeHistoryQuery;
+import com.punchsettle.server.pojo.settle.SettleUserHistoryQuery;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.Cache;
 import org.springframework.cache.CacheManager;
 import org.springframework.cache.annotation.Cacheable;
 import org.springframework.stereotype.Component;
@@ -62,6 +71,7 @@ import com.punchsettle.server.utiis.UserUtils;
  * @date 2025/5/3 9:32
  * @description 统计数据服务类
  */
+@Slf4j
 @Component
 public class StatManagerImpl implements IStatManager {
 
@@ -100,6 +110,12 @@ public class StatManagerImpl implements IStatManager {
     @Autowired
     private CacheManager cacheManager;
 
+    @Autowired
+    private ISettleUserHistoryService settleUserHistoryService;
+
+    @Autowired
+    private IRewardExchangeHistoryService rewardExchangeHistoryService;
+
     @Override
     @Cacheable(cacheNames = CacheNameConstant.STAT_POINTS_LINE, key = "T(com.punchsettle.server.utiis.UserUtils).getCurrentUserId()")
     public LineVO queryStatPointsLine() {
@@ -121,18 +137,15 @@ public class StatManagerImpl implements IStatManager {
 
         List<Integer> settlePointsList = new ArrayList<>(lineCategories.length);
         List<Integer> consumePointsList = new ArrayList<>(lineCategories.length);
-        List<Integer> totalPointsList = new ArrayList<>(lineCategories.length);
         for (String lineCategory : lineCategories) {
             StatPoints statPoints = statPointsMap.get(lineCategory);
             if (Objects.isNull(statPoints)) {
                 settlePointsList.add(null);
                 consumePointsList.add(null);
-                totalPointsList.add(null);
                 continue;
             }
             settlePointsList.add(statPoints.getSettlePoints());
             consumePointsList.add(statPoints.getConsumePoints());
-            totalPointsList.add(statPoints.getTotalPoints());
         }
 
         LineSeriesVO settlePointsLineSeriesVO = new LineSeriesVO();
@@ -143,13 +156,9 @@ public class StatManagerImpl implements IStatManager {
         consumePointsLineSeriesVO.setName("消耗积分");
         consumePointsLineSeriesVO.setData(consumePointsList.toArray(Integer[]::new));
 
-        LineSeriesVO totalPointsLineSeriesVO = new LineSeriesVO();
-        totalPointsLineSeriesVO.setName("总积分");
-        totalPointsLineSeriesVO.setData(totalPointsList.toArray(Integer[]::new));
-
         LineVO lineVO = new LineVO();
         lineVO.setCategories(lineCategories);
-        lineVO.setSeries(Arrays.asList(settlePointsLineSeriesVO, consumePointsLineSeriesVO, totalPointsLineSeriesVO));
+        lineVO.setSeries(Arrays.asList(settlePointsLineSeriesVO, consumePointsLineSeriesVO));
         return lineVO;
     }
 
@@ -384,4 +393,70 @@ public class StatManagerImpl implements IStatManager {
 
         cacheManager.getCache(CacheNameConstant.STAT_NEW_USER_LINE).clear();
     }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void statPoints(List<Long> userIds, LocalDate statDate) {
+        // 校验是否重复统计
+        StatPointsQuery statPointsQuery = new StatPointsQuery();
+        statPointsQuery.setUserIds(userIds);
+        statPointsQuery.setStatTime(statDate.toString());
+        List<StatPoints> oldStatPoints = statPointsService.queryByCondition(statPointsQuery);
+        // 已统计用户列表
+        Set<Long> statUserIds = oldStatPoints.stream().map(StatPoints::getUserId).collect(Collectors.toSet());
+        // 过滤已统计数据
+        userIds = userIds.stream().filter(userId -> !statUserIds.contains(userId)).toList();
+
+        if (CollectionUtils.isEmpty(userIds)) {
+            log.info("========== 积分数据统计定时任务,没有需要统计的用户 结束执行 ==========");
+            return;
+        }
+
+        // 兑换开始时间
+        String exchangeTimeFrom = String.format("%s 00:00:00.000", statDate);
+        // 兑换结束时间
+        String exchangeTimeTo = String.format("%s 23:59:59.999", statDate);
+
+        // 查询结算数据
+        SettleUserHistoryQuery settleUserHistoryQuery = new SettleUserHistoryQuery();
+        settleUserHistoryQuery.setSettleDate(statDate.toString());
+        settleUserHistoryQuery.setUserIds(userIds);
+        settleUserHistoryQuery.setSettleResults(Arrays.asList(SettleResultEnum.SETTLE, SettleResultEnum.NO_SETTLED));
+        List<SettleUserHistory> settleUserHistories = settleUserHistoryService.querySettleUserHistory(settleUserHistoryQuery);
+        // 用户ID-结算数据 关联
+        Map<Long, SettleUserHistory> settleUserHistoryMap = settleUserHistories.stream().collect(Collectors.toMap(SettleUserHistory::getUserId, Function.identity(), (key1, key2) -> key1));
+
+        // 查询消费记录
+        RewardExchangeHistoryQuery rewardExchangeHistoryQuery = new RewardExchangeHistoryQuery();
+        rewardExchangeHistoryQuery.setUserIds(userIds);
+        rewardExchangeHistoryQuery.setExchangeTimeFrom(exchangeTimeFrom);
+        rewardExchangeHistoryQuery.setExchangeTimeTo(exchangeTimeTo);
+        List<RewardExchangeHistory> rewardExchangeHistories = rewardExchangeHistoryService.queryByCondition(rewardExchangeHistoryQuery);
+        // 用户ID - 兑换列表
+        Map<Long, List<RewardExchangeHistory>> rewardExchangeHistoryMap = rewardExchangeHistories.stream().collect(Collectors.groupingBy(RewardExchangeHistory::getUserId));
+
+        List<StatPoints> addStatPointsList = userIds.stream().map(userId -> {
+            // 结算数据
+            SettleUserHistory settleUserHistory = settleUserHistoryMap.get(userId);
+            // 兑换列表
+            List<RewardExchangeHistory> rewardExchangeHistoryList = rewardExchangeHistoryMap.get(userId);
+            // 消耗总积分
+            int consumePoints = rewardExchangeHistoryList.stream()
+                    .mapToInt(rewardExchangeHistory -> Optional.ofNullable(rewardExchangeHistory.getExchangeTotalPoints()).orElse(0))
+                    .sum();
+
+            StatPoints addStatPoints = new StatPoints();
+            addStatPoints.setUserId(userId);
+            addStatPoints.setStatTime(statDate.toString());
+            addStatPoints.setSettlePoints(Objects.isNull(settleUserHistory) ? 0 : Optional.ofNullable(settleUserHistory.getSettlePoints()).orElse(0));
+            addStatPoints.setConsumePoints(consumePoints);
+            return addStatPoints;
+        }).toList();
+
+        statPointsService.batchAdd(addStatPointsList);
+
+        // 清除缓存
+        Cache cache = cacheManager.getCache(CacheNameConstant.STAT_POINTS_LINE);
+        userIds.forEach(userId -> cache.evict(userId));
+    }
 }

+ 49 - 0
src/main/java/com/punchsettle/server/task/StatPointsTask.java

@@ -0,0 +1,49 @@
+package com.punchsettle.server.task;
+
+import java.time.LocalDate;
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+import com.punchsettle.server.atomic.service.IUserService;
+import com.punchsettle.server.service.manager.IStatManager;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * @author tyuio
+ * @version 1.0.0
+ * @date 2025/5/8 19:18
+ * @description 积分数据统计 任务
+ */
+@Slf4j
+@Component
+public class StatPointsTask {
+
+    @Autowired
+    private IUserService userService;
+
+    @Autowired
+    private IStatManager statManager;
+
+    public void execute() {
+        log.info("========== 积分数据统计定时任务 开始执行 ==========");
+
+        List<Long> userIds = userService.listId();
+        if (CollectionUtils.isEmpty(userIds)) {
+            log.info("========== 积分数据统计定时任务,没有待统计的用户 结束执行 ==========");
+        }
+
+        // 结算日期
+        LocalDate settleDate = LocalDate.now().minusDays(1);
+
+        // 统计
+        statManager.statPoints(userIds, settleDate);
+
+        log.info("========== 积分数据统计定时任务 结束执行 ==========");
+    }
+
+
+}