From c58c68283ec0d1832143f7e3add43f24b8aba374 Mon Sep 17 00:00:00 2001
From: zss <zss@example.com>
Date: 星期四, 02 四月 2026 10:03:58 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev_宁夏_中盛建材' into dev_宁夏_中盛建材

---
 src/main/java/com/ruoyi/home/dto/SolidWasteCoreIndicatorsDto.java                |   26 ++++++
 src/main/java/com/ruoyi/home/controller/HomeController.java                      |   18 ++++
 src/main/java/com/ruoyi/production/service/impl/ProductionRecordServiceImpl.java |    6 +
 src/main/java/com/ruoyi/home/service/HomeService.java                            |    6 +
 src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java                   |  151 +++++++++++++++++++++++++++++++++++++
 5 files changed, 206 insertions(+), 1 deletions(-)

diff --git a/src/main/java/com/ruoyi/home/controller/HomeController.java b/src/main/java/com/ruoyi/home/controller/HomeController.java
index 26b071c..c435928 100644
--- a/src/main/java/com/ruoyi/home/controller/HomeController.java
+++ b/src/main/java/com/ruoyi/home/controller/HomeController.java
@@ -397,6 +397,24 @@
         return AjaxResult.success(homeService.energy(dto));
     }
 
+    @GetMapping("/solidWaste/coreIndicators")
+    @ApiOperation("鍥哄簾娑堢撼閲�-鏍稿績鎸囨爣")
+    public AjaxResult coreIndicators(productionStatisticsDto dto){
+        return AjaxResult.success(homeService.coreIndicators(dto));
+    }
+
+    @GetMapping("/solidWaste/trends")
+    @ApiOperation("鍥哄簾娑堢撼閲�-鍥哄簾娑堢撼瓒嬪娍")
+    public AjaxResult trends(productionStatisticsDto dto){
+        return AjaxResult.success(homeService.trends(dto));
+    }
+
+    @GetMapping("/solidWaste/typeDistribution")
+    @ApiOperation("鍥哄簾娑堢撼閲�-鍥哄簾绫诲瀷鍒嗗竷")
+    public AjaxResult typeDistribution(productionStatisticsDto dto){
+        return AjaxResult.success(homeService.typeDistribution(dto));
+    }
+
     @GetMapping("/manage")
     @ApiOperation("棣栭〉--缁忚惀鍏虫敞")
     public AjaxResult manage() {
diff --git a/src/main/java/com/ruoyi/home/dto/SolidWasteCoreIndicatorsDto.java b/src/main/java/com/ruoyi/home/dto/SolidWasteCoreIndicatorsDto.java
new file mode 100644
index 0000000..b212243
--- /dev/null
+++ b/src/main/java/com/ruoyi/home/dto/SolidWasteCoreIndicatorsDto.java
@@ -0,0 +1,26 @@
+package com.ruoyi.home.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * 鍥哄簾娑堢撼閲忔牳蹇冩寚鏍嘍to
+ *
+ * @author deslrey
+ * @version 1.0
+ * @since 2026/04/02
+ */
+@Data
+@ApiModel(value = "SolidWasteCoreIndicatorsDto", description = "鍥哄簾娑堢撼閲忔牳蹇冩寚鏍嘍to")
+public class SolidWasteCoreIndicatorsDto {
+
+    @ApiModelProperty("鍚堣閲�")
+    private BigDecimal totalAmount = BigDecimal.ZERO;
+
+    @ApiModelProperty("绱娑堢撼閲� (鑷�2022骞磋捣)")
+    private BigDecimal cumulativeAmount = BigDecimal.ZERO;
+
+}
diff --git a/src/main/java/com/ruoyi/home/service/HomeService.java b/src/main/java/com/ruoyi/home/service/HomeService.java
index 4ffeef3..f6f6a50 100644
--- a/src/main/java/com/ruoyi/home/service/HomeService.java
+++ b/src/main/java/com/ruoyi/home/service/HomeService.java
@@ -120,5 +120,11 @@
 
     List<HomeEnergyStatisticsDto> energy(productionStatisticsDto dto);
 
+    SolidWasteCoreIndicatorsDto coreIndicators(productionStatisticsDto dto);
+
+    List<SolidWasteStatisticsDto> trends(productionStatisticsDto dto);
+
+    List<MapDto> typeDistribution(productionStatisticsDto dto);
+
     Map<String,Long> manage();
 }
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..621276d 100644
--- a/src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java
+++ b/src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java
@@ -3435,6 +3435,157 @@
     }
 
     @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
     public Map<String, Long> manage() {
         Map<String, Long> map = new HashMap<>();
         //鐢熶骇璁㈠崟鎬绘暟
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductionRecordServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductionRecordServiceImpl.java
index 22695ae..c3fcb00 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductionRecordServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductionRecordServiceImpl.java
@@ -206,10 +206,14 @@
         BigDecimal totalQty = productOrder.getQuantity() == null ? BigDecimal.ZERO : productOrder.getQuantity();
         //  鍓╀綑鍙姤宸ユ暟閲�
         BigDecimal remainQty = totalQty.subtract(completeQty);
-        //  鏈鎶ュ伐鍚堟牸鏁伴噺涓嶈兘瓒呰繃鍓╀綑鏁伴噺锛堟牎楠屽繀椤诲湪绱姞鍓嶆墽琛岋級
+        //  鏈鎶ュ伐鍚堟牸鏁伴噺涓嶈兘瓒呰繃鍓╀綑鏁伴噺
         if (qualifiedQty.compareTo(remainQty) > 0) {
             throw new ServiceException("鎶ュ伐澶辫触锛屾湰娆℃姤宸ユ暟閲忎笉鑳藉ぇ浜庡墿浣欏彲鎶ュ伐鏁伴噺锛屽墿浣欐姤宸ユ暟閲�:[" + remainQty + "]");
         }
+        //  鏈鎶ュ伐涓嶅悎鏍兼暟閲忎笉鑳借秴杩囨湰娆℃姤宸ユ暟閲�
+        if (dto.getUnqualifiedQuantity() != null && dto.getUnqualifiedQuantity().compareTo(dto.getQuantity()) > 0) {
+            throw new ServiceException("鎶ュ伐澶辫触锛屾湰娆℃姤宸ヤ笉鍚堟牸鏁伴噺涓嶈兘澶т簬鎶ュ伐鏁伴噺锛屾姤宸ユ暟閲�:[" + dto.getQuantity() + "]");
+        }
         //  鍘嗗彶宸插畬鎴� + 鏈鍚堟牸鏁伴噺
         BigDecimal newCompleteQty = completeQty.add(qualifiedQty);
         productOrder.setCompleteQuantity(newCompleteQty);

--
Gitblit v1.9.3