From 940ceef4c4adf20c0b9da9270f1cd5ed58e14a4c Mon Sep 17 00:00:00 2001
From: gongchunyi <deslre0381@gmail.com>
Date: 星期一, 02 二月 2026 15:22:21 +0800
Subject: [PATCH] feat: 进销质量类分析大屏接口
---
src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java | 548 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 539 insertions(+), 9 deletions(-)
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 a377159..7e96c10 100644
--- a/src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java
+++ b/src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java
@@ -20,6 +20,7 @@
import com.ruoyi.collaborativeApproval.pojo.Notice;
import com.ruoyi.common.enums.ApproveTypeEnum;
import com.ruoyi.common.utils.SecurityUtils;
+import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.device.mapper.DeviceRepairMapper;
import com.ruoyi.device.pojo.DeviceRepair;
import com.ruoyi.dto.MapDto;
@@ -48,7 +49,9 @@
import com.ruoyi.purchase.pojo.PaymentRegistration;
import com.ruoyi.purchase.pojo.PurchaseLedger;
import com.ruoyi.quality.mapper.QualityInspectMapper;
+import com.ruoyi.quality.mapper.QualityUnqualifiedMapper;
import com.ruoyi.quality.pojo.QualityInspect;
+import com.ruoyi.quality.pojo.QualityUnqualified;
import com.ruoyi.sales.mapper.ReceiptPaymentMapper;
import com.ruoyi.sales.mapper.SalesLedgerMapper;
import com.ruoyi.sales.mapper.SalesLedgerProductMapper;
@@ -94,9 +97,6 @@
private StockInventoryMapper stockInventoryMapper;
@Autowired
- private ProcurementRecordMapper procurementRecordStorageMapper;
-
- @Autowired
private QualityInspectMapper qualityStatisticsMapper;
@Autowired
@@ -113,27 +113,36 @@
@Autowired
private NoticeMapper noticeMapper;
+
@Autowired
private ProductOrderMapper productOrderMapper;
+
@Autowired
private ProductWorkOrderMapper productWorkOrderMapper;
- @Autowired
- private ProductModelMapper productModelMapper;
+
@Autowired
private ProductMapper productMapper;
- @Autowired
- private StockUtils stockUtils;
+
@Autowired
private StaffOnJobMapper staffOnJobMapper;
+
@Autowired
private CustomerMapper customerMapper;
+
@Autowired
private SupplierManageMapper supplierManageMapper;
+
@Autowired
private HomeMapper homeMapper;
@Autowired
private ProductionProductOutputMapper productionProductOutputMapper;
+
+ @Autowired
+ private QualityInspectMapper qualityInspectMapper;
+
+ @Autowired
+ private QualityUnqualifiedMapper qualityUnqualifiedMapper;
@Override
public HomeBusinessDto business() {
@@ -1812,7 +1821,8 @@
String endStr = endDate.plusDays(1).atStartOfDay().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
- List<Map<String, Object>> wagesList = salesLedgerProductionAccountingMapper.selectDailyWagesStats(startStr, endStr);
+ List<Map<String, Object>> wagesList = salesLedgerProductionAccountingMapper.selectDailyWagesStats(startStr,
+ endStr);
if (CollectionUtils.isEmpty(wagesList)) {
return new ArrayList<>();
@@ -1882,4 +1892,524 @@
return dto;
}
-}
+
+ @Override
+ public List<QualityQualifiedAnalysisDto> rawMaterialDetection(Integer type) {
+ return commonDetection(type, 0);
+ }
+
+ @Override
+ public List<QualityQualifiedAnalysisDto> processDetection(Integer type) {
+ return commonDetection(type, 1);
+ }
+
+ @Override
+ public List<QualityQualifiedAnalysisDto> factoryDetection(Integer type) {
+ return commonDetection(type, 2);
+ }
+
+ private List<QualityQualifiedAnalysisDto> commonDetection(Integer type, Integer inspectType) {
+
+ LocalDate[] range = calcDateRange(type);
+ LocalDate startDate = range[0];
+ LocalDate endDate = range[1];
+
+ String startStr = startDate.atStartOfDay()
+ .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
+ String endStr = endDate.atTime(LocalTime.MAX)
+ .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
+
+ List<QualityInspect> list = qualityInspectMapper.selectList(
+ new LambdaQueryWrapper<QualityInspect>()
+ .eq(QualityInspect::getInspectType, inspectType)
+ .eq(QualityInspect::getInspectState, 1)
+ .ge(QualityInspect::getCheckTime, startStr)
+ .le(QualityInspect::getCheckTime, endStr));
+
+ return buildQualifiedAnalysis(list);
+ }
+
+ private LocalDate[] calcDateRange(Integer type) {
+ LocalDate today = LocalDate.now();
+ LocalDate startDate;
+ LocalDate endDate;
+
+ switch (type) {
+ case 1: // 鍛�
+ startDate = today.with(DayOfWeek.MONDAY);
+ endDate = today.with(DayOfWeek.SUNDAY);
+ break;
+ case 2: // 鏈�
+ startDate = today.with(TemporalAdjusters.firstDayOfMonth());
+ endDate = today.with(TemporalAdjusters.lastDayOfMonth());
+ break;
+ case 3: // 瀛e害
+ int currentMonth = today.getMonthValue();
+ int startMonth = ((currentMonth - 1) / 3) * 3 + 1;
+ startDate = LocalDate.of(today.getYear(), startMonth, 1);
+ endDate = LocalDate.of(today.getYear(), startMonth + 2, 1)
+ .with(TemporalAdjusters.lastDayOfMonth());
+ break;
+ default:
+ startDate = today.with(DayOfWeek.MONDAY);
+ endDate = today.with(DayOfWeek.SUNDAY);
+ }
+
+ return new LocalDate[]{startDate, endDate};
+ }
+
+ private List<QualityQualifiedAnalysisDto> buildQualifiedAnalysis(List<QualityInspect> list) {
+ List<QualityQualifiedAnalysisDto> result = new ArrayList<>();
+ QualityQualifiedAnalysisDto dto = new QualityQualifiedAnalysisDto();
+
+ if (CollectionUtils.isEmpty(list)) {
+ dto.setQualifiedCount(0);
+ dto.setUnqualifiedCount(0);
+ dto.setQualifiedRate(BigDecimal.ZERO.setScale(2));
+ dto.setUnqualifiedRate(BigDecimal.ZERO.setScale(2));
+ result.add(dto);
+ return result;
+ }
+
+ BigDecimal qualifiedCount = BigDecimal.ZERO;
+ BigDecimal unqualifiedCount = BigDecimal.ZERO;
+
+ for (QualityInspect item : list) {
+ if ("鍚堟牸".equals(item.getCheckResult())) {
+ qualifiedCount = qualifiedCount.add(item.getQuantity());
+ } else {
+ unqualifiedCount = unqualifiedCount.add(item.getQuantity());
+ }
+ }
+
+ BigDecimal totalCount = qualifiedCount.add(unqualifiedCount);
+
+ dto.setQualifiedCount(qualifiedCount.intValue());
+ dto.setUnqualifiedCount(unqualifiedCount.intValue());
+
+ if (totalCount.compareTo(BigDecimal.ZERO) == 0) {
+ dto.setQualifiedRate(BigDecimal.ZERO.setScale(2));
+ dto.setUnqualifiedRate(BigDecimal.ZERO.setScale(2));
+ result.add(dto);
+ return result;
+ }
+
+ BigDecimal hundred = BigDecimal.valueOf(100);
+
+ dto.setQualifiedRate(qualifiedCount.divide(totalCount, 4, RoundingMode.HALF_UP)
+ .multiply(hundred)
+ .setScale(2, RoundingMode.HALF_UP));
+
+ dto.setUnqualifiedRate(unqualifiedCount.divide(totalCount, 4, RoundingMode.HALF_UP)
+ .multiply(hundred)
+ .setScale(2, RoundingMode.HALF_UP));
+
+ result.add(dto);
+ return result;
+ }
+
+ @Override
+ public QualityInspectionCountDto qualityInspectionCount() {
+ // 鑾峰彇浠婂ぉ鐨勫紑濮嬪拰缁撴潫鏃ユ湡,鍖呭惈鏃跺垎绉�
+ LocalDateTime todayStart = LocalDateTime.now().withHour(0).withMinute(0).withSecond(0).withNano(0);
+ LocalDateTime todayEnd = LocalDateTime.now().withHour(23).withMinute(59).withSecond(59).withNano(0);
+ // 鑾峰彇鍓嶄竴澶╃殑寮�濮嬪拰缁撴潫鏃ユ湡,鍖呭惈鏃跺垎绉�
+ LocalDateTime prevStart = todayStart.minusDays(1);
+ LocalDateTime prevEnd = todayEnd.minusDays(1);
+ // 鏌ヨ鍑烘埅姝粖鏃ョ殑鎬绘楠屾暟
+ List<QualityInspect> todayList = qualityInspectMapper.selectList(new LambdaQueryWrapper<QualityInspect>()
+ // .eq(QualityInspect::getInspectState, 1)
+ .le(QualityInspect::getCheckTime, todayEnd));
+ // 鏌ヨ鍑烘埅姝㈠墠涓�澶╃殑鎬绘楠屾暟
+ List<QualityInspect> prevList = qualityInspectMapper.selectList(new LambdaQueryWrapper<QualityInspect>()
+ // .eq(QualityInspect::getInspectState, 1)
+ .le(QualityInspect::getCheckTime, prevEnd));
+ // 璁$畻浠婃棩鐨勬�绘楠屾暟
+ BigDecimal todayCount = todayList.stream()
+ .map(QualityInspect::getQuantity)
+ .reduce(BigDecimal.ZERO, BigDecimal::add);
+ // 璁$畻鍓嶄竴澶╃殑鎬绘楠屾暟
+ BigDecimal prevCount = prevList.stream()
+ .map(QualityInspect::getQuantity)
+ .reduce(BigDecimal.ZERO, BigDecimal::add);
+
+ // 璁$畻浠婃棩鐩稿鏄ㄥぉ鐨勪竴涓�绘瘮澧為暱
+ BigDecimal growthRate = calcGrowthRate(todayCount, prevCount);
+
+ // 璁$畻浠婂ぉ鐨勫緟瀹屾垚鏁伴噺
+ List<QualityInspect> todayPendingList = qualityInspectMapper.selectList(new LambdaQueryWrapper<QualityInspect>()
+ .eq(QualityInspect::getInspectState, 0)
+ .ge(QualityInspect::getCheckTime, todayStart)
+ .le(QualityInspect::getCheckTime, todayEnd));
+
+ // 璁$畻鍓嶄竴澶╃殑寰呭畬鎴愭暟閲�
+ List<QualityInspect> prevPendingList = qualityInspectMapper.selectList(new LambdaQueryWrapper<QualityInspect>()
+ .eq(QualityInspect::getInspectState, 0)
+ .ge(QualityInspect::getCheckTime, prevStart)
+ .le(QualityInspect::getCheckTime, prevEnd));
+ // 璁$畻浠婂ぉ鐨勫緟瀹屾垚鏁伴噺
+ BigDecimal todayPendingCount = todayPendingList.stream()
+ .map(QualityInspect::getQuantity)
+ .reduce(BigDecimal.ZERO, BigDecimal::add);
+
+ // 璁$畻鍓嶄竴澶╃殑寰呭畬鎴愭暟閲�
+ BigDecimal prevPendingCount = prevPendingList.stream()
+ .map(QualityInspect::getQuantity)
+ .reduce(BigDecimal.ZERO, BigDecimal::add);
+ // 璁$畻浠婂ぉ鐨勫緟瀹屾垚鏁伴噺鐩稿鏄ㄥぉ鐨勪竴涓悓姣斿闀�
+ BigDecimal todayPendingCountGrowthRate = calcGrowthRate(todayPendingCount, prevPendingCount);
+ // 璁$畻浠婂ぉ鐨勫凡瀹屾垚鏁伴噺
+ List<QualityInspect> todayCompletedList = qualityInspectMapper
+ .selectList(new LambdaQueryWrapper<QualityInspect>()
+ .eq(QualityInspect::getInspectState, 1)
+ .ge(QualityInspect::getCheckTime, todayStart)
+ .le(QualityInspect::getCheckTime, todayEnd));
+ // 璁$畻鍓嶄竴澶╃殑宸插畬鎴愭暟閲�
+ List<QualityInspect> prevCompletedList = qualityInspectMapper
+ .selectList(new LambdaQueryWrapper<QualityInspect>()
+ .eq(QualityInspect::getInspectState, 1)
+ .ge(QualityInspect::getCheckTime, prevStart)
+ .le(QualityInspect::getCheckTime, prevEnd));
+ // 璁$畻浠婂ぉ鐨勫凡瀹屾垚鏁伴噺
+ BigDecimal todayCompletedCount = todayCompletedList.stream()
+ .map(QualityInspect::getQuantity)
+ .reduce(BigDecimal.ZERO, BigDecimal::add);
+ // 璁$畻鍓嶄竴澶╃殑宸插畬鎴愭暟閲�
+ BigDecimal prevCompletedCount = prevCompletedList.stream()
+ .map(QualityInspect::getQuantity)
+ .reduce(BigDecimal.ZERO, BigDecimal::add);
+ // 璁$畻浠婂ぉ鐨勫凡瀹屾垚鏁伴噺鐩稿鏄ㄥぉ鐨勪竴涓悓姣斿闀�
+ BigDecimal todayCompletedCountGrowthRate = calcGrowthRate(todayCompletedCount, prevCompletedCount);
+ QualityInspectionCountDto dto = new QualityInspectionCountDto();
+ dto.setTotalCount(todayCount);
+ dto.setTotalCountGrowthRate(growthRate);
+ dto.setTodayPendingCount(todayPendingCount);
+ dto.setTodayPendingCountGrowthRate(todayPendingCountGrowthRate);
+ dto.setTodayCompletedCount(todayCompletedCount);
+ dto.setTodayCompletedCountGrowthRate(todayCompletedCountGrowthRate);
+ return dto;
+ }
+
+ private BigDecimal calcGrowthRate(BigDecimal today, BigDecimal prev) {
+ if (prev == null || prev.compareTo(BigDecimal.ZERO) == 0) {
+ return BigDecimal.ZERO.setScale(2);
+ }
+ return today.subtract(prev)
+ .divide(prev, 4, RoundingMode.HALF_UP)
+ .multiply(BigDecimal.valueOf(100))
+ .setScale(2, RoundingMode.HALF_UP);
+ }
+
+ @Override
+ public NonComplianceWarningDto nonComplianceWarning() {
+
+ // 杩戜竷澶╂椂闂村尯闂�
+ LocalDateTime[] range = lastSevenDaysRange();
+ LocalDateTime startTime = range[0];
+ LocalDateTime endTime = range[1];
+
+ // 鏌ヨ杩戜竷澶╁凡澶勭悊涓嶅悎鏍兼暟鎹�
+ List<QualityUnqualified> list = qualityUnqualifiedMapper.selectList(
+ new LambdaQueryWrapper<QualityUnqualified>()
+ .eq(QualityUnqualified::getInspectState, 1)
+ .ge(QualityUnqualified::getCheckTime, startTime)
+ .le(QualityUnqualified::getCheckTime, endTime));
+
+ NonComplianceWarningDto dto = new NonComplianceWarningDto();
+
+ if (CollectionUtils.isEmpty(list)) {
+ dto.setRawMaterialRatio(BigDecimal.ZERO);
+ dto.setSemiFinishedProductRatio(BigDecimal.ZERO);
+ dto.setFinishedProductRatio(BigDecimal.ZERO);
+ dto.setChildren(new ArrayList<>());
+ return dto;
+ }
+
+ // 鏌ヨ鎵�鏈変骇鍝�
+ List<Product> products = productMapper.selectList(null);
+
+ Map<Long, Product> productMap = products.stream()
+ .collect(Collectors.toMap(Product::getId, p -> p));
+
+ BigDecimal rawMaterialCount = BigDecimal.ZERO;
+ BigDecimal semiFinishedCount = BigDecimal.ZERO;
+ BigDecimal finishedCount = BigDecimal.ZERO;
+
+ List<NonComplianceWarningDto.Item> children = new ArrayList<>();
+
+ for (QualityUnqualified item : list) {
+
+ BigDecimal quantity = item.getQuantity();
+ Long productId = item.getProductId();
+
+ Product product = productMap.get(productId);
+ if (product == null) {
+ continue;
+ }
+
+ // 鎵惧埌浜у搧澶х被
+ Product parent = product.getParentId() == null
+ ? product
+ : productMap.get(product.getParentId());
+
+ if (parent == null) {
+ continue;
+ }
+
+ switch (parent.getProductName()) {
+ case "鍘熸潗鏂�":
+ rawMaterialCount = rawMaterialCount.add(quantity);
+ break;
+ case "鍗婃垚鍝�":
+ semiFinishedCount = semiFinishedCount.add(quantity);
+ break;
+ case "鎴愬搧":
+ finishedCount = finishedCount.add(quantity);
+ break;
+ default:
+ break;
+ }
+
+ // 缁勮鏄庣粏
+ NonComplianceWarningDto.Item child = new NonComplianceWarningDto.Item();
+ // child.setProductTitle(item.getProductName());
+ child.setProductTitle(parent.getProductName());
+ child.setDescription(item.getDefectivePhenomena());
+ child.setDate(formatDate(item.getCheckTime()));
+ children.add(child);
+ }
+
+ BigDecimal total = rawMaterialCount
+ .add(semiFinishedCount)
+ .add(finishedCount);
+
+ dto.setRawMaterialRatio(calcRate(rawMaterialCount, total));
+ dto.setSemiFinishedProductRatio(calcRate(semiFinishedCount, total));
+ dto.setFinishedProductRatio(calcRate(finishedCount, total));
+ dto.setChildren(children);
+
+ return dto;
+ }
+
+ private BigDecimal calcRate(BigDecimal part, BigDecimal total) {
+ if (total == null || total.compareTo(BigDecimal.ZERO) == 0) {
+ return BigDecimal.ZERO.setScale(2);
+ }
+ return part.divide(total, 4, RoundingMode.HALF_UP)
+ .multiply(BigDecimal.valueOf(100))
+ .setScale(2, RoundingMode.HALF_UP);
+ }
+
+ public static String formatDate(Date date) {
+ if (date == null) {
+ return null;
+ }
+ return date.toInstant()
+ .atZone(ZoneId.systemDefault())
+ .toLocalDate()
+ .format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
+ }
+
+ /**
+ * 鑾峰彇杩戜竷澶╃殑鏃堕棿鍖洪棿锛堝寘鍚粖澶╋級
+ */
+ public static LocalDateTime[] lastSevenDaysRange() {
+ LocalDate today = LocalDate.now();
+
+ LocalDateTime startTime = today.minusDays(6).atStartOfDay();
+ LocalDateTime endTime = today.atTime(23, 59, 59);
+
+ return new LocalDateTime[]{startTime, endTime};
+ }
+
+ @Override
+ public List<CompletedInspectionCountDto> completedInspectionCount() {
+ // 杩戜竷澶╂椂闂村尯闂�
+ LocalDateTime[] range = lastSevenDaysRange();
+ LocalDateTime startTime = range[0];
+ LocalDateTime endTime = range[1];
+
+ // 鏌ヨ杩戜竷澶╁凡瀹屾垚鐨勬楠屾暟鎹�
+ List<QualityInspect> list = qualityInspectMapper.selectList(new LambdaQueryWrapper<QualityInspect>()
+ .eq(QualityInspect::getInspectState, 1)
+ .ge(QualityInspect::getCheckTime, startTime)
+ .le(QualityInspect::getCheckTime, endTime));
+
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM-dd");
+
+ Map<String, CompletedInspectionCountDto> resultMap = new LinkedHashMap<>();
+
+ for (int i = 6; i >= 0; i--) {
+ LocalDate date = LocalDate.now().minusDays(i);
+ String dateStr = date.format(formatter);
+
+ CompletedInspectionCountDto dto = new CompletedInspectionCountDto();
+ dto.setDateStr(dateStr);
+ dto.setQualifiedCount(BigDecimal.ZERO);
+ dto.setUnqualifiedCount(BigDecimal.ZERO);
+ dto.setPassRate(BigDecimal.ZERO);
+
+ resultMap.put(dateStr, dto);
+ }
+
+ // 绱姞鍚堟牸 / 涓嶅悎鏍兼暟閲�
+ for (QualityInspect item : list) {
+
+ String dateStr = item.getCheckTime()
+ .toInstant()
+ .atZone(ZoneId.systemDefault())
+ .toLocalDate()
+ .format(formatter);
+
+ CompletedInspectionCountDto dto = resultMap.get(dateStr);
+ if (dto == null) {
+ continue;
+ }
+
+ BigDecimal quantity = item.getQuantity();
+
+ if ("鍚堟牸".equals(item.getCheckResult())) {
+ dto.setQualifiedCount(dto.getQualifiedCount().add(quantity));
+ } else {
+ dto.setUnqualifiedCount(dto.getUnqualifiedCount().add(quantity));
+ }
+ }
+
+ // 璁$畻鍚堟牸鐜�
+ for (CompletedInspectionCountDto dto : resultMap.values()) {
+ BigDecimal total = dto.getQualifiedCount().add(dto.getUnqualifiedCount());
+ dto.setPassRate(calcRate(dto.getQualifiedCount(), total));
+ }
+
+ return new ArrayList<>(resultMap.values());
+ }
+
+ @Override
+ public List<UnqualifiedProductRankDto> unqualifiedProductRanking() {
+
+ List<QualityInspect> list = qualityInspectMapper.selectList(new LambdaQueryWrapper<QualityInspect>()
+ .eq(QualityInspect::getInspectState, 1));
+
+ if (CollectionUtils.isEmpty(list)) {
+ return new ArrayList<>();
+ }
+
+ Map<Long, String> productNameMap = productMapper.selectList(null)
+ .stream()
+ .collect(Collectors.toMap(Product::getId, Product::getProductName));
+
+ Map<Long, List<QualityInspect>> groupMap = list.stream()
+ .collect(Collectors.groupingBy(QualityInspect::getProductId));
+
+ List<UnqualifiedProductRankDto> resultList = new ArrayList<>();
+
+ for (Map.Entry<Long, List<QualityInspect>> entry : groupMap.entrySet()) {
+
+ Long productId = entry.getKey();
+ List<QualityInspect> items = entry.getValue();
+
+ BigDecimal totalCount = BigDecimal.ZERO;
+ BigDecimal qualifiedCount = BigDecimal.ZERO;
+ BigDecimal unqualifiedCount = BigDecimal.ZERO;
+
+ for (QualityInspect item : items) {
+ BigDecimal qty = item.getQuantity();
+ totalCount = totalCount.add(qty);
+
+ if ("鍚堟牸".equals(item.getCheckResult())) {
+ qualifiedCount = qualifiedCount.add(qty);
+ } else {
+ unqualifiedCount = unqualifiedCount.add(qty);
+ }
+ }
+
+ if (totalCount.compareTo(BigDecimal.ZERO) == 0) {
+ continue;
+ }
+
+ BigDecimal passRate = qualifiedCount
+ .divide(totalCount, 4, RoundingMode.HALF_UP)
+ .multiply(new BigDecimal("100"))
+ .setScale(2, RoundingMode.HALF_UP);
+
+ UnqualifiedProductRankDto dto = new UnqualifiedProductRankDto();
+ dto.setProductName(productNameMap.get(productId));
+ dto.setTotalCount(totalCount);
+ dto.setCompletedCount(qualifiedCount);
+ dto.setPassRate(passRate);
+
+ resultList.add(dto);
+ }
+
+ resultList.sort(Comparator.comparing(UnqualifiedProductRankDto::getPassRate));
+
+ return resultList.stream().limit(5).collect(Collectors.toList());
+ }
+
+ @Override
+ public List<MapDto> unqualifiedProductProcessingAnalysis() {
+
+ List<QualityUnqualified> list = qualityUnqualifiedMapper.selectList(null);
+ if (CollectionUtils.isEmpty(list)) {
+ return new ArrayList<>();
+ }
+
+ // 缁熻姣忕澶勭悊缁撴灉鐨勬暟閲�
+ Map<String, BigDecimal> countMap = new HashMap<>();
+ for (QualityUnqualified item : list) {
+ if (StringUtils.isEmpty(item.getDealResult()) || item.getQuantity() == null) {
+ continue;
+ }
+ countMap.merge(item.getDealResult(), item.getQuantity(), BigDecimal::add);
+ }
+
+ if (countMap.isEmpty()) {
+ return new ArrayList<>();
+ }
+
+ // 璁$畻鎬绘暟
+ BigDecimal totalCount = countMap.values()
+ .stream()
+ .reduce(BigDecimal.ZERO, BigDecimal::add);
+
+ if (totalCount.compareTo(BigDecimal.ZERO) == 0) {
+ return new ArrayList<>();
+ }
+
+ // 鎸夋暟閲忓�掑簭鎺掑簭
+ List<Map.Entry<String, BigDecimal>> sortedList = countMap.entrySet()
+ .stream()
+ .sorted((a, b) -> b.getValue().compareTo(a.getValue()))
+ .collect(Collectors.toList());
+
+ List<MapDto> result = new ArrayList<>();
+
+ int limit = Math.min(3, sortedList.size());
+ BigDecimal otherCount = BigDecimal.ZERO;
+
+ for (int i = 0; i < sortedList.size(); i++) {
+ Map.Entry<String, BigDecimal> entry = sortedList.get(i);
+
+ if (i < limit) {
+ MapDto dto = new MapDto();
+ dto.setName(entry.getKey());
+ dto.setValue(entry.getValue().setScale(2, RoundingMode.HALF_UP).toPlainString());
+ dto.setRate(calcRate(entry.getValue(), totalCount).toString());
+ result.add(dto);
+ } else {
+ otherCount = otherCount.add(entry.getValue());
+ }
+ }
+
+ if (otherCount.compareTo(BigDecimal.ZERO) > 0) {
+ MapDto otherDto = new MapDto();
+ otherDto.setName("鍏朵粬");
+ otherDto.setValue(otherCount.setScale(2, RoundingMode.HALF_UP).toPlainString());
+ otherDto.setRate(calcRate(otherCount, totalCount).toString());
+ result.add(otherDto);
+ }
+
+ return result;
+ }
+
+}
\ No newline at end of file
--
Gitblit v1.9.3