From 92d4fac0b58498efc6be7764f00364535beb3d71 Mon Sep 17 00:00:00 2001 From: liding <756868258@qq.com> Date: 星期二, 08 七月 2025 18:02:00 +0800 Subject: [PATCH] 1.首页数据 2.装备数据 --- main-business/src/main/java/com/ruoyi/business/service/impl/SalesRecordServiceImpl.java | 286 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 286 insertions(+), 0 deletions(-) diff --git a/main-business/src/main/java/com/ruoyi/business/service/impl/SalesRecordServiceImpl.java b/main-business/src/main/java/com/ruoyi/business/service/impl/SalesRecordServiceImpl.java index 46d6e5b..2f162a7 100644 --- a/main-business/src/main/java/com/ruoyi/business/service/impl/SalesRecordServiceImpl.java +++ b/main-business/src/main/java/com/ruoyi/business/service/impl/SalesRecordServiceImpl.java @@ -1,6 +1,7 @@ package com.ruoyi.business.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -10,6 +11,7 @@ import com.ruoyi.basic.mapper.CoalInfoMapper; import com.ruoyi.basic.mapper.CustomerMapper; import com.ruoyi.business.dto.SalesRecordDto; +import com.ruoyi.business.dto.YearlyQueryDto; import com.ruoyi.business.entity.OfficialInventory; import com.ruoyi.business.entity.SalesRecord; import com.ruoyi.business.mapper.OfficialInventoryMapper; @@ -23,12 +25,21 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.text.DecimalFormat; import java.time.LocalDate; +import java.time.YearMonth; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; +import java.time.temporal.TemporalAdjusters; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors; +import java.util.*; /** * <p> @@ -218,4 +229,279 @@ // 鎵ц鎵归噺閫昏緫鍒犻櫎 return salesRecordMapper.update(null, updateWrapper); } + + @Override + public Map<String, Object> getYearlyMonthlySales(YearlyQueryDto query) { + // 1. 澶勭悊榛樿鏌ヨ锛堜笉浼犲弬鏁版椂锛� + if (query == null || query.getTimeRange() == null || query.getTimeRange().length == 0) { + query = getDefaultQuery(); + } + + // 2. 瑙f瀽鏃堕棿鑼冨洿 + LocalDate[] dateRange = parseAndValidateDateRange(query.getTimeRange()); + LocalDate startDate = dateRange[0]; + LocalDate endDate = dateRange[1]; + + // 3. 鏌ヨ鏁版嵁 + List<SalesRecord> records = salesRecordMapper.findByDateRange( + startDate.withDayOfMonth(1), + endDate.withDayOfMonth(1).with(TemporalAdjusters.lastDayOfMonth()) + ); + + // 4. 鏋勫缓鍝嶅簲 + return buildResponse(query.getTimeRange(), records, startDate, endDate); + } + + // 鑾峰彇榛樿鏌ヨ锛堝綋鍓嶅勾搴︽渶杩�6涓湀锛� + private YearlyQueryDto getDefaultQuery() { + LocalDate now = LocalDate.now(); + LocalDate startDate = now.minusMonths(5).withDayOfMonth(1); + + String[] timeRange = { + startDate.format(DateTimeFormatter.ofPattern("yyyy-MM")), + now.format(DateTimeFormatter.ofPattern("yyyy-MM")) + }; + + YearlyQueryDto defaultQuery = new YearlyQueryDto(); + defaultQuery.setTimeRange(timeRange); + return defaultQuery; + } + + // 瑙f瀽骞堕獙璇佹棩鏈熻寖鍥� + private LocalDate[] parseAndValidateDateRange(String[] timeRange) { + if (timeRange == null || timeRange.length != 2) { + throw new IllegalArgumentException("鏃堕棿鑼冨洿鍙傛暟鏍煎紡涓嶆纭�"); + } + + LocalDate startDate = parseDate(timeRange[0]); + LocalDate endDate = parseDate(timeRange[1]); + + if (startDate.isAfter(endDate)) { + throw new IllegalArgumentException("寮�濮嬫棩鏈熶笉鑳芥櫄浜庣粨鏉熸棩鏈�"); + } + + return new LocalDate[]{startDate, endDate}; + } + + // 瑙f瀽鏃ユ湡锛堟牸寮忥細yyyy-MM锛� + private LocalDate parseDate(String dateStr) { + try { + return YearMonth.parse(dateStr).atDay(1); + } catch (DateTimeParseException e) { + throw new IllegalArgumentException("鏃ユ湡鏍煎紡涓嶆纭紝搴斾负 yyyy-MM", e); + } + } + + // 鏋勫缓鍝嶅簲鏁版嵁 + private Map<String, Object> buildResponse(String[] timeRange, + List<SalesRecord> records, + LocalDate startDate, + LocalDate endDate) { + Map<String, Object> response = new LinkedHashMap<>(); + response.put("timeRange", timeRange); + response.put("data", formatMonthlyData(records, startDate, endDate)); + response.put("isDefaultQuery", timeRange.equals(getDefaultQuery().getTimeRange())); + return response; + } + + // 鏍煎紡鍖栨湀搴︽暟鎹� + private Map<String, Integer> formatMonthlyData(List<SalesRecord> records, + LocalDate startDate, + LocalDate endDate) { + // 棰勫畾涔夋牸寮忓寲鍣� + DateTimeFormatter monthFormatter = DateTimeFormatter.ofPattern("yyyy-MM"); + + // 浣跨敤 TreeMap 鑷姩鎸夐敭鎺掑簭 + Map<String, Integer> monthlyData = records.stream() + .collect(Collectors.groupingBy( + r -> r.getSaleDate().format(monthFormatter), + TreeMap::new, + // 鍏抽敭淇敼锛氬鐞� saleQuantity 涓� null 鐨勬儏鍐碉紝榛樿鎸� 0 璁$畻 + Collectors.summingInt(r -> { + BigDecimal quantity = r.getSaleQuantity(); + return quantity != null ? quantity.intValue() : 0; // 涓夌洰杩愮畻绗﹀垽鏂� + }) + )); + + // 濉厖缂哄け鏈堜唤 + YearMonth start = YearMonth.from(startDate); + YearMonth end = YearMonth.from(endDate); + + for (YearMonth month = start; !month.isAfter(end); month = month.plusMonths(1)) { + String monthKey = month.format(monthFormatter); + monthlyData.putIfAbsent(monthKey, 0); + } + + return monthlyData; + } + + @Override + public Map<String, Object> selectAllInfo() { + Map<String, Object> result = new LinkedHashMap<>(); + + //钀ユ敹閲戦 + LocalDate today = LocalDate.now(); + LocalDate yesterday = today.minusDays(1); + + BigDecimal revenueAmount; + List<SalesRecord> salesRecords = salesRecordMapper.selectList(null); + revenueAmount = salesRecords.stream() + .map(SalesRecord::getTotalAmount) + .reduce(BigDecimal.ZERO, BigDecimal::add); + + //浠婃棩钀ユ敹 + BigDecimal todayRevenue = salesRecords.stream() + .filter(record -> today.equals(record.getSaleDate())) + .map(SalesRecord::getTotalAmount) + .reduce(BigDecimal.ZERO, BigDecimal::add); + + //鏄ㄦ棩钀ユ敹 + BigDecimal yesterdayRevenue = salesRecords.stream() + .filter(record -> yesterday.equals(record.getSaleDate())) + .map(SalesRecord::getTotalAmount) + .reduce(BigDecimal.ZERO, BigDecimal::add); + + // 璁$畻澧為暱鐧惧垎姣� + BigDecimal increases = BigDecimal.ZERO; + String trend = "+"; + + if (yesterdayRevenue.compareTo(BigDecimal.ZERO) != 0) { + increases = todayRevenue.subtract(yesterdayRevenue) + .divide(yesterdayRevenue, 4, RoundingMode.HALF_UP) + .multiply(new BigDecimal(100)); + + if (increases.compareTo(BigDecimal.ZERO) > 0) { + trend = "+"; + } else if (increases.compareTo(BigDecimal.ZERO) < 0) { + trend = "鈥�"; + } + } + + // 6. 鏍煎紡鍖栫櫨鍒嗘瘮鏄剧ず + DecimalFormat formatNo = new DecimalFormat("0.00%"); + String changeRate = formatNo.format(increases.divide(new BigDecimal(100), 4, RoundingMode.HALF_UP)); + + //渚涘簲閲� + BigDecimal saleQuantity = salesRecords.stream() + .map(SalesRecord::getSaleQuantity) + .reduce(BigDecimal.ZERO, BigDecimal::add); + + //浠婃棩渚涘簲閲� + BigDecimal todaySaleQuantity = salesRecords.stream() + .filter(record -> today.equals(record.getSaleDate())) + .map(SalesRecord::getSaleQuantity) + .reduce(BigDecimal.ZERO, BigDecimal::add); + + //鏄ㄦ棩渚涘簲閲� + BigDecimal yesterdaySaleQuantity = salesRecords.stream() + .filter(record -> yesterday.equals(record.getSaleDate())) + .map(SalesRecord::getSaleQuantity) + .reduce(BigDecimal.ZERO, BigDecimal::add); + + // 璁$畻澧為暱鐧惧垎姣� + BigDecimal increasesQuantity = BigDecimal.ZERO; + String trendQuantity = "+"; + + if (yesterdaySaleQuantity.compareTo(BigDecimal.ZERO) != 0) { + increasesQuantity = todaySaleQuantity.subtract(yesterdaySaleQuantity) + .divide(yesterdaySaleQuantity, 4, RoundingMode.HALF_UP) + .multiply(new BigDecimal(100)); + + if (increasesQuantity.compareTo(BigDecimal.ZERO) > 0) { + trendQuantity = "+"; + } else if (increasesQuantity.compareTo(BigDecimal.ZERO) < 0) { + trendQuantity = "鈥�"; + } + } + + // 鏍煎紡鍖栨暟閲忕櫨鍒嗘瘮鏄剧ず + DecimalFormat formatNoQuantity = new DecimalFormat("0.00%"); + String saleQuantityRate = formatNoQuantity.format(increasesQuantity.divide(new BigDecimal(100), 4, RoundingMode.HALF_UP)); + + //钀ユ敹鍒嗗竷 + //鑾峰彇鎵�鏈夌叅绉嶄俊鎭�(id鍜屽悕绉扮殑鏄犲皠) + Map<Long, String> coalIdToNameMap = coalInfoMapper.selectList(null).stream() + .collect(Collectors.toMap( + CoalInfo::getId, + CoalInfo::getCoal + )); + + // 3. 鎸夌叅绉岻D缁熻鎬婚噾棰� + Map<Long, BigDecimal> revenueByCoalId = salesRecords.stream() + .collect(Collectors.groupingBy( + SalesRecord::getCoalId, + Collectors.reducing( + BigDecimal.ZERO, + SalesRecord::getTotalAmount, + BigDecimal::add + ) + )); + + // 鐓ょ閿�鍞垎甯冿紙鍗曠嫭浣滀负涓�涓瓙Map锛� + Map<String, BigDecimal> revenueDistribution = new LinkedHashMap<>(); + coalIdToNameMap.forEach((id, name) -> { + BigDecimal amount = revenueByCoalId.getOrDefault(id, BigDecimal.ZERO) + .setScale(2, RoundingMode.HALF_UP); + if (amount.compareTo(BigDecimal.ZERO) > 0) { + revenueDistribution.put(name, amount); + } + }); + + //閿�鍞暟鎹� + // 鎸塩oalId鍒嗙粍骞跺悎骞舵暟閲忓拰閲戦 + Map<Long, Map<String, Object>> resultMap = new LinkedHashMap<>(); + + for (SalesRecord record : salesRecords) { + Long coalId = record.getCoalId(); + + // 灏嗘暟閲忓拰閲戦杞崲涓築igDecimal + BigDecimal quantity = record.getInventoryQuantity(); + BigDecimal amount = record.getTotalAmount(); + + if (resultMap.containsKey(coalId)) { + Map<String, Object> existing = resultMap.get(coalId); + + // 鑾峰彇鐜版湁鐨凚igDecimal鍊� + BigDecimal existingQuantity = (BigDecimal) existing.get("inventoryQuantity"); + BigDecimal existingAmount = (BigDecimal) existing.get("totalAmount"); + + // 浣跨敤BigDecimal杩涜鍔犳硶杩愮畻 + existing.put("inventoryQuantity", existingQuantity.add(quantity)); + existing.put("totalAmount", existingAmount.add(amount)); + } else { + Map<String, Object> newRecord = new HashMap<>(); + newRecord.put("coalId", coalId); + newRecord.put("inventoryQuantity", quantity); + newRecord.put("totalAmount", amount); + resultMap.put(coalId, newRecord); + } + } + + // 3. 鑾峰彇鎵�鏈夋秹鍙婄殑coalId + List<Long> coalIds = new ArrayList<>(resultMap.keySet()); + + // 4. 鎵归噺鏌ヨ鐓ょ淇℃伅骞跺~鍏呭埌缁撴灉涓� + if (!coalIds.isEmpty()) { + List<CoalInfo> coalInfos = coalInfoMapper.selectBatchIds(coalIds); + for (CoalInfo coalInfo : coalInfos) { + Map<String, Object> record = resultMap.get(coalInfo.getId()); + if (record != null) { + record.put("coalName", coalInfo.getCoal()); + } + } + } + + // 鏈�缁堢粨鏋滄槸涓�涓狶ist<Map>锛屾瘡涓狹ap鍖呭惈鍚堝苟鍚庣殑閿�鍞暟鎹拰瀵瑰簲鐨勭叅绉嶄俊鎭� + List<Map<String, Object>> results = new ArrayList<>(resultMap.values()); + result.put("revenueAmount", revenueAmount.setScale(2, RoundingMode.HALF_UP)); + result.put("changeRate", changeRate); + result.put("trend", trend); + result.put("saleQuantity", saleQuantity); + result.put("saleQuantityRate", saleQuantityRate); + result.put("trendQuantity", trendQuantity); + result.put("revenueDistribution", revenueDistribution); + result.put("salesResults", results); + + return result; + } } -- Gitblit v1.9.3