zhanghl
2025-05-23 1c61a282a831cea285ddb503bdb810df9250b191
[钣金计划大表] 增加分布式锁
已修改7个文件
74 ■■■■ 文件已修改
aps-modules/aps-core/src/main/java/com/aps/core/controller/mainPlan/ApsPlate/ApsPlateProcessShopStatController.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
aps-modules/aps-core/src/main/java/com/aps/core/enums/PLAN_TASK_TYPE.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
aps-modules/aps-core/src/main/java/com/aps/core/enums/REDIS_LOCK_KEY.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
aps-modules/aps-core/src/main/java/com/aps/core/service/ApsPlanTaskService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlanTaskServiceImpl.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlate/ApsPlateProcessShopStatServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlate/ApsPlateProcessStatServiceImpl.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
aps-modules/aps-core/src/main/java/com/aps/core/controller/mainPlan/ApsPlate/ApsPlateProcessShopStatController.java
@@ -6,9 +6,11 @@
import com.aps.common.log.enums.BusinessType;
import com.aps.common.security.annotation.RequiresPermissions;
import com.aps.core.domain.ApsPlate.ApsPlateProcessShopStat;
import com.aps.core.service.ApsPlanTaskService;
import com.aps.core.service.ApsPlate.IApsPlateProcessShopStatService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@@ -27,7 +29,8 @@
{
    @Autowired
    private IApsPlateProcessShopStatService apsPlateProcessShopStatService;
    @Resource
    ApsPlanTaskService apsPlanTaskService;
    /**
     * 导出钣金车间统计列表
@@ -48,13 +51,13 @@
    @Operation(summary = "钣金计划大表", description = "更新统计数据")
    @Log(title = "钣金车间统计", businessType = BusinessType.UPDATE)
    @RequiresPermissions("plateProcessShopStat:update")
    //@RequiresPermissions("plateProcessShopStat:update")
    @PostMapping("/update")
    public AjaxResult update()
    {
        try {
            apsPlateProcessShopStatService.saveShopStat();
            return toAjax(true);
           return  apsPlanTaskService.generatorPlatePlanTable();
        } catch (Exception e) {
          return AjaxResult.error("更新失败!"+e.getMessage());
        }
aps-modules/aps-core/src/main/java/com/aps/core/enums/PLAN_TASK_TYPE.java
@@ -2,8 +2,8 @@
public enum PLAN_TASK_TYPE {
    PLATE_PLAN("PlateOrderPlan","生成钣金工单计划");
    PLATE_PLAN("PlateOrderPlan","生成钣金工单计划"),
    PLATE_SHOP_PLAN_TABLE("PlateShopPlanTable","生成钣金计划大表");
    private String code;
    private String desc;
aps-modules/aps-core/src/main/java/com/aps/core/enums/REDIS_LOCK_KEY.java
@@ -3,8 +3,9 @@
public enum REDIS_LOCK_KEY {
    /*钣金工单计划任务*/
    PLATE_ORDER_PLAN("PLAN_TASK:PLATE_ORDER_PLAN");
    PLATE_ORDER_PLAN("PLAN_TASK:PLATE_ORDER_PLAN"),
    /*钣金计划大表*/
    PLATE_SHOP_PLAN_TABLE("PLAN_TASK:PLATE_SHOP_PLAN_TABLE");
    private String key;
    public String getKey() {
aps-modules/aps-core/src/main/java/com/aps/core/service/ApsPlanTaskService.java
@@ -23,4 +23,6 @@
    void updateTaskStatus(String batchNum, PLAN_TASK_STATUS status);
    AjaxResult generatorPlan();
    AjaxResult generatorPlatePlanTable();
}
aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlanTaskServiceImpl.java
@@ -1,7 +1,6 @@
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;
@@ -10,9 +9,9 @@
import com.aps.core.enums.PLAN_TASK_TYPE;
import com.aps.core.enums.REDIS_LOCK_KEY;
import com.aps.core.mapper.ApsPlateStandardRequireOrderEndDayMapper;
import com.aps.core.service.ApsPlate.IApsPlateProcessShopStatService;
import com.aps.core.service.ApsPlate.IApsPlateStandardRequireBatchService;
import com.aps.core.service.ApsPlate.IApsPlateStandardRequireService;
import com.aps.core.service.ApsPlateStandardRequireOrderEndDayService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -26,6 +25,7 @@
import static com.aps.common.core.web.domain.AjaxResult.success;
import static com.aps.core.enums.REDIS_LOCK_KEY.PLATE_ORDER_PLAN;
/**
* @author zhl
@@ -50,6 +50,9 @@
    @Resource
    ApsPlateStandardRequireOrderEndDayMapper  orderEndDayMapper;
    @Resource
    IApsPlateProcessShopStatService plateProcessShopStatService;
    @Override
    public Page<ApsPlanTask> pagingList(Page<ApsPlanTask> page ,ApsPlanTask task){
@@ -123,6 +126,38 @@
            redisLockUtils.releaseLock(plateOrderPlanKey, PLAN_TASK_TYPE.PLATE_PLAN.getCode());
        }
    }
    @Override
    public AjaxResult generatorPlatePlanTable() {
        String plateOrderPlanKey = REDIS_LOCK_KEY.PLATE_SHOP_PLAN_TABLE.getKey();
        boolean existsLock = redisLockUtils.existLock(plateOrderPlanKey, PLAN_TASK_TYPE.PLATE_SHOP_PLAN_TABLE.getCode());
        if (existsLock) {
            return AjaxResult.warn("钣金计划大表计划任务正在执行中!");
        }
        LambdaQueryWrapper<ApsPlanTask> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ApsPlanTask::getTaskType, PLAN_TASK_TYPE.PLATE_SHOP_PLAN_TABLE.getCode());
        queryWrapper.eq(ApsPlanTask::getTaskStatus, PLAN_TASK_STATUS.IN_PROCESS.getCode());
        boolean existsDbTask = mapper.exists(queryWrapper);
        if (existsDbTask) {
            return AjaxResult.warn("钣金计划大表任务正在执行中!!");
        }
        String currentBatchNum =  String.valueOf(IdUtil.getSnowflakeNextId()) ;
        try {
            redisLockUtils.getLock(plateOrderPlanKey, PLAN_TASK_TYPE.PLATE_SHOP_PLAN_TABLE.getCode(), 15 * 60L);
            this.savePlanTask( currentBatchNum);
            Thread.sleep(60000);
            plateProcessShopStatService.saveShopStat();
            this.updateTaskStatus(currentBatchNum, PLAN_TASK_STATUS.FINISHED);
            log.info("钣金计划大表任务执行完成!" + currentBatchNum);
            return success();
        } catch (Exception e) {
            redisLockUtils.releaseLock(plateOrderPlanKey, PLAN_TASK_TYPE.PLATE_SHOP_PLAN_TABLE.getCode());
            log.error("钣金计划大表任务执行失败!" + e.getMessage());
            this.updateTaskStatus(currentBatchNum, PLAN_TASK_STATUS.ERROR);
            return AjaxResult.error("钣金计划大表任务执行失败!" + e.getMessage());
        } finally {
            redisLockUtils.releaseLock(plateOrderPlanKey, PLAN_TASK_TYPE.PLATE_SHOP_PLAN_TABLE.getCode());
        }
    }
}
aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlate/ApsPlateProcessShopStatServiceImpl.java
@@ -304,7 +304,7 @@
        List<SysDictData> documentStatusDic = DictUtils.getDictCache("aps_document_status");
        // 构建结果列表
        planList.forEach(
        planList.stream().parallel().forEach(
                 plan -> {
                    // 根据 docNo 获取对应的 shopStatList
                    List<ApsPlateProcessShopStat> shopStatList = shopStatesByDocNo.getOrDefault(plan.getDocumentNumber(), Collections.emptyList());
aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlate/ApsPlateProcessStatServiceImpl.java
@@ -112,11 +112,13 @@
        String batchNum = IdUtils.fastSimpleUUID();
        List<ApsPlateProcessStat> tempList = apsPlateProcessStatMapper.queryTempStat();
        Map<String, List<ApsPlateProcessStat>> groupByOrderNo = tempList.stream().collect(groupingBy(ApsPlateProcessStat::getWorkOrderNo));
        Boolean hasBefore = false;
        LocalDateTime now = LocalDateTime.now();
        List<ApsPlateProcessStat> totalList=new ArrayList<>();
        for (Map.Entry<String, List<ApsPlateProcessStat>> entry : groupByOrderNo.entrySet()) {
            List<ApsPlateProcessStat> statPerOrder = entry.getValue();
        ArrayList<Map.Entry<String, List<ApsPlateProcessStat>>> orderProcessRoutes = new ArrayList<>(groupByOrderNo.entrySet());
        orderProcessRoutes.stream().parallel().forEach(x->{
            boolean hasBefore = false;
            List<ApsPlateProcessStat>  statPerOrder = x.getValue();
            /*num 为根据完工时间排序出的序号,按此排序,可保证是按完工时间倒叙排列*/
            statPerOrder.sort((a, b)->a.getNum().compareTo(b.getNum()));
            ApsPlateProcessStat last=null;
@@ -180,10 +182,9 @@
                }
                last = stat;
                totalList.add(stat);
                //apsPlateProcessStatMapper.insertApsPlateProcessStat(stat);
            }
            hasBefore=false;
        }
        });
        return totalList;
    }