chenhj
2 天以前 9dcd90dc8e329900e6058ac0a3aa44a9e7e04599
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
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<PendingInventory>() {
 
            @Override
            public void handleResult(ResultContext<? extends PendingInventory> resultContext) {
                PendingInventory pendingInventory = resultContext.getResultObject();
                executor.submit(() -> {
                    handleInventorySummary(pendingInventory, null);
                });
 
            }
        });
    }
 
    // 更新正式库存节点
    private void updateOfficialInventory() {
        officialInventoryMapper.selectList(Wrappers.emptyWrapper(), new ResultHandler<OfficialInventory>() {
 
            @Override
            public void handleResult(ResultContext<? extends OfficialInventory> resultContext) {
                OfficialInventory officialInventory = resultContext.getResultObject();
                executor.submit(() -> {
                    handleInventorySummary(null, officialInventory);
                });
 
            }
        });
    }
 
    // 更新节点数据
    private void handleInventorySummary(PendingInventory pendingInventory, OfficialInventory officialInventory) {
        InventorySummary inventorySummary = null;
        List<InputInventoryRecord> inputInventoryRecordList = new ArrayList<>();
        List<OutputInventoryRecord> outputInventoryRecordList = new ArrayList<>();
 
        if (pendingInventory != null) {
            inventorySummary = inventorySummaryMapper.getInventorySummaryForUpdateByInventoryIdAndType(pendingInventory.getId(), PENDING_INVENTORY);
            inputInventoryRecordList = inputInventoryRecordMapper.selectList(new LambdaQueryWrapper<InputInventoryRecord>()
                    .eq(InputInventoryRecord::getInventoryId, pendingInventory.getId())
                    .eq(InputInventoryRecord::getInventoryType, PENDING_INVENTORY)
                    .gt(InputInventoryRecord::getId, inventorySummary == null ? 0 : inventorySummary.getInputEndRecordId()));
            outputInventoryRecordList = outputInventoryRecordMapper.selectList(new LambdaQueryWrapper<OutputInventoryRecord>()
                    .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<InputInventoryRecord>()
                    .eq(InputInventoryRecord::getInventoryId, officialInventory.getId())
                    .eq(InputInventoryRecord::getInventoryType, OFFICIAL_INVENTORY)
                    .gt(InputInventoryRecord::getId, inventorySummary == null ? 0 : inventorySummary.getInputEndRecordId()));
            outputInventoryRecordList = outputInventoryRecordMapper.selectList(new LambdaQueryWrapper<OutputInventoryRecord>()
                    .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);
    }
}