From a610cbd7e6b7631254f15c832afce6e747b3581d Mon Sep 17 00:00:00 2001
From: huminmin <mac@MacBook-Pro.local>
Date: 星期四, 02 四月 2026 14:36:02 +0800
Subject: [PATCH] 生产报表相关接口
---
src/main/java/com/ruoyi/production/service/ProductionStatisticService.java | 46 ++++
src/main/java/com/ruoyi/production/controller/ProductionStatisticController.java | 61 ++++++
src/main/java/com/ruoyi/production/service/impl/ProductionStatisticServiceImpl.java | 430 +++++++++++++++++++++++++++++++++++++++++++
src/main/java/com/ruoyi/production/dto/ProductionStatisticDto.java | 11 +
4 files changed, 548 insertions(+), 0 deletions(-)
diff --git a/src/main/java/com/ruoyi/production/controller/ProductionStatisticController.java b/src/main/java/com/ruoyi/production/controller/ProductionStatisticController.java
new file mode 100644
index 0000000..e72254d
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/controller/ProductionStatisticController.java
@@ -0,0 +1,61 @@
+package com.ruoyi.production.controller;
+
+import com.ruoyi.framework.web.domain.AjaxResult;
+import com.ruoyi.home.dto.processDataProductionStatisticsDto;
+import com.ruoyi.production.service.ProductionStatisticService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+@RequestMapping("productStatistics")
+@RestController
+@Api(tags = "鐢熶骇缁熻")
+public class ProductionStatisticController {
+
+ @Autowired
+ private ProductionStatisticService productionStatisticService;
+
+ @ApiOperation(value = "鑾峰彇鐢熶骇宸ュ崟鏁伴噺缁熻鏁版嵁")
+ @GetMapping("/workOrderCount")
+ public AjaxResult getWorkOrderCount() {
+ return AjaxResult.success(productionStatisticService.getWorkOrderCount());
+ }
+
+ @ApiOperation(value = "鑾峰彇璐ㄩ噺缁熻鏁版嵁")
+ @GetMapping("/qualityStatistics")
+ public AjaxResult getQualityStatistics() {
+ return AjaxResult.success(productionStatisticService.getQualityStatistics());
+ }
+
+ @ApiOperation(value = "鑾峰彇浜ч噺缁熻鏁版嵁")
+ @GetMapping("/productionStatistics")
+ public AjaxResult getProductionStatistics() {
+ return AjaxResult.success(productionStatisticService.getProductionStatistics());
+ }
+
+ @ApiOperation(value = "鑾峰彇浜у搧浜у嚭鍒嗘瀽锛堥ゼ鐘跺浘锛�")
+ @GetMapping("/productOutputCategoryPieData")
+ public AjaxResult getProductOutputCategoryPieData() {
+ return AjaxResult.success(productionStatisticService.getProductOutputCategoryPieData());
+ }
+
+ @ApiOperation(value = "鑾峰彇宸ュ崟浜у嚭涓嶈壇鍘熷洜缁熻鍒嗘瀽")
+ @GetMapping("/defectReasonAnalysis")
+ public AjaxResult getDefectReasonAnalysis() {
+ return AjaxResult.success(productionStatisticService.getDefectReasonAnalysis());
+ }
+
+ @ApiOperation(value = "鑾峰彇宸ュ簭涓嶈壇鐜囧垎鏋�")
+ @GetMapping("/processDefectRateAnalysis")
+ public AjaxResult getProcessDefectRateAnalysis(
+ @RequestParam(required = false) String startDate,
+ @RequestParam(required = false) String endDate) {
+ return AjaxResult.success(productionStatisticService.getProcessDefectRateAnalysis(startDate, endDate));
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/ruoyi/production/dto/ProductionStatisticDto.java b/src/main/java/com/ruoyi/production/dto/ProductionStatisticDto.java
new file mode 100644
index 0000000..83ac7f9
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/dto/ProductionStatisticDto.java
@@ -0,0 +1,11 @@
+package com.ruoyi.production.dto;
+
+import lombok.Data;
+
+@Data
+public class ProductionStatisticDto {
+ private Long totalCount;
+ private Long inProgressCount;
+ private Long completedCount;
+ private Long pendingCount;
+}
diff --git a/src/main/java/com/ruoyi/production/service/ProductionStatisticService.java b/src/main/java/com/ruoyi/production/service/ProductionStatisticService.java
new file mode 100644
index 0000000..54c6409
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/service/ProductionStatisticService.java
@@ -0,0 +1,46 @@
+package com.ruoyi.production.service;
+
+import com.ruoyi.home.dto.processDataProductionStatisticsDto;
+import com.ruoyi.production.dto.ProductionStatisticDto;
+
+import java.util.List;
+import java.util.Map;
+
+public interface ProductionStatisticService {
+
+ /**
+ * 鑾峰彇宸ュ崟缁熻鏁版嵁
+ * @return 鍖呭惈宸ュ崟鎬绘暟銆佽繘琛屼腑宸ュ崟銆佸畬鎴愬伐鍗曠殑Map
+ */
+ ProductionStatisticDto getWorkOrderCount();
+
+ /**
+ * 鑾峰彇璐ㄩ噺缁熻鏁版嵁
+ * @return 鍖呭惈鍚堟牸鐜囥�佷笉鑹巼銆佹姤搴熸�绘暟鐨凪ap
+ */
+ Map<String, Object> getQualityStatistics();
+
+ /**
+ * 鑾峰彇浜ч噺缁熻鏁版嵁
+ * @return 鍖呭惈鎬讳骇閲忔�婚銆佺敓浜ф�讳骇銆佺敓浜ф�绘秷鑰椼�佷骇鍝佹�讳緵搴斿叕鍙哥殑Map
+ */
+ Map<String, Object> getProductionStatistics();
+
+ /**
+ * 鑾峰彇鍚勫伐搴忓畬鎴愬垎鏋愭暟鎹紙楗肩姸鍥撅級
+ * @return 宸ュ簭瀹屾垚鍒嗘瀽鏁版嵁鍒楄〃
+ */
+ List<Map<String, Object>> getProductOutputCategoryPieData();
+
+ /**
+ * 鑾峰彇宸ュ崟浜у嚭涓嶈壇鍘熷洜缁熻鍒嗘瀽
+ * @return 涓嶈壇鍘熷洜缁熻鏁版嵁鍒楄〃
+ */
+ List<Map<String, Object>> getDefectReasonAnalysis();
+
+ /**
+ * 鑾峰彇宸ュ簭涓嶈壇鐜囧垎鏋愶紙鎶樼嚎鍥撅級
+ * @return 鍚勫伐搴忎笉鑹巼鏁版嵁鍒楄〃
+ */
+ List<Map<String, Object>> getProcessDefectRateAnalysis(String startDate, String endDate);
+}
\ No newline at end of file
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductionStatisticServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductionStatisticServiceImpl.java
new file mode 100644
index 0000000..17dc1c4
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductionStatisticServiceImpl.java
@@ -0,0 +1,430 @@
+package com.ruoyi.production.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.ruoyi.basic.mapper.ProductMapper;
+import com.ruoyi.basic.mapper.ProductModelMapper;
+import com.ruoyi.basic.mapper.SupplierManageMapper;
+import com.ruoyi.basic.pojo.Product;
+import com.ruoyi.basic.pojo.ProductModel;
+import com.ruoyi.basic.pojo.SupplierManage;
+import com.ruoyi.home.dto.processDataProductionStatisticsDto;
+import com.ruoyi.production.dto.ProductionStatisticDto;
+import com.ruoyi.production.mapper.ProductProcessMapper;
+import com.ruoyi.production.mapper.ProductWorkOrderMapper;
+import com.ruoyi.production.mapper.ProductionProductInputMapper;
+import com.ruoyi.production.mapper.ProductionProductOutputMapper;
+import com.ruoyi.production.pojo.ProductProcess;
+import com.ruoyi.production.pojo.ProductWorkOrder;
+import com.ruoyi.production.pojo.ProductionProductInput;
+import com.ruoyi.production.pojo.ProductionProductOutput;
+import com.ruoyi.production.service.ProductionStatisticService;
+import com.ruoyi.quality.mapper.QualityInspectMapper;
+import com.ruoyi.quality.pojo.QualityInspect;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.YearMonth;
+import java.time.ZoneId;
+import java.util.Date;
+import java.util.Set;
+import java.util.TreeSet;
+import java.time.temporal.TemporalAdjusters;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 鐢熶骇缁熻鏈嶅姟瀹炵幇绫�
+ */
+@Service
+public class ProductionStatisticServiceImpl implements ProductionStatisticService {
+
+ @Autowired
+ private ProductProcessMapper productProcessMapper;
+
+ @Autowired
+ private ProductWorkOrderMapper productWorkOrderMapper;
+
+ @Autowired
+ private ProductionProductOutputMapper productionProductOutputMapper;
+
+ @Autowired
+ private ProductionProductInputMapper productionProductInputMapper;
+
+ @Autowired
+ private QualityInspectMapper qualityInspectMapper;
+
+ @Autowired
+ private SupplierManageMapper supplierManageMapper;
+
+ @Autowired
+ private ProductModelMapper productModelMapper;
+
+ @Autowired
+ private ProductMapper productMapper;
+
+ @Override
+ public ProductionStatisticDto getWorkOrderCount() {
+ ProductionStatisticDto dto = new ProductionStatisticDto();
+
+ // 鏌ヨ宸ュ崟鎬绘暟
+ Long totalCount = productWorkOrderMapper.selectCount(null);
+ dto.setTotalCount(totalCount);
+
+ // 鏌ヨ杩涜涓伐鍗曪紙瀹屾垚鏁伴噺灏忎簬闇�姹傛暟閲忥級
+ Long inProgressCount = productWorkOrderMapper.selectCount(
+ new LambdaQueryWrapper<ProductWorkOrder>()
+ .apply("complete_quantity < plan_quantity and complete_quantity > 0")
+ );
+ dto.setInProgressCount(inProgressCount);
+
+ // 鏌ヨ宸插畬鎴愬伐鍗曪紙瀹屾垚鏁伴噺澶т簬绛変簬闇�姹傛暟閲忥級
+ Long completedCount = productWorkOrderMapper.selectCount(
+ new LambdaQueryWrapper<ProductWorkOrder>()
+ .apply("complete_quantity >= plan_quantity and complete_quantity > 0")
+ );
+ dto.setCompletedCount(completedCount);
+
+ // 鏌ヨ寰呭畬鎴愬伐鍗曪紙瀹屾垚鏁伴噺涓�0锛�
+ Long pendingCount = productWorkOrderMapper.selectCount(
+ new LambdaQueryWrapper<ProductWorkOrder>()
+ .eq(ProductWorkOrder::getCompleteQuantity, 0)
+ );
+ dto.setPendingCount(pendingCount);
+
+ return dto;
+ }
+
+ @Override
+ public Map<String, Object> getQualityStatistics() {
+ Map<String, Object> result = new HashMap<>();
+
+ // 鏌ヨ鎵�鏈夋姤宸ヨ褰�
+ List<ProductionProductOutput> outputList = productionProductOutputMapper.selectList(null);
+
+ // 璁$畻鎶ュ伐鎬绘暟銆佹姤搴熸�绘暟鍜屼笉鑹�绘暟
+ BigDecimal totalOutput = BigDecimal.ZERO;
+ BigDecimal totalScrap = BigDecimal.ZERO;
+ BigDecimal totalDefect = BigDecimal.ZERO;
+
+ for (ProductionProductOutput output : outputList) {
+ // 鎶ュ伐鎬绘暟
+ if (output.getQuantity() != null) {
+ totalOutput = totalOutput.add(output.getQuantity());
+ }
+ // 鎶ュ簾鏁伴噺
+ if (output.getScrapQty() != null) {
+ totalScrap = totalScrap.add(output.getScrapQty());
+ }
+ // 涓嶈壇鏁伴噺锛堜粠QualityInspect琛ㄦ煡璇級
+ List<QualityInspect> qualityInspects = qualityInspectMapper.selectList(
+ new LambdaQueryWrapper<QualityInspect>()
+ .eq(QualityInspect::getProductMainId, output.getProductMainId())
+ );
+ for (QualityInspect inspect : qualityInspects) {
+ if (inspect.getDefectiveQuantity() != null) {
+ totalDefect = totalDefect.add(inspect.getDefectiveQuantity());
+ }
+ }
+ }
+
+ // 璁$畻鍚堟牸鏁伴噺
+ BigDecimal qualifiedQuantity = totalOutput.subtract(totalScrap).subtract(totalDefect);
+
+ // 璁$畻鍚堟牸鐜囧拰涓嶈壇鐜�
+ double qualifiedRate = 0.0;
+ double defectRate = 0.0;
+ if (totalOutput.compareTo(BigDecimal.ZERO) > 0) {
+ // 浣跨敤BigDecimal纭繚绮惧害
+ BigDecimal qualifiedRateBD = qualifiedQuantity.divide(totalOutput, 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100));
+ BigDecimal defectRateBD = totalDefect.divide(totalOutput, 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100));
+ // 淇濈暀涓や綅灏忔暟
+ qualifiedRate = qualifiedRateBD.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
+ defectRate = defectRateBD.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
+ }
+
+ result.put("qualifiedRate", qualifiedRate); // 鍚堟牸鐜�
+ result.put("defectRate", defectRate); // 涓嶈壇鐜�
+ result.put("scrapCount", totalScrap.intValue()); // 鎶ュ簾鎬绘暟
+
+ return result;
+ }
+
+ @Override
+ public Map<String, Object> getProductionStatistics() {
+ Map<String, Object> result = new HashMap<>();
+
+ // 鑾峰彇褰撳墠鏈堜唤鍜屼笂涓�涓湀浠界殑寮�濮嬪拰缁撴潫鏃堕棿
+ LocalDateTime now = LocalDateTime.now();
+ YearMonth currentMonth = YearMonth.from(now);
+ LocalDateTime currentMonthStart = now.with(TemporalAdjusters.firstDayOfMonth()).with(LocalTime.MIN);
+ LocalDateTime currentMonthEnd = currentMonth.atEndOfMonth().atTime(23, 59, 59);
+ LocalDateTime lastMonth = now.minusMonths(1);
+ LocalDateTime lastMonthStart = lastMonth.with(TemporalAdjusters.firstDayOfMonth()).with(LocalTime.MIN);
+ LocalDateTime lastMonthEnd = currentMonthStart.minusDays(1).withHour(23).withMinute(59).withSecond(59);
+
+ // 璁$畻鐢熶骇鎬讳骇鍑猴紙褰撳墠鏈堬級
+ List<ProductionProductOutput> currentOutputList = productionProductOutputMapper.selectList(
+ new LambdaQueryWrapper<ProductionProductOutput>()
+ .ge(ProductionProductOutput::getCreateTime, currentMonthStart)
+ .le(ProductionProductOutput::getCreateTime, currentMonthEnd)
+ );
+ BigDecimal currentProductionOutput = BigDecimal.ZERO;
+ for (ProductionProductOutput output : currentOutputList) {
+ if (output.getQuantity() != null) {
+ currentProductionOutput = currentProductionOutput.add(output.getQuantity());
+ }
+ }
+
+ // 璁$畻鐢熶骇鎬讳骇鍑猴紙涓婃湀锛�
+ List<ProductionProductOutput> lastOutputList = productionProductOutputMapper.selectList(
+ new LambdaQueryWrapper<ProductionProductOutput>()
+ .ge(ProductionProductOutput::getCreateTime, lastMonthStart)
+ .le(ProductionProductOutput::getCreateTime, lastMonthEnd)
+ );
+ BigDecimal lastProductionOutput = BigDecimal.ZERO;
+ for (ProductionProductOutput output : lastOutputList) {
+ if (output.getQuantity() != null) {
+ lastProductionOutput = lastProductionOutput.add(output.getQuantity());
+ }
+ }
+
+ // 璁$畻鐢熶骇鎬绘秷鑰楋紙褰撳墠鏈堬級
+ List<ProductionProductInput> currentInputList = productionProductInputMapper.selectList(
+ new LambdaQueryWrapper<ProductionProductInput>()
+ .ge(ProductionProductInput::getCreateTime, currentMonthStart)
+ .le(ProductionProductInput::getCreateTime, currentMonthEnd)
+ );
+ BigDecimal currentProductionConsumption = BigDecimal.ZERO;
+ for (ProductionProductInput input : currentInputList) {
+ if (input.getQuantity() != null) {
+ currentProductionConsumption = currentProductionConsumption.add(input.getQuantity());
+ }
+ }
+
+ // 璁$畻鐢熶骇鎬绘秷鑰楋紙涓婃湀锛�
+ List<ProductionProductInput> lastInputList = productionProductInputMapper.selectList(
+ new LambdaQueryWrapper<ProductionProductInput>()
+ .ge(ProductionProductInput::getCreateTime, lastMonthStart)
+ .le(ProductionProductInput::getCreateTime, lastMonthEnd)
+ );
+ BigDecimal lastProductionConsumption = BigDecimal.ZERO;
+ for (ProductionProductInput input : lastInputList) {
+ if (input.getQuantity() != null) {
+ lastProductionConsumption = lastProductionConsumption.add(input.getQuantity());
+ }
+ }
+
+ // 璁$畻渚涘簲鍟嗘暟閲忥紙褰撳墠鏈堬級
+ List<SupplierManage> currentSuppliers = supplierManageMapper.selectList(
+ new LambdaQueryWrapper<SupplierManage>()
+ .ge(SupplierManage::getCreateTime, currentMonthStart)
+ .le(SupplierManage::getCreateTime, currentMonthEnd)
+ );
+ int currentSupplierCount = currentSuppliers != null ? currentSuppliers.size() : 0;
+
+ // 璁$畻渚涘簲鍟嗘暟閲忥紙涓婃湀锛�
+ List<SupplierManage> lastSuppliers = supplierManageMapper.selectList(
+ new LambdaQueryWrapper<SupplierManage>()
+ .ge(SupplierManage::getCreateTime, lastMonthStart)
+ .le(SupplierManage::getCreateTime, lastMonthEnd)
+ );
+ int lastSupplierCount = lastSuppliers != null ? lastSuppliers.size() : 0;
+
+ // 璁$畻瓒嬪娍
+ double productionOutputMonthlyChange = 0.0;
+ if (lastProductionOutput.compareTo(BigDecimal.ZERO) > 0) {
+ productionOutputMonthlyChange = (currentProductionOutput.subtract(lastProductionOutput)
+ .divide(lastProductionOutput, 4, BigDecimal.ROUND_HALF_UP).doubleValue()) * 100;
+ }
+
+ double productionConsumptionMonthlyChange = 0.0;
+ if (lastProductionConsumption.compareTo(BigDecimal.ZERO) > 0) {
+ productionConsumptionMonthlyChange = (currentProductionConsumption.subtract(lastProductionConsumption)
+ .divide(lastProductionConsumption, 4, BigDecimal.ROUND_HALF_UP).doubleValue()) * 100;
+ }
+
+ double supplierCountMonthlyChange = 0.0;
+ if (lastSupplierCount > 0) {
+ supplierCountMonthlyChange = ((currentSupplierCount - lastSupplierCount) * 100.0) / lastSupplierCount;
+ }
+
+ result.put("productionOutput", currentProductionOutput.doubleValue()); // 鐢熶骇鎬讳骇
+ result.put("productionConsumption", currentProductionConsumption.doubleValue()); // 鐢熶骇鎬绘秷鑰�
+ result.put("productionOutputMonthlyChange", productionOutputMonthlyChange); // 鐢熶骇鎬讳骇鏈堝害鍙樺寲
+ result.put("productionConsumptionMonthlyChange", productionConsumptionMonthlyChange); // 鐢熶骇鎬绘秷鑰楁湀搴﹀彉鍖�
+ result.put("supplierCount", currentSupplierCount); // 浜у搧鎬讳緵搴斿叕鍙�
+ result.put("supplierCountMonthlyChange", supplierCountMonthlyChange); // 渚涘簲鍟嗘暟閲忔湀搴﹀彉鍖�
+
+ return result;
+ }
+
+ @Override
+ public List<Map<String, Object>> getProductOutputCategoryPieData() {
+ List<Map<String, Object>> result = new ArrayList<>();
+ // 鎸変骇鍝佸ぇ绫�
+ // 鏌ヨ鎵�鏈夋姤宸ヨ褰�
+ List<ProductionProductOutput> outputList = productionProductOutputMapper.selectList(null);
+
+ // 鎸変骇鍝佸垎缁勮绠椾骇鍑烘暟閲�
+ Map<Long, BigDecimal> productOutputMap = new HashMap<>();
+
+ for (ProductionProductOutput output : outputList) {
+ if (output.getProductModelId() != null && output.getQuantity() != null) {
+ // 鏍规嵁productModelId鏌ヨProductModel
+ ProductModel productModel = productModelMapper.selectById(output.getProductModelId());
+ if (productModel != null && productModel.getProductId() != null) {
+ // 鏍规嵁productId鏌ヨProduct
+ Product product = productMapper.selectById(productModel.getProductId());
+ if (product != null) {
+ // 鎸変骇鍝両D鍒嗙粍璁$畻浜у嚭鏁伴噺
+ productOutputMap.put(product.getId(),
+ productOutputMap.getOrDefault(product.getId(), BigDecimal.ZERO).add(output.getQuantity()));
+ }
+ }
+ }
+ }
+
+ // 杞崲涓虹粨鏋滄牸寮�
+ for (Map.Entry<Long, BigDecimal> entry : productOutputMap.entrySet()) {
+ Product product = productMapper.selectById(entry.getKey());
+ if (product != null) {
+ Map<String, Object> item = new HashMap<>();
+ item.put("name", product.getProductName());
+ item.put("value", entry.getValue().intValue());
+ result.add(item);
+ }
+ }
+
+ return result;
+ }
+
+ @Override
+ public List<Map<String, Object>> getDefectReasonAnalysis() {
+ List<Map<String, Object>> result = new ArrayList<>();
+
+ // 鏌ヨ鎵�鏈夎川閲忔楠岃褰�
+ List<QualityInspect> qualityInspectList = qualityInspectMapper.selectList(null);
+
+ // 鎸変笉鑹師鍥犲垎缁勭粺璁℃暟閲�
+ Map<String, Integer> reasonCountMap = new HashMap<>();
+
+ for (QualityInspect inspect : qualityInspectList) {
+ if (inspect.getDefectiveReason() != null && !inspect.getDefectiveReason().isEmpty()) {
+ String reason = inspect.getDefectiveReason();
+ reasonCountMap.put(reason, reasonCountMap.getOrDefault(reason, 0) + 1);
+ }
+ }
+
+ // 杞崲涓虹粨鏋滄牸寮�
+ for (Map.Entry<String, Integer> entry : reasonCountMap.entrySet()) {
+ Map<String, Object> item = new HashMap<>();
+ item.put("name", entry.getKey());
+ item.put("value", entry.getValue());
+ result.add(item);
+ }
+
+ return result;
+ }
+
+ @Override
+ public List<Map<String, Object>> getProcessDefectRateAnalysis(String startDate, String endDate) {
+ List<Map<String, Object>> result = new ArrayList<>();
+
+ // 榛樿鏌ヨ杩戜竴涓湀鏁版嵁
+ if (startDate == null || endDate == null) {
+ LocalDate now = LocalDate.now();
+ startDate = now.minusMonths(1).toString();
+ endDate = now.toString();
+ }
+
+ // 瑙f瀽鏃ユ湡
+ LocalDate startLocalDate = LocalDate.parse(startDate);
+ LocalDate endLocalDate = LocalDate.parse(endDate);
+
+ // 鏌ヨ鎵�鏈夊伐搴�
+ List<ProductProcess> processList = productProcessMapper.selectList(null);
+
+ // 鏀堕泦鎵�鏈夋棩鏈�
+ Set<LocalDate> dateSet = new TreeSet<>();
+ LocalDate currentDate = startLocalDate;
+ while (!currentDate.isAfter(endLocalDate)) {
+ dateSet.add(currentDate);
+ currentDate = currentDate.plusDays(1);
+ }
+
+ // 鏋勫缓缁撴灉鏁版嵁
+ for (LocalDate date : dateSet) {
+ Map<String, Object> item = new HashMap<>();
+ item.put("date", date.toString());
+
+ // 鍒濆鍖栨瘡鏃ユ�绘暟閲忓拰涓嶈壇鏁伴噺
+ BigDecimal dailyTotalQuantity = BigDecimal.ZERO;
+ BigDecimal dailyDefectiveQuantity = BigDecimal.ZERO;
+
+ // 鍒濆鍖栧伐搴忔暟鎹垪琛�
+ List<Map<String, Object>> processesList = new ArrayList<>();
+
+ for (ProductProcess process : processList) {
+ if (process.getName() != null) {
+ // 鏌ヨ璇ュ伐搴忓湪鎸囧畾鏃ユ湡鐨勮川閲忔楠岃褰�
+ List<QualityInspect> qualityInspects = qualityInspectMapper.selectList(
+ new LambdaQueryWrapper<QualityInspect>()
+ .eq(QualityInspect::getProcess, process.getName())
+ .ge(QualityInspect::getCheckTime, Date.from(date.atStartOfDay(ZoneId.systemDefault()).toInstant()))
+ .lt(QualityInspect::getCheckTime, Date.from(date.plusDays(1).atStartOfDay(ZoneId.systemDefault()).toInstant()))
+ );
+
+ // 璁$畻璇ュ伐搴忕殑鎬绘楠屾暟閲忓拰涓嶈壇鏁伴噺
+ BigDecimal processTotalQuantity = BigDecimal.ZERO;
+ BigDecimal processDefectiveQuantity = BigDecimal.ZERO;
+
+ for (QualityInspect inspect : qualityInspects) {
+ if (inspect.getQuantity() != null) {
+ processTotalQuantity = processTotalQuantity.add(inspect.getQuantity());
+ dailyTotalQuantity = dailyTotalQuantity.add(inspect.getQuantity());
+ }
+ if (inspect.getDefectiveQuantity() != null) {
+ processDefectiveQuantity = processDefectiveQuantity.add(inspect.getDefectiveQuantity());
+ dailyDefectiveQuantity = dailyDefectiveQuantity.add(inspect.getDefectiveQuantity());
+ }
+ }
+
+ // 璁$畻璇ュ伐搴忕殑涓嶈壇鐜�
+ double processDefectRate = 0.0;
+ if (processTotalQuantity.compareTo(BigDecimal.ZERO) > 0) {
+ // 璁$畻涓嶈壇鐜囷紝淇濈暀涓や綅灏忔暟
+ BigDecimal defectRateDecimal = processDefectiveQuantity.divide(processTotalQuantity, 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100));
+ processDefectRate = defectRateDecimal.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
+ }
+
+ // 鏋勫缓宸ュ簭鏁版嵁瀵硅薄
+ Map<String, Object> processMap = new HashMap<>();
+ processMap.put(process.getName(), processDefectRate);
+ processesList.add(processMap);
+ }
+ }
+
+ // 璁$畻姣忔棩骞冲潎涓嶈壇鐜�
+ double dailyAverageDefectRate = 0.0;
+ if (dailyTotalQuantity.compareTo(BigDecimal.ZERO) > 0) {
+ // 璁$畻涓嶈壇鐜囷紝淇濈暀涓や綅灏忔暟
+ BigDecimal defectRateDecimal = dailyDefectiveQuantity.divide(dailyTotalQuantity, 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100));
+ dailyAverageDefectRate = defectRateDecimal.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
+ }
+
+ // 娣诲姞骞冲潎涓嶈壇鐜囧拰宸ュ簭鏁版嵁鍒扮粨鏋滈」
+ item.put("averageDefectRate", dailyAverageDefectRate);
+ item.put("processes", processesList);
+
+ result.add(item);
+ }
+
+ return result;
+ }
+}
\ No newline at end of file
--
Gitblit v1.9.3