From 263b034b4058bb7a36c709278abdc88ca1ba26c1 Mon Sep 17 00:00:00 2001
From: gongchunyi <deslre0381@gmail.com>
Date: 星期一, 30 三月 2026 18:01:25 +0800
Subject: [PATCH] feat: 生产成本导入数据入库

---
 src/main/java/com/ruoyi/production/service/impl/ProductionCostServiceImpl.java |  206 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 206 insertions(+), 0 deletions(-)

diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductionCostServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductionCostServiceImpl.java
new file mode 100644
index 0000000..152173d
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductionCostServiceImpl.java
@@ -0,0 +1,206 @@
+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;
+    }
+
+}

--
Gitblit v1.9.3