package com.ruoyi.production.service.impl; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.production.dto.GroupKeyDto; import com.ruoyi.production.dto.ProductionCostAccountDto; import com.ruoyi.production.mapper.ProductionCostMapper; import com.ruoyi.production.service.ProductionCostService; import com.ruoyi.production.utils.UnitUtils; import com.ruoyi.production.vo.ProductionCostAggregationVo; import com.ruoyi.production.vo.ProductionCostSummaryVo; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.*; import java.util.stream.Collectors; /** *
* 生产成本核算服务接口实现类 *
* * @author deslrey * @version 1.0 * @since 2026/03/30 11:21 */ @Slf4j @Service public class ProductionCostServiceImpl implements ProductionCostService { @Autowired private ProductionCostMapper productionCostMapper; @Override public ProductionCostSummaryVo getCostSummary(ProductionCostAccountDto dto) { if (dto.getEndDate() != null) { dto.setEndDate(dto.getEndDate().plusDays(1)); } return productionCostMapper.selectCostSummary(dto); } @Override public IPage getProductAggregationPage(Page page, ProductionCostAccountDto dto) { dto.setGroupType(1); // 按产品汇总 List fullList = getCostAggregationList(dto); return getMemoryPage(page, fullList); } @Override public IPage getOrderAggregationPage(Page page, ProductionCostAccountDto dto) { dto.setGroupType(2); // 按订单汇总 List fullList = getCostAggregationList(dto); return getMemoryPage(page, fullList); } @Override public List getProductTop(ProductionCostAccountDto dto) { dto.setGroupType(1); List fullList = getCostAggregationList(dto); if (fullList.isEmpty()) { return new ArrayList<>(); } Map topMap = new HashMap<>(); for (ProductionCostAggregationVo vo : fullList) { String name = vo.getName(); if (topMap.containsKey(name)) { ProductionCostAggregationVo existing = topMap.get(name); existing.setTotalCost(existing.getTotalCost().add(vo.getTotalCost())); existing.setQuantity(existing.getQuantity().add(vo.getQuantity())); } else { ProductionCostAggregationVo clone = new ProductionCostAggregationVo(); clone.setName(name); clone.setTotalCost(vo.getTotalCost()); clone.setQuantity(vo.getQuantity()); clone.setUnit(vo.getUnit()); topMap.put(name, clone); } } return topMap.values().stream() .sorted(Comparator.comparing(ProductionCostAggregationVo::getTotalCost).reversed()) .limit(10) .collect(Collectors.toList()); } @Override public List getOrderTop(ProductionCostAccountDto dto) { dto.setGroupType(2); List fullList = getCostAggregationList(dto); if (fullList.isEmpty()) { return new ArrayList<>(); } Map topMap = new HashMap<>(); for (ProductionCostAggregationVo vo : fullList) { String orderNo = vo.getName(); if (topMap.containsKey(orderNo)) { ProductionCostAggregationVo existing = topMap.get(orderNo); existing.setTotalCost(existing.getTotalCost().add(vo.getTotalCost())); } else { ProductionCostAggregationVo clone = new ProductionCostAggregationVo(); clone.setName(orderNo); clone.setTotalCost(vo.getTotalCost()); clone.setStrength(vo.getStrength()); topMap.put(orderNo, clone); } } return topMap.values().stream() .sorted(Comparator.comparing(ProductionCostAggregationVo::getTotalCost).reversed()) .limit(10) .collect(Collectors.toList()); } /** * 获取全量聚合汇总数据 */ private List getCostAggregationList(ProductionCostAccountDto dto) { if (dto.getEndDate() != null) { dto.setEndDate(dto.getEndDate().plusDays(1)); } List rawList; boolean isOrderAggregation = (dto.getGroupType() != null && dto.getGroupType() == 2); if (isOrderAggregation) { rawList = productionCostMapper.selectCostAggregationByOrder(dto); } else { rawList = productionCostMapper.selectCostAggregationByCategory(dto); } if (rawList == null || rawList.isEmpty()) { return rawList != null ? rawList : new ArrayList<>(); } Map aggregationMap = new LinkedHashMap<>(); for (ProductionCostAggregationVo vo : rawList) { String originalUnit = vo.getUnit(); String normalizedUnit = UnitUtils.normalizeUnit(originalUnit); BigDecimal convertedQty = UnitUtils.convertValueToTon(vo.getQuantity(), originalUnit); // 根据汇总模式设置 Key 和显示列 GroupKeyDto key; if (isOrderAggregation) { // 按订单汇总:Key = 日期 + 订单号 + 原料名 + 原料规格 + 单位 key = new GroupKeyDto(vo.getDate(), vo.getName(), vo.getModel(), vo.getStrength(), normalizedUnit); } else { // 按产品汇总:Key = 日期 + 原料名 + 原料规格 + 单位 key = new GroupKeyDto(vo.getDate(), vo.getName(), vo.getModel(), null, normalizedUnit); vo.setStrength(null); } if (aggregationMap.containsKey(key)) { ProductionCostAggregationVo existing = aggregationMap.get(key); existing.setQuantity(existing.getQuantity().add(convertedQty)); existing.setTotalCost(existing.getTotalCost().add(vo.getTotalCost())); } else { vo.setUnit(normalizedUnit); vo.setQuantity(convertedQty); aggregationMap.put(key, vo); } } List resultList = new ArrayList<>(aggregationMap.values()); for (ProductionCostAggregationVo vo : resultList) { if (vo.getQuantity() != null) { vo.setQuantity(vo.getQuantity().setScale(2, RoundingMode.HALF_UP)); } if (vo.getTotalCost() != null) { vo.setTotalCost(vo.getTotalCost().setScale(2, RoundingMode.HALF_UP)); } } return resultList; } private IPage getMemoryPage(Page page, List list) { int total = list.size(); long size = page.getSize(); long current = page.getCurrent(); if (size == -1 || current == -1) { page.setTotal(total); page.setRecords(list); return page; } int fromIndex = (int) ((current - 1) * size); int toIndex = Math.min(fromIndex + (int) size, total); List subList; if (fromIndex >= 0 && fromIndex < total) { subList = list.subList(fromIndex, toIndex); } else { subList = new ArrayList<>(); } page.setTotal(total); page.setRecords(subList); return page; } }