From 173f44a1f9a59509996192e3446cbd26f2613b5e Mon Sep 17 00:00:00 2001
From: maven <2163098428@qq.com>
Date: 星期五, 10 十月 2025 15:55:32 +0800
Subject: [PATCH] yys 新增关键煤种锁仓模块
---
main-business/src/main/java/com/ruoyi/business/service/impl/SalesRecordServiceImpl.java | 541 +++++++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 518 insertions(+), 23 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 8d2899c..da90280 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,27 +1,47 @@
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.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.basic.entity.CoalInfo;
import com.ruoyi.basic.entity.Customer;
+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;
import com.ruoyi.business.mapper.SalesRecordMapper;
import com.ruoyi.business.service.SalesRecordService;
+import com.ruoyi.business.vo.SalesRecordExportVo;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.base.BaseException;
+import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
+import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.mapper.SysUserMapper;
+import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
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.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
/**
* <p>
@@ -32,6 +52,7 @@
* @since 2025-06-11
*/
@Service
+@Slf4j
@RequiredArgsConstructor
public class SalesRecordServiceImpl extends ServiceImpl<SalesRecordMapper, SalesRecord> implements SalesRecordService {
@@ -43,12 +64,83 @@
private final OfficialInventoryMapper officialInventoryMapper;
+ private final CoalInfoMapper coalInfoMapper;
+
@Override
- public IPage<SalesRecord> selectSalesRecordList(Page page, SalesRecordDto salesRecordDto) {
+ public IPage<SalesRecordDto> selectSalesRecordList(Page<SalesRecord> page, SalesRecordDto salesRecordDto) {
+ // 1. 鍒涘缓鏌ヨ鏉′欢锛屾寜鍒涘缓鏃堕棿鍊掑簭鎺掑簭
LambdaQueryWrapper<SalesRecord> queryWrapper = new LambdaQueryWrapper<>();
+
+ // 鎸夋棩鏈熸煡璇�
+ if (salesRecordDto.getSaleDate() != null) {
+ queryWrapper.eq(SalesRecord::getSaleDate, salesRecordDto.getSaleDate());
+ }
+
+ // 鎸夌叅绉嶅悕绉版煡璇�
+ if (StringUtils.isNotBlank(salesRecordDto.getCoal())) {
+ LambdaQueryWrapper<CoalInfo> coalQueryWrapper = new LambdaQueryWrapper<>();
+ coalQueryWrapper.like(CoalInfo::getCoal, salesRecordDto.getCoal());
+ List<CoalInfo> coalInfos = coalInfoMapper.selectList(coalQueryWrapper);
+
+ if (!coalInfos.isEmpty()) {
+ List<Long> coalIds = coalInfos.stream()
+ .map(CoalInfo::getId)
+ .collect(Collectors.toList());
+ queryWrapper.in(SalesRecord::getCoalId, coalIds);
+ } else {
+ // 濡傛灉娌℃湁鍖归厤鐨勭叅绉嶏紝鐩存帴杩斿洖绌虹粨鏋�
+ queryWrapper.eq(SalesRecord::getCoalId, -1L); // 浣跨敤涓嶅彲鑳藉瓨鍦ㄧ殑ID
+ }
+ }
+
queryWrapper.orderByDesc(SalesRecord::getCreateTime);
- return salesRecordMapper.selectPage(page, queryWrapper);
+
+ // 2. 鑾峰彇鍒嗛〉鐨勯攢鍞褰�
+ IPage<SalesRecord> salesRecordPage = salesRecordMapper.selectPage(page, queryWrapper);
+
+ // 3. 鎵归噺鏌ヨ鎵�鏈塁oalInfo
+ List<Long> coalIds = salesRecordPage.getRecords().stream()
+ .map(SalesRecord::getCoalId) // 鑾峰彇鎵�鏈塖alesRecord鐨刢oalId
+ .collect(Collectors.toList());
+ Map<Long, CoalInfo> coalInfoMap;
+
+ // 濡傛灉鏈夌叅鐐璉D锛屾墽琛屾壒閲忔煡璇�
+ if (!coalIds.isEmpty()) {
+ // 浣跨敤selectList杩涜鎵归噺鏌ヨ
+ LambdaQueryWrapper<CoalInfo> coalInfoQueryWrapper = new LambdaQueryWrapper<>();
+ coalInfoQueryWrapper.in(CoalInfo::getId, coalIds);
+ List<CoalInfo> coalInfos = coalInfoMapper.selectList(coalInfoQueryWrapper);
+
+ // 灏嗘煡璇㈢粨鏋滄斁鍏ap涓紝鐓ょ偔ID涓洪敭锛孋oalInfo涓哄��
+ coalInfoMap = coalInfos.stream()
+ .collect(Collectors.toMap(CoalInfo::getId, Function.identity()));
+ } else {
+ coalInfoMap = new HashMap<>();
+ }
+
+ // 4. 鍒涘缓杩斿洖缁撴灉椤碉紝浣跨敤BeanUtils杩涜灞炴�у鍒�
+ Page<SalesRecordDto> resultPage = new Page<>();
+ BeanUtils.copyProperties(salesRecordPage, resultPage); // 澶嶅埗鍒嗛〉淇℃伅
+
+ // 5. 杞崲SalesRecord涓篠alesRecordDto锛屽苟璁剧疆姣忔潯閿�鍞褰曠殑鐓ょ偔淇℃伅
+ List<SalesRecordDto> dtoList = salesRecordPage.getRecords().stream().map(salesRecord -> {
+ SalesRecordDto dto = new SalesRecordDto();
+ BeanUtils.copyProperties(salesRecord, dto); // 灏哠alesRecord鐨勫睘鎬у鍒跺埌SalesRecordDto涓�
+
+ // 璁剧疆Coal淇℃伅
+ CoalInfo coalInfo = coalInfoMap.get(salesRecord.getCoalId());
+ if (coalInfo != null) {
+ dto.setCoal(coalInfo.getCoal());
+ }
+
+ return dto;
+ }).collect(Collectors.toList());
+
+ resultPage.setRecords(dtoList); // 璁剧疆杞崲鍚庣殑DTO鍒楄〃
+
+ return resultPage;
}
+
@Override
@Transactional(rollbackFor = Exception.class)
@@ -56,20 +148,20 @@
// 鍙傛暟鏍¢獙
validateSalesRecordDto(salesRecordDto);
- // 鏇存柊姝e紡搴撳緟琛ュ簱鏁伴噺
+ // 鑾峰彇鐓ょ搴撳瓨淇℃伅
OfficialInventory officialInventory = officialInventoryMapper.selectById(salesRecordDto.getCoalId());
if (officialInventory == null) {
throw new BaseException("姝e紡搴撶叅绉嶄俊鎭笉瀛樺湪");
}
- if (salesRecordDto.getSaleQuantity().compareTo(officialInventory.getInventoryQuantity()) > 0){
- throw new BaseException("閿�鍞暟閲忎笉鑳藉ぇ浜庡簱瀛樻暟閲�");
- }
- officialInventory.setInventoryQuantity(officialInventory.getInventoryQuantity().subtract(salesRecordDto.getSaleQuantity()));
- officialInventory.setPendingReplenishment(salesRecordDto.getSaleQuantity());
- officialInventoryMapper.updateById(officialInventory);
+
+ // 澶勭悊閿�鍞暟閲忓彉鏇撮�昏緫
+ SalesRecord existingRecord = salesRecordDto.getId() == null ? null : salesRecordMapper.selectById(salesRecordDto.getId());
+ handleQuantityChanges(salesRecordDto, officialInventory, existingRecord);
// 鏋勫缓閿�鍞褰曞疄浣�
- SalesRecord salesRecord = buildSalesRecord(salesRecordDto,officialInventory.getCoalId());
+ SalesRecord salesRecord = buildSalesRecord(salesRecordDto, officialInventory.getCoalId());
+ // 璁剧疆閿�鍞褰曚腑鐨勫簱瀛樻暟閲�
+ salesRecord.setInventoryQuantity(officialInventory.getInventoryQuantity());
// 澶勭悊鏂板/鏇存柊閫昏緫
if (salesRecordDto.getId() == null) {
@@ -79,22 +171,56 @@
}
}
- private void validateSalesRecordDto(SalesRecordDto dto) {
- if (dto == null) {
- throw new BaseException("閿�鍞褰曟暟鎹笉鑳戒负绌�");
+ private void handleQuantityChanges(SalesRecordDto dto, OfficialInventory officialInventory, SalesRecord existingRecord) {
+ if (existingRecord == null) {
+ // 鏂板璁板綍
+ if (dto.getSaleQuantity().compareTo(officialInventory.getInventoryQuantity()) > 0) {
+ throw new BaseException("閿�鍞暟閲忎笉鑳藉ぇ浜庡簱瀛樻暟閲�");
+ }
+ // 鏇存柊搴撳瓨鏁伴噺
+ officialInventory.setInventoryQuantity(officialInventory.getInventoryQuantity().subtract(dto.getSaleQuantity()));
+ // 璁剧疆寰呰ˉ搴撴暟閲�
+ if (dto.isAdd()) {
+ officialInventory.setPendingReplenishment(
+ officialInventory.getPendingReplenishment() == null ?
+ dto.getSaleQuantity() :
+ officialInventory.getPendingReplenishment().add(dto.getSaleQuantity())
+ );
+ }
+ } else {
+ // 鏇存柊璁板綍
+ // 姣旇緝閿�鍞暟閲忔槸鍚︽湁鍙樺寲
+ int quantityComparison = dto.getSaleQuantity().compareTo(existingRecord.getSaleQuantity());
+ if (quantityComparison != 0) {
+ // 璁$畻鏁伴噺宸��
+ BigDecimal quantityDiff = dto.getSaleQuantity().subtract(existingRecord.getSaleQuantity());
+
+ // 妫�鏌ユ柊鏁伴噺鏄惁浼氬鑷村簱瀛樹笉瓒�
+ if (quantityComparison > 0 && quantityDiff.compareTo(officialInventory.getInventoryQuantity()) > 0) {
+ throw new BaseException("閿�鍞暟閲忓鍔犲悗涓嶈兘澶т簬搴撳瓨鏁伴噺");
+ }
+
+ // 鏇存柊搴撳瓨鏁伴噺
+ officialInventory.setInventoryQuantity(officialInventory.getInventoryQuantity().subtract(quantityDiff));
+
+ // 鏇存柊寰呰ˉ搴撴暟閲忥紙濡傛灉鏄渶瑕佽ˉ搴撶殑璁板綍锛�
+ if (dto.isAdd()) {
+ BigDecimal pendingDiff = officialInventory.getPendingReplenishment() == null ?
+ quantityDiff :
+ officialInventory.getPendingReplenishment().add(quantityDiff);
+ officialInventory.setPendingReplenishment(pendingDiff);
+ }
+ }
}
- if (dto.getRegistrantId() == null) {
- throw new BaseException("鐧昏浜篒D涓嶈兘涓虹┖");
- }
- if (dto.getCustomerId() == null) {
- throw new BaseException("瀹㈡埛ID涓嶈兘涓虹┖");
- }
- if (dto.getCoalId() == null) {
- throw new BaseException("璇烽�夋嫨涓�鏉$叅绉嶄俊鎭�");
+
+ // 鏇存柊搴撳瓨璁板綍
+ int updateResult = officialInventoryMapper.updateById(officialInventory);
+ if (updateResult <= 0) {
+ throw new BaseException("搴撳瓨鏇存柊澶辫触");
}
}
- private SalesRecord buildSalesRecord(SalesRecordDto dto,Long coalId) {
+ private SalesRecord buildSalesRecord(SalesRecordDto dto, Long coalId) {
SalesRecord record = new SalesRecord();
BeanUtils.copyProperties(dto, record);
@@ -103,7 +229,7 @@
if (registrant == null) {
throw new BaseException("鐧昏浜轰俊鎭笉瀛樺湪");
}
- record.setRegistrant(registrant.getUserName());
+ record.setRegistrant(registrant.getNickName());
// 璁剧疆瀹㈡埛淇℃伅
Customer customer = customerMapper.selectById(dto.getCustomerId());
@@ -134,6 +260,21 @@
return record;
}
+ private void validateSalesRecordDto(SalesRecordDto dto) {
+ if (dto == null) {
+ throw new BaseException("閿�鍞褰曟暟鎹笉鑳戒负绌�");
+ }
+ if (dto.getRegistrantId() == null) {
+ throw new BaseException("鐧昏浜篒D涓嶈兘涓虹┖");
+ }
+ if (dto.getCustomerId() == null) {
+ throw new BaseException("瀹㈡埛ID涓嶈兘涓虹┖");
+ }
+ if (dto.getCoalId() == null) {
+ throw new BaseException("璇烽�夋嫨涓�鏉$叅绉嶄俊鎭�");
+ }
+ }
+
private int insertSalesRecord(SalesRecord record) {
int result = salesRecordMapper.insert(record);
if (result <= 0) {
@@ -163,4 +304,358 @@
// 鎵ц鎵归噺閫昏緫鍒犻櫎
return salesRecordMapper.update(null, updateWrapper);
}
+
+ @Override
+ public void salesRecordExport(HttpServletResponse response, SalesRecordDto salesRecordDto) {
+ List<Long> ids = salesRecordDto.getExportIds();
+ List<SalesRecord> list;
+ if (ids != null && !ids.isEmpty()) {
+ list = salesRecordMapper.selectByIds(ids);
+ } else {
+ list = salesRecordMapper.selectList(null);
+ }
+ List<SalesRecordExportVo> exportData = convertToExportVo(list);
+ ExcelUtil<SalesRecordExportVo> util = new ExcelUtil<>(SalesRecordExportVo.class);
+ util.exportExcel(response, exportData, "閿�鍞嚭搴撴暟鎹�");
+ }
+
+ private List<SalesRecordExportVo> convertToExportVo(List<SalesRecord> list) {
+ // 1. 鎻愬墠鏀堕泦鎵�鏈夐渶瑕佹煡璇㈢殑coalId锛岄伩鍏峃+1鏌ヨ闂
+ Set<Long> coalIds = list.stream()
+ .filter(Objects::nonNull)
+ .map(SalesRecord::getCoalId)
+ .filter(Objects::nonNull)
+ .collect(Collectors.toSet());
+
+ // 2. 鎵归噺鏌ヨcoalInfo鏁版嵁
+ Map<Long, CoalInfo> coalInfoMap = CollectionUtils.isEmpty(coalIds)
+ ? Collections.emptyMap()
+ : coalInfoMapper.selectByIds(coalIds).stream()
+ .filter(Objects::nonNull)
+ .collect(Collectors.toMap(CoalInfo::getId, Function.identity()));
+
+ // 3. 杞崲鏁版嵁
+ return list.stream()
+ .filter(Objects::nonNull)
+ .map(record -> {
+ try {
+ SalesRecordExportVo vo = new SalesRecordExportVo();
+
+ // 鎷疯礉鍩虹灞炴��
+ BeanUtils.copyProperties(record, vo);
+
+ // 璁剧疆鍏宠仈鐨刢oal淇℃伅
+ Optional.ofNullable(record.getCoalId())
+ .map(coalInfoMap::get)
+ .ifPresent(coalInfo -> vo.setCoal(coalInfo.getCoal()));
+ return vo;
+ } catch (Exception e) {
+ log.error("杞崲閿�鍞褰昖O寮傚父锛岃褰旾D: {}", record.getId(), e);
+ return null;
+ }
+ })
+ .filter(Objects::nonNull)
+ .collect(Collectors.toList());
+ }
+
+ @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.selectByIds(coalIds);
+ for (CoalInfo coalInfo : coalInfos) {
+ Map<String, Object> record = resultMap.get(coalInfo.getId());
+ if (record != null) {
+ record.put("coalName", coalInfo.getCoal());
+ }
+ }
+ }
+
+ List<Map<String, Object>> results = new ArrayList<>(resultMap.values());
+
+ //鏈堝害鏁版嵁
+ //鏌ヨ鎵�鏈夌叅绉嶄俊鎭�
+ List<CoalInfo> allCoalTypes = coalInfoMapper.selectList(
+ new QueryWrapper<CoalInfo>().orderByAsc("id")
+ );
+ //棰勮绠楅攢閲忥細鎸塩oalId鍒嗙粍缁熻鎬婚攢閲�
+ Map<Long, BigDecimal> salesByCoalId = salesRecords.stream()
+ .collect(Collectors.groupingBy(
+ SalesRecord::getCoalId,
+ Collectors.reducing(
+ BigDecimal.ZERO,
+ SalesRecord::getSaleQuantity,
+ BigDecimal::add
+ )
+ ));
+
+ // 2. 鍒涘缓 resultMouth锛屽瓨鍌ㄧ叅绉嶅強鍏堕攢閲忥紙Map 缁撴瀯锛�
+ Map<String, BigDecimal> resultMouthMap = new LinkedHashMap<>();
+ for (CoalInfo coal : allCoalTypes) {
+ resultMouthMap.put(
+ coal.getCoal(), // 鐓ょ鍚嶇О锛堝 "鏃犵儫鐓�"锛�
+ salesByCoalId.getOrDefault(coal.getId(), BigDecimal.valueOf(0)) // 閿�閲�
+ );
+ }
+
+ 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);
+ result.put("resultMouth", resultMouthMap);
+
+ return result;
+ }
}
--
Gitblit v1.9.3