package com.ruoyi.business.task; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.ruoyi.business.entity.*; import com.ruoyi.business.mapper.*; import lombok.extern.slf4j.Slf4j; import org.apache.ibatis.session.ResultContext; import org.apache.ibatis.session.ResultHandler; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import static com.ruoyi.business.constant.InventoryRecordConstant.OFFICIAL_INVENTORY; import static com.ruoyi.business.constant.InventoryRecordConstant.PENDING_INVENTORY; @Slf4j @Component public class InventorySummaryTask { @Autowired private PendingInventoryMapper pendingInventoryMapper; @Autowired private OfficialInventoryMapper officialInventoryMapper; @Autowired private InventorySummaryMapper inventorySummaryMapper; @Autowired private InputInventoryRecordMapper inputInventoryRecordMapper; @Autowired private OutputInventoryRecordMapper outputInventoryRecordMapper; private final ExecutorService executor = Executors.newFixedThreadPool(5); // 每隔10天的凌晨3点执行 @Scheduled(cron = "0 0 3 1/10 * ?") @Transactional public void updateInventorySummary() { log.info("开始执行库存节点统计定时任务: " + System.currentTimeMillis()); log.info("更新待入库库存节点"); updatePendingInventory(); log.info("更新正式库存节点"); updateOfficialInventory(); log.info("结束执行库存节点统计定时任务: " + System.currentTimeMillis()); } // 更新待入库库存节点 private void updatePendingInventory() { pendingInventoryMapper.selectList(Wrappers.emptyWrapper(), new ResultHandler() { @Override public void handleResult(ResultContext resultContext) { PendingInventory pendingInventory = resultContext.getResultObject(); executor.submit(() -> { handleInventorySummary(pendingInventory, null); }); } }); } // 更新正式库存节点 private void updateOfficialInventory() { officialInventoryMapper.selectList(Wrappers.emptyWrapper(), new ResultHandler() { @Override public void handleResult(ResultContext resultContext) { OfficialInventory officialInventory = resultContext.getResultObject(); executor.submit(() -> { handleInventorySummary(null, officialInventory); }); } }); } // 更新节点数据 private void handleInventorySummary(PendingInventory pendingInventory, OfficialInventory officialInventory) { InventorySummary inventorySummary = null; List inputInventoryRecordList = new ArrayList<>(); List outputInventoryRecordList = new ArrayList<>(); if (pendingInventory != null) { inventorySummary = inventorySummaryMapper.getInventorySummaryForUpdateByInventoryIdAndType(pendingInventory.getId(), PENDING_INVENTORY); inputInventoryRecordList = inputInventoryRecordMapper.selectList(new LambdaQueryWrapper() .eq(InputInventoryRecord::getInventoryId, pendingInventory.getId()) .eq(InputInventoryRecord::getInventoryType, PENDING_INVENTORY) .gt(InputInventoryRecord::getId, inventorySummary == null ? 0 : inventorySummary.getInputEndRecordId())); outputInventoryRecordList = outputInventoryRecordMapper.selectList(new LambdaQueryWrapper() .eq(OutputInventoryRecord::getInventoryId, pendingInventory.getId()) .eq(OutputInventoryRecord::getInventoryType, PENDING_INVENTORY) .gt(OutputInventoryRecord::getId, inventorySummary == null ? 0 : inventorySummary.getOutputEndRecordId())); if (inventorySummary == null) { inventorySummary = new InventorySummary(); inventorySummary.setInventoryQuantity(BigDecimal.ZERO); inventorySummary.setInventoryId(pendingInventory.getId()); inventorySummary.setInventoryType(PENDING_INVENTORY); } } if (officialInventory != null) { inventorySummary = inventorySummaryMapper.getInventorySummaryForUpdateByInventoryIdAndType(officialInventory.getId(), OFFICIAL_INVENTORY); inputInventoryRecordList = inputInventoryRecordMapper.selectList(new LambdaQueryWrapper() .eq(InputInventoryRecord::getInventoryId, officialInventory.getId()) .eq(InputInventoryRecord::getInventoryType, OFFICIAL_INVENTORY) .gt(InputInventoryRecord::getId, inventorySummary == null ? 0 : inventorySummary.getInputEndRecordId())); outputInventoryRecordList = outputInventoryRecordMapper.selectList(new LambdaQueryWrapper() .eq(OutputInventoryRecord::getInventoryId, officialInventory.getId()) .eq(OutputInventoryRecord::getInventoryType, OFFICIAL_INVENTORY) .gt(OutputInventoryRecord::getId, inventorySummary == null ? 0 : inventorySummary.getOutputEndRecordId())); if (inventorySummary == null) { inventorySummary = new InventorySummary(); inventorySummary.setInventoryQuantity(BigDecimal.ZERO); inventorySummary.setInventoryId(officialInventory.getId()); inventorySummary.setInventoryType(OFFICIAL_INVENTORY); } } BigDecimal total = inventorySummary.getInventoryQuantity(); BigDecimal inputTotal = BigDecimal.ZERO; if (CollectionUtils.isNotEmpty(inputInventoryRecordList)) { inputTotal = inputInventoryRecordList.stream().map(InputInventoryRecord::getQuantity).reduce(BigDecimal::add).orElse(BigDecimal.ZERO); inventorySummary.setInputEndRecordId(inputInventoryRecordList.get(inputInventoryRecordList.size() - 1).getId()); } BigDecimal outputTotal = BigDecimal.ZERO; if (CollectionUtils.isNotEmpty(outputInventoryRecordList)) { outputTotal = outputInventoryRecordList.stream().map(OutputInventoryRecord::getQuantity).reduce(BigDecimal::add).orElse(BigDecimal.ZERO); inventorySummary.setOutputEndRecordId(outputInventoryRecordList.get(outputInventoryRecordList.size() - 1).getId()); } if (inputTotal.compareTo(outputTotal) > 0) { total = total.add(inputTotal.subtract(outputTotal)); } inventorySummary.setInventoryQuantity(total); inventorySummaryMapper.insertOrUpdate(inventorySummary); } }