package com.gunshi.project.hsz.service; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.gunshi.project.hsz.entity.dto.RiceWaterCaculateDto; import com.gunshi.project.hsz.entity.so.RiceRqWaterPageSo; import com.gunshi.project.hsz.entity.vo.RiceRqWaterCaculateVo; import com.gunshi.project.hsz.entity.vo.TyYearRainfallVo; import com.gunshi.project.hsz.mapper.RiceRqWaterMapper; import com.gunshi.project.hsz.model.*; import com.gunshi.project.hsz.util.LocalDateTimeUtils; import com.ruoyi.common.utils.StringUtils; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.math.RoundingMode; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.YearMonth; import java.util.*; import java.util.stream.Collectors; /** * 描述: 水稻需水主表 * author: xusan * date: 2024-09-04 13:42:40 */ @Service @Slf4j @Transactional(rollbackFor = Exception.class) public class RiceRqWaterService extends ServiceImpl { @Autowired private RiceGrowConfigService riceGrowConfigService; @Autowired private RiceIrrigationUseService riceIrrigationUseService; @Autowired private RiceWaterForecastCycleService riceWaterForecastCycleService; @Autowired private RiceWaterForecastMonthService riceWaterForecastMonthService; @Autowired private RiceWaterKiService riceWaterKiService; public Page pageQuery(RiceRqWaterPageSo page) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); if(page.getYear() != null){ queryWrapper.eq(RiceRqWater::getYear,page.getYear()); } if(!StringUtils.isBlank(page.getPlanName())){ queryWrapper.like(RiceRqWater::getPlanName,page.getPlanName()); } queryWrapper.orderByDesc(RiceRqWater::getCreateTime); Page riceRqWaterPage = this.baseMapper.selectPage(page.getPageSo().toPage(), queryWrapper); List records = riceRqWaterPage.getRecords(); for (RiceRqWater record : records) { //灌水定额配置 record.setRiceWaterKis(riceWaterKiService.selectByRiceWaterId(record.getId())); //水稻生长系数配置 record.setRiceGrowConfig(riceGrowConfigService.selectByRiceWaterId(record.getId())); //按月份 record.setRiceWaterForecastMonths(riceWaterForecastMonthService.selectByRiceWaterId(record.getId())); //按生长周期 record.setRiceWaterForecastCycles(riceWaterForecastCycleService.selectByRiceWaterId(record.getId())); } return riceRqWaterPage; } public RiceRqWater queryById(Long id) { RiceRqWater riceRqWater = this.baseMapper.selectById(id); if(riceRqWater == null){ return riceRqWater; } riceRqWater.setRiceWaterKis(riceWaterKiService.selectByRiceWaterId(riceRqWater.getId())); //水稻生长系数配置 riceRqWater.setRiceGrowConfig(riceGrowConfigService.selectByRiceWaterId(riceRqWater.getId())); //按月份 riceRqWater.setRiceWaterForecastMonths(riceWaterForecastMonthService.selectByRiceWaterId(riceRqWater.getId())); //按生长周期 riceRqWater.setRiceWaterForecastCycles(riceWaterForecastCycleService.selectByRiceWaterId(riceRqWater.getId())); return riceRqWater; } public RiceRqWater saveData(RiceRqWater dto) { RiceGrowConfig riceGrowConfig = dto.getRiceGrowConfig(); List riceWaterKis = dto.getRiceWaterKis(); List riceWaterForecastCycles = dto.getRiceWaterForecastCycles(); List riceWaterForecastMonths = dto.getRiceWaterForecastMonths(); dto.setReqWater(riceGrowConfig.getIrrigationUse()); dto.setCreateTime(LocalDateTime.now()); save(dto); riceGrowConfig.setRiceWaterId(dto.getId()); riceWaterKis.stream().forEach(o ->{ o.setRiceWaterId(dto.getId()); }); riceWaterForecastCycles.stream().forEach(o ->{ o.setRiceWaterId(dto.getId()); }); riceWaterForecastMonths.stream().forEach(o ->{ o.setRiceWaterId(dto.getId()); }); riceWaterKiService.saveBatch(riceWaterKis); riceGrowConfigService.save(riceGrowConfig); riceWaterForecastCycleService.saveBatch(riceWaterForecastCycles); riceWaterForecastMonthService.saveBatch(riceWaterForecastMonths); return dto; } public RiceRqWater updateData(RiceRqWater dto) { RiceGrowConfig riceGrowConfig = dto.getRiceGrowConfig(); List riceWaterKis = dto.getRiceWaterKis(); List riceWaterForecastCycles = dto.getRiceWaterForecastCycles(); List riceWaterForecastMonths = dto.getRiceWaterForecastMonths(); dto.setReqWater(riceGrowConfig.getIrrigationUse()); dto.setCreateTime(LocalDateTime.now()); updateById(dto); riceWaterKiService.removeByRiceWaterId(dto.getId()); riceGrowConfigService.removeByRiceWaterId(dto.getId()); riceIrrigationUseService.removeByRiceWaterId(dto.getId()); riceWaterForecastCycleService.removeByRiceWaterId(dto.getId()); riceWaterForecastMonthService.removeByRiceWaterId(dto.getId()); riceWaterKis.stream().forEach(o ->{ o.setRiceWaterId(dto.getId()); }); riceWaterForecastCycles.stream().forEach(o ->{ o.setRiceWaterId(dto.getId()); }); riceWaterForecastMonths.stream().forEach(o ->{ o.setRiceWaterId(dto.getId()); }); riceGrowConfig.setRiceWaterId(dto.getId()); riceWaterKiService.saveBatch(riceWaterKis); riceGrowConfigService.save(riceGrowConfig); riceWaterForecastCycleService.saveBatch(riceWaterForecastCycles); riceWaterForecastMonthService.saveBatch(riceWaterForecastMonths); return dto; } public Boolean delData(Long id) { removeById(id); riceWaterKiService.removeByRiceWaterId(id); riceGrowConfigService.removeByRiceWaterId(id); riceIrrigationUseService.removeByRiceWaterId(id); riceWaterForecastCycleService.removeByRiceWaterId(id); riceWaterForecastMonthService.removeByRiceWaterId(id); return true; } public List stageCaculate(RiceWaterCaculateDto dto) { RiceGrowConfig riceGrowConfig = dto.getRiceGrowConfig(); List riceWaterKis = dto.getRiceWaterKis(); orderByStartTimeAsc(riceWaterKis); // 早稻需水系数 BigDecimal α1 = riceGrowConfig.getΑ1(); if(α1 == null){ throw new IllegalArgumentException("早稻需水系数不能为空"); } // 渗漏强度 BigDecimal lkIntensity = riceGrowConfig.getLkIntensity(); if(lkIntensity == null){ throw new IllegalArgumentException("渗漏强度不能为空"); } // 生长期水面蒸发量(mm) BigDecimal ed1 = riceGrowConfig.getEd1(); if(ed1 == null){ throw new IllegalArgumentException("生长期水面蒸发量不能为空"); } for (RiceWaterKi riceWaterKi : riceWaterKis) { // 计算阶段耗水量 if(riceWaterKi.getRiceGrowStage().contains("泡田")){ riceWaterKi.setKi(riceGrowConfig.getΑ1());//需水系数 riceWaterKi.setWaterRqStage(riceGrowConfig.getKaQuota());//泡田定额 continue; } BigDecimal waterRqStage = calculateWaterRqStage(riceWaterKi, α1, ed1, lkIntensity); riceWaterKi.setWaterRqStage(waterRqStage.setScale(1,RoundingMode.UP)); } return riceWaterKis; } /** * 计算阶段耗水量 * 公式:ki * α1 * ed1 + days * lkIntensity */ private BigDecimal calculateWaterRqStage(RiceWaterKi riceWaterKi, BigDecimal α1, BigDecimal ed1, BigDecimal lkIntensity) { // 获取需水模系数 BigDecimal ki = riceWaterKi.getKi(); if(ki == null){ throw new IllegalArgumentException("需水模型系数不能为空"); } // 计算天数(如果days为空,则根据开始结束日期计算) Integer days = riceWaterKi.getDays(); if (days == null && riceWaterKi.getStartTime() != null && riceWaterKi.getEndTime() != null) { days = calculateDaysBetween(riceWaterKi.getStartTime(), riceWaterKi.getEndTime()); riceWaterKi.setDays(days); // 同时设置回实体中 } if (days == null) { days = 0; } // 计算公式:ki * α1 * ed1 + days * lkIntensity BigDecimal part1 = ki.multiply(α1).multiply(ed1); BigDecimal part2 = new BigDecimal(days).multiply(lkIntensity); return part1.add(part2); } /** * 计算两个LocalDateTime之间的天数(包含开始和结束日期) * 例如:2025-04-26 ~ 2025-05-06 = 11天 */ private Integer calculateDaysBetween(LocalDateTime startTime, LocalDateTime endTime) { if (startTime == null || endTime == null) { return 0; } // 使用LocalDate来计算天数,忽略时间部分 long days = java.time.temporal.ChronoUnit.DAYS.between( startTime.toLocalDate(), endTime.toLocalDate() ); // 因为包含开始和结束日期,所以需要+1 return (int) days + 1; } @Autowired private TyYearRainfallService tyYearRainfallService; public List irrigationCaculate(RiceWaterCaculateDto dto) { List riceWaterKis = dto.getRiceWaterKis(); List res = new ArrayList<>(); orderByStartTimeAsc(riceWaterKis); RiceGrowConfig riceGrowConfig = dto.getRiceGrowConfig(); riceGrowConfig.setCycle(LocalDateTimeUtils.getTotalDayByRangeDate(riceWaterKis.getFirst().getStartTime(),riceWaterKis.getLast().getEndTime())); Integer year = riceGrowConfig.getYear();//相似年 List tyYearRainfallVos = tyYearRainfallService.queryList(); List collect = tyYearRainfallVos.stream().filter(o -> { return o.getYear().equals(year); }).collect(Collectors.toList()); if(collect == null || collect.isEmpty()){ throw new IllegalArgumentException("对不起,没有该年份的降雨资料"); } TyYearRainfallVo tyYearRainfallVo = collect.get(0); List list = tyYearRainfallVo.getList();//获取月份的降雨资料 //泡田定额 BigDecimal kaQuota = riceGrowConfig.getKaQuota(); // 泡田期是第一个元素 RiceWaterKi kaPeriod = riceWaterKis.get(0); LocalDateTime kaStartTime = kaPeriod.getStartTime(); LocalDateTime kaEndTime = kaPeriod.getEndTime(); int totalKaDays = calculateTotalKaDays(kaStartTime, kaEndTime); // 生育期数据(排除泡田期) List growPeriods = riceWaterKis.subList(1, riceWaterKis.size()); // 用于存储去重后的月份(1-12) Set monthSet = new HashSet<>(); // 添加泡田期的月份 monthSet.add(kaStartTime.getMonthValue()); monthSet.add(kaEndTime.getMonthValue()); // 遍历集合,提取每个元素的 startTime 和 endTime 对应的月份 for (RiceWaterKi riceWaterKi : riceWaterKis) { LocalDateTime start = riceWaterKi.getStartTime(); LocalDateTime end = riceWaterKi.getEndTime(); if (start != null) { monthSet.add(start.getMonthValue()); } if (end != null) { monthSet.add(end.getMonthValue()); } } // 将去重后的月份转为列表并按从小到大排序 List sortedMonths = monthSet.stream() .sorted() .collect(Collectors.toList()); for (Integer sortedMonth : sortedMonths) { RiceIrrigationUse riceIrrigationUse = new RiceIrrigationUse(); riceIrrigationUse.setMonth(sortedMonth); BigDecimal irrigationVolume = BigDecimal.ZERO; // 计算泡田期在当前月份的耗水量 /** * 由于这个方法是按照月份进行计算的,所以当后面的生长期有属于泡田期的月份时,那么也要把泡田期的算上 * 比如 泡田期3.30~4.25 * 返青期4·26~5·6 * 属于四月份的有泡田期和返青期,那么计算的时候就要把泡田期在四月份的灌溉用水量和返青期在四月份的灌溉用水量计算上 */ if (isMonthInKaPeriod(sortedMonth, kaStartTime, kaEndTime)) { int kaDaysInMonth = calculateKaDaysInMonth(kaStartTime, kaEndTime, sortedMonth); BigDecimal kaConsumption = kaQuota.divide(BigDecimal.valueOf(totalKaDays), 2, RoundingMode.HALF_UP) .multiply(BigDecimal.valueOf(kaDaysInMonth)); irrigationVolume = irrigationVolume.add(kaConsumption); } // 修正:计算生育期在当前月份的总耗水量(按Excel逻辑) BigDecimal growConsumption = calculateGrowConsumptionForMonth(sortedMonth, growPeriods); irrigationVolume = irrigationVolume.add(growConsumption); // 计算该月份所有生育阶段的总有效降雨量 BigDecimal monthlyRainfall = calculateTotalEffectiveRainfallForMonth(sortedMonth, growPeriods, list); irrigationVolume = irrigationVolume.subtract(monthlyRainfall); // 如果计算结果是负数,则设为0 // if (irrigationVolume.compareTo(BigDecimal.ZERO) < 0) { // irrigationVolume = BigDecimal.ZERO; // } // 保留2位小数 irrigationVolume = irrigationVolume.setScale(2,RoundingMode.UP); riceIrrigationUse.setIrrigationUse(irrigationVolume); res.add(riceIrrigationUse); } return res; } /** * 计算指定月份生育期的总耗水量(按Excel逻辑) */ private BigDecimal calculateGrowConsumptionForMonth(int month, List growPeriods) { BigDecimal totalConsumption = BigDecimal.ZERO; for (RiceWaterKi growPeriod : growPeriods) { LocalDateTime startTime = growPeriod.getStartTime(); LocalDateTime endTime = growPeriod.getEndTime(); // 检查该阶段是否包含这个月份 if (LocalDateTimeUtils.isMonthInPeriod(month, startTime, endTime)) { // 获取阶段在该月份的天数 int daysInMonth = LocalDateTimeUtils.calculateDaysInMonthForPeriod(startTime, endTime, month); if (daysInMonth > 0) { // 判断阶段是否跨月份 List monthsInStage = LocalDateTimeUtils.getMonthsInPeriod(startTime, endTime); if (monthsInStage.size() == 1) { // 不跨月份:直接使用完整耗水量 totalConsumption = totalConsumption.add(growPeriod.getWaterRqStage()); } else { // 跨月份:按天数比例分配耗水量 //当前月份对应阶段的耗水量/当前阶段的全天数 /** * 比如 * 泡田期 3.30~4.25 * 返青期 4·26~5·6 这里就跨月份了 * 同时month为4 表示4月份 * 那么计算公式为 返青期耗水量/返青期天数11天*返青期四月份天数(ps 泡田期在四月份的耗水量已经计算完了) */ BigDecimal dailyConsumption = growPeriod.getWaterRqStage() .divide(BigDecimal.valueOf(growPeriod.getDays()), 2, RoundingMode.HALF_UP); //再去乘当前阶段在当前月份的天数 BigDecimal monthlyConsumption = dailyConsumption.multiply(BigDecimal.valueOf(daysInMonth)); totalConsumption = totalConsumption.add(monthlyConsumption); } } } } return totalConsumption; } /** * 计算指定月份所有生育阶段的总有效降雨量 */ private BigDecimal calculateTotalEffectiveRainfallForMonth(int month, List growPeriods, List rainfallList) { BigDecimal totalRainfall = BigDecimal.ZERO; for (RiceWaterKi growPeriod : growPeriods) { LocalDateTime startTime = growPeriod.getStartTime(); LocalDateTime endTime = growPeriod.getEndTime(); // 检查该阶段是否包含这个月份 if (LocalDateTimeUtils.isMonthInPeriod(month, startTime, endTime)) { // 使用getMonthlyRainfall方法计算该阶段在该月份的有效降雨量 BigDecimal stageRainfall = getMonthlyRainfall(rainfallList, month, startTime, endTime); totalRainfall = totalRainfall.add(stageRainfall); } } return totalRainfall.setScale(1, RoundingMode.HALF_UP); } /** * 判断月份是否在泡田期内 */ private boolean isMonthInKaPeriod(int month, LocalDateTime kaStart, LocalDateTime kaEnd) { int startMonth = kaStart.getMonthValue(); int endMonth = kaEnd.getMonthValue(); return month >= startMonth && month <= endMonth; } /** * 计算泡田期在当前月份的天数 */ private int calculateKaDaysInMonth(LocalDateTime kaStart, LocalDateTime kaEnd, int targetMonth) { int startMonth = kaStart.getMonthValue(); int endMonth = kaEnd.getMonthValue(); // 如果整个泡田期都在目标月份内 if (startMonth == targetMonth && endMonth == targetMonth) { return (int) java.time.temporal.ChronoUnit.DAYS.between(kaStart.toLocalDate(), kaEnd.toLocalDate()) + 1; } // 如果泡田期开始时间在目标月份,结束时间在下个月 if (startMonth == targetMonth && endMonth > targetMonth) { LocalDate lastDayOfMonth = kaStart.toLocalDate().withDayOfMonth(kaStart.toLocalDate().lengthOfMonth()); return (int) java.time.temporal.ChronoUnit.DAYS.between(kaStart.toLocalDate(), lastDayOfMonth) + 1; } // 如果泡田期结束时间在目标月份,开始时间在上个月 if (endMonth == targetMonth && startMonth < targetMonth) { LocalDate firstDayOfMonth = kaEnd.toLocalDate().withDayOfMonth(1); return (int) java.time.temporal.ChronoUnit.DAYS.between(firstDayOfMonth, kaEnd.toLocalDate()) + 1; } return 0; } /** * 计算泡田期总天数 */ private int calculateTotalKaDays(LocalDateTime kaStart, LocalDateTime kaEnd) { return (int) java.time.temporal.ChronoUnit.DAYS.between(kaStart.toLocalDate(), kaEnd.toLocalDate()) + 1; } /** * 将ki的数据按照月份从小到大排序 */ private void orderByStartTimeAsc(List riceWaterKis) { Collections.sort(riceWaterKis, (ki1, ki2) -> { LocalDateTime time1 = ki1.getStartTime(); LocalDateTime time2 = ki2.getStartTime(); if (time1 == null) return -1; if (time2 == null) return 1; return time1.compareTo(time2); }); } public List irrigationComprehensiveCaculateMonth(RiceWaterCaculateDto dto) { RiceGrowConfig riceGrowConfig = dto.getRiceGrowConfig(); List riceIrrigationUses = irrigationCaculate(dto);//获取灌区水稻用水量 BigDecimal totalWaterUse = BigDecimal.ZERO; for (RiceIrrigationUse riceIrrigationUs : riceIrrigationUses) { totalWaterUse = totalWaterUse.add(riceIrrigationUs.getIrrigationUse()); } riceGrowConfig.setWaterUse(totalWaterUse); List res = new ArrayList<>(); //灌溉区面积(亩) BigDecimal sArea = riceGrowConfig.getArea(); for (RiceIrrigationUse riceIrrigationUse : riceIrrigationUses) { RiceWaterForecastMonth entity = new RiceWaterForecastMonth(); entity.setMonth(riceIrrigationUse.getMonth()); BigDecimal irrigationUse = riceIrrigationUse.getIrrigationUse(); // 计算公式:2/3 * irrigationUse * sArea / 10000 BigDecimal value = new BigDecimal("2") .divide(new BigDecimal("3"), 9, RoundingMode.HALF_UP) // 2/3,保留10位小数 .multiply(irrigationUse) .multiply(sArea) .divide(new BigDecimal("10000")); // 除以10000,保留2位小数 entity.setIrrigationUse(value); res.add(entity); } return res; } public List irrigationComprehensiveCaculateCycle(RiceWaterCaculateDto dto) { List riceWaterKis = dto.getRiceWaterKis(); orderByStartTimeAsc(riceWaterKis); RiceGrowConfig riceGrowConfig = dto.getRiceGrowConfig(); BigDecimal kaQuota = riceGrowConfig.getKaQuota();//泡田定额 Integer year = riceGrowConfig.getYear();//相似年 BigDecimal sArea = riceGrowConfig.getArea(); List tyYearRainfallVos = tyYearRainfallService.queryList(); List collect = tyYearRainfallVos.stream().filter(o -> { return o.getYear().equals(year); }).collect(Collectors.toList()); if(collect == null || collect.isEmpty()){ throw new IllegalArgumentException("对不起,没有该年份的降雨资料"); } TyYearRainfallVo tyYearRainfallVo = collect.get(0); List rainfallList = tyYearRainfallVo.getList();//获取月份的降雨资料 List res = new ArrayList<>(); for (int i = 0; i < riceWaterKis.size(); i++) { RiceWaterKi riceWaterKi = riceWaterKis.get(i); RiceWaterForecastCycle data = new RiceWaterForecastCycle(); data.setRiceGrowStage(riceWaterKi.getRiceGrowStage()); data.setOrder(i + 1); //泡田期为定值,泡田定额 if(riceWaterKi.getRiceGrowStage().contains("泡田")){ data.setIrrigationUse(kaQuota); data.setRiceGrowStage("泡田期"); res.add(data); } else { LocalDateTime startTime = riceWaterKi.getStartTime(); LocalDateTime endTime = riceWaterKi.getEndTime(); BigDecimal irrigationUse = calculateIrrigationUse(riceWaterKi, rainfallList, startTime, endTime); data.setIrrigationUse(irrigationUse.setScale(2,RoundingMode.HALF_UP)); res.add(data); } } for (RiceWaterForecastCycle re : res) { BigDecimal irrigationUse = re.getIrrigationUse(); BigDecimal value = new BigDecimal("2") .divide(new BigDecimal("3"), 9, RoundingMode.HALF_UP) // 2/3,保留10位小数 .multiply(irrigationUse) .multiply(sArea) .divide(new BigDecimal("10000")); // 除以10000,保留2位小数 re.setIrrigationUse(value); } return res; } /** * 计算非泡田期的灌溉用水量 */ private BigDecimal calculateIrrigationUse(RiceWaterKi riceWaterKi, List rainfallList, LocalDateTime startTime, LocalDateTime endTime) { // 阶段用水量(从waterRqStage获取) BigDecimal stageWaterUse = riceWaterKi.getWaterRqStage(); if (stageWaterUse == null) { stageWaterUse = BigDecimal.ZERO; } // 计算有效降雨量 BigDecimal effectiveRainfall = calculateEffectiveRainfall(rainfallList, startTime, endTime); // 灌溉用水量 = 阶段用水量 - 有效降雨量 BigDecimal irrigationUse = stageWaterUse.subtract(effectiveRainfall); // 确保不会出现负值 return irrigationUse.compareTo(BigDecimal.ZERO) > 0 ? irrigationUse : BigDecimal.ZERO; } /** * 计算阶段内的有效降雨量 */ private BigDecimal calculateEffectiveRainfall(List rainfallList, LocalDateTime stageStartTime, LocalDateTime stageEndTime) { BigDecimal totalEffectiveRainfall = BigDecimal.ZERO; // 获取阶段跨越的月份 Set months = LocalDateTimeUtils.getMonthsInPeriodSet(stageStartTime, stageEndTime); for (Integer month : months) { BigDecimal monthlyRainfall = getMonthlyRainfall(rainfallList, month, stageStartTime, stageEndTime); totalEffectiveRainfall = totalEffectiveRainfall.add(monthlyRainfall); } return totalEffectiveRainfall; } /** * 从降雨资料中获取指定月份的降雨量,并根据阶段实际使用天数进行调整 */ private BigDecimal getMonthlyRainfall(List rainfallList, int month, LocalDateTime stageStartTime, LocalDateTime stageEndTime) { if (rainfallList == null || stageStartTime == null || stageEndTime == null) { return BigDecimal.ZERO; } // 获取原始月降雨量 BigDecimal originalRainfall = rainfallList.stream() .filter(rainfall -> rainfall.getMonth() != null && rainfall.getMonth() == month) .findFirst() .map(TyYearRainfall::getDrp) .orElse(BigDecimal.ZERO); // 计算阶段在该月份的实际使用天数 int daysInMonth = LocalDateTimeUtils.calculateDaysInMonthForPeriod(stageStartTime, stageEndTime, month); int totalDaysInMonth = LocalDateTimeUtils.getTotalDaysInMonth(stageStartTime.getYear(), month); if (daysInMonth > 0 && totalDaysInMonth > 0) { // 按实际使用天数比例计算有效降雨量 return originalRainfall .multiply(BigDecimal.valueOf(daysInMonth)) .divide(BigDecimal.valueOf(totalDaysInMonth), 2, RoundingMode.HALF_UP); } return BigDecimal.ZERO; } public RiceRqWaterCaculateVo caculate(RiceWaterCaculateDto dto) { //先计算阶段耗水量 RiceGrowConfig riceGrowConfig = dto.getRiceGrowConfig(); RiceRqWaterCaculateVo vo = new RiceRqWaterCaculateVo(); List riceWaterKis = stageCaculate(dto); dto.setRiceWaterKis(riceWaterKis); //计算灌区水稻用水量-按月份 List riceWaterForecastMonths = irrigationComprehensiveCaculateMonth(dto); BigDecimal monthTotal = BigDecimal.ZERO; for (RiceWaterForecastMonth riceWaterForecastMonth : riceWaterForecastMonths) { monthTotal = monthTotal.add(riceWaterForecastMonth.getIrrigationUse()); // riceWaterForecastMonth.setIrrigationUse(riceWaterForecastMonth.getIrrigationUse().setScale(2,RoundingMode.HALF_UP)); } riceGrowConfig.setIrrigationUse(monthTotal); //计算灌区水稻用水量-按周期 List riceWaterForecastCycles = irrigationComprehensiveCaculateCycle(dto); BigDecimal cycleTotal = BigDecimal.ZERO; for (RiceWaterForecastCycle riceWaterForecastCycle : riceWaterForecastCycles) { cycleTotal = cycleTotal.add(riceWaterForecastCycle.getIrrigationUse()); // riceWaterForecastCycle.setIrrigationUse(riceWaterForecastCycle.getIrrigationUse().setScale(2,RoundingMode.HALF_UP)); } vo.setIrrigationMonthTotalUse(monthTotal.setScale(2,RoundingMode.HALF_UP)); vo.setIrrigationCycleTotalUse(cycleTotal.setScale(2,RoundingMode.HALF_UP)); vo.setRiceWaterKis(riceWaterKis); vo.setRiceWaterForecastMonths(riceWaterForecastMonths); vo.setRiceWaterForecastCycles(riceWaterForecastCycles); vo.setRiceGrowConfig(riceGrowConfig); return vo; } }