Przeglądaj źródła

增加佳友厚苑气象设备与农事相关查询

jiuling 1 miesiąc temu
rodzic
commit
b1ca7c1ab0

+ 9 - 0
ruoyi-modules/ruoyi-base/src/main/java/com/ruoyi/base/controller/WeatherRealtimeDataController.java

@@ -56,7 +56,16 @@ public class WeatherRealtimeDataController extends BaseController
         return success(list);
     }
 
+    /**
+     * 查询气象站实时数据列表
+     */
+    @PostMapping("/listWeatherStatisticsJyhy")
+    public AjaxResult listWeatherJYHY(@RequestBody WeatherDataStatistics weatherRealtimeData)
+    {
 
+        WeatherDataStatisticsVo list = weatherRealtimeDataService.listWeatherJYHY(weatherRealtimeData);
+        return success(list);
+    }
 
     /**
      * 导出气象站实时数据列表

+ 2 - 0
ruoyi-modules/ruoyi-base/src/main/java/com/ruoyi/base/domain/AgriculturalTasks.java

@@ -37,6 +37,8 @@ public class AgriculturalTasks extends BaseEntity
     @Excel(name = "任务类型", readConverterExp = "0=施肥,1=灌溉,2=打药,3=采摘,4=巡检,5=除草,6=其他")
     private String typeName;
 
+    /*任务类型ID查询条件*/
+    private List<String> typeNameList;
     /** 作物名称 */
     @Excel(name = "作物名称")
     private String growCrops;

+ 8 - 0
ruoyi-modules/ruoyi-base/src/main/java/com/ruoyi/base/domain/Batch.java

@@ -92,6 +92,14 @@ public class Batch extends BaseEntity
     @Excel(name = "开始种植时间", width = 30, dateFormat = "yyyy-MM-dd")
     private Date startPlantingTime;
 
+    /*生长期养护时间*/
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    private Date growingPeriodTime;
+
+    /*巡检日期*/
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    private Date inspectionTime;
+
    private String produceDateStart;
    private String produceDateEnd;
    private String packageDateStart;

+ 5 - 0
ruoyi-modules/ruoyi-base/src/main/java/com/ruoyi/base/domain/WeatherDataStatistics.java

@@ -6,6 +6,7 @@ import com.ruoyi.common.core.web.domain.BaseEntity;
 import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
+import org.springframework.format.annotation.DateTimeFormat;
 
 import java.math.BigDecimal;
 import java.time.LocalDate;
@@ -89,7 +90,11 @@ public class WeatherDataStatistics extends BaseEntity {
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     @Excel(name = "采集时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
     private Date collectTime;
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
     private LocalDateTime beginCollectTime;
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
     private LocalDateTime endCollectTime;
     private Integer NumberDay;
 }

+ 2 - 0
ruoyi-modules/ruoyi-base/src/main/java/com/ruoyi/base/mapper/AgriculturalTasksMapper.java

@@ -79,4 +79,6 @@ public interface AgriculturalTasksMapper
     public int deleteAgriculturalTasksByIds(Long[] ids);
 
     int countStatusTypeTasks(AgriculturalTasks agriculturalTasks);
+
+    AgriculturalTasks selectAgriculturalTasks(AgriculturalTasks agriculturalTasks);
 }

+ 8 - 0
ruoyi-modules/ruoyi-base/src/main/java/com/ruoyi/base/service/IAgriculturalTasksService.java

@@ -21,6 +21,14 @@ public interface IAgriculturalTasksService
      */
     public AgriculturalTasks selectAgriculturalTasksById(Long id);
 
+    /**
+     * 根据条件查询农事任务
+     *
+     * @param agriculturalTasks 农事任务
+     * @return 农事任务
+     */
+    public AgriculturalTasks selectAgriculturalTasks(AgriculturalTasks agriculturalTasks);
+
     /**
      * 查询农事任务列表
      *

+ 7 - 0
ruoyi-modules/ruoyi-base/src/main/java/com/ruoyi/base/service/IWeatherRealtimeDataService.java

@@ -84,4 +84,11 @@ public interface IWeatherRealtimeDataService {
      */
 
     WeatherDataStatisticsVo selectWeatherStatisticsList(WeatherDataStatistics weatherRealtimeData);
+
+    /**
+     * 根据设备ID查询气象设备统计数据列表(佳友厚苑)
+     * @param weatherRealtimeData
+     * @return
+     */
+    WeatherDataStatisticsVo listWeatherJYHY(WeatherDataStatistics weatherRealtimeData);
 }

+ 5 - 0
ruoyi-modules/ruoyi-base/src/main/java/com/ruoyi/base/service/impl/AgriculturalTasksServiceImpl.java

@@ -51,6 +51,11 @@ public class AgriculturalTasksServiceImpl implements IAgriculturalTasksService
         return agriculturalTasksMapper.selectAgriculturalTasksById(id);
     }
 
+    @Override
+    public AgriculturalTasks selectAgriculturalTasks(AgriculturalTasks agriculturalTasks) {
+        return agriculturalTasksMapper.selectAgriculturalTasks(agriculturalTasks);
+    }
+
     /**
      * 查询农事任务列表
      *

+ 44 - 7
ruoyi-modules/ruoyi-base/src/main/java/com/ruoyi/base/service/impl/BatchServiceImpl.java

@@ -1,9 +1,13 @@
 package com.ruoyi.base.service.impl;
 
 import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.Collections;
 import java.util.Date;
 import java.util.List;
 
+import com.ruoyi.base.domain.AgriculturalTasks;
+import com.ruoyi.base.service.IAgriculturalTasksService;
 import com.ruoyi.common.core.exception.ServiceException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -24,16 +28,36 @@ public class BatchServiceImpl implements IBatchService
     @Autowired
     private BatchMapper batchMapper;
 
-    /**
-     * 查询批次管理
-     *
-     * @param id 批次管理主键
-     * @return 批次管理
-     */
+    @Autowired
+    IAgriculturalTasksService agriculturalTasksService;
+
     @Override
     public Batch selectBatchById(Long id)
     {
-        return batchMapper.selectBatchById(id);
+        Batch batch = batchMapper.selectBatchById(id);
+        if (batch == null) {
+            return null;
+        }
+
+        // 生长期养护类型(施肥:0;灌溉:1;打药:2;除草:5)
+        List<String> growingTypes = Arrays.asList("0", "1", "2", "5");
+
+        // 巡检类型
+        List<String> inspectionTypes = Collections.singletonList("4");
+
+
+        AgriculturalTasks growingTask = getNearestTask(batch, growingTypes);
+        AgriculturalTasks inspectionTask = getNearestTask(batch, inspectionTypes);
+
+
+        if (inspectionTask != null) {
+            batch.setInspectionTime(inspectionTask.getCompletionTime());
+        }
+        if (growingTask != null) {
+            batch.setGrowingPeriodTime(growingTask.getCompletionTime());
+        }
+
+        return batch;
     }
 
     /**
@@ -144,4 +168,17 @@ public class BatchServiceImpl implements IBatchService
     {
         return batchMapper.deleteBatchById(id);
     }
+
+    private AgriculturalTasks getNearestTask(Batch batch, List<String> typeNames) {
+        AgriculturalTasks query = new AgriculturalTasks();
+        query.setCompletionTime(batch.getStartPlantingTime());
+        query.setTypeNameList(typeNames);
+        if (batch.getFarmId() != null) {
+            query.setFarmId(batch.getFarmId());
+        }
+        if (batch.getFieldId() != null) {
+            query.setPlotId(batch.getFieldId());
+        }
+        return agriculturalTasksService.selectAgriculturalTasks(query);
+    }
 }

+ 194 - 0
ruoyi-modules/ruoyi-base/src/main/java/com/ruoyi/base/service/impl/WeatherRealtimeDataServiceImpl.java

@@ -1,11 +1,14 @@
 package com.ruoyi.base.service.impl;
 
+import com.ruoyi.base.domain.Device;
 import com.ruoyi.base.domain.WeatherDataStatistics;
 import com.ruoyi.base.domain.WeatherRealtimeData;
+import com.ruoyi.base.mapper.DeviceMapper;
 import com.ruoyi.base.mapper.WeatherRealtimeDataMapper;
 import com.ruoyi.base.service.IWeatherRealtimeDataService;
 import com.ruoyi.base.vo.WeatherDataStatisticsVo;
 import com.ruoyi.common.core.utils.DateUtils;
+import com.ruoyi.common.core.utils.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.util.ObjectUtils;
@@ -29,6 +32,9 @@ public class WeatherRealtimeDataServiceImpl implements IWeatherRealtimeDataServi
     @Autowired
     private WeatherRealtimeDataMapper weatherRealtimeDataMapper;
 
+    @Autowired
+    private DeviceMapper deviceMapper;
+
     /**
      * 查询气象站实时数据
      *
@@ -279,6 +285,194 @@ public class WeatherRealtimeDataServiceImpl implements IWeatherRealtimeDataServi
         return weatherDataStatisticsVo;
     }
 
+    @Override
+    public WeatherDataStatisticsVo listWeatherJYHY(WeatherDataStatistics weatherRealtimeData) {
+        WeatherDataStatisticsVo vo = new WeatherDataStatisticsVo();
+        if (weatherRealtimeData == null
+                || weatherRealtimeData.getBeginCollectTime() == null
+                || weatherRealtimeData.getEndCollectTime() == null
+                || weatherRealtimeData.getParams() == null) {
+            return vo;
+        }
+
+        Object plotIdObj = weatherRealtimeData.getParams().get("plotId");
+        if (StringUtils.isNull(plotIdObj) ) {
+            return vo;
+        }
+        Long plotId = Long.valueOf(plotIdObj.toString());
+
+        List<BigDecimal> maxTemp = new ArrayList<>();
+        List<BigDecimal> minTemp = new ArrayList<>();
+        List<Double> humidity = new ArrayList<>();
+        List<Double> rainfall = new ArrayList<>();
+        List<Double> wind = new ArrayList<>();
+        List<Double> soilN = new ArrayList<>();
+        List<Double> soilP = new ArrayList<>();
+        List<Double> soilK = new ArrayList<>();
+
+        // 时间处理
+        LocalDateTime startOfPreviousDay = LocalDateTime.of(
+                weatherRealtimeData.getBeginCollectTime().toLocalDate(),
+                LocalTime.MIDNIGHT
+        );
+        LocalDateTime endOfPreviousDay = LocalDateTime.of(
+                weatherRealtimeData.getEndCollectTime().toLocalDate(),
+                LocalTime.MAX);
+
+        weatherRealtimeData.setBeginCollectTime(startOfPreviousDay);
+        weatherRealtimeData.setEndCollectTime(endOfPreviousDay);
+
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("M-d");
+        List<String> dateList = new ArrayList<>();
+        for (LocalDateTime date = startOfPreviousDay; !date.isAfter(endOfPreviousDay); date = date.plusDays(1)) {
+            dateList.add(date.format(formatter));
+        }
+        vo.setWeatherDate(dateList);
+
+
+        // 根据地块ID查出当前地块下的气象设备
+        List<Device> devices = deviceMapper.selectDeviceByField(plotId);
+
+        Optional<Device> weatherDeviceOpt = devices.stream()
+                .filter(d -> "4".equals(d.getDeviceTypeId()))
+                .findFirst();
+
+        if (!weatherDeviceOpt.isPresent()) {
+            return buildEmptyVo(vo, dateList.size());
+        }
+
+        weatherRealtimeData.setDeviceId(weatherDeviceOpt.get().getDeviceId());
+
+        // 查询具体数据
+        List<WeatherDataStatistics> list =
+                weatherRealtimeDataMapper.selectWeatherStatisticsList(weatherRealtimeData);
+        Map<String, WeatherDataStatistics> map = list.stream()
+                .collect(Collectors.toMap(
+                        s -> s.getDate().format(formatter),
+                        s -> s,
+                        (a, b) -> a
+                ));
+
+
+        // 填充数据
+        for (String date : dateList) {
+            WeatherDataStatistics data = map.get(date);
+
+            if (data == null) {
+                fillNull(maxTemp, minTemp, humidity, rainfall, wind, soilN, soilP, soilK);
+            } else {
+                maxTemp.add(data.getMaxTemperature());
+                minTemp.add(data.getMinTemperature());
+                humidity.add(data.getAvgHumidity());
+                rainfall.add(data.getAvgRainfall());
+                wind.add(data.getAvgWindSpeed());
+                soilN.add(data.getAvgSoilN());
+                soilP.add(data.getAvgSoilP());
+                soilK.add(data.getAvgSoilK());
+            }
+        }
+
+        BigDecimal avgHumidityAverage = list.stream()
+                .map(WeatherDataStatistics::getAvgHumidity)
+                .filter(d -> !Double.isNaN(d)) // 过滤掉无效值
+                .reduce(Double::sum)
+                .flatMap(sum -> !list.isEmpty() ?
+                        Optional.of(BigDecimal.valueOf(sum / list.size())) : Optional.empty())
+                .map(avg -> avg.setScale(2, BigDecimal.ROUND_HALF_UP))
+                .orElse(BigDecimal.ZERO);
+
+        BigDecimal avgTemperatureAverage = list.stream()
+                .map(WeatherDataStatistics::getAvgTemperature)  // 假设WeatherDataStatistics类中有getAvgTemperature方法
+                .filter(Objects::nonNull)  // 过滤掉空值
+                .filter(temp -> temp.compareTo(BigDecimal.ZERO) >= 0)  // 过滤掉无效值
+                .reduce(BigDecimal::add)
+                .flatMap(sum -> !list.isEmpty() ?
+                        Optional.of(sum.divide(BigDecimal.valueOf(list.size()), 2, BigDecimal.ROUND_HALF_UP)) : Optional.empty())
+                .orElse(BigDecimal.ZERO);
+
+        BigDecimal avgSoilNAverage = list.stream()
+                .map(WeatherDataStatistics::getAvgSoilN)
+                .filter(Objects::nonNull)
+                .filter(d -> !d.isNaN()) // 如果是Double类型
+                .map(BigDecimal::valueOf) // 转换为BigDecimal
+                .reduce(BigDecimal.ZERO, BigDecimal::add)
+                .divide(BigDecimal.valueOf(Math.max(1, list.size())), 2, BigDecimal.ROUND_HALF_UP);
+        BigDecimal avgSoilPAverage = list.stream()
+                .map(WeatherDataStatistics::getAvgSoilP)
+                .filter(Objects::nonNull)
+                .filter(d -> !d.isNaN()) // 如果是Double类型
+                .map(BigDecimal::valueOf) // 转换为BigDecimal
+                .reduce(BigDecimal.ZERO, BigDecimal::add)
+                .divide(BigDecimal.valueOf(Math.max(1, list.size())), 2, BigDecimal.ROUND_HALF_UP);
+        BigDecimal avgSoilKAverage = list.stream()
+                .map(WeatherDataStatistics::getAvgSoilK)
+                .filter(Objects::nonNull)
+                .filter(d -> !d.isNaN()) // 如果是Double类型
+                .map(BigDecimal::valueOf) // 转换为BigDecimal
+                .reduce(BigDecimal.ZERO, BigDecimal::add)
+                .divide(BigDecimal.valueOf(Math.max(1, list.size())), 2, BigDecimal.ROUND_HALF_UP);
+
+
+
+        BigDecimal avgWindSpeedAverage = list.stream()
+                .map(WeatherDataStatistics::getAvgWindSpeed)
+                .filter(d -> !Double.isNaN(d))
+                .reduce(Double::sum)
+                .flatMap(sum -> !list.isEmpty() ?
+                        Optional.of(BigDecimal.valueOf(sum / list.size())) : Optional.empty())
+                .map(avg -> avg.setScale(2, BigDecimal.ROUND_HALF_UP))
+                .orElse(BigDecimal.ZERO);
+
+        BigDecimal totalRainfallAccumulated = list.stream()
+                .map(WeatherDataStatistics::getDateRainfallA)
+                .filter(rainfalls -> rainfalls != null && rainfalls.compareTo(BigDecimal.ZERO) >= 0)
+                .reduce(BigDecimal.ZERO, BigDecimal::add);
+
+        WeatherRealtimeData weatherRealtimeDataVo = new WeatherRealtimeData();
+        weatherRealtimeDataVo.setHumidity(avgHumidityAverage);
+        weatherRealtimeDataVo.setTemperature(avgTemperatureAverage);
+        weatherRealtimeDataVo.setWindSpeed(avgWindSpeedAverage);
+        weatherRealtimeDataVo.setRainfallA(totalRainfallAccumulated);
+        weatherRealtimeDataVo.setSoilN(avgSoilNAverage);
+        weatherRealtimeDataVo.setSoilP(avgSoilPAverage);
+        weatherRealtimeDataVo.setSoilK(avgSoilKAverage);
+        vo.setWeatherRealtimeData(weatherRealtimeDataVo);
+
+
+        vo.setWeatherMaxTemperature(maxTemp);
+        vo.setWeatherMinTemperature(minTemp);
+        vo.setWeatherHumidity(humidity);
+        vo.setWeatherRainfall(rainfall);
+        vo.setWeatherWindSpeed(wind);
+        vo.setWeatherAvgSoilN(soilN);
+        vo.setWeatherAvgSoilP(soilP);
+        vo.setWeatherAvgSoilK(soilK);
+
+        return vo;
+    }
+
+    private void fillNull(List<?>... lists) {
+        for (List list : lists) {
+            list.add(null);
+        }
+    }
+
+    private WeatherDataStatisticsVo buildEmptyVo(WeatherDataStatisticsVo vo, int size) {
+        for (int i = 0; i < size; i++) {
+            fillNull(
+                    vo.getWeatherMaxTemperature(),
+                    vo.getWeatherMinTemperature(),
+                    vo.getWeatherHumidity(),
+                    vo.getWeatherRainfall(),
+                    vo.getWeatherWindSpeed(),
+                    vo.getWeatherAvgSoilN(),
+                    vo.getWeatherAvgSoilP(),
+                    vo.getWeatherAvgSoilK()
+            );
+        }
+        return vo;
+    }
+
     private WeatherDataStatisticsVo twentyFourHours(String deviceId) {
 
         WeatherDataStatisticsVo weatherDataStatisticsVo = new WeatherDataStatisticsVo();

+ 19 - 0
ruoyi-modules/ruoyi-base/src/main/resources/mapper/base/AgriculturalTasksMapper.xml

@@ -44,6 +44,25 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     <sql id="selectAgriculturalTasksVo">
         select id, plot_id, farm_id, field_name, grow_crops, task_name, task_images, type_name, task_status, execute_time, assignee_id, assignee_name, remark, completion_time, completion_desc, create_by, create_time, update_time, update_by from agricultural_tasks
     </sql>
+    <select id="selectAgriculturalTasks" parameterType="AgriculturalTasks" resultMap="AgriculturalTasksResult">
+        SELECT at1.*, sd.dept_name
+        FROM agricultural_tasks at1
+        LEFT JOIN sys_dept sd ON at1.farm_id = sd.dept_id
+        <where>
+            <if test="typeNameList != null and typeNameList.size() > 0">
+                AND at1.type_name IN
+                <foreach collection="typeNameList" item="item" open="(" separator="," close=")">
+                    #{item}
+                </foreach>
+            </if>
+            <if test="plotId != null ">and at1.plot_id = #{plotId}</if>
+            <if test="farmId != null ">and at1.farm_id = #{farmId}</if>
+            AND at1.completion_time > #{completionTime}
+        </where>
+
+        ORDER BY at1.completion_time ASC
+        LIMIT 1
+    </select>
 
     <select id="selectAgriculturalTasksList" parameterType="AgriculturalTasks" resultMap="AgriculturalTasksResult">
         select at1.*,sd.dept_name,su.nick_name,

+ 1 - 1
ruoyi-modules/ruoyi-base/src/main/resources/mapper/base/WeatherRealtimeDataMapper.xml

@@ -91,7 +91,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 
     </select>
     <select id="selectWeatherStatisticsList" resultType="com.ruoyi.base.domain.WeatherDataStatistics"  resultMap="WeatherDataStatisticsResult">
-        select  date, max_temperature, min_temperature,avg_temperature, avg_humidity, avg_rainfall, avg_wind_speed,avg_soil_n, avg_soil_p, avg_soil_k
+        select  date, max_temperature, min_temperature,avg_temperature, avg_humidity, avg_rainfall, avg_wind_speed,avg_soil_n, avg_soil_p, avg_soil_k,avg_soil_temperature,avg_soil_humidity,date_rainfall_a
         from weather_data_statistics
         <where>
             <if test="beginCollectTime != null  and endCollectTime != null ">