package com.punchsettle.server.service.manager.impl; import java.time.DayOfWeek; import java.time.LocalDate; import java.util.ArrayList; import java.util.HashMap; 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.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; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import com.punchsettle.server.atomic.ContinueTask; import com.punchsettle.server.atomic.entity.PiMultiTask; import com.punchsettle.server.atomic.entity.PiMultiTaskExt; import com.punchsettle.server.atomic.entity.PiMultiTaskHistory; import com.punchsettle.server.atomic.entity.PiMultiTaskRela; import com.punchsettle.server.atomic.entity.PiStatus; import com.punchsettle.server.atomic.entity.PiTask; 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; import com.punchsettle.server.atomic.service.IPiTaskService; import com.punchsettle.server.atomic.service.ISettleUserHistoryService; import com.punchsettle.server.atomic.service.ISettleTaskRelaHistoryService; import com.punchsettle.server.common.utils.Assert; import com.punchsettle.server.constant.ArchiveStatusEnum; import com.punchsettle.server.constant.CacheNameConstant; import com.punchsettle.server.constant.ContinueStageEnum; import com.punchsettle.server.constant.ContinueStatusEnum; import com.punchsettle.server.constant.PunchInResultEnum; import com.punchsettle.server.constant.SettleResultEnum; import com.punchsettle.server.constant.VersionStatusEnum; import com.punchsettle.server.pojo.punchIn.PiMultiTaskExtQuery; import com.punchsettle.server.pojo.punchIn.PiMultiTaskHistoryQuery; import com.punchsettle.server.pojo.punchIn.PiMultiTaskQuery; import com.punchsettle.server.pojo.punchIn.PiStatusQuery; import com.punchsettle.server.pojo.punchIn.PiTaskData; 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.service.manager.IPunchInCoreManager; import com.punchsettle.server.service.manager.ISettleCoreManager; import com.punchsettle.server.service.manager.ISettleManager; import com.punchsettle.server.utiis.DateUtils; import lombok.extern.slf4j.Slf4j; /** * @author tyuio * @version 1.0.0 * @description 结算服务类 * @date 2024/12/12 22:29 */ @Slf4j @Service public class SettleManagerImpl implements ISettleManager { @Autowired private ISettleUserHistoryService settleUserHistoryService; @Autowired private IPiTaskService piTaskService; @Autowired private IPiTaskExtService piTaskExtService; @Autowired private IPiTaskHistoryService piTaskHistoryService; @Autowired private IPiStatusService piStatusService; @Autowired private IPiMultiTaskService piMultiTaskService; @Autowired private IPiMultiTaskExtService piMultiTaskExtService; @Autowired private IPiMultiTaskHistoryService piMultiTaskHistoryService; @Autowired private IPiMultiTaskRelaService piMultiTaskRelaService; @Autowired private IPunchInCoreManager punchInCoreManager; @Autowired private ISettleCoreManager settleCoreManager; @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 querySettlePointsHistory(Long userId, String settleMonth) { Assert.isNullInBusiness(settleMonth, "结算月份不能为空"); Assert.isNullInBusiness(userId, "用户ID不能为空"); SettleUserHistoryQuery settleUserHistoryQuery = new SettleUserHistoryQuery(); settleUserHistoryQuery.setUserId(userId); settleUserHistoryQuery.setSettleDateLike(settleMonth); List settlePointsHistories = settleUserHistoryService.querySettleUserHistory(settleUserHistoryQuery); if (CollectionUtils.isEmpty(settlePointsHistories)) { return List.of(); } return settlePointsHistories.stream().map(settlePointsHistory -> { SettlePointsHistoryVO settlePointsHistoryVO = new SettlePointsHistoryVO(); BeanUtils.copyProperties(settlePointsHistory, settlePointsHistoryVO); return settlePointsHistoryVO; }).collect(Collectors.toList()); } @Override @Transactional(rollbackFor = Exception.class) public void settle(List userIds, String punchInDateStr, Long settleTaskHistoryId) { // 打卡日期 LocalDate punchInDate = LocalDate.parse(punchInDateStr); // 是否周一 boolean isMonday = DayOfWeek.MONDAY.equals(punchInDate.getDayOfWeek()); // 是否打卡所在月第一天 boolean isFirstDayOfMonth = punchInDate.getDayOfMonth() == 1; // 周期数 String yearWeek = DateUtils.getYearWeek(punchInDate); // 月份数 String yearMonth = DateUtils.getYearMonth(punchInDate); // 打卡状态 更新列表 List addPiStatusList = new ArrayList<>(); // 新增结算用户记录 List addSettleUserHistories = new ArrayList<>(); // 用户ID-结算任务关联记录 Map> settleTaskRelaHistoryMap = new HashMap<>(); // 获取结算数据 List settleDataList = getSettleData(userIds, punchInDateStr); for (SettleData settleData : settleDataList) { // 新增结算用户记录 SettleUserHistory addSettleUserHistory = new SettleUserHistory(); 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); // 不存在打卡任务则跳过 if (CollectionUtils.isEmpty(settleData.getPiTaskDataList())) { addSettleUserHistory.setSettlePoints(0); continue; } // 总结算积分 int totalSettlePoints = 0; // 新增结算任务关联记录 List addSettleTaskRelaHistories = new ArrayList<>(); settleTaskRelaHistoryMap.put(settleData.getUserId(), addSettleTaskRelaHistories); // 单任务处理 for (PiTaskData piTaskData : settleData.getPiTaskDataList()) { // 打卡任务 PiTask piTask = piTaskData.getPiTask(); // 结算任务关联记录 SettleTaskRelaHistory addSettleTaskRelaHistory = new SettleTaskRelaHistory(); addSettleTaskRelaHistory.setSettleTaskHistoryId(settleTaskHistoryId); addSettleTaskRelaHistory.setUserId(settleData.getUserId()); addSettleTaskRelaHistory.setSettleDate(punchInDateStr); addSettleTaskRelaHistory.setPiTaskId(piTask.getId()); addSettleTaskRelaHistory.setPiTaskUniqueId(piTask.getUniqueId()); // 有打卡任务,但是今天无需结算 boolean repeatResult = punchInCoreManager.judgeRepeat(piTask, punchInDate); if (!repeatResult) { addSettleTaskRelaHistory.setSettleResult(SettleResultEnum.NOT_SETTLED); addSettleTaskRelaHistory.setSettlePoints(0); addSettleTaskRelaHistories.add(addSettleTaskRelaHistory); continue; } // 打卡任务打卡记录 PiTaskHistory piTaskHistory = piTaskData.getPiTaskHistory(); // 打卡任务状态 PiStatus oldPiStatus = piTaskData.getPiStatus(); // 打卡任务拖扎信息 List piTaskExtList = piTaskData.getPiTaskExtList(); // 复制昨天的打卡记录 PiStatus piStatus = new PiStatus(); BeanUtils.copyProperties(oldPiStatus, piStatus); piStatus.setStatusDate(punchInDateStr); addPiStatusList.add(piStatus); // 更新打卡状态 refreshPiStatus(oldPiStatus, piTask, piTaskHistory, punchInDate, isMonday, isFirstDayOfMonth, yearWeek, yearMonth); // 计算积分,要先刷新打卡状态 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); } // TODO 未处理多任务结算 // 设置总结算积分 addSettleUserHistory.setSettlePoints(totalSettlePoints); } // 数据入库 if (!CollectionUtils.isEmpty(addSettleUserHistories)) { settleUserHistoryService.insertList(addSettleUserHistories); // 处理关联数据 List addSettleTaskRelaHistories = addSettleUserHistories.stream().map(settleUserHistory -> { List settleTaskRelaHistories = settleTaskRelaHistoryMap.get(settleUserHistory.getUserId()); if (!CollectionUtils.isEmpty(settleTaskRelaHistories)) { settleTaskRelaHistories.stream().forEach(v -> v.setSettleUserHistoryId(settleUserHistory.getId())); } return settleTaskRelaHistories; }).flatMap(List::stream) // 将每个List中的元素展平 .collect(Collectors.toList()); if (!CollectionUtils.isEmpty(addSettleTaskRelaHistories)) { settleTaskRelaHistoryService.insertList(addSettleTaskRelaHistories); } } if (!CollectionUtils.isEmpty(addPiStatusList)) { piStatusService.batchUpdate(addPiStatusList); } } /** * 获取用户ID-打卡结算数据关联 * * @param userIds 设计的用户 * @param punchInDateStr 打卡日期 * @return */ private List getSettleData(List userIds, String punchInDateStr) { // 获取多任务信息,用户ID-多任务关联 PiMultiTaskQuery piMultiTaskQuery = new PiMultiTaskQuery(); piMultiTaskQuery.setMultiTaskTaskStatus(VersionStatusEnum.ACTIVE); piMultiTaskQuery.setUserIds(userIds); List piMultiTasks = piMultiTaskService.queryByCondition(piMultiTaskQuery); Map piMultiTaskMap = piMultiTasks.stream() .collect(Collectors.toMap(PiMultiTask::getUserId, Function.identity(), (key1, key2) -> key1)); // 多任务ID Set multiTaskIds = piMultiTasks.stream().map(PiMultiTask::getId).collect(Collectors.toSet()); // 多任务唯一ID Set multiTaskUniqueIds = piMultiTasks.stream().map(PiMultiTask::getUniqueId).collect(Collectors.toSet()); // 获取多任务拓展信息,多任务ID-多任务拓展关联 PiMultiTaskExtQuery piMultiTaskExtQuery = new PiMultiTaskExtQuery(); piMultiTaskExtQuery.setMultiTaskIds(multiTaskIds); List piMultiTaskExtList = piMultiTaskExtService.queryByCondition(piMultiTaskExtQuery); Map> piMultiTaskExtMap = piMultiTaskExtList.stream().collect(Collectors.groupingBy(PiMultiTaskExt::getMultiTaskId)); // 获取多任务打卡历史信息,多任务唯一ID-多任务打卡历史关联 PiMultiTaskHistoryQuery piMultiTaskHistoryQuery = new PiMultiTaskHistoryQuery(); piMultiTaskHistoryQuery.setPunchInMultiTaskUniqueIds(multiTaskUniqueIds); piMultiTaskHistoryQuery.setPunchInDate(punchInDateStr); List piMultiTaskHistories = piMultiTaskHistoryService.queryByCondition(piMultiTaskHistoryQuery); Map piMultiTaskHistoryMap = piMultiTaskHistories.stream().collect( Collectors.toMap(PiMultiTaskHistory::getMultiTaskUniqueId, Function.identity(), (key1, key2) -> key1)); // 打卡任务状态 PiStatusQuery piStatusQuery = new PiStatusQuery(); piStatusQuery.setUserIds(userIds); List piStatusList = piStatusService.queryByCondition(piStatusQuery); // 打卡任务状态,多任务唯一ID-打卡状态关联 Map piStatusMapInMultiTask = piStatusList.stream().filter(v -> Objects.nonNull(v.getMultiTaskUniqueId())).collect(Collectors.toMap(PiStatus::getMultiTaskUniqueId, Function.identity(), (key1, key2) -> key1)); // 打卡任务状态,任务唯一ID-打卡状态关联 Map piStatusMapInTask = piStatusList.stream().filter(v -> Objects.nonNull(v.getTaskUniqueId())).collect(Collectors.toMap(PiStatus::getTaskUniqueId, Function.identity(), (key1, key2) -> key1)); // 多任务关联打卡任务,多任务ID-多任务关联打卡任务关联 List piMultiTaskRelaList = piMultiTaskRelaService.queryByMultiTaskId(multiTaskIds); Map> piMultiTaskRelaMap = piMultiTaskRelaList.stream().collect(Collectors.groupingBy(PiMultiTaskRela::getMultiTaskId)); // 获取打卡任务信息,打卡任务唯一ID-打卡任务关联 PiTaskQuery piTaskQuery = new PiTaskQuery(); piTaskQuery.setTaskStatus(VersionStatusEnum.ACTIVE); piTaskQuery.setArchiveStatus(ArchiveStatusEnum.ACTIVE); piTaskQuery.setUserIds(userIds); List piTasks = piTaskService.queryByCondition(piTaskQuery); Map> piTaskMap = piTasks.stream().collect(Collectors.groupingBy(PiTask::getCreatedBy)); // 获取打卡记录,任务唯一 ID-打卡记录关联 PiTaskHistoryQuery piTaskHistoryQuery = new PiTaskHistoryQuery(); piTaskHistoryQuery.setPunchInDate(punchInDateStr); piTaskHistoryQuery.setUserIds(userIds); List punchInTaskHistories = piTaskHistoryService.queryByCondition(piTaskHistoryQuery); Map piTaskHistoryMap = punchInTaskHistories.stream().collect(Collectors.toMap(PiTaskHistory::getTaskUniqueId, Function.identity(), (key1, key2) -> key1)); // 打卡任务ID Set punchInTaskIds = piTasks.stream().map(PiTask::getId).collect(Collectors.toSet()); // 获取打卡任务拓展表,打卡任务ID-打卡任务拓展关联 PiTaskExtQuery piTaskExtQuery = new PiTaskExtQuery(); piTaskExtQuery.setPunchInTaskIds(punchInTaskIds); List piTaskExtList = piTaskExtService.queryByCondition(piTaskExtQuery); Map> piTaskExtGroupList = piTaskExtList.stream().collect(Collectors.groupingBy(PiTaskExt::getTaskId)); 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 tempPiMultiTaskExtList = piMultiTaskExtMap.get(piMultiTask.getId()); // settleData.setPiMultiTaskExtList(tempPiMultiTaskExtList); // 获取并设置对应的多任务打卡记录 // PiMultiTaskHistory piMultiTaskHistory = piMultiTaskHistoryMap.get(piMultiTask.getUniqueId()); // settleData.setPiMultiTaskHistory(piMultiTaskHistory); // // // 获取多任务与打卡任务的关联信息 // List tempPiMultiTaskRelaList = piMultiTaskRelaMap.get(piMultiTask.getId()); // Set relaContainTaskIdList = // tempPiMultiTaskRelaList.stream().map(PiMultiTaskRela::getTaskId).collect(Collectors.toSet()); // // // 获取并设置多任务的状态信息 // PiStatus piStatusInMultiTask = piStatusMapInMultiTask.get(piMultiTask.getUniqueId()); // settleData.setPiStatus(piStatusInMultiTask); // 获取任务列表 List piTasksList = piTaskMap.get(userId); // 打卡任务数据 List piTaskDataList = new ArrayList<>(piTasksList.size()); // 关联的打卡任务记录 // List relaPunchInTaskHistories = new ArrayList<>(relaContainTaskIdList.size()); for (PiTask piTask : piTasksList) { PiTaskData piTaskData = new PiTaskData(); piTaskData.setPiTask(piTask); // 获取并设置打卡任务 PiTaskHistory piTaskHistory = piTaskHistoryMap.get(piTask.getUniqueId()); piTaskData.setPiTaskHistory(piTaskHistory); //设置多任务与打卡记录的关联信息 // if (relaContainTaskIdList.contains(piTask.getId())) { // relaPunchInTaskHistories.add(piTaskHistory); // } // 获取并设置拓展信息 List tempPiTaskExtList = piTaskExtGroupList.get(piTask.getId()); piTaskData.setPiTaskExtList(tempPiTaskExtList); // 获取并设置任务状态 PiStatus piStatusInTask = piStatusMapInTask.get(piTask.getUniqueId()); piTaskData.setPiStatus(piStatusInTask); piTaskDataList.add(piTaskData); } settleData.setPiTaskDataList(piTaskDataList); // settleData.setRelaPunchInTaskHistories(relaPunchInTaskHistories); return settleData; }).collect(Collectors.toList()); } /** * 更新打卡任务状态 * @param piStatus 打卡任务状态 * @param piTask 打卡任务 * @param piTaskHistory 打卡任务记录 * @param punchInDate 打卡日期 * @param isMonday 是否周一 * @param isFirstDayOfMonth 是否本月第一天 * @param yearWeek 周数 * @param yearMonth 月份数 */ private void refreshPiStatus(PiStatus piStatus, PiTask piTask, PiTaskHistory piTaskHistory, LocalDate punchInDate, boolean isMonday, boolean isFirstDayOfMonth, String yearWeek, String yearMonth) { // 获取打卡结果 PunchInResultEnum punchInResult = Objects.isNull(piTaskHistory) ? PunchInResultEnum.UNDONE : piTaskHistory.getPunchInResult(); // 刷新打卡状态中的连续任务数据 refreshContinueData(piStatus, punchInResult, piTask, punchInDate); // 周一或月初 if (isMonday || isFirstDayOfMonth) { piStatus.setRepeatCategory(piTask.getRepeatCategory()); piStatus.setRepeatCustomDay(piTask.getRepeatCustomDay()); } // 周一 if (isMonday) { piStatus.setStatTimeInWeek(yearWeek); // 设置本周总打卡次数 int PunchInTotalCountInWeek = punchInCoreManager.getPunchInTotalCountInRange(piTask.getRepeatCategory(), piTask.getRepeatCustomDay(), DateUtils.getFirstDayOfWeek(punchInDate), DateUtils.getLastDayOfWeek(punchInDate)); piStatus.setPunchInTotalCountInWeek(PunchInTotalCountInWeek); // 重置数据 piStatus.setPunchInCountInWeek(0); piStatus.setPunchInDoneCountInWeek(0); piStatus.setRepeatPrevTotalCountInWeek(0); piStatus.setRepeatStartDateInWeek(punchInDate); } // 打卡日所在月的第一天 if (isFirstDayOfMonth) { piStatus.setStatTimeInMonth(yearMonth); // 设置本月总打卡次数 int PunchInTotalCountInMonth = punchInCoreManager.getPunchInTotalCountInRange(piTask.getRepeatCategory(), piTask.getRepeatCustomDay(), DateUtils.getFirstDayOfMonth(punchInDate), DateUtils.getLastDayOfMonth(punchInDate)); piStatus.setPunchInTotalCountInMonth(PunchInTotalCountInMonth); // 重置数据 piStatus.setPunchInCountInMonth(0); piStatus.setPunchInDoneCountInMonth(0); piStatus.setRepeatPrevTotalCountInMonth(0); piStatus.setRepeatStartDateInMonth(punchInDate); } // 重复类型发生变换,总打卡次数=历史真实发生的总打卡次数+变换前发生的总打卡次数+变换后可能的总打卡次数 if (!piStatus.getRepeatCategory().equals(piTask.getRepeatCategory())) { // 历史真实发生的总打卡次数(周) Integer oldPrevTotalCountInWeek = Optional.ofNullable(piStatus.getRepeatPrevTotalCountInWeek()).orElse(0); // 变换前发生的总打卡次数(周) int prevTotalCountInWeek = punchInCoreManager.getPunchInTotalCountInRange(piStatus.getRepeatCategory(), piStatus.getRepeatCustomDay(), piStatus.getRepeatStartDateInWeek(), punchInDate.minusDays(1)); // 变换后可能的总打卡次数(周) int punchInTotalCountInWeek = punchInCoreManager.getPunchInTotalCountInRange(piTask.getRepeatCategory(), piTask.getRepeatCustomDay(), punchInDate, DateUtils.getLastDayOfWeek(punchInDate)); // 历史真实发生的总打卡次数(月) Integer oldPrevTotalCountInMonth = Optional.ofNullable(piStatus.getRepeatPrevTotalCountInMonth()).orElse(0); // 变换前发生的总打卡次数(月) int prevTotalCountInMonth = punchInCoreManager.getPunchInTotalCountInRange(piStatus.getRepeatCategory(), piStatus.getRepeatCustomDay(), piStatus.getRepeatStartDateInMonth(), punchInDate.minusDays(1)); // 变换后可能的总打卡次数(月 ) int punchInTotalCountInMonth = punchInCoreManager.getPunchInTotalCountInRange(piTask.getRepeatCategory(), piTask.getRepeatCustomDay(), punchInDate, DateUtils.getLastDayOfMonth(punchInDate)); // 设置实时数据 piStatus.setRepeatPrevTotalCountInWeek(prevTotalCountInWeek + oldPrevTotalCountInWeek); piStatus.setPunchInTotalCountInWeek(Optional.ofNullable(piStatus.getRepeatPrevTotalCountInWeek()).orElse(0) + punchInTotalCountInWeek); piStatus.setRepeatPrevTotalCountInMonth(prevTotalCountInMonth + oldPrevTotalCountInMonth); piStatus.setPunchInTotalCountInMonth(Optional.ofNullable(piStatus.getRepeatPrevTotalCountInMonth()).orElse(0) + punchInTotalCountInMonth); } // 存在打卡记录则已打卡数加1 if (Objects.nonNull(piTaskHistory)) { 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(Optional.ofNullable(piStatus.getPunchInDoneCountInWeek()).orElse(0) + 1); piStatus.setPunchInDoneCountInMonth(Optional.ofNullable(piStatus.getPunchInDoneCountInMonth()).orElse(0) + 1); } } /** * 刷新打卡状态中的连续任务数据 * @param piStatus * @param punchInResult * @param continueTask * @param punchInDate */ private void refreshContinueData(PiStatus piStatus, PunchInResultEnum punchInResult, ContinueTask continueTask, LocalDate punchInDate) { // 设置任务连续状态 ContinueStatusEnum oldTaskContinueStatus = piStatus.getTaskContinueStatus(); piStatus.setTaskContinueStatus(punchInResult.equals(PunchInResultEnum.DONE) ? ContinueStatusEnum.CONTINUE : ContinueStatusEnum.INTERRUPTED); piStatus.setTaskContinueDay(oldTaskContinueStatus.equals(piStatus.getTaskContinueStatus()) ? piStatus.getTaskContinueDay() + 1 : 1); // 旧的连续阶段 ContinueStageEnum oldContinueStage = piStatus.getContinueStage(); // 判断当前处于的连续阶段 ContinueStageEnum continueStageResult = punchInCoreManager.judgeContinueStage(continueTask, punchInResult, piStatus, punchInDate); piStatus.setContinueStage(continueStageResult); // 下面3种情况不处理:宽限期 变 宽限期;正常打卡期 变 正常打卡期;惩罚期 变 惩罚期; // 宽限期 变 正常打卡期,则设置阶段开始时间,重置中断次数 if (ContinueStageEnum.GRACE_STAGE.equals(oldContinueStage) && ContinueStageEnum.NORMAL_STAGE.equals(continueStageResult)) { piStatus.setStageStartDate(punchInDate); piStatus.setContinueInterruptedCount(0); } // 如果正常打卡期 变 惩罚期,则设置阶段开始时间和阶段结束时间,增加中断次数 if (ContinueStageEnum.NORMAL_STAGE.equals(oldContinueStage) && ContinueStageEnum.PENALTY_STAGE.equals(continueStageResult)) { piStatus.setStageStartDate(punchInDate); piStatus.setStageEndDate(punchInDate.plusDays(continueTask.getPenaltyDay())); piStatus.setContinueInterruptedCount(piStatus.getContinueInterruptedCount() + 1); } // 如果惩罚期 变 正常打卡期,则设置阶段开始时间 if (ContinueStageEnum.PENALTY_STAGE.equals(oldContinueStage) && ContinueStageEnum.NORMAL_STAGE.equals(continueStageResult)) { 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 settleUserHistories = settleUserHistoryService.querySettleUserHistory(settleUserHistoryQuery); if (CollectionUtils.isEmpty(settleUserHistories)) { log.info("========== 积分分发定时任务,没有可分发的积分 结束执行 =========="); return; } // 用户ID-用户结算记录关联 Map settleUserHistoryMap = settleUserHistories.stream().collect(Collectors.toMap(SettleUserHistory::getUserId, Function.identity(), (key1, key2) -> key1)); // 用户ID列表 Set userIds = settleUserHistories.stream().map(SettleUserHistory::getUserId).collect(Collectors.toSet()); // 用户信息, 用户ID-用户信息关联 List users = userService.listByIds(userIds); Map 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 accounts = accountService.getAccountByCondition(accountQuery); Map accountMap = accounts.stream().collect(Collectors.toMap(Account::getUserId, Function.identity(), (key1, key2) -> key1)); // 用户信息 更新列表 List updateUserList = new ArrayList<>(); // 账户信息 更新列表 List updateAccountList = new ArrayList<>(); // 转账记录 新增列表 List addAccountTransferHistories = new ArrayList<>(); // 结算用户信息 更新列表 List 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); } } }