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;
|
|
/**
|
* <br>
|
* 生产成本核算服务接口实现类
|
* </br>
|
*
|
* @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<ProductionCostAggregationVo> getProductAggregationPage(Page<ProductionCostAggregationVo> page, ProductionCostAccountDto dto) {
|
dto.setGroupType(1); // 按产品汇总
|
List<ProductionCostAggregationVo> fullList = getCostAggregationList(dto);
|
return getMemoryPage(page, fullList);
|
}
|
|
@Override
|
public IPage<ProductionCostAggregationVo> getOrderAggregationPage(Page<ProductionCostAggregationVo> page, ProductionCostAccountDto dto) {
|
dto.setGroupType(2); // 按订单汇总
|
List<ProductionCostAggregationVo> fullList = getCostAggregationList(dto);
|
return getMemoryPage(page, fullList);
|
}
|
|
@Override
|
public List<ProductionCostAggregationVo> getProductTop(ProductionCostAccountDto dto) {
|
dto.setGroupType(1);
|
List<ProductionCostAggregationVo> fullList = getCostAggregationList(dto);
|
if (fullList.isEmpty()) {
|
return new ArrayList<>();
|
}
|
|
Map<String, ProductionCostAggregationVo> 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<ProductionCostAggregationVo> getOrderTop(ProductionCostAccountDto dto) {
|
dto.setGroupType(2);
|
List<ProductionCostAggregationVo> fullList = getCostAggregationList(dto);
|
if (fullList.isEmpty()) {
|
return new ArrayList<>();
|
}
|
|
Map<String, ProductionCostAggregationVo> 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<ProductionCostAggregationVo> getCostAggregationList(ProductionCostAccountDto dto) {
|
if (dto.getEndDate() != null) {
|
dto.setEndDate(dto.getEndDate().plusDays(1));
|
}
|
|
List<ProductionCostAggregationVo> 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<GroupKeyDto, ProductionCostAggregationVo> 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<ProductionCostAggregationVo> 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 <T> IPage<T> getMemoryPage(Page<T> page, List<T> 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<T> subList;
|
if (fromIndex >= 0 && fromIndex < total) {
|
subList = list.subList(fromIndex, toIndex);
|
} else {
|
subList = new ArrayList<>();
|
}
|
|
page.setTotal(total);
|
page.setRecords(subList);
|
return page;
|
}
|
|
}
|