liding
昨天 f904274947d9a4bb44037e4d18a7d85c6aadaf7b
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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
package com.ruoyi.business.service.impl;
 
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.ruoyi.business.dto.ProductionMasterDto;
import com.ruoyi.business.entity.Production;
import com.ruoyi.business.entity.ProductionInventory;
import com.ruoyi.business.entity.ProductionMaster;
import com.ruoyi.business.mapper.OfficialInventoryMapper;
import com.ruoyi.business.mapper.ProductionInventoryMapper;
import com.ruoyi.business.mapper.ProductionMapper;
import com.ruoyi.business.mapper.ProductionMasterMapper;
import com.ruoyi.business.service.ProductionMasterService;
import com.ruoyi.common.utils.bean.BeanUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
 
import java.math.BigDecimal;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
 
/**
 * <p>
 * 生产主表 服务实现类
 * </p>
 *
 * @author ruoyi
 * @since 2025-06-13
 */
@Service
@RequiredArgsConstructor
public class ProductionMasterServiceImpl extends ServiceImpl<ProductionMasterMapper, ProductionMaster> implements ProductionMasterService {
 
    private final ProductionMasterMapper productionMasterMapper;
 
    private final ProductionInventoryMapper productionInventoryMapper;
 
    private final ProductionMapper productionMapper;
 
    private final OfficialInventoryMapper officialInventoryMapper;
 
    @Override
    public IPage<ProductionMasterDto> selectPMList(Page page, ProductionMasterDto productionMasterDto) {
        // 1. 构建主表查询条件
        LambdaQueryWrapper<ProductionMaster> masterQueryWrapper = new LambdaQueryWrapper<>();
 
        // 2. 执行主表分页查询
        IPage<ProductionMaster> entityPage = productionMasterMapper.selectPage(page, masterQueryWrapper);
 
        // 3. 提取主表ID列表用于批量查询子表数据
        List<Long> masterIds = entityPage.getRecords().stream()
                .map(ProductionMaster::getId)
                .collect(Collectors.toList());
 
        // 4. 批量查询关联数据(避免N+1问题)
        Map<Long, List<Production>> productionMap = queryProductionByMasterIds(masterIds);
        Map<Long, List<ProductionInventory>> inventoryMap = queryInventoryByMasterIds(masterIds);
 
        // 5. 转换数据并组装结果
        List<ProductionMasterDto> dtoList = entityPage.getRecords().stream()
                .map(record -> {
                    ProductionMasterDto dto = new ProductionMasterDto();
                    BeanUtils.copyProperties(record, dto);
                    dto.setProductionList(productionMap.getOrDefault(record.getId(), Collections.emptyList()));
                    dto.setProductionInventoryList(inventoryMap.getOrDefault(record.getId(), Collections.emptyList()));
                    return dto;
                })
                .collect(Collectors.toList());
 
        // 6. 构建返回结果
        IPage<ProductionMasterDto> dtoPage = new Page<>();
        BeanUtils.copyProperties(entityPage, dtoPage, "records");
        dtoPage.setRecords(dtoList);
 
        return dtoPage;
    }
 
    /**
     * 批量查询Production数据
     */
    private Map<Long, List<Production>> queryProductionByMasterIds(List<Long> masterIds) {
        if (masterIds.isEmpty()) {
            return Collections.emptyMap();
        }
 
        LambdaQueryWrapper<Production> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(Production::getProductionMasterId, masterIds);
        List<Production> productions = productionMapper.selectList(queryWrapper);
 
        return productions.stream()
                .collect(Collectors.groupingBy(Production::getProductionMasterId));
    }
 
    /**
     * 批量查询ProductionInventory数据
     */
    private Map<Long, List<ProductionInventory>> queryInventoryByMasterIds(List<Long> masterIds) {
        if (masterIds.isEmpty()) {
            return Collections.emptyMap();
        }
 
        LambdaQueryWrapper<ProductionInventory> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(ProductionInventory::getProductionMasterId, masterIds);
        List<ProductionInventory> inventoryList = productionInventoryMapper.selectList(queryWrapper);
 
        return inventoryList.stream()
                .collect(Collectors.groupingBy(ProductionInventory::getProductionMasterId));
    }
 
    @Override
    @Transactional
    public int addOrEditPM(ProductionMasterDto productionMasterDto) {
        // 1. 直接计算聚合值,避免创建多余列表
        BigDecimal totalPurchasePrice = BigDecimal.ZERO;
        BigDecimal totalLaborCost = BigDecimal.ZERO;
        BigDecimal totalEnergyConsumptionCost = BigDecimal.ZERO;
        BigDecimal totalTotalCost = BigDecimal.ZERO;
        BigDecimal totalEquipmentDepreciation = BigDecimal.ZERO;
        int totalProductionQuantity = 0;
        StringBuilder coalBuilder = new StringBuilder("["); // 优化字符串拼接
 
        for (Production production : productionMasterDto.getProductionList()) {
            totalPurchasePrice = totalPurchasePrice.add(production.getPurchasePrice());
            totalLaborCost = totalLaborCost.add(production.getLaborCost());
            totalEnergyConsumptionCost = totalEnergyConsumptionCost.add(production.getEnergyConsumptionCost());
            totalTotalCost = totalTotalCost.add(production.getTotalCost());
            totalEquipmentDepreciation = totalEquipmentDepreciation.add(production.getEquipmentDepreciation());
            totalProductionQuantity += production.getProductionQuantity();
            coalBuilder.append(production.getCoal()).append(",");
        }
 
        // 处理coal字符串拼接
        String coalStr = coalBuilder.length() > 1 ?
                coalBuilder.deleteCharAt(coalBuilder.length()-1).append("]").toString() : "[]";
 
        // 2. 创建主表对象
        ProductionMaster productionMaster = new ProductionMaster();
        productionMaster.setProductionQuantity(totalProductionQuantity);
        productionMaster.setTotalCost(totalTotalCost);
        productionMaster.setEquipmentDepreciation(totalEquipmentDepreciation);
        productionMaster.setEnergyConsumptionCost(totalEnergyConsumptionCost);
        productionMaster.setLaborCost(totalLaborCost);
        productionMaster.setCoal(coalStr);
 
        Long masterId = productionMasterDto.getId();
        productionMaster.setId(masterId);
 
        // 3. 统一子表处理逻辑
        if (masterId == null) {
            productionMasterMapper.insert(productionMaster);
            masterId = productionMaster.getId(); // 获取新生成的ID
        } else {
            // 删除关联子表数据(使用更高效的in删除)
            productionMapper.delete(new LambdaQueryWrapper<Production>()
                    .eq(Production::getProductionMasterId, masterId));
 
            productionInventoryMapper.delete(new LambdaQueryWrapper<ProductionInventory>()
                    .eq(ProductionInventory::getProductionMasterId, masterId));
 
            productionMasterMapper.updateById(productionMaster);
        }
 
        // 4. 批量插入子表数据
        batchInsertProductions(masterId, productionMasterDto.getProductionList());
        batchInsertInventories(masterId, productionMasterDto.getProductionInventoryList());
 
        return 1;
    }
 
    // 批量插入生产数据
    private void batchInsertProductions(Long masterId, List<Production> productions) {
        List<Production> insertList = productions.stream()
                .peek(p -> {
                    p.setId(null);
                    p.setProductionMasterId(masterId);
                })
                .collect(Collectors.toList());
 
        if (!insertList.isEmpty()) {
            for (Production production : productions) {
                production.setId(null);
                production.setProductionMasterId(masterId);
                productionMapper.insert(production);
            }
        }
    }
 
    // 批量插入库存数据
    private void batchInsertInventories(Long masterId, List<ProductionInventory> inventories) {
        List<ProductionInventory> insertList = inventories.stream()
                .peek(inv -> {
                    inv.setId(null);
                    inv.setProductionMasterId(masterId);
                })
                .collect(Collectors.toList());
 
        if (!insertList.isEmpty()) {
            for (ProductionInventory inventory : inventories) {
                inventory.setId(null);
                inventory.setProductionMasterId(masterId);
                productionInventoryMapper.insert(inventory);
            }
        }
    }
 
    @Override
    public int delByIds(Long[] ids) {
        return 0;
    }
}