From a4a1dfdf28789ba6b649cc4b8a5d8e6025f52a0f Mon Sep 17 00:00:00 2001
From: gongchunyi <deslre0381@gmail.com>
Date: 星期五, 10 四月 2026 16:53:22 +0800
Subject: [PATCH] fix:生产订单绑定工艺路线清空绑定的BOM结构
---
src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java | 471 ++++++++++++++++++++++++++++++++++++++++++++++++++--------
1 files changed, 406 insertions(+), 65 deletions(-)
diff --git a/src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java b/src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java
index 8d7b825..acd2b54 100644
--- a/src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java
+++ b/src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java
@@ -36,6 +36,8 @@
import com.ruoyi.productionPlan.enums.AddressRegionEnum;
import com.ruoyi.productionPlan.mapper.SalesDeliveryMapper;
import com.ruoyi.productionPlan.pojo.SalesDelivery;
+import com.ruoyi.productionPlan.pojo.ProductionPlan;
+import com.ruoyi.productionPlan.service.ProductionPlanService;
import com.ruoyi.project.system.domain.SysDept;
import com.ruoyi.project.system.domain.SysDictData;
import com.ruoyi.project.system.mapper.SysDeptMapper;
@@ -58,8 +60,10 @@
import com.ruoyi.staff.mapper.StaffOnJobMapper;
import com.ruoyi.staff.pojo.StaffOnJob;
import com.ruoyi.stock.mapper.StockInventoryMapper;
-import com.ruoyi.energy.mapper.EnergyConsumptionDetailMapper;
+import com.ruoyi.energy.mapper.EnergyMapper;
+import com.ruoyi.energy.pojo.Energy;
import com.ruoyi.energy.dto.EnergyCostDto;
+import com.ruoyi.energy.mapper.EnergyConsumptionDetailMapper;
import com.ruoyi.energy.vo.EnergyStatisticsVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@@ -158,6 +162,10 @@
@Autowired
private SalesDeliveryMapper salesDeliveryMapper;
+
+ @Autowired
+ private EnergyMapper energyMapper;
+
@Override
public HomeBusinessDto business() {
@@ -2558,7 +2566,7 @@
lastDay = date.with(TemporalAdjusters.lastDayOfYear());
}
LocalDate finalLastDay = lastDay;
- salesDeliveries = salesDeliveries
+ List<SalesDelivery> salesDeliverie = salesDeliveries
.stream()
.filter(delivery -> {
LocalDate deliveryDate = delivery.getDeliveryDate();
@@ -2570,9 +2578,9 @@
AddressRegionEnum::getRegionName, // 鍖哄煙鍚嶄綔涓簁ey
enumItem -> 0L // 鍒濆鍊煎叏閮ㄤ负0
));
- if (!CollectionUtils.isEmpty(salesDeliveries)) {
+ if (!CollectionUtils.isEmpty(salesDeliverie)) {
// 鎸夊尯鍩熷垎缁勶紝缁熻姣忎釜鍖哄煙鐨勯攢閲忔�诲拰
- regionCountMap = salesDeliveries.stream()
+ regionCountMap = salesDeliverie.stream()
.filter(delivery -> delivery.getDeliveryPlace() != null)
.collect(Collectors.groupingBy(
delivery -> {
@@ -2582,7 +2590,7 @@
Collectors.summingLong(delivery -> delivery.getVolume() != null ? delivery.getVolume().longValue() : 0L)
));
}
- regionCountMap.put("鍏ㄩ儴", salesDeliveries.stream()
+ regionCountMap.put("鍏ㄩ儴", salesDeliverie.stream()
.mapToLong(item -> item.getVolume() != null ? item.getVolume().longValue() : 0L)
.sum());
maps.add(regionCountMap);
@@ -2590,54 +2598,6 @@
salesTotalDto.setDates(dates);
salesTotalDto.setCustomerTrends(maps);
return salesTotalDto;
- }
-
- @Override
- public List<SalesTotalDetailDto> salesRanking(SalesDeliveryDto salesDeliveryDto) {
- List<SalesTotalDetailDto> salesTotalDetailDtos = new ArrayList<>();
- List<LocalDate> dates = convertDateList(salesDeliveryDto.getDays());
- List<SalesDelivery> salesDeliveries = salesDeliveryMapper.selectList(Wrappers.<SalesDelivery>lambdaQuery()
- .eq(SalesDelivery::getProductName, salesDeliveryDto.getType()));
- for (LocalDate date : dates) {
- LocalDate firstDay = date.with(TemporalAdjusters.firstDayOfMonth());
- LocalDate lastDay = date.with(TemporalAdjusters.lastDayOfMonth());
- if (salesDeliveryDto.getDays().equals("骞�")) {
- lastDay = date.with(TemporalAdjusters.lastDayOfYear());
- }
- LocalDate finalLastDay = lastDay;
- salesDeliveries = salesDeliveries
- .stream()
- .filter(delivery -> {
- LocalDate deliveryDate = delivery.getDeliveryDate();
- return !deliveryDate.isBefore(firstDay) && !deliveryDate.isAfter(finalLastDay);
- })
- .collect(Collectors.toList());
- Map<String, Long> regionCountMap = Arrays.stream(AddressRegionEnum.values())
- .collect(Collectors.toMap(
- AddressRegionEnum::getRegionName, // 鍖哄煙鍚嶄綔涓簁ey
- enumItem -> 0L // 鍒濆鍊煎叏閮ㄤ负0
- ));
- if (!CollectionUtils.isEmpty(salesDeliveries)) {
- // 鎸夊尯鍩熷垎缁勶紝缁熻姣忎釜鍖哄煙鐨勯攢閲忔�诲拰
- regionCountMap = salesDeliveries.stream()
- .filter(delivery -> delivery.getDeliveryPlace() != null)
- .collect(Collectors.groupingBy(
- delivery -> {
- AddressRegionEnum regionEnum = AddressRegionEnum.matchRegion(delivery.getDeliveryPlace());
- return regionEnum != null ? regionEnum.getRegionName() : null;
- },
- Collectors.summingLong(delivery -> delivery.getVolume() != null ? delivery.getVolume().longValue() : 0L)
- ));
- }
- regionCountMap.put("鍏ㄩ儴", salesDeliveries.stream()
- .mapToLong(item -> item.getVolume() != null ? item.getVolume().longValue() : 0L)
- .sum());
- SalesTotalDetailDto salesTotalDetailDto = new SalesTotalDetailDto();
- salesTotalDetailDto.setDate(date);
- salesTotalDetailDto.setType(salesDeliveryDto.getType());
- salesTotalDetailDtos.add(salesTotalDetailDto);
- }
- return salesTotalDetailDtos;
}
@Override
@@ -2654,7 +2614,7 @@
lastDay = date.with(TemporalAdjusters.lastDayOfYear());
}
LocalDate finalLastDay = lastDay;
- salesDeliveries = salesDeliveries
+ List<SalesDelivery> salesDeliverie = salesDeliveries
.stream()
.filter(delivery -> {
LocalDate deliveryDate = delivery.getDeliveryDate();
@@ -2666,9 +2626,9 @@
AddressRegionEnum::getRegionName, // 鍖哄煙鍚嶄綔涓簁ey
enumItem -> 0L // 鍒濆鍊煎叏閮ㄤ负0
));
- if (!CollectionUtils.isEmpty(salesDeliveries)) {
+ if (!CollectionUtils.isEmpty(salesDeliverie)) {
// 鎸夊尯鍩熷垎缁勶紝缁熻姣忎釜鍖哄煙鐨勯攢閲忔�诲拰
- regionCountMap = salesDeliveries.stream()
+ regionCountMap = salesDeliverie.stream()
.filter(delivery -> delivery.getDeliveryPlace() != null)
.collect(Collectors.groupingBy(
delivery -> {
@@ -2678,7 +2638,7 @@
Collectors.summingLong(delivery -> delivery.getPrice() != null ? delivery.getPrice().longValue() : 0L)
));
}
- regionCountMap.put("鍏ㄩ儴", salesDeliveries.stream()
+ regionCountMap.put("鍏ㄩ儴", salesDeliverie.stream()
.mapToLong(item -> item.getPrice() != null ? item.getPrice().longValue() : 0L)
.sum());
maps.add(regionCountMap);
@@ -2686,14 +2646,6 @@
salesTotalDto.setDates(dates);
salesTotalDto.setCustomerTrends(maps);
return salesTotalDto;
- }
-
- @Override
- public List<SalesTotalDetailDto> salesDataRanking(SalesDeliveryDto salesDeliveryDto) {
- List<SalesTotalDetailDto> salesTotalDetailDtos = new ArrayList<>();
- List<LocalDate> dates = convertDateList(salesDeliveryDto.getDays());
-
- return salesTotalDetailDtos;
}
@Override
@@ -3405,6 +3357,13 @@
}
if (!CollectionUtils.isEmpty(costDtos)) {
+ // 鑾峰彇鍗曚綅
+ List<Energy> energies = energyMapper.selectList(Wrappers.<Energy>lambdaQuery()
+ .in(Energy::getEnergyTyep, Arrays.asList("姘�", "鐢�", "姘�")));
+ String waterUnit = energies.stream().filter(e -> "姘�".equals(e.getEnergyTyep())).map(Energy::getUnit).findFirst().orElse("");
+ String electricityUnit = energies.stream().filter(e -> "鐢�".equals(e.getEnergyTyep())).map(Energy::getUnit).findFirst().orElse("");
+ String steamUnit = energies.stream().filter(e -> "姘�".equals(e.getEnergyTyep())).map(Energy::getUnit).findFirst().orElse("");
+
for (EnergyCostDto costDto : costDtos) {
String dateStr = costDto.getMeterReadingDate();
String label = "";
@@ -3427,11 +3386,165 @@
dayDto.setWater(water);
dayDto.setElectricity(electricity);
dayDto.setSteam(steam);
+ dayDto.setWaterUnit(waterUnit);
+ dayDto.setElectricityUnit(electricityUnit);
+ dayDto.setSteamUnit(steamUnit);
}
}
}
return new ArrayList<>(resultData.values());
+ }
+
+ @Override
+ public SolidWasteCoreIndicatorsDto coreIndicators(productionStatisticsDto dto) {
+ if (dto == null) {
+ dto = new productionStatisticsDto();
+ dto.setDateType(1);
+ }
+
+ LocalDate now = LocalDate.now();
+ LocalDate startDate = null;
+ if (dto.getDateType() != null && dto.getDateType() == 1) { // 鏈湀鑷充粖
+ startDate = now.withDayOfMonth(1);
+ } else { // 鏈勾鑷充粖
+ startDate = now.withDayOfYear(1);
+ }
+
+ // 绱娑堢撼閲忎粠2022-01-01寮�濮�
+ LocalDate cumulativeStartDate = LocalDate.of(2022, 1, 1);
+ // 鏌ヨ浠�2022-01-01鑷充粖鐨勬墍鏈夋姤宸ユ暟鎹�
+ List<ProductionProductMain> mainList = productionProductMainService.list(Wrappers.<ProductionProductMain>lambdaQuery()
+ .ge(ProductionProductMain::getReportingTime, cumulativeStartDate.atStartOfDay()));
+ if (CollectionUtils.isEmpty(mainList)) return new SolidWasteCoreIndicatorsDto();
+
+ List<Long> mainIds = mainList.stream().map(ProductionProductMain::getId).collect(Collectors.toList());
+ Map<Long, ProductionProductMain> mainMap = mainList.stream().collect(Collectors.toMap(ProductionProductMain::getId, m -> m));
+
+ // 鑾峰彇鎶曞叆鏄庣粏
+ List<ProductionProductInput> allInputs = productionProductInputService.list(Wrappers.<ProductionProductInput>lambdaQuery()
+ .in(ProductionProductInput::getProductMainId, mainIds));
+ if (CollectionUtils.isEmpty(allInputs)) return new SolidWasteCoreIndicatorsDto();
+
+ // 鑾峰彇瑙勬牸鍜岀墿鏂欏悕绉�
+ Set<Long> skuIds = allInputs.stream().map(ProductionProductInput::getProductId).filter(Objects::nonNull).collect(Collectors.toSet());
+ Map<Long, String> skuToMaterialNameMap = new HashMap<>();
+ if (!skuIds.isEmpty()) {
+ List<ProductMaterialSku> skus = productMaterialSkuService.listByIds(skuIds);
+ Set<Long> productIds = skus.stream().map(ProductMaterialSku::getProductId).filter(Objects::nonNull).collect(Collectors.toSet());
+ Map<Long, String> materialNameMap = productMaterialService.listByIds(productIds).stream()
+ .collect(Collectors.toMap(ProductMaterial::getId, ProductMaterial::getProductName));
+ skuToMaterialNameMap = skus.stream()
+ .filter(s -> s.getProductId() != null && materialNameMap.containsKey(s.getProductId()))
+ .collect(Collectors.toMap(ProductMaterialSku::getId, s -> materialNameMap.get(s.getProductId())));
+ }
+
+ BigDecimal totalAmount = BigDecimal.ZERO;
+ BigDecimal cumulativeAmount = BigDecimal.ZERO;
+
+ Set<String> targetMaterials = new HashSet<>(Arrays.asList("绮夌叅鐏�", "鐭宠啅", "鐭崇伆"));
+
+ for (ProductionProductInput input : allInputs) {
+ String materialName = skuToMaterialNameMap.get(input.getProductId());
+ if (materialName == null || !targetMaterials.contains(materialName)) continue;
+
+ ProductionProductMain main = mainMap.get(input.getProductMainId());
+ if (main == null || main.getReportingTime() == null) continue;
+
+ BigDecimal qty = UnitUtils.convertValueToTon(input.getQuantity(), input.getUnit());
+ // 绱姞绱娑堢撼閲�
+ cumulativeAmount = cumulativeAmount.add(qty);
+
+ if (!main.getReportingTime().toLocalDate().isBefore(startDate)) {
+ totalAmount = totalAmount.add(qty);
+ }
+ }
+
+ SolidWasteCoreIndicatorsDto result = new SolidWasteCoreIndicatorsDto();
+ result.setTotalAmount(totalAmount.setScale(2, RoundingMode.HALF_UP));
+ result.setCumulativeAmount(cumulativeAmount.setScale(2, RoundingMode.HALF_UP));
+ return result;
+ }
+
+ @Override
+ public List<SolidWasteStatisticsDto> trends(productionStatisticsDto dto) {
+ return solidWaste(dto);
+ }
+
+ @Override
+ public List<MapDto> typeDistribution(productionStatisticsDto dto) {
+ if (dto == null) {
+ dto = new productionStatisticsDto();
+ dto.setDateType(1);
+ }
+
+ LocalDate now = LocalDate.now();
+ LocalDate startDate = null;
+ if (dto.getDateType() != null && dto.getDateType() == 1) { // 鏈湀鑷充粖
+ startDate = now.withDayOfMonth(1);
+ } else { // 鏈勾鑷充粖
+ startDate = now.withDayOfYear(1);
+ }
+
+ // 鏌ヨ鎶ュ伐涓昏〃
+ List<ProductionProductMain> mainList = productionProductMainService.list(Wrappers.<ProductionProductMain>lambdaQuery()
+ .ge(ProductionProductMain::getReportingTime, startDate.atStartOfDay()));
+ if (CollectionUtils.isEmpty(mainList)) return new ArrayList<>();
+
+ List<Long> mainIds = mainList.stream().map(ProductionProductMain::getId).collect(Collectors.toList());
+
+ // 鑾峰彇鎶曞叆鏄庣粏
+ List<ProductionProductInput> allInputs = productionProductInputService.list(Wrappers.<ProductionProductInput>lambdaQuery()
+ .in(ProductionProductInput::getProductMainId, mainIds));
+ if (CollectionUtils.isEmpty(allInputs)) return new ArrayList<>();
+
+ // 鑾峰彇瑙勬牸鍜岀墿鏂欏悕绉�
+ Set<Long> skuIds = allInputs.stream().map(ProductionProductInput::getProductId).filter(Objects::nonNull).collect(Collectors.toSet());
+ Map<Long, String> skuToMaterialNameMap = new HashMap<>();
+ if (!skuIds.isEmpty()) {
+ List<ProductMaterialSku> skus = productMaterialSkuService.listByIds(skuIds);
+ Set<Long> productIds = skus.stream().map(ProductMaterialSku::getProductId).filter(Objects::nonNull).collect(Collectors.toSet());
+ Map<Long, String> materialNameMap = productMaterialService.listByIds(productIds).stream()
+ .collect(Collectors.toMap(ProductMaterial::getId, ProductMaterial::getProductName));
+ skuToMaterialNameMap = skus.stream()
+ .filter(s -> s.getProductId() != null && materialNameMap.containsKey(s.getProductId()))
+ .collect(Collectors.toMap(ProductMaterialSku::getId, s -> materialNameMap.get(s.getProductId())));
+ }
+
+ Map<String, BigDecimal> countMap = new HashMap<>();
+ countMap.put("绮夌叅鐏�", BigDecimal.ZERO);
+ countMap.put("鐭宠啅", BigDecimal.ZERO);
+ countMap.put("鐭崇伆", BigDecimal.ZERO);
+
+ BigDecimal total = BigDecimal.ZERO;
+
+ for (ProductionProductInput input : allInputs) {
+ String materialName = skuToMaterialNameMap.get(input.getProductId());
+ if (materialName == null || !countMap.containsKey(materialName)) continue;
+
+ BigDecimal qty = UnitUtils.convertValueToTon(input.getQuantity(), input.getUnit());
+ countMap.put(materialName, countMap.get(materialName).add(qty));
+ total = total.add(qty);
+ }
+
+ List<MapDto> result = new ArrayList<>();
+ for (Map.Entry<String, BigDecimal> entry : countMap.entrySet()) {
+ MapDto mapDto = new MapDto();
+ mapDto.setName(entry.getKey());
+ BigDecimal value = entry.getValue().setScale(2, RoundingMode.HALF_UP);
+ mapDto.setValue(value.toString());
+
+ if (total.compareTo(BigDecimal.ZERO) > 0) {
+ BigDecimal rate = entry.getValue().divide(total, 4, RoundingMode.HALF_UP)
+ .multiply(new BigDecimal("100")).setScale(2, RoundingMode.HALF_UP);
+ mapDto.setRate(rate.toString());
+ } else {
+ mapDto.setRate("0.00");
+ }
+ result.add(mapDto);
+ }
+
+ return result;
}
@Override
@@ -3454,4 +3567,232 @@
map.put("materialInspection", materialInspection);
return map;
}
+
+ @Autowired
+ private ProductionPlanService productionPlanService;
+
+ @Override
+ public List<PlanTrendsDto> planTrends(Integer type) {
+ LocalDate now = LocalDate.now();
+ LocalDate startDate;
+ DateTimeFormatter formatter;
+ int points;
+
+ if (type == null) type = 1;
+
+ if (type == 1) { // 鍛�
+ startDate = now.with(DayOfWeek.MONDAY);
+ points = (int) ChronoUnit.DAYS.between(startDate, now) + 1;
+ formatter = DateTimeFormatter.ofPattern("MM-dd");
+ } else if (type == 2) { // 鏈�
+ startDate = now.with(TemporalAdjusters.firstDayOfMonth());
+ points = now.getDayOfMonth();
+ formatter = DateTimeFormatter.ofPattern("MM-dd");
+ } else { // 骞�
+ startDate = now.with(TemporalAdjusters.firstDayOfYear());
+ points = now.getMonthValue();
+ formatter = DateTimeFormatter.ofPattern("yyyy-MM");
+ }
+
+ Map<String, PlanTrendsDto> resultMap = new LinkedHashMap<>();
+ for (int i = 0; i < points; i++) {
+ String label = (type == 3)
+ ? startDate.plusMonths(i).format(formatter)
+ : startDate.plusDays(i).format(formatter);
+ PlanTrendsDto dto = new PlanTrendsDto();
+ dto.setDateStr(label);
+ dto.setPlannedVolume(BigDecimal.ZERO);
+ dto.setLowerVolume(BigDecimal.ZERO);
+ dto.setCompletionVolume(BigDecimal.ZERO);
+ resultMap.put(label, dto);
+ }
+ // 缁熻璁″垝閲�
+ List<ProductionPlan> plans = productionPlanService.list(Wrappers.<ProductionPlan>lambdaQuery()
+ .ge(ProductionPlan::getStartDate, Date.from(startDate.atStartOfDay(ZoneId.systemDefault()).toInstant())));
+ for (ProductionPlan plan : plans) {
+ if (plan.getStartDate() == null || plan.getVolume() == null) continue;
+ LocalDate d = plan.getStartDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
+ String label = d.format(formatter);
+ if (resultMap.containsKey(label)) {
+ PlanTrendsDto dto = resultMap.get(label);
+ dto.setPlannedVolume(dto.getPlannedVolume().add(plan.getVolume()));
+ }
+ }
+ // 缁熻涓嬪彂閲�
+ List<ProductOrder> orders = productOrderMapper.selectList(Wrappers.<ProductOrder>lambdaQuery()
+ .ge(ProductOrder::getStartTime, startDate.atStartOfDay()));
+ for (ProductOrder order : orders) {
+ if (order.getStartTime() == null || order.getQuantity() == null) continue;
+ LocalDate d = order.getStartTime().toLocalDate();
+ String label = d.format(formatter);
+ if (resultMap.containsKey(label)) {
+ PlanTrendsDto dto = resultMap.get(label);
+ dto.setLowerVolume(dto.getLowerVolume().add(order.getQuantity()));
+ }
+ }
+ // 缁熻瀹屾垚閲�
+ List<ProductionProductOutput> outputs = productionProductOutputMapper.selectList(Wrappers.<ProductionProductOutput>lambdaQuery()
+ .ge(ProductionProductOutput::getCreateTime, startDate.atStartOfDay()));
+ for (ProductionProductOutput output : outputs) {
+ if (output.getCreateTime() == null || output.getQuantity() == null) continue;
+ LocalDate d = output.getCreateTime().toLocalDate();
+ String label = d.format(formatter);
+ if (resultMap.containsKey(label)) {
+ PlanTrendsDto dto = resultMap.get(label);
+ dto.setCompletionVolume(dto.getCompletionVolume().add(output.getQuantity()));
+ }
+ }
+
+ return new ArrayList<>(resultMap.values());
+ }
+ @Override
+ public List<RawMaterialProductionDto> rawMaterialProductions(String month) {
+ YearMonth yearMonth;
+ try {
+ yearMonth = YearMonth.parse(month);
+ } catch (Exception e) {
+ log.error("瑙f瀽鏈堜唤澶辫触: {}", month);
+ return Collections.emptyList();
+ }
+ LocalDateTime monthStart = yearMonth.atDay(1).atStartOfDay();
+ LocalDateTime monthEnd = yearMonth.atEndOfMonth().atTime(LocalTime.MAX);
+
+ // 鑾峰彇浜у搧绫诲瀷瀛楀吀
+ List<SysDictData> sysDictDataList = sysDictDataMapper.selectDictDataByType("product_type");
+ Map<Long, String> dictCodeToLabelMap = sysDictDataList.stream()
+ .filter(d -> d.getDictCode() != null && d.getDictLabel() != null)
+ .collect(Collectors.toMap(SysDictData::getDictCode, SysDictData::getDictLabel));
+
+ // 鏌ヨ褰撴湀鎶ュ伐涓昏〃
+ List<ProductionProductMain> mainList = productionProductMainService.list(Wrappers.<ProductionProductMain>lambdaQuery()
+ .between(ProductionProductMain::getReportingTime, monthStart, monthEnd));
+
+ if (CollectionUtils.isEmpty(mainList)) {
+ return Collections.emptyList();
+ }
+
+ List<Long> mainIds = mainList.stream().map(ProductionProductMain::getId).collect(Collectors.toList());
+ List<Long> orderIds = mainList.stream().map(ProductionProductMain::getProductOrderId).distinct().collect(Collectors.toList());
+ Map<Long, ProductionProductMain> mainMap = mainList.stream().collect(Collectors.toMap(ProductionProductMain::getId, m -> m));
+
+ // 鑾峰彇璁㈠崟瀵瑰簲鐨勪骇鍝佺被鍨�
+ Map<Long, Long> orderRouteMap = new HashMap<>();
+ if (!CollectionUtils.isEmpty(orderIds)) {
+ List<ProductionOrderRoute> routes = productionOrderRouteService.list(Wrappers.<ProductionOrderRoute>lambdaQuery()
+ .in(ProductionOrderRoute::getOrderId, orderIds));
+ orderRouteMap = routes.stream()
+ .filter(r -> r.getOrderId() != null && r.getDictCode() != null)
+ .collect(Collectors.toMap(ProductionOrderRoute::getOrderId, ProductionOrderRoute::getDictCode, (v1, v2) -> v1));
+ }
+
+ // 鑾峰彇鎶曞叆鍜屼骇鍑烘槑缁�
+ List<ProductionProductInput> allInputs = productionProductInputService.list(Wrappers.<ProductionProductInput>lambdaQuery()
+ .in(ProductionProductInput::getProductMainId, mainIds));
+ List<ProductionProductOutput> allOutputs = productionProductOutputService.list(Wrappers.<ProductionProductOutput>lambdaQuery()
+ .in(ProductionProductOutput::getProductMainId, mainIds));
+
+ // 鑾峰彇 SKU 鐨勭墿鏂欏悕绉�
+ Set<Long> inputSkuIds = allInputs.stream().map(ProductionProductInput::getProductId).filter(Objects::nonNull).collect(Collectors.toSet());
+ Map<Long, String> skuToMaterialNameMap = new HashMap<>();
+ if (!inputSkuIds.isEmpty()) {
+ List<ProductMaterialSku> skus = productMaterialSkuService.listByIds(inputSkuIds);
+ Set<Long> productIds = skus.stream().map(ProductMaterialSku::getProductId).filter(Objects::nonNull).collect(Collectors.toSet());
+ Map<Long, String> materialNameMap = productMaterialService.listByIds(productIds).stream()
+ .collect(Collectors.toMap(ProductMaterial::getId, ProductMaterial::getProductName));
+ skuToMaterialNameMap = skus.stream()
+ .filter(s -> s.getProductId() != null && materialNameMap.containsKey(s.getProductId()))
+ .collect(Collectors.toMap(ProductMaterialSku::getId, s -> materialNameMap.get(s.getProductId())));
+ }
+
+ BigDecimal yield35 = BigDecimal.ZERO;
+ BigDecimal yield50 = BigDecimal.ZERO;
+ BigDecimal yieldPlate = BigDecimal.ZERO;
+
+ // 鏉愯川鍚嶇О -> [3.5鐢ㄩ噺, 5.0鐢ㄩ噺, 鏉挎潗鐢ㄩ噺]
+ Map<String, BigDecimal[]> materialConsumptionMap = new LinkedHashMap<>();
+
+ // 缁熻浜ч噺
+ for (ProductionProductOutput output : allOutputs) {
+ ProductionProductMain main = mainMap.get(output.getProductMainId());
+ if (main == null) continue;
+ Long dictCode = orderRouteMap.get(main.getProductOrderId());
+ String label = dictCodeToLabelMap.get(dictCode);
+ BigDecimal qty = output.getQuantity() != null ? output.getQuantity() : BigDecimal.ZERO;
+
+ if (label != null) {
+ if (label.contains("3.5")) yield35 = yield35.add(qty);
+ else if (label.contains("5.0")) yield50 = yield50.add(qty);
+ else if (label.contains("鏉挎潗")) yieldPlate = yieldPlate.add(qty);
+ }
+ }
+
+ // 缁熻娑堣�楅噺
+ for (ProductionProductInput input : allInputs) {
+ ProductionProductMain main = mainMap.get(input.getProductMainId());
+ if (main == null) continue;
+ Long dictCode = orderRouteMap.get(main.getProductOrderId());
+ String label = dictCodeToLabelMap.get(dictCode);
+ String materialName = skuToMaterialNameMap.get(input.getProductId());
+ if (materialName == null) continue;
+
+ BigDecimal qty = UnitUtils.convertValueToTon(input.getQuantity(), input.getUnit());
+
+ materialConsumptionMap.putIfAbsent(materialName, new BigDecimal[]{BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO});
+ BigDecimal[] consumptions = materialConsumptionMap.get(materialName);
+
+ if (label != null) {
+ if (label.contains("3.5")) consumptions[0] = consumptions[0].add(qty);
+ else if (label.contains("5.0")) consumptions[1] = consumptions[1].add(qty);
+ else if (label.contains("鏉挎潗")) consumptions[2] = consumptions[2].add(qty);
+ }
+ }
+
+ List<RawMaterialProductionDto> result = new ArrayList<>();
+
+ // 浜ч噺琛�
+ RawMaterialProductionDto yieldRow = new RawMaterialProductionDto();
+ yieldRow.setItemName("浜ч噺");
+ yieldRow.setUsage35(yield35);
+ yieldRow.setUsage50(yield50);
+ yieldRow.setUsagePlate(yieldPlate);
+ yieldRow.setTotalUsage(yield35.add(yield50).add(yieldPlate));
+ yieldRow.setBlockTotalUsage(yield35.add(yield50));
+ result.add(yieldRow);
+
+ // 鐗╂枡琛�
+ List<String> targetMaterials = Arrays.asList(
+ "绮夌叅鐏�", "姘存偿", "鐭崇伆", "閾濈矇", "鐭宠啅", "鑴辨ā鍓�",
+ "鎵撳寘甯�", "鍐锋嫈涓�", "姘у寲闀�", "鍗℃墸", "闃茶厫鍓�"
+ );
+
+ for (String materialName : targetMaterials) {
+ BigDecimal[] consumptions = materialConsumptionMap.getOrDefault(materialName,
+ new BigDecimal[]{BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO});
+
+ RawMaterialProductionDto row = new RawMaterialProductionDto();
+ row.setItemName(materialName);
+ row.setUsage35(consumptions[0]);
+ row.setUsage50(consumptions[1]);
+ row.setUsagePlate(consumptions[2]);
+
+ // 璁$畻鍗曡��
+ row.setUnitConsumption35(calculateUnitConsumption(consumptions[0], yield35));
+ row.setUnitConsumption50(calculateUnitConsumption(consumptions[1], yield50));
+ row.setUnitConsumptionPlate(calculateUnitConsumption(consumptions[2], yieldPlate));
+
+ row.setTotalUsage(consumptions[0].add(consumptions[1]).add(consumptions[2]));
+ row.setBlockTotalUsage(consumptions[0].add(consumptions[1]));
+ result.add(row);
+ }
+
+ return result;
+ }
+
+ private BigDecimal calculateUnitConsumption(BigDecimal usage, BigDecimal yield) {
+ if (yield == null || yield.compareTo(BigDecimal.ZERO) == 0) {
+ return BigDecimal.ZERO;
+ }
+ return usage.divide(yield, 4, RoundingMode.HALF_UP);
+ }
+
}
--
Gitblit v1.9.3