Преглед на файлове

【feat】【v3】
1.修复自动打卡异常
2.修复拓展信息无法保存异常
3.增加校验注解

ChenYL преди 10 месеца
родител
ревизия
a0440439d8

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

@@ -2,6 +2,7 @@ package com.punchsettle.server.atomic.mapper;
 
 import com.punchsettle.server.atomic.entity.PiTaskExt;
 import tk.mybatis.mapper.common.Mapper;
+import tk.mybatis.mapper.common.special.InsertListMapper;
 
 /**
  * @author tyuio
@@ -9,6 +10,6 @@ import tk.mybatis.mapper.common.Mapper;
  * @description 打卡任务拓展表 Mapper
  * @date 2025/04/08 10:30
  */
-public interface PiTaskExtMapper extends Mapper<PiTaskExt> {
+public interface PiTaskExtMapper extends Mapper<PiTaskExt>, InsertListMapper<PiTaskExt> {
 
 }

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

@@ -19,4 +19,10 @@ public interface IPiTaskExtService {
      * @return
      */
     List<PiTaskExt> queryByCondition(PiTaskExtQuery piTaskExtQuery);
+
+    /**
+     * 批量新增
+     * @param piTaskExtList
+     */
+    void batchAdd(List<PiTaskExt> piTaskExtList);
 }

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

@@ -37,4 +37,10 @@ public class PiTaskExtServiceImpl implements IPiTaskExtService {
         }
         return piTaskExtMapper.selectByExample(weekend);
     }
+
+    @Override
+    public void batchAdd(List<PiTaskExt> piTaskExtList) {
+        Assert.notEmpty(piTaskExtList);
+        piTaskExtMapper.insertList(piTaskExtList);
+    }
 }

+ 3 - 1
src/main/java/com/punchsettle/server/atomic/service/impl/PiTaskServiceImpl.java

@@ -53,7 +53,9 @@ public class PiTaskServiceImpl implements IPiTaskService {
         if (Objects.nonNull(piTaskQuery.getAutoArchiveDateLt())) {
             criteria.andLessThan(PiTask::getAutoArchiveDate, piTaskQuery.getAutoArchiveDateLt());
         }
-
+        if (Objects.nonNull(piTaskQuery.getAutoStatus())) {
+            criteria.andEqualTo(PiTask::getAutoStatus, piTaskQuery.getAutoStatus());
+        }
         weekend.excludeProperties(BaseEntity::getLastUpdatedBy,
                 BaseEntity::getLastUpdateTime,
                 BaseEntity::getVersion,

+ 5 - 5
src/main/java/com/punchsettle/server/pojo/punchIn/PiTaskExtRequest.java → src/main/java/com/punchsettle/server/pojo/punchIn/PiTaskExtDto.java

@@ -11,19 +11,19 @@ import lombok.Data;
  * @description 打卡任务拓展信息
  */
 @Data
-public class PiTaskExtRequest {
+public class PiTaskExtDto {
 
     /**
      * 起始值(单位:次)
      */
-    @NotNull(message = "起始值不能为空")
-    @Positive(message = "起始值必须大于0")
+    @NotNull(message = "积分区间起始值不能为空")
+    @Positive(message = "积分区间起始值必须大于0")
     private Integer initialValue;
 
     /**
      * 奖励的积分(额外)
      */
-    @NotNull(message = "奖励积分(额外)不能为空")
-    @Positive(message = "奖励积分(额外)必须大于0")
+    @NotNull(message = "积分区间的奖励积分不能为空")
+    @Positive(message = "积分区间的奖励积分必须大于0")
     private Integer extraPoints;
 }

+ 3 - 2
src/main/java/com/punchsettle/server/pojo/punchIn/PiTaskRequest.java

@@ -194,11 +194,12 @@ public class PiTaskRequest {
     /**
      * 拓展信息(当天打卡)
      */
-    private List<PiTaskExtRequest> taskExtList;
+    @Valid
+    private List<PiTaskExtDto> taskExtList;
 
     /**
      * 拓展信息(连续打卡)
      */
     @Valid
-    private List<PiTaskExtRequest> continueTaskExtList;
+    private List<PiTaskExtDto> continueTaskExtList;
 }

+ 13 - 0
src/main/java/com/punchsettle/server/pojo/punchIn/PiTaskVO.java

@@ -2,6 +2,7 @@ package com.punchsettle.server.pojo.punchIn;
 
 import java.time.LocalDate;
 import java.time.LocalTime;
+import java.util.List;
 
 import com.punchsettle.server.common.constant.CommonEnableStatusEnum;
 import com.punchsettle.server.constant.CompareRuleEnum;
@@ -10,6 +11,7 @@ import com.punchsettle.server.constant.PunchInExtraMethodEnum;
 import com.punchsettle.server.constant.PunchInMethodEnum;
 import com.punchsettle.server.constant.RepeatCategoryEnum;
 
+import jakarta.validation.Valid;
 import lombok.Data;
 
 /**
@@ -170,4 +172,15 @@ public class PiTaskVO {
      * @see CommonEnableStatusEnum
      */
     private CommonEnableStatusEnum taskPointsStatus;
+
+    /**
+     * 拓展信息(当天打卡)
+     */
+    private List<PiTaskExtDto> taskExtList;
+
+    /**
+     * 拓展信息(连续打卡)
+     */
+    @Valid
+    private List<PiTaskExtDto> continueTaskExtList;
 }

+ 2 - 2
src/main/java/com/punchsettle/server/service/controller/AccountController.java

@@ -68,7 +68,7 @@ public class AccountController {
      * @param request
      */
     @PostMapping("/saveAccount")
-    public void saveAccount(@RequestBody AccountRequest request) {
+    public void saveAccount(@RequestBody @Validated AccountRequest request) {
         accountManager.saveAccount(request);
     }
 
@@ -84,7 +84,7 @@ public class AccountController {
      * 转账
      */
     @PostMapping("/transfer")
-    public void transfer(@RequestBody TransferRequest request) {
+    public void transfer(@RequestBody @Validated TransferRequest request) {
         accountManager.transfer(request);
     }
 

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

@@ -68,7 +68,7 @@ public class PunchInController {
      * 保存打卡任务
      */
     @PostMapping("/saveTask")
-    public void saveTask(@RequestBody PiTaskRequest request) {
+    public void saveTask(@RequestBody @Validated PiTaskRequest request) {
         punchInManager.saveTask(request);
     }
 
@@ -84,7 +84,7 @@ public class PunchInController {
      * 打卡
      */
     @PostMapping("/doPunchIn")
-    public void doPunchIn(@RequestBody PunchInRequest request) {
+    public void doPunchIn(@RequestBody @Validated PunchInRequest request) {
         punchInManager.doPunchIn(request);
     }
 
@@ -112,7 +112,7 @@ public class PunchInController {
      * @return
      */
     @PostMapping("/queryStat")
-    public PiTaskStatVO queryStat(@RequestBody PiTaskStatQuery query) {
+    public PiTaskStatVO queryStat(@RequestBody @Validated PiTaskStatQuery query) {
         return punchInManager.queryStat(query);
     }
 

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

@@ -55,7 +55,7 @@ public class RewardController {
      * @param request
      */
     @PostMapping("/saveReward")
-    public void saveReward(@RequestBody RewardRequest request) {
+    public void saveReward(@RequestBody @Validated RewardRequest request) {
         rewardManager.saveReward(request);
     }
 
@@ -72,7 +72,7 @@ public class RewardController {
      * 兑换奖励
      */
     @PostMapping("/exchangeReward")
-    public void exchangeReward(@RequestBody RewardExchangeRequest request) {
+    public void exchangeReward(@RequestBody @Validated RewardExchangeRequest request) {
         rewardManager.exchangeReward(request);
     }
 

+ 2 - 0
src/main/java/com/punchsettle/server/service/controller/StatController.java

@@ -1,6 +1,7 @@
 package com.punchsettle.server.service.controller;
 
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
@@ -13,6 +14,7 @@ import com.punchsettle.server.service.manager.IStatManager;
  * @date 2025/5/3 20:27
  * @description 数据统计
  */
+@Validated
 @RestController
 @RequestMapping("/stat")
 public class StatController {

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

@@ -21,6 +21,7 @@ import me.chanjar.weixin.common.error.WxErrorException;
  * @description 用户 controller
  * @date 2024/12/13 15:09
  */
+@Validated
 @RestController
 @RequestMapping("/user")
 public class UserController {

+ 91 - 8
src/main/java/com/punchsettle/server/service/manager/impl/PunchInManagerImpl.java

@@ -25,9 +25,11 @@ import org.springframework.util.StringUtils;
 import com.punchsettle.server.atomic.StatPiTask;
 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.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.ISettleTaskRelaHistoryService;
@@ -39,6 +41,7 @@ import com.punchsettle.server.common.utils.Assert;
 import com.punchsettle.server.constant.ArchiveStatusEnum;
 import com.punchsettle.server.constant.CacheNameConstant;
 import com.punchsettle.server.constant.ContinueStatusEnum;
+import com.punchsettle.server.constant.PunchInDimensionEnum;
 import com.punchsettle.server.constant.PunchInExtraMethodEnum;
 import com.punchsettle.server.constant.PunchInMethodEnum;
 import com.punchsettle.server.constant.PunchInResultEnum;
@@ -47,6 +50,8 @@ import com.punchsettle.server.constant.RepeatCategoryEnum;
 import com.punchsettle.server.constant.SettleResultEnum;
 import com.punchsettle.server.constant.StatPeriodEnum;
 import com.punchsettle.server.constant.VersionStatusEnum;
+import com.punchsettle.server.pojo.punchIn.PiTaskExtDto;
+import com.punchsettle.server.pojo.punchIn.PiTaskExtQuery;
 import com.punchsettle.server.pojo.punchIn.PiTaskHistoryQuery;
 import com.punchsettle.server.pojo.punchIn.PiTaskHistorySimpleVO;
 import com.punchsettle.server.pojo.punchIn.PiTaskHistoryVO;
@@ -111,6 +116,9 @@ public class PunchInManagerImpl implements IPunchInManager {
     @Autowired
     private ISettleTaskRelaHistoryService settleTaskRelaHistoryService;
 
+    @Autowired
+    private IPiTaskExtService piTaskExtService;
+
     /**
      * 默认时间00:00:00.000
      */
@@ -282,11 +290,39 @@ public class PunchInManagerImpl implements IPunchInManager {
     @Override
     public PiTaskVO queryTask(Long id) {
         Assert.isNullInBusiness(id, "请传入待查询的任务ID");
-        return Optional.ofNullable(piTaskService.getById(id)).map(piTask -> {
-            PiTaskVO piTaskVO = new PiTaskVO();
-            BeanUtils.copyProperties(piTask, piTaskVO);
+
+        PiTaskVO piTaskVO = new PiTaskVO();
+
+        // 获取打卡任务
+        PiTask piTask = Optional.ofNullable(piTaskService.getById(id)).orElseThrow(() -> BusinessException.fail("无法查询到该打卡任务"));
+        BeanUtils.copyProperties(piTask, piTaskVO);
+
+        // 获取拓展信息
+        PiTaskExtQuery piTaskExtQuery = new PiTaskExtQuery();
+        piTaskExtQuery.setPunchInTaskIds(Arrays.asList(piTask.getId()));
+        List<PiTaskExt> piTaskExtList = piTaskExtService.queryByCondition(piTaskExtQuery);
+        // 没有拓展信息直接返回
+        if (CollectionUtils.isEmpty(piTaskExtList)) {
             return piTaskVO;
-        }).orElseThrow(() -> BusinessException.fail("无法查询到该打卡任务"));
+        }
+
+        // 拓展信息(当天打卡)
+        List<PiTaskExtDto> taskExtList = piTaskExtList.stream().filter(piTaskExt -> PunchInDimensionEnum.ONE_DAY.equals(piTaskExt.getDimension())).map(piTaskExt -> {
+            PiTaskExtDto piTaskExtDto = new PiTaskExtDto();
+            BeanUtils.copyProperties(piTaskExt, piTaskExtDto);
+            return piTaskExtDto;
+        }).toList();
+        piTaskVO.setTaskExtList(taskExtList);
+
+        // 拓展信息(连续打卡)
+        List<PiTaskExtDto> continueTaskExtList = piTaskExtList.stream().filter(piTaskExt -> PunchInDimensionEnum.MULTI_DAY.equals(piTaskExt.getDimension())).map(piTaskExt -> {
+            PiTaskExtDto piTaskExtDto = new PiTaskExtDto();
+            BeanUtils.copyProperties(piTaskExt, piTaskExtDto);
+            return piTaskExtDto;
+        }).toList();
+        piTaskVO.setContinueTaskExtList(continueTaskExtList);
+
+        return piTaskVO;
     }
 
     @Override
@@ -329,15 +365,31 @@ public class PunchInManagerImpl implements IPunchInManager {
             if (PunchInExtraMethodEnum.FIXED.equals(request.getExtraMethod()) && Objects.isNull(request.getExtraPoints())) {
                 throw BusinessException.fail("额外奖励方式为固定,额外奖励积分不能为空");
             }
-            if (PunchInExtraMethodEnum.INTERVAL.equals(request.getExtraMethod()) && CollectionUtils.isEmpty(request.getTaskExtList())) {
-                throw BusinessException.fail("额外奖励方式为区间,积分区间信息不能为空");
+            if (PunchInExtraMethodEnum.INTERVAL.equals(request.getExtraMethod())) {
+                if (CollectionUtils.isEmpty(request.getTaskExtList())) {
+                    throw BusinessException.fail("额外奖励方式为区间,积分区间信息不能为空");
+                }
+                Map<Integer, List<PiTaskExtDto>> initialValueMap = request.getTaskExtList().stream().collect(Collectors.groupingBy(PiTaskExtDto::getInitialValue));
+                for (List<PiTaskExtDto> value : initialValueMap.values()) {
+                    if (value.size() > 1) {
+                        throw BusinessException.fail("任务积分区间不能有重复的起始值");
+                    }
+                }
             }
         }
         if (CommonEnableStatusEnum.ENABLED.equals(request.getContinueStatus()) && (Objects.isNull(request.getGraceDay()) || Objects.isNull(request.getContinueInterruptedCount()) || Objects.isNull(request.getPenaltyDay()))) {
             throw BusinessException.fail("启用了连续规则,宽限期、连续中断次数、惩罚天数不能为空");
         }
-        if (CommonEnableStatusEnum.ENABLED.equals(request.getTaskPointsStatus()) && CollectionUtils.isEmpty(request.getContinueTaskExtList())) {
-            throw BusinessException.fail("启用了任务积分计算,连续任务积分区间信息不能为空");
+        if (CommonEnableStatusEnum.ENABLED.equals(request.getTaskPointsStatus())) {
+            if (CollectionUtils.isEmpty(request.getContinueTaskExtList())) {
+                throw BusinessException.fail("启用了任务积分计算,连续任务积分区间信息不能为空");
+            }
+            Map<Integer, List<PiTaskExtDto>> initialValueMap = request.getContinueTaskExtList().stream().collect(Collectors.groupingBy(PiTaskExtDto::getInitialValue));
+            for (List<PiTaskExtDto> value : initialValueMap.values()) {
+                if (value.size() > 1) {
+                    throw BusinessException.fail("连续任务积分区间不能有重复的起始值");
+                }
+            }
         }
         if (Objects.nonNull(request.getAutoArchiveDate()) && request.getAutoArchiveDate().isBefore(today)) {
             throw BusinessException.fail("任务自动归档时间无效,必需大于等于当前时间");
@@ -351,6 +403,28 @@ public class PunchInManagerImpl implements IPunchInManager {
         addPiTask.setTaskVersion(0);
         addPiTask.setArchiveStatus(ArchiveStatusEnum.ACTIVE);
 
+        // 拓展信息(当天打卡)
+        List<PiTaskExt> taskExtList = Optional.ofNullable(request.getTaskExtList()).orElse(List.of()).stream()
+                .sorted(Comparator.comparing(PiTaskExtDto::getInitialValue))
+                .map(piTaskExtDto -> {
+            PiTaskExt piTaskExt = new PiTaskExt();
+            BeanUtils.copyProperties(piTaskExtDto, piTaskExt);
+            piTaskExt.setUserId(currentUserId);
+            piTaskExt.setDimension(PunchInDimensionEnum.ONE_DAY);
+            return piTaskExt;
+        }).toList();
+
+        // 拓展信息(连续打卡)
+        List<PiTaskExt> continueTaskExtList = Optional.ofNullable(request.getContinueTaskExtList()).orElse(List.of()).stream()
+                .sorted(Comparator.comparing(PiTaskExtDto::getInitialValue))
+                .map(piTaskExtDto -> {
+            PiTaskExt piTaskExt = new PiTaskExt();
+            BeanUtils.copyProperties(piTaskExtDto, piTaskExt);
+            piTaskExt.setUserId(currentUserId);
+            piTaskExt.setDimension(PunchInDimensionEnum.MULTI_DAY);
+            return piTaskExt;
+        }).toList();
+
         // 如果任务已存在,则更新任务版本号、设置唯一ID、旧数据归档
         if (Objects.nonNull(request.getId())) {
             PiTask piTask = Optional.ofNullable(piTaskService.getById(request.getId())).orElseThrow(() -> BusinessException.fail("无法查询到该打卡任务"));
@@ -378,6 +452,15 @@ public class PunchInManagerImpl implements IPunchInManager {
 
         // 保存数据
         piTaskService.insert(addPiTask);
+        if (!CollectionUtils.isEmpty(taskExtList)) {
+            taskExtList.forEach(v -> v.setTaskId(addPiTask.getId()));
+            piTaskExtService.batchAdd(taskExtList);
+        }
+        if (!CollectionUtils.isEmpty(continueTaskExtList)) {
+            continueTaskExtList.forEach(v -> v.setTaskId(addPiTask.getId()));
+            piTaskExtService.batchAdd(continueTaskExtList);
+        }
+
         // 如果首次保存,需要设置唯一ID
         if (Objects.isNull(addPiTask.getUniqueId())) {
             PiTask updatePiTask = new PiTask();

+ 1 - 0
src/main/java/com/punchsettle/server/task/PiTaskAutoPunchInTask.java

@@ -142,6 +142,7 @@ public class PiTaskAutoPunchInTask {
         }).toList();
 
         if (CollectionUtils.isEmpty(addPiTaskHistories)) {
+            log.info("========== 打卡任务自动打卡定时任务,没有需要自动打卡的任务2 结束执行 ==========");
             return;
         }