zhanghl
2025-05-19 26dc5221f84b6cbb3a03f04423ef1736f657f293
钣金工单计划:增加Redis锁 和 业务幂等判断
已修改4个文件
已添加1个文件
89 ■■■■■ 文件已修改
aps-common/aps-common-redis/src/main/java/com/aps/common/redis/service/RedisLockUtils.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
aps-modules/aps-core/src/main/java/com/aps/core/controller/mainPlan/ApsPlate/ApsPlateStandardRequireController.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
aps-modules/aps-core/src/main/java/com/aps/core/enums/REDIS_LOCK_KEY.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
aps-modules/aps-core/src/main/java/com/aps/core/service/ApsPlanTaskService.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlanTaskServiceImpl.java 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
aps-common/aps-common-redis/src/main/java/com/aps/common/redis/service/RedisLockUtils.java
@@ -26,6 +26,13 @@
    /**
     * åˆ¤æ–­æ˜¯å¦å­˜åœ¨é”
     * */
    public boolean existLock(String key,String value){
        return this.redisTemplate.opsForValue().get(key).equals(value);
    }
    /**
     *  åР锁
     **/
    public Boolean getLock(String key,String value,Long timeoutSeconds){
aps-modules/aps-core/src/main/java/com/aps/core/controller/mainPlan/ApsPlate/ApsPlateStandardRequireController.java
@@ -138,14 +138,11 @@
    /**
     * ç”Ÿæˆé’£é‡‘计划
     * */
    @PostMapping("/generatorPlan")
    public AjaxResult generatorPlan()
    {
        String batchNum= requireBatchService.getNewBatchNumber();
        planTaskService.savePlanTask(batchNum);
        apsPlateStandardRequireService.generatorPlan(batchNum);
        planTaskService.updateTaskStatus(batchNum, PLAN_TASK_STATUS.FINISHED);
        return success();
        return  planTaskService.generatorPlan();
    }
}
aps-modules/aps-core/src/main/java/com/aps/core/enums/REDIS_LOCK_KEY.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,17 @@
package com.aps.core.enums;
public enum REDIS_LOCK_KEY {
    /*钣金工单计划任务*/
    PLATE_ORDER_PLAN("PLAN_TASK:PLATE_ORDER_PLAN");
    private String key;
    public String getKey() {
        return key;
    }
    REDIS_LOCK_KEY(String key) {
        this.key = key;
    }
}
aps-modules/aps-core/src/main/java/com/aps/core/service/ApsPlanTaskService.java
@@ -1,5 +1,6 @@
package com.aps.core.service;
import com.aps.common.core.web.domain.AjaxResult;
import com.aps.core.domain.ApsPlanTask;
import com.aps.core.enums.PLAN_TASK_STATUS;
import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -20,4 +21,6 @@
    void savePlanTask(String batchNum);
    void updateTaskStatus(String batchNum, PLAN_TASK_STATUS status);
    AjaxResult generatorPlan();
}
aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlanTaskServiceImpl.java
@@ -1,34 +1,52 @@
package com.aps.core.service.impl;
import cn.hutool.core.util.IdUtil;
import com.aps.common.core.domain.R;
import com.aps.common.core.utils.DateUtils;
import com.aps.common.core.web.domain.AjaxResult;
import com.aps.common.redis.service.RedisLockUtils;
import com.aps.common.security.utils.SecurityUtils;
import com.aps.core.enums.PLAN_TASK_STATUS;
import com.aps.core.enums.PLAN_TASK_TYPE;
import com.aps.core.enums.REDIS_LOCK_KEY;
import com.aps.core.service.ApsPlate.IApsPlateStandardRequireBatchService;
import com.aps.core.service.ApsPlate.IApsPlateStandardRequireService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.aps.core.domain.ApsPlanTask;
import com.aps.core.service.ApsPlanTaskService;
import com.aps.core.mapper.ApsPlanTaskMapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import static com.aps.common.core.web.domain.AjaxResult.success;
import static com.aps.core.enums.REDIS_LOCK_KEY.PLATE_ORDER_PLAN;
/**
* @author zhl
* @description é’ˆå¯¹è¡¨ã€aps_plan_task(计划生成日志表)】的数据库操作Service实现
* @createDate 2025-05-16 14:41:49
*/
@Slf4j
@Service
public class ApsPlanTaskServiceImpl extends ServiceImpl<ApsPlanTaskMapper, ApsPlanTask> implements ApsPlanTaskService{
    @Autowired
    ApsPlanTaskMapper mapper;
    @Autowired
    private IApsPlateStandardRequireService apsPlateStandardRequireService;
    @Resource
    IApsPlateStandardRequireBatchService requireBatchService;
    @Resource
    RedisLockUtils redisLockUtils;
    @Override
    public Page<ApsPlanTask> pagingList(Page<ApsPlanTask> page ,ApsPlanTask task){
        LambdaQueryWrapper<ApsPlanTask> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.like( !task.getTaskType().isEmpty(),  ApsPlanTask::getTaskType,task.getTaskType());
@@ -65,6 +83,39 @@
                .build();
        baseMapper.update(task,queryWrapper);
    }
    @Override
    public AjaxResult generatorPlan()
    {
        String plateOrderPlanKey = PLATE_ORDER_PLAN.getKey();
        boolean existsLock = redisLockUtils.existLock(plateOrderPlanKey, PLAN_TASK_TYPE.PLATE_PLAN.getCode());
        if (existsLock){
            return AjaxResult.warn("钣金工单计划任务正在执行中!");
        }
        LambdaQueryWrapper<ApsPlanTask> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.eq(ApsPlanTask::getTaskType,PLAN_TASK_TYPE.PLATE_PLAN.getCode());
        queryWrapper.eq(ApsPlanTask::getTaskStatus,PLAN_TASK_STATUS.IN_PROCESS.getCode());
        boolean existsDbTask = mapper.exists(queryWrapper);
        if (existsDbTask){
            return AjaxResult.warn("钣金工单计划任务正在执行中!!");
        }
        try {
            redisLockUtils.getLock(plateOrderPlanKey,PLAN_TASK_TYPE.PLATE_PLAN.getCode(), 3*60L);
            String batchNum= requireBatchService.getNewBatchNumber();
            this.savePlanTask(batchNum);
            apsPlateStandardRequireService.generatorPlan(batchNum);
            this.updateTaskStatus(batchNum, PLAN_TASK_STATUS.FINISHED);
            log.info("计划任务执行完成!"+batchNum);
            return success();
        }catch (Exception e){
            redisLockUtils.releaseLock(plateOrderPlanKey,PLAN_TASK_TYPE.PLATE_PLAN.getCode());
            log.error("计划任务执行失败!"+e.getMessage());
            return AjaxResult.error("计划任务执行失败!"+e.getMessage());
        }finally {
            redisLockUtils.releaseLock(plateOrderPlanKey,PLAN_TASK_TYPE.PLATE_PLAN.getCode());
        }
    }
}