Kaynağa Gözat

提交代码

KR0282 1 yıl önce
ebeveyn
işleme
812453318f
44 değiştirilmiş dosya ile 1541 ekleme ve 425 silme
  1. 14 0
      pom.xml
  2. 18 0
      src/main/java/com/keystar/plane/inspection/constant/MissionConstant.java
  3. 1 1
      src/main/java/com/keystar/plane/inspection/controller/NestController.java
  4. 18 10
      src/main/java/com/keystar/plane/inspection/controller/PhotoController.java
  5. 108 19
      src/main/java/com/keystar/plane/inspection/controller/ReportController.java
  6. 5 0
      src/main/java/com/keystar/plane/inspection/entity/PhotoResultEntity.java
  7. 6 0
      src/main/java/com/keystar/plane/inspection/entity/PlanePhotoEntity.java
  8. 36 0
      src/main/java/com/keystar/plane/inspection/entity/PlaneTaskEntity.java
  9. 12 0
      src/main/java/com/keystar/plane/inspection/mapper/PlanePhotoMapper.java
  10. 18 0
      src/main/java/com/keystar/plane/inspection/mapper/PlaneTaskMapper.java
  11. 7 6
      src/main/java/com/keystar/plane/inspection/mqtt/PlaneMqttHandler.java
  12. 27 1
      src/main/java/com/keystar/plane/inspection/mqtt/RecognizeMqttHandler.java
  13. 2 1
      src/main/java/com/keystar/plane/inspection/service/IReportService.java
  14. 8 1
      src/main/java/com/keystar/plane/inspection/service/MqttService.java
  15. 1 1
      src/main/java/com/keystar/plane/inspection/service/NestService.java
  16. 2 1
      src/main/java/com/keystar/plane/inspection/service/PhotoResultService.java
  17. 13 5
      src/main/java/com/keystar/plane/inspection/service/PhotoService.java
  18. 9 0
      src/main/java/com/keystar/plane/inspection/service/PlanePhotoService.java
  19. 19 0
      src/main/java/com/keystar/plane/inspection/service/PlaneTaskService.java
  20. 86 0
      src/main/java/com/keystar/plane/inspection/service/impl/MinioService.java
  21. 174 17
      src/main/java/com/keystar/plane/inspection/service/impl/MqttServiceImpl.java
  22. 46 34
      src/main/java/com/keystar/plane/inspection/service/impl/NestServiceImpl.java
  23. 43 16
      src/main/java/com/keystar/plane/inspection/service/impl/PhotoResultServiceImpl.java
  24. 107 22
      src/main/java/com/keystar/plane/inspection/service/impl/PhotoServiceImpl.java
  25. 20 0
      src/main/java/com/keystar/plane/inspection/service/impl/PlanePhotoServiceImpl.java
  26. 56 0
      src/main/java/com/keystar/plane/inspection/service/impl/PlaneTaskServiceImpl.java
  27. 119 48
      src/main/java/com/keystar/plane/inspection/service/impl/ReportServiceImpl.java
  28. 50 0
      src/main/java/com/keystar/plane/inspection/utils/FileUtil.java
  29. 68 68
      src/main/java/com/keystar/plane/inspection/utils/FileUtils.java
  30. 79 3
      src/main/java/com/keystar/plane/inspection/utils/GisCheckUtils.java
  31. 72 2
      src/main/java/com/keystar/plane/inspection/utils/PhotoUtils.java
  32. 1 3
      src/main/java/com/keystar/plane/inspection/vo/DegreesVo.java
  33. 1 1
      src/main/java/com/keystar/plane/inspection/vo/LoginVo.java
  34. 1 1
      src/main/java/com/keystar/plane/inspection/vo/NestStatusVo.java
  35. 1 1
      src/main/java/com/keystar/plane/inspection/vo/PhotoMessageVo.java
  36. 1 1
      src/main/java/com/keystar/plane/inspection/vo/PhotoResultVo.java
  37. 6 2
      src/main/java/com/keystar/plane/inspection/vo/PlanePhotoVo.java
  38. 10 0
      src/main/java/com/keystar/plane/inspection/vo/PlaneTaskVo.java
  39. 31 0
      src/main/java/com/keystar/plane/inspection/vo/UploadVo.java
  40. 0 87
      src/main/java/com/keystar/plane/inspection/websocket/BaseWebsocketClient.java
  41. 0 44
      src/main/java/com/keystar/plane/inspection/websocket/DeviceWebsocketClient.java
  42. 31 3
      src/main/resources/mapper/PlanePhotoMapper.xml
  43. 24 0
      src/main/resources/mapper/PlaneTaskMapper.xml
  44. 190 26
      src/test/java/com/keystar/plane/inspection/PlaneInspectionApplicationTests.java

+ 14 - 0
pom.xml

@@ -198,6 +198,20 @@
 			<artifactId>aspectjweaver</artifactId>
 			<version>${aspectj.version}</version>
 		</dependency>
+
+		<!-- 图片压缩处理 -->
+		<dependency>
+			<groupId>net.coobird</groupId>
+			<artifactId>thumbnailator</artifactId>
+			<version>0.4.8</version>
+		</dependency>
+
+		<!-- 上传文件 -->
+		<dependency>
+			<groupId>commons-fileupload</groupId>
+			<artifactId>commons-fileupload</artifactId>
+			<version>1.3.3</version>
+		</dependency>
 	</dependencies>
 
 	<dependencyManagement>

+ 18 - 0
src/main/java/com/keystar/plane/inspection/constant/MissionConstant.java

@@ -9,4 +9,22 @@ import java.util.Map;
 public class MissionConstant {
 
     public static final int[] MISSION_ID = new int[] {2420, 2424, 2425};
+
+//    // 航线2420巡检的方阵
+//    public static final String[] MISSION_2420 = new String[] {"FZ13", "FZ14", "FZ15", "FZ16"};
+//
+//    // 航线2424巡检的方阵
+//    public static final String[] MISSION_2424 = new String[] {"FZ01", "FZ02", "FZ03", "FZ09", "FZ10"};
+//
+//    // 航线2425巡检方阵
+//    public static final String[] MISSION_2425 = new String[] {"FZ04", "FZ05", "FZ06", "FZ07", "FZ08", "FZ11", "FZ12"};
+
+    // 航线2382巡检方阵
+    public static final String[] MISSION_2382 = new String[] {"FZ04", "FZ05", "FZ06", "FZ07", "FZ08", "FZ11", "FZ12"};
+
+    // 航线2374巡检方阵
+    public static final String[] MISSION_2374 = new String[] {"FZ13", "FZ14", "FZ15", "FZ16"};
+
+    // 航线2387巡检方阵
+    public static final String[] MISSION_2387 = new String[] {"FZ01", "FZ02", "FZ03", "FZ09", "FZ10"};
 }

+ 1 - 1
src/main/java/com/keystar/plane/inspection/controller/NestController.java

@@ -2,7 +2,7 @@ package com.keystar.plane.inspection.controller;
 
 import com.keystar.plane.inspection.bo.DateBo;
 import com.keystar.plane.inspection.bo.PlaneInspectionBo;
-import com.keystar.plane.inspection.dao.NestStatusVo;
+import com.keystar.plane.inspection.vo.NestStatusVo;
 import com.keystar.plane.inspection.mqtt.PlaneMqttHandler;
 import com.keystar.plane.inspection.service.LoginService;
 import com.keystar.plane.inspection.service.NestService;

+ 18 - 10
src/main/java/com/keystar/plane/inspection/controller/PhotoController.java

@@ -1,15 +1,9 @@
 package com.keystar.plane.inspection.controller;
 
-import cn.hutool.core.util.IdUtil;
 import com.drew.imaging.jpeg.JpegProcessingException;
-import com.keystar.mqtt.bo.MqttMessageBo;
 import com.keystar.plane.inspection.bo.NewFileBo;
-import com.keystar.plane.inspection.bo.PhotoBo;
-import com.keystar.plane.inspection.bo.PhotoMqttMessageBo;
 import com.keystar.plane.inspection.bo.PvNameBo;
-import com.keystar.plane.inspection.dao.PhotoResultVo;
-import com.keystar.plane.inspection.dao.PlanePhotoVo;
-import com.keystar.plane.inspection.entity.PlanePhotoEntity;
+import com.keystar.plane.inspection.vo.PhotoResultVo;
 import com.keystar.plane.inspection.service.MqttService;
 import com.keystar.plane.inspection.service.PhotoService;
 import com.keystar.plane.inspection.service.PlanePhotoService;
@@ -22,9 +16,9 @@ import org.springframework.web.bind.annotation.*;
 import java.io.File;
 import java.io.IOException;
 import java.text.ParseException;
-import java.text.SimpleDateFormat;
 import java.util.ArrayList;
-import java.util.Date;
+import java.util.Arrays;
+import java.util.Comparator;
 import java.util.List;
 
 @Slf4j
@@ -56,7 +50,7 @@ public class PhotoController {
      *  发送最新任务图片Mqtt给图像识别
      **/
     @GetMapping("/sendMqtt")
-    public void sendMqtt() throws IOException, JpegProcessingException, ParseException, InterruptedException {
+    public void sendMqtt() throws IOException, JpegProcessingException, ParseException {
         mqttService.sendPhotoMqtt();
     }
 
@@ -80,4 +74,18 @@ public class PhotoController {
         log.info(htsptLose.toString());
     }
 
+    /**
+     *  发送指定目录下的无人机图片给图像识别 + 图片入库
+     **/
+    @PostMapping("/sendPhoto")
+    public List<String> sendPhoto(@RequestBody NewFileBo newFileBo) throws JpegProcessingException, IOException, ParseException {
+        File[] files = mqttService.sendPhotoMatt(newFileBo);
+        List<String> fileName = new ArrayList<>();
+        for (File file : files){
+            if (file.isFile()) {
+                fileName.add(file.getName());
+            }
+        }
+        return fileName;
+    }
 }

+ 108 - 19
src/main/java/com/keystar/plane/inspection/controller/ReportController.java

@@ -6,16 +6,25 @@ package com.keystar.plane.inspection.controller;
  * @Describe 报告接口调用测试类
  */
 
+import cn.hutool.core.text.CharSequenceUtil;
+import cn.hutool.core.util.StrUtil;
 import com.keystar.plane.inspection.bo.PlaneInspectionPicBo;
 import com.keystar.plane.inspection.bo.PlaneInspectionResultBo;
 import com.keystar.plane.inspection.bo.PlaneInspectionResultDetailBo;
+import com.keystar.plane.inspection.constant.LocationConstant;
+import com.keystar.plane.inspection.constant.MissionConstant;
+import com.keystar.plane.inspection.entity.PhotoResultEntity;
 import com.keystar.plane.inspection.entity.PlanePhotoEntity;
 import com.keystar.plane.inspection.mapper.PhotoResultMapper;
+import com.keystar.plane.inspection.mapper.PlanePhotoMapper;
 import com.keystar.plane.inspection.service.IReportService;
 import com.keystar.plane.inspection.service.PhotoResultService;
 import com.keystar.plane.inspection.service.PlanePhotoService;
 import com.keystar.plane.inspection.service.TangyangDataService;
+import com.keystar.plane.inspection.service.impl.MinioService;
 import com.keystar.plane.inspection.service.impl.ReportServiceImpl;
+import com.keystar.plane.inspection.utils.FileUtil;
+import com.keystar.plane.inspection.utils.RedisUtils;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.aop.framework.AopContext;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -24,6 +33,12 @@ import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
 import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
 import java.text.ParseException;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -39,18 +54,18 @@ public class ReportController {
     private IReportService reportService;
 
     @Autowired
-    private PlanePhotoService planePhotoService;
-
-    @Resource
-    private PhotoResultMapper photoResultMapper;
+    private PhotoResultService photoResultService;
 
     @Autowired
-    private TangyangDataService tangyangDataService;
+    private MinioService minioService;
 
-    @Autowired
-    private PhotoResultService photoResultService;
+    @Resource
+    private PlanePhotoMapper planePhotoMapper;
+
+    @Resource
+    private PhotoResultMapper photoResultMapper;
 
-    /*@GetMapping("/test")
+    @GetMapping("/test")
     public void test() {
 
         Map<String, String> mFlyCountMap = new HashMap<>();
@@ -175,12 +190,16 @@ public class ReportController {
 
         planeInspectionResultBo.setPics(new ArrayList<>());
         PlaneInspectionPicBo planeInspectionPicBo1 = new PlaneInspectionPicBo();
-        planeInspectionPicBo1.setVisible(reportService.pic2Base64FromMinio("/nest/photo/2420/1872/方阵13-16巡检任务0224-2023-02-26-15-18-29-DJI_20230226144300_0006_THRM.jpg"));
-        planeInspectionPicBo1.setInfrared(reportService.pic2Base64FromMinio("/nest/photo/2420/1872/方阵13-16巡检任务0224-2023-02-26-15-18-38-DJI_20230226144304_0007_ZOOM.jpg"));
+        planeInspectionPicBo1.setInfraredId("1");
+        planeInspectionPicBo1.setVisibleId("2");
+        planeInspectionPicBo1.setVisible(photoResultService.pic2Base64FromMinio("/nest/photo/2420/1872/方阵13-16巡检任务0224-2023-02-26-15-18-29-DJI_20230226144300_0006_THRM.jpg"));
+        planeInspectionPicBo1.setInfrared(photoResultService.pic2Base64FromMinio("/nest/photo/2420/1872/方阵13-16巡检任务0224-2023-02-26-15-18-38-DJI_20230226144304_0007_ZOOM.jpg"));
         planeInspectionResultBo.getPics().add(planeInspectionPicBo1);
         PlaneInspectionPicBo planeInspectionPicBo2 = new PlaneInspectionPicBo();
-        planeInspectionPicBo2.setVisible(reportService.pic2Base64FromMinio("/nest/photo/2420/1872/方阵13-16巡检任务0224-2023-02-26-15-18-34-DJI_20230226144302_0006_ZOOM.jpg"));
-        planeInspectionPicBo2.setInfrared(reportService.pic2Base64FromMinio("/nest/photo/2420/1872/方阵13-16巡检任务0224-2023-02-26-15-18-48-DJI_20230226144308_0010_THRM.jpg"));
+        planeInspectionPicBo2.setInfraredId("3");
+        planeInspectionPicBo2.setVisibleId("4");
+        planeInspectionPicBo2.setVisible("");
+        planeInspectionPicBo2.setInfrared("");
         planeInspectionResultBo.getPics().add(planeInspectionPicBo2);
 
         planeInspectionResultBoList.add(planeInspectionResultBo);
@@ -206,23 +225,93 @@ public class ReportController {
 
         planeInspectionResultBoNext.setPics(new ArrayList<>());
         PlaneInspectionPicBo planeInspectionPicBo3 = new PlaneInspectionPicBo();
-        planeInspectionPicBo3.setInfrared(reportService.pic2Base64FromMinio("/nest/photo/2420/1872/方阵13-16巡检任务0224-2023-02-26-15-18-39-DJI_20230226144304_0008_THRM.jpg"));
-        planeInspectionPicBo3.setVisible(reportService.pic2Base64FromMinio("/nest/photo/2420/1872/方阵13-16巡检任务0224-2023-02-26-15-18-52-DJI_20230226144310_0010_ZOOM.jpg"));
+        planeInspectionPicBo3.setInfraredId("5");
+        planeInspectionPicBo3.setVisibleId("6");
+        planeInspectionPicBo3.setInfrared(photoResultService.pic2Base64FromMinio("/nest/photo/2420/1872/方阵13-16巡检任务0224-2023-02-26-15-18-39-DJI_20230226144304_0008_THRM.jpg"));
+        planeInspectionPicBo3.setVisible(photoResultService.pic2Base64FromMinio("/nest/photo/2420/1872/方阵13-16巡检任务0224-2023-02-26-15-18-52-DJI_20230226144310_0010_ZOOM.jpg"));
         planeInspectionResultBoNext.getPics().add(planeInspectionPicBo3);
         PlaneInspectionPicBo planeInspectionPicBo4 = new PlaneInspectionPicBo();
-        planeInspectionPicBo4.setInfrared(reportService.pic2Base64FromMinio("/nest/photo/2420/1872/方阵13-16巡检任务0224-2023-02-26-15-18-35-DJI_20230226144302_0007_THRM.jpg"));
-        planeInspectionPicBo4.setVisible(reportService.pic2Base64FromMinio("/nest/photo/2420/1872/方阵13-16巡检任务0224-2023-02-26-15-18-42-DJI_20230226144306_0008_ZOOM.jpg"));
+        planeInspectionPicBo4.setInfraredId("7");
+        planeInspectionPicBo4.setVisibleId("8");
+        planeInspectionPicBo4.setInfrared("");
+        planeInspectionPicBo4.setVisible(photoResultService.pic2Base64FromMinio("/nest/photo/2420/1872/方阵13-16巡检任务0224-2023-02-26-15-18-35-DJI_20230226144302_0007_THRM.jpg"));
         planeInspectionResultBoNext.getPics().add(planeInspectionPicBo4);
 
         planeInspectionResultBoList.add(planeInspectionResultBoNext);
 
         //生成报告主函数
         reportService.createReport(mFlyCountMap, mSummaryMap, planeInspectionResultBoList);
-    }*/
+    }
 
+    /**
+     *  生成月报告
+     **/
     @GetMapping("/getMonthReport")
-    public void getMonthReport() throws ParseException {
-
+    public void getMonthReport() throws ParseException, IOException {
         reportService.getMonthReport();
     }
+
+//    @GetMapping("/download")
+//    public void download(HttpServletResponse response) throws UnsupportedEncodingException {
+//        FileUtil.download(response, "F:\\temp\\10.doc");
+//    }
+
+    /**
+     * 下载最新的报告
+     */
+    @GetMapping("/download")
+    public String download(HttpServletResponse response) throws IOException {
+
+        // 获取最新的报告地址
+        String resourceFullName = minioService.getReportPath();
+
+        OutputStream outputStream = response.getOutputStream();
+        // 拿到文件路径
+        String[] strings = StrUtil.splitToArray(resourceFullName, "/");
+        String url = strings[1];
+        // 获取文件对象
+        InputStream inputStream = minioService.getObject(url, StrUtil.sub(resourceFullName,
+                CharSequenceUtil.length(strings[1])+2, CharSequenceUtil.length(resourceFullName)));
+        try {
+            response.reset();
+            response.setHeader("Content-Disposition", "attachment;filename=" +
+                    URLEncoder.encode(resourceFullName.substring(resourceFullName.lastIndexOf("/") + 1), "UTF-8"));
+            response.setContentType("application/octet-stream");
+            response.setCharacterEncoding("UTF-8");
+            // 输出文件
+            outputStream.write(FileUtil.readInputStream(inputStream));
+            outputStream.flush();
+        } catch (Exception ex) {
+            log.error("下载文件:{}",ex);
+            return "下载文件失败";
+        }finally {
+            // 关闭输出流
+            outputStream.close();
+        }
+        return "下载文件成功";
+    }
+    
+    /**
+     *  查询异常光伏板板数量
+     **/
+    @GetMapping("/getAbnormal")
+    public Integer getAbnormal(){
+        int allAbnormal = 0;
+        int abnormal;
+        for (int i = 0; i < 3; i++) {
+            int missionId = MissionConstant.MISSION_ID[i];
+            String key = "PlaneInspection:abnormalPvPanels:" + missionId;
+            if (RedisUtils.hasKey(key)){
+                abnormal = Integer.parseInt(RedisUtils.get(key).toString());
+            }else {
+                List<PlanePhotoEntity> photoEntityList = planePhotoMapper.queryNewRecordByMission(missionId);
+                PlanePhotoEntity photoEntity = photoEntityList.get(0);
+                List<PhotoResultEntity> list = photoResultMapper.queryFltPVPanel(photoEntity.getRecordId(), null);
+                abnormal = list.size();
+            }
+            allAbnormal += abnormal;
+        }
+        return allAbnormal;
+    }
+
 }

+ 5 - 0
src/main/java/com/keystar/plane/inspection/entity/PhotoResultEntity.java

@@ -53,4 +53,9 @@ public class PhotoResultEntity {
      *  异常位置
      **/
     private String coordinates;
+
+    /**
+     *  时间
+     **/
+    private String time;
 }

+ 6 - 0
src/main/java/com/keystar/plane/inspection/entity/PlanePhotoEntity.java

@@ -58,6 +58,12 @@ public class PlanePhotoEntity implements Serializable {
     private String pvName;
 
     /**
+     *  图片中心光伏板名字
+     **/
+    @TableField(value = "center_pv_name")
+    private String centerPvName;
+
+    /**
      *  光伏板坐标
      **/
     @TableField(value = "array_box")

+ 36 - 0
src/main/java/com/keystar/plane/inspection/entity/PlaneTaskEntity.java

@@ -0,0 +1,36 @@
+package com.keystar.plane.inspection.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ *  文件任务
+ **/
+@Data
+@TableName("kr_plane_task")
+public class PlaneTaskEntity {
+
+    private static final long serialVersionUID = 1650634709644831520L;
+
+    /**
+     *  id
+     **/
+    private Long id;
+
+    /**
+     *  航线id
+     **/
+    private Integer missionId;
+
+    /**
+     *  架次id
+     **/
+    private Integer recordId;
+
+    /**
+     *  记录时间
+     **/
+    private Date data;
+}

+ 12 - 0
src/main/java/com/keystar/plane/inspection/mapper/PlanePhotoMapper.java

@@ -8,7 +8,9 @@ import com.keystar.plane.inspection.entity.PlanePhotoEntity;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
 import org.mybatis.spring.annotation.MapperScan;
+import sun.print.PSPrinterJob;
 
+import javax.xml.crypto.Data;
 import java.util.Date;
 import java.util.List;
 
@@ -44,4 +46,14 @@ public interface PlanePhotoMapper extends BaseMapper<PlanePhotoEntity> {
      *  根据架次id查询图片信息
      **/
     List<PlanePhotoEntity> queryPhotoByRecordId(@Param("recordId") Integer recordId);
+
+    /**
+     *  查询本月飞过的航线
+     **/
+    List<PlanePhotoEntity> queryEffectiveMission(DateBo dateBo);
+
+    /**
+     *  查询本月飞过的航线和架次
+     **/
+    List<PlanePhotoEntity> queryMonthRecord(DateBo dateBo);
 }

+ 18 - 0
src/main/java/com/keystar/plane/inspection/mapper/PlaneTaskMapper.java

@@ -0,0 +1,18 @@
+package com.keystar.plane.inspection.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.keystar.plane.inspection.bo.DateBo;
+import com.keystar.plane.inspection.entity.PlaneTaskEntity;
+import com.keystar.plane.inspection.vo.PlaneTaskVo;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+@Mapper
+public interface PlaneTaskMapper extends BaseMapper<PlaneTaskEntity> {
+
+    int queryAllTask();
+
+    List<PlaneTaskVo> queryFinishedTask(DateBo dateBo);
+
+}

+ 7 - 6
src/main/java/com/keystar/plane/inspection/mqtt/PlaneMqttHandler.java

@@ -1,6 +1,5 @@
 package com.keystar.plane.inspection.mqtt;
 
-import cn.hutool.core.util.ReUtil;
 import com.alibaba.fastjson.JSON;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.keystar.mqtt.annotation.MqttHandlerType;
@@ -8,8 +7,9 @@ import com.keystar.mqtt.annotation.MqttSubScribe;
 import com.keystar.mqtt.handler.AbstractMqttHandler;
 import com.keystar.plane.inspection.constant.PlaneStatusConstant;
 import com.keystar.plane.inspection.constant.UrlConstant;
-import com.keystar.plane.inspection.dao.LoginVo;
-import com.keystar.plane.inspection.dao.PlanePhotoVo;
+import com.keystar.plane.inspection.mapper.PlaneTaskMapper;
+import com.keystar.plane.inspection.service.PlaneTaskService;
+import com.keystar.plane.inspection.vo.LoginVo;
 import com.keystar.plane.inspection.service.MqttService;
 import com.keystar.plane.inspection.utils.HttpUtils;
 import com.keystar.plane.inspection.utils.RedisUtils;
@@ -17,14 +17,12 @@ import com.keystar.plane.inspection.utils.Utils;
 import lombok.SneakyThrows;
 import lombok.extern.slf4j.Slf4j;
 import org.eclipse.paho.client.mqttv3.MqttMessage;
-import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.autoconfigure.cache.CacheProperties;
 import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Service;
 
 import java.io.IOException;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Map;
 
 @MqttHandlerType(
@@ -43,6 +41,9 @@ public class PlaneMqttHandler implements AbstractMqttHandler {
     @Autowired
     MqttService mqttService;
 
+    @Autowired
+    PlaneTaskMapper planeTaskMapper;
+
 
     @SneakyThrows
     @Override

+ 27 - 1
src/main/java/com/keystar/plane/inspection/mqtt/RecognizeMqttHandler.java

@@ -10,14 +10,18 @@ import com.keystar.mqtt.handler.AbstractMqttHandler;
 import com.keystar.plane.inspection.bo.RecognizeMessageBo;
 import com.keystar.plane.inspection.entity.PhotoResultEntity;
 import com.keystar.plane.inspection.entity.PlanePhotoEntity;
+import com.keystar.plane.inspection.mapper.PhotoResultMapper;
 import com.keystar.plane.inspection.service.PhotoResultService;
 import com.keystar.plane.inspection.service.PlanePhotoService;
+import com.keystar.plane.inspection.utils.RedisUtils;
 import lombok.extern.slf4j.Slf4j;
 import org.eclipse.paho.client.mqttv3.MqttMessage;
 import org.springframework.beans.factory.annotation.Autowired;
 
 import java.io.IOException;
+import java.text.SimpleDateFormat;
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.List;
 import java.util.Map;
 
@@ -37,18 +41,35 @@ public class RecognizeMqttHandler implements AbstractMqttHandler {
     @Autowired
     PlanePhotoService planePhotoService;
 
+    @Autowired
+    PhotoResultMapper photoResultMapper;
+
     @Override
     public void handle(MqttMessage message) throws IOException {
 
+        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHH:mm:ss");
+        String time = simpleDateFormat.format(new Date());
         String messageContent = new String(message.getPayload());
         log.info("======接收到的识别结果mq: " + messageContent);
         JSONObject messageObject = JSONObject.parseObject(messageContent);
         JSONArray dataList = messageObject.getJSONArray("data");
+
+        int missionId = 0;
+        int recordId = 0;
         // 将dataList中的结果遍历
         for( Object data : dataList){
             JSONObject dataObject = JSONObject.parseObject(data.toString());
             // 图片id
             String id = dataObject.getString("id");
+            // 获取航线id,架次
+            if (missionId == 0){
+                PlanePhotoEntity photo = new PlanePhotoEntity();
+                photo.setId(Long.parseLong(id));
+                PlanePhotoEntity byId = planePhotoService.getById(photo);
+                missionId = byId.getMissionId();
+                recordId = byId.getRecordId();
+            }
+
 //            JSONObject id1 = dataObject.getJSONObject("id");
 //            String id = id1.toJSONString();
 //            String id = dataObject.getJSONObject("id").toJSONString();
@@ -87,10 +108,15 @@ public class RecognizeMqttHandler implements AbstractMqttHandler {
                 photoResultEntity.setType(recognizeMessageBo.getResult().getType());
                 String joined = String.join(",", recognizeMessageBo.getResult().getCoordinates());
                 photoResultEntity.setCoordinates(joined);
+                photoResultEntity.setTime(time);
                 log.info("======识别结果入库:" + photoResultEntity);
                 photoResultService.save(photoResultEntity);
             }
-
         }
+
+        // 将识别返回的异常光伏板数量存入redis
+        List<PhotoResultEntity> list = photoResultMapper.queryFltPVPanel(recordId, null);
+        String key = "PlaneInspection:abnormalPvPanels:" + missionId;
+        RedisUtils.set(key, String.valueOf(list.size()));
     }
 }

+ 2 - 1
src/main/java/com/keystar/plane/inspection/service/IReportService.java

@@ -8,6 +8,7 @@ package com.keystar.plane.inspection.service;
 
 import com.keystar.plane.inspection.bo.PlaneInspectionResultBo;
 
+import java.io.IOException;
 import java.text.ParseException;
 import java.util.List;
 import java.util.Map;
@@ -16,6 +17,6 @@ public interface IReportService {
 
     void createReport(Map<String, String> mFlyCountMap, Map<String, String> mSummaryMap, List<PlaneInspectionResultBo> planeInspectionResultBoList);
 
-    void getMonthReport() throws ParseException;
+    void getMonthReport() throws ParseException, IOException;
 
 }

+ 8 - 1
src/main/java/com/keystar/plane/inspection/service/MqttService.java

@@ -2,8 +2,10 @@ package com.keystar.plane.inspection.service;
 
 import com.drew.imaging.jpeg.JpegProcessingException;
 import com.fasterxml.jackson.core.JsonProcessingException;
+import com.keystar.plane.inspection.bo.NewFileBo;
 import com.keystar.plane.inspection.bo.PhotoMqttMessageBo;
 
+import java.io.File;
 import java.io.IOException;
 import java.text.ParseException;
 import java.util.List;
@@ -28,6 +30,11 @@ public interface MqttService {
     /**
      *  发送最新任务的红外图片给图像识别
      **/
-    void sendPhotoMqtt() throws IOException, JpegProcessingException, ParseException, InterruptedException;
+    void sendPhotoMqtt() throws IOException, JpegProcessingException, ParseException;
+
+    /**
+     *  发送指定文件下的图片给图像识别
+     **/
+    File[] sendPhotoMatt(NewFileBo newFile) throws JpegProcessingException, IOException, ParseException;
 
 }

+ 1 - 1
src/main/java/com/keystar/plane/inspection/service/NestService.java

@@ -3,7 +3,7 @@ package com.keystar.plane.inspection.service;
 
 import com.keystar.plane.inspection.bo.DateBo;
 import com.keystar.plane.inspection.bo.PlaneInspectionBo;
-import com.keystar.plane.inspection.dao.NestStatusVo;
+import com.keystar.plane.inspection.vo.NestStatusVo;
 
 /**
  *  机巢状态类

+ 2 - 1
src/main/java/com/keystar/plane/inspection/service/PhotoResultService.java

@@ -5,6 +5,7 @@ import com.keystar.plane.inspection.bo.PhotoBo;
 import com.keystar.plane.inspection.bo.PlaneInspectionResultBo;
 import com.keystar.plane.inspection.entity.PhotoResultEntity;
 
+import java.io.IOException;
 import java.util.List;
 
 /**
@@ -20,7 +21,7 @@ public interface PhotoResultService extends IService<PhotoResultEntity> {
     /**
      *  list全部的异常结果信息给巡检报告
      **/
-    List<PlaneInspectionResultBo> listInspectionResult();
+    List<PlaneInspectionResultBo> listInspectionResult() throws IOException;
 
     String pic2Base64FromMinio(String minioAddr);
 

+ 13 - 5
src/main/java/com/keystar/plane/inspection/service/PhotoService.java

@@ -1,14 +1,14 @@
 package com.keystar.plane.inspection.service;
 
 import com.drew.imaging.jpeg.JpegProcessingException;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.keystar.plane.inspection.bo.PhotoBo;
+import com.keystar.plane.inspection.bo.Location;
 import com.keystar.plane.inspection.bo.PvNameBo;
-import com.keystar.plane.inspection.dao.PhotoResultVo;
-import com.keystar.plane.inspection.dao.PlanePhotoVo;
+import com.keystar.plane.inspection.entity.PlanePhotoEntity;
+import com.keystar.plane.inspection.vo.PhotoMessageVo;
+import com.keystar.plane.inspection.vo.PhotoResultVo;
+import com.keystar.plane.inspection.vo.PlanePhotoVo;
 
 import java.io.IOException;
-import java.util.List;
 
 public interface PhotoService {
 
@@ -22,6 +22,14 @@ public interface PhotoService {
      **/
     PhotoResultVo getPhotoMsg(PvNameBo pvNameBo);
 
+    /**
+     *  通过图片和异常坐标判断异常是在那个组串上
+     **/
+    PlanePhotoVo queryPhoto(PhotoMessageVo photoMessage, Location location) throws IOException, JpegProcessingException;
 
+    /**
+     *  将minio图片画框并转成base64
+     **/
+    String addBorderToBase64(PlanePhotoEntity photo) throws IOException;
 
 }

+ 9 - 0
src/main/java/com/keystar/plane/inspection/service/PlanePhotoService.java

@@ -45,5 +45,14 @@ public interface PlanePhotoService extends IService<PlanePhotoEntity> {
      **/
     List<PlanePhotoEntity> queryNewRecordByMission();
 
+    /**
+     *  查询本月有效航线
+     **/
+    List<Integer> getEffectiveMission() throws ParseException;
+
+    /**
+     *  查询本月有效航线中的最新架次
+     **/
+    List<PlanePhotoEntity> queryNewRecordMonth() throws ParseException;
 
 }

+ 19 - 0
src/main/java/com/keystar/plane/inspection/service/PlaneTaskService.java

@@ -0,0 +1,19 @@
+package com.keystar.plane.inspection.service;
+
+import com.keystar.plane.inspection.bo.DateBo;
+import com.keystar.plane.inspection.entity.PlaneTaskEntity;
+
+/**
+ *  无人机任务接口
+ **/
+public interface PlaneTaskService{
+
+    void insertTask(PlaneTaskEntity planeTaskEntity);
+
+    int queryAllTask();
+
+    int queryFinishedTask(DateBo dateBo);
+
+
+
+}

+ 86 - 0
src/main/java/com/keystar/plane/inspection/service/impl/MinioService.java

@@ -1,27 +1,43 @@
 package com.keystar.plane.inspection.service.impl;
 
 import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.map.MapUtil;
+import cn.hutool.core.text.CharSequenceUtil;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSONObject;
 import com.keystar.plane.inspection.config.MinIoConfig;
+import com.keystar.plane.inspection.utils.FileUtil;
+import com.keystar.plane.inspection.vo.UploadVo;
 import io.minio.MinioClient;
 import io.minio.Result;
 import io.minio.errors.*;
 import io.minio.messages.Item;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.cloud.context.config.annotation.RefreshScope;
 import org.springframework.stereotype.Service;
+import org.springframework.web.bind.annotation.GetMapping;
 import org.xmlpull.v1.XmlPullParserException;
 
 import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.Valid;
+import javax.validation.constraints.NotNull;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URLEncoder;
 import java.security.InvalidKeyException;
 import java.security.NoSuchAlgorithmException;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.stream.Collectors;
 
 @Service
 @Slf4j
+@RefreshScope
 public class MinioService {
 
     @Resource
@@ -30,6 +46,9 @@ public class MinioService {
     @Autowired
     private MinIoConfig minIoConfig;
 
+    @Value("${report.bucket}")
+    private String bucket;
+
 
     /**
      * 判断 bucket是否存在
@@ -124,8 +143,75 @@ public class MinioService {
         return infraredList;
     }
 
+    /**
+     * 文件上传
+     */
+    public void putObject(String bucketName, String objectName, InputStream stream,String contentType)  {
+        if (!bucketExists(bucketName)){
+            log.error("bucket不存在");
+        }
+        try {
+            minioClient.putObject(bucketName,objectName,stream,contentType);
+        } catch (Exception e) {
+            log.error("上传文件{}到桶{},出现错误:{}",objectName,bucketName,e);
+        }
+    }
+
+    public void upload(@Valid UploadVo uploadVo)  {
+        log.info("上传图片信息,fileSize:{},fileName:{}", uploadVo.getFile().getSize(), uploadVo.getFile().getOriginalFilename());
 
+        if (StrUtil.isEmpty(uploadVo.getResourceName())){
+            uploadVo.setResourceName(uploadVo.getFile().getOriginalFilename());
+        }
 
+        try {
+            this.putObject(uploadVo.getBucketName(),uploadVo.getPath(),uploadVo.getFile().getInputStream(),uploadVo.getFile().getContentType());
+        }catch (IOException ioe){
+            log.error("获取图片流失败:{}",ioe);
+        }
+    }
+
+    /**
+     * 下载文件
+     */
+    public String download(String resourceFullName, HttpServletResponse response) throws IOException {
+
+        OutputStream outputStream = response.getOutputStream();
+        // 拿到文件路径
+        String[] strings = StrUtil.splitToArray(resourceFullName, "/");
+        String url = strings[1];
+        // 获取文件对象
+        InputStream inputStream = this.getObject(url, StrUtil.sub(resourceFullName,
+                CharSequenceUtil.length(strings[1])+2, CharSequenceUtil.length(resourceFullName)));
+        try {
+            response.reset();
+            response.setHeader("Content-Disposition", "attachment;filename=" +
+                    URLEncoder.encode(resourceFullName.substring(resourceFullName.lastIndexOf("/") + 1), "UTF-8"));
+            response.setContentType("application/octet-stream");
+            response.setCharacterEncoding("UTF-8");
+            // 输出文件
+            outputStream.write(FileUtil.readInputStream(inputStream));
+            outputStream.flush();
+        } catch (Exception ex) {
+            log.error("下载文件:{}",ex);
+            return "下载文件失败";
+        }finally {
+            // 关闭输出流
+            outputStream.close();
+        }
+        return "下载文件成功";
+    }
+
+    /**
+     *  获取最新的巡检报告的地址
+     **/
+    public String getReportPath(){
+        // 获取bucket中的报告地址
+        List<Item> dateList = this.listObject(bucket);
+        String date = dateList.get(dateList.size()-1).objectName();
+        // 拼接地址
+        return "/" + bucket + "/" + date;
+    }
     
 
 }

+ 174 - 17
src/main/java/com/keystar/plane/inspection/service/impl/MqttServiceImpl.java

@@ -4,15 +4,17 @@ import cn.hutool.core.util.IdUtil;
 import com.drew.imaging.jpeg.JpegProcessingException;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
-import com.keystar.mqtt.bo.MqttMessageBo;
 import com.keystar.plane.inspection.bo.NewFileBo;
 import com.keystar.plane.inspection.bo.PhotoMqttMessageBo;
-import com.keystar.plane.inspection.dao.PlanePhotoVo;
+import com.keystar.plane.inspection.entity.PlaneTaskEntity;
+import com.keystar.plane.inspection.mapper.PlaneTaskMapper;
+import com.keystar.plane.inspection.service.PlaneTaskService;
+import com.keystar.plane.inspection.utils.FileUtil;
+import com.keystar.plane.inspection.vo.PlanePhotoVo;
 import com.keystar.plane.inspection.entity.PlanePhotoEntity;
 import com.keystar.plane.inspection.service.MqttService;
 import com.keystar.plane.inspection.service.PhotoService;
 import com.keystar.plane.inspection.service.PlanePhotoService;
-import com.keystar.plane.inspection.utils.FileUtil;
 import lombok.extern.slf4j.Slf4j;
 import org.eclipse.paho.client.mqttv3.MqttAsyncClient;
 import org.eclipse.paho.client.mqttv3.MqttException;
@@ -22,7 +24,6 @@ import org.springframework.stereotype.Service;
 
 import java.io.File;
 import java.io.IOException;
-import java.net.URLEncoder;
 import java.nio.charset.StandardCharsets;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
@@ -44,6 +45,8 @@ public class MqttServiceImpl implements MqttService {
     @Autowired
     MqttService mqttService;
 
+    @Autowired
+    PlaneTaskService planeTaskService;
 
 
     private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
@@ -115,13 +118,9 @@ public class MqttServiceImpl implements MqttService {
     }
 
     @Override
-    public void sendPhotoMqtt() throws IOException, JpegProcessingException, ParseException, InterruptedException {
+    public void sendPhotoMqtt() throws IOException, JpegProcessingException, ParseException{
+        // 读取最新文件的地址
         NewFileBo newFile = FileUtil.getNewFilePath();
-//        NewFileBo newFile = new NewFileBo();
-//        newFile.setMissionId(2425);
-//        newFile.setRecordId(1890);
-//        newFile.setPath("F:\\2425\\1890");
-//        newFile.setPath("C:\\Users\\KR0282\\Desktop\\photo\\1");
         log.info("=====返回的最新的图片文件目录:" + newFile.toString());
         File path = new File(newFile.getPath());
         log.info("=====图片目录:" + path.getPath());
@@ -129,16 +128,39 @@ public class MqttServiceImpl implements MqttService {
         SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
         String visibleImage = null;
         Long photoId = null;
+
         if (files != null){
+
+            // 将最新的无人机任务一起同步到数据库中
+            PlaneTaskEntity planeTaskEntity = new PlaneTaskEntity();
+            planeTaskEntity.setId(IdUtil.getSnowflake().nextId());
+            planeTaskEntity.setMissionId(newFile.getMissionId());
+            planeTaskEntity.setRecordId(newFile.getRecordId());
+            planeTaskEntity.setData(new Date(files[0].lastModified()));
+            planeTaskService.insertTask(planeTaskEntity);
+
             log.info("======目录里面的文件数:" + files.length);
+
+            // 将文件夹中的文件名放在map中
+            Map<String, String> fileNameMap = new HashMap<>();
+            for (File file : files){
+                String[] strings = file.getName().split("_");
+                String key = strings[2] + "_" + strings[3];
+                fileNameMap.put(key,file.getName());
+            }
             // 取出红外图片
             List <PlanePhotoEntity> photoEntityList = new ArrayList<>();
             for ( File file : files){
                 log.info("========图片名:" + file.getPath());
                 if (file.getName().contains("THRM.jpg") || file.getName().contains("T.jpg") || file.getName().contains("T.JPG") || file.getName().contains("THRM.JPG")){
                     log.info("=======红外图片地址:" + file.getPath());
+                    PlanePhotoVo planePhotoVo;
                     // 且图片是在光伏区内
-                    PlanePhotoVo planePhotoVo = photoService.queryPhoto(file.getPath());
+                    try {
+                        planePhotoVo = photoService.queryPhoto(file.getPath());
+                    }catch (JpegProcessingException e){
+                        continue;
+                    }
                     log.info("======图片算法判断结果:"+ planePhotoVo.toString());
                     if (planePhotoVo.getPZName() != null){
                         // 将图片入库
@@ -175,6 +197,7 @@ public class MqttServiceImpl implements MqttService {
                         planePhotoEntity.setPzName(planePhotoVo.getPZName());
                         String joined = String.join(",", planePhotoVo.getPVNames());
                         planePhotoEntity.setPvName(joined);
+                        planePhotoEntity.setCenterPvName(planePhotoVo.getCenterPvName());
                         planePhotoEntity.setTime(sd.parse(sd.format(new Date(file.lastModified()))));
                         planePhotoEntity.setMissionId(newFile.getMissionId());
                         planePhotoEntity.setRecordId(newFile.getRecordId());
@@ -196,13 +219,13 @@ public class MqttServiceImpl implements MqttService {
                     }
                 }
                 // 将红外对应的可见光图片,更新到数据库
+                log.info("=====可见光图片地址:" + visibleImage);
                 if (visibleImage != null){
-                    if (file.getName().contains(visibleImage)){
-                        PlanePhotoEntity photoEntity = new PlanePhotoEntity();
-                        photoEntity.setId(photoId);
-                        photoEntity.setVisibleImagePath("/nest/photo/"+newFile.getMissionId()+"/"+newFile.getRecordId()+"/" + file.getName());
-                        planePhotoService.updateById(photoEntity);
-                    }
+                    String visibleImagePath = fileNameMap.get(visibleImage);
+                    PlanePhotoEntity photoEntity = new PlanePhotoEntity();
+                    photoEntity.setId(photoId);
+                    photoEntity.setVisibleImagePath("/nest/photo/"+newFile.getMissionId()+"/"+newFile.getRecordId()+"/" + visibleImagePath);
+                    planePhotoService.updateById(photoEntity);
                 }
             }
             // 遍历完图片后,一起入库和发给图像识别
@@ -231,5 +254,139 @@ public class MqttServiceImpl implements MqttService {
         }
     }
 
+    @Override
+    public File[] sendPhotoMatt(NewFileBo newFile) throws JpegProcessingException, IOException, ParseException {
+//        // 读取最新文件的地址
+//        NewFileBo newFile = FileUtil.getNewFilePath();
+//        NewFileBo newFile = new NewFileBo();
+//        newFile.setMissionId(2374);
+//        newFile.setRecordId(1827);
+//        newFile.setPath("F:\\photo\\nest\\photo\\2374\\1827");
+        log.info("=====返回的最新的图片文件目录:" + newFile.toString());
+        File path = new File(newFile.getPath());
+        log.info("=====图片目录:" + path.getPath());
+        File[] files = path.listFiles();
+        SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        String visibleImage = null;
+        Long photoId = null;
+        if (files != null){
+            log.info("======目录里面的文件数:" + files.length);
+//            // 按时间排序
+//            Arrays.sort(files, Comparator.comparingLong(File::lastModified));
+
+            // 将文件夹中的文件名放在map中
+            Map<String, String> fileNameMap = new HashMap<>();
+            for (File file : files){
+                String[] strings = file.getName().split("_");
+                String key = strings[2] + "_" + strings[3];
+                fileNameMap.put(key,file.getName());
+            }
+            // 取出红外图片
+            List <PlanePhotoEntity> photoEntityList = new ArrayList<>();
+            for ( File file : files){
+                log.info("========图片名:" + file.getPath());
+                if (file.getName().contains("THRM.jpg") || file.getName().contains("T.jpg") || file.getName().contains("T.JPG") || file.getName().contains("THRM.JPG")){
+                    log.info("=======红外图片地址:" + file.getPath());
+                    PlanePhotoVo planePhotoVo;
+                    // 且图片是在光伏区内
+                    try {
+                        planePhotoVo = photoService.queryPhoto(file.getPath());
+                    }catch (JpegProcessingException e){
+                        continue;
+                    }
+                    log.info("======图片算法判断结果:"+ planePhotoVo.toString());
+                    if (planePhotoVo.getPZName() != null){
+                        // 将图片入库
+                        PlanePhotoEntity planePhotoEntity = new PlanePhotoEntity();
+                        planePhotoEntity.setId(IdUtil.getSnowflake().nextId());
+                        // minio地址
+                        String minioPath = "/nest/photo/"+newFile.getMissionId()+"/"+newFile.getRecordId()+"/"+file.getName();
+
+//                        String s = new String(minioPath.getBytes(StandardCharsets.UTF_8));
+//                        String encode = URLEncoder.encode(s, "UTF-8");
+                        planePhotoEntity.setInfraredImagePath(minioPath);
+                        // 根据红外地址获取可见光地址,根据红外图片的后缀,拼接可见光图片的后缀
+                        String infraredStr = file.getName().split("_")[3];
+                        String visibleStr = null;
+                        switch (infraredStr)
+                        {
+                            case "T.JPG" :
+                                visibleStr = "Z.JPG";
+                                break;
+                            case "T.jpg" :
+                                visibleStr = "Z.jpg";
+                                break;
+                            case "THRM.JPG" :
+                                visibleStr = "ZOOM.JPG";
+                                break;
+                            case "THRM.jpg" :
+                                visibleStr = "ZOOM.jpg";
+                                break;
+                            default:
+                        }
+                        visibleImage = file.getName().split("_")[2] + "_" + visibleStr;
+                        photoId = planePhotoEntity.getId();
+
+                        planePhotoEntity.setPzName(planePhotoVo.getPZName());
+                        String joined = String.join(",", planePhotoVo.getPVNames());
+                        planePhotoEntity.setPvName(joined);
+                        planePhotoEntity.setCenterPvName(planePhotoVo.getCenterPvName());
+                        planePhotoEntity.setTime(sd.parse(sd.format(new Date(file.lastModified()))));
+                        planePhotoEntity.setMissionId(newFile.getMissionId());
+                        planePhotoEntity.setRecordId(newFile.getRecordId());
+                        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
+                        planePhotoEntity.setDate(Integer.parseInt(dateFormat.format(new Date(file.lastModified()))));
+                        photoEntityList.add(planePhotoEntity);
+                        planePhotoService.save(planePhotoEntity);
+                        log.info("======将图片入库:" + planePhotoEntity.toString());
+
+//                        // 发送mqtt给图像识别
+//                        Thread.sleep(3000);
+//                        PhotoMqttMessageBo photoMqttMessageBo = new PhotoMqttMessageBo();
+//                        photoMqttMessageBo.setId(planePhotoEntity.getId());
+//                        photoMqttMessageBo.setFunc_index("0");
+//                        photoMqttMessageBo.setInfrared_image_path(minioPath);
+//                        mqttService.sendMqtt(photoMqttMessageBo);
+//                        log.info("======将图片发送mqtt给图像识别:" + photoMqttMessageBo.toString());
+
+                    }
+                }
+                // 将红外对应的可见光图片,更新到数据库
+                log.info("=====可见光图片地址:" + visibleImage);
+                if (visibleImage != null){
+                    String visibleImagePath = fileNameMap.get(visibleImage);
+                    PlanePhotoEntity photoEntity = new PlanePhotoEntity();
+                    photoEntity.setId(photoId);
+                    photoEntity.setVisibleImagePath("/nest/photo/"+newFile.getMissionId()+"/"+newFile.getRecordId()+"/" + visibleImagePath);
+                    planePhotoService.updateById(photoEntity);
+                }
+            }
+            // 遍历完图片后,一起入库和发给图像识别
+//            planePhotoService.saveBatch(photoEntityList);
+            log.info("======遍历完成,将图像信息入库======");
+            List<String> funcIndex = new ArrayList<>();
+            // 二极管故障
+            funcIndex.add("1");
+            // 遮挡
+            funcIndex.add("1");
+            // 掉串
+            funcIndex.add("0");
+            List<PhotoMqttMessageBo> messageBoList = new ArrayList<>();
+            for ( PlanePhotoEntity photoEntity : photoEntityList){
+                PhotoMqttMessageBo photoMqttMessageBo = new PhotoMqttMessageBo();
+                photoMqttMessageBo.setId(photoEntity.getId());
+                photoMqttMessageBo.setFuncIndex(funcIndex);
+                photoMqttMessageBo.setVisibleImagePath("");
+                photoMqttMessageBo.setInfraredImagePath(photoEntity.getInfraredImagePath());
+                messageBoList.add(photoMqttMessageBo);
+            }
+            mqttService.sendMqtt(messageBoList);
+
+        }else {
+            log.info("======文件夹是空的======");
+        }
+
+        return files;
+    }
 
 }

+ 46 - 34
src/main/java/com/keystar/plane/inspection/service/impl/NestServiceImpl.java

@@ -7,7 +7,8 @@ import com.keystar.plane.inspection.bo.DateBo;
 import com.keystar.plane.inspection.bo.PlaneInspectionBo;
 import com.keystar.plane.inspection.bo.TaskMissionRecordBo;
 import com.keystar.plane.inspection.constant.UrlConstant;
-import com.keystar.plane.inspection.dao.NestStatusVo;
+import com.keystar.plane.inspection.service.PlaneTaskService;
+import com.keystar.plane.inspection.vo.NestStatusVo;
 import com.keystar.plane.inspection.enums.NestStatusEnum;
 import com.keystar.plane.inspection.service.LoginService;
 import com.keystar.plane.inspection.service.NestService;
@@ -34,6 +35,9 @@ public class NestServiceImpl implements NestService {
     @Autowired
     private LoginService loginService;
 
+    @Autowired
+    private PlaneTaskService planeTaskService;
+
     @Override
     public String getNestStatus() {
 
@@ -67,40 +71,48 @@ public class NestServiceImpl implements NestService {
      **/
     @Override
     public PlaneInspectionBo getInspection(DateBo dateBo) throws Exception {
-        // 先拿token
-        String token = loginService.getToken();
+//        // 先拿token
+//        String token = loginService.getToken();
+//        PlaneInspectionBo planeInspectionBo = new PlaneInspectionBo();
+//        if (token != null){
+//            // 访问无人机任务接口
+//            Map<String, String> headers = new HashMap<>();
+//            headers.put("Authorization", token);
+//
+//            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
+//            Map<String,Object> paramMap = new HashMap<>();
+//            paramMap.put("startTime",dateFormat.format(dateBo.getStartTime()));
+//            paramMap.put("endTime",dateFormat.format(dateBo.getEndTime()));
+//
+//            String response = HttpUtils.doPost(UrlConstant.PLANE_TASK, paramMap, headers);
+//            JSONObject jsonObject = JSONObject.parseObject(response);
+//            JSONObject param = jsonObject.getJSONObject("param");
+//            JSONObject result = param.getJSONObject("result");
+//            JSONArray taskList = result.getJSONArray("taskMissionRecordsEntityList");
+//            List<TaskMissionRecordBo> missionList = taskList.toJavaList(TaskMissionRecordBo.class);
+//
+//            planeInspectionBo.setAllTask(missionList.size());
+//            int finish = 0;
+//            int unfinished = 0;
+//            for ( TaskMissionRecordBo recordBo : missionList){
+//                if (recordBo.getTaskCount() > 0){
+//                    finish +=1 ;
+//                }else {
+//                    unfinished +=1 ;
+//                }
+//            }
+//            planeInspectionBo.setFinishedTask(finish);
+//            planeInspectionBo.setUnfinishedTask(unfinished);
+//            planeInspectionBo.setPlaneStatus(getNestStatus());
+//            }
+        int all = planeTaskService.queryAllTask();
+        int finish = planeTaskService.queryFinishedTask(dateBo);
         PlaneInspectionBo planeInspectionBo = new PlaneInspectionBo();
-        if (token != null){
-            // 访问无人机任务接口
-            Map<String, String> headers = new HashMap<>();
-            headers.put("Authorization", token);
-
-            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
-            Map<String,Object> paramMap = new HashMap<>();
-            paramMap.put("startTime",dateFormat.format(dateBo.getStartTime()));
-            paramMap.put("endTime",dateFormat.format(dateBo.getEndTime()));
-
-            String response = HttpUtils.doPost(UrlConstant.PLANE_TASK, paramMap, headers);
-            JSONObject jsonObject = JSONObject.parseObject(response);
-            JSONObject param = jsonObject.getJSONObject("param");
-            JSONObject result = param.getJSONObject("result");
-            JSONArray taskList = result.getJSONArray("taskMissionRecordsEntityList");
-            List<TaskMissionRecordBo> missionList = taskList.toJavaList(TaskMissionRecordBo.class);
-
-            planeInspectionBo.setAllTask(missionList.size());
-            int finish = 0;
-            int unfinished = 0;
-            for ( TaskMissionRecordBo recordBo : missionList){
-                if (recordBo.getTaskCount() > 0){
-                    finish +=1 ;
-                }else {
-                    unfinished +=1 ;
-                }
-            }
-            planeInspectionBo.setFinishedTask(finish);
-            planeInspectionBo.setUnfinishedTask(unfinished);
-            planeInspectionBo.setPlaneStatus(getNestStatus());
-            }
+        planeInspectionBo.setAllTask(all);
+        planeInspectionBo.setFinishedTask(finish);
+        planeInspectionBo.setUnfinishedTask(all - finish);
+        planeInspectionBo.setPlaneStatus(getNestStatus());
+
         return planeInspectionBo;
         }
 

+ 43 - 16
src/main/java/com/keystar/plane/inspection/service/impl/PhotoResultServiceImpl.java

@@ -3,26 +3,25 @@ package com.keystar.plane.inspection.service.impl;
 import cn.hutool.core.text.CharSequenceUtil;
 import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.keystar.plane.inspection.bo.PhotoBo;
-import com.keystar.plane.inspection.bo.PlaneInspectionPicBo;
-import com.keystar.plane.inspection.bo.PlaneInspectionResultBo;
-import com.keystar.plane.inspection.bo.PlaneInspectionResultDetailBo;
+import com.keystar.plane.inspection.bo.*;
+import com.keystar.plane.inspection.constant.LocationConstant;
 import com.keystar.plane.inspection.entity.PhotoResultEntity;
 import com.keystar.plane.inspection.entity.PlanePhotoEntity;
 import com.keystar.plane.inspection.mapper.PhotoResultMapper;
 import com.keystar.plane.inspection.mapper.PlanePhotoMapper;
 import com.keystar.plane.inspection.service.PhotoResultService;
+import com.keystar.plane.inspection.service.PhotoService;
 import com.keystar.plane.inspection.service.PlanePhotoService;
+import com.keystar.plane.inspection.utils.GisCheckUtils;
+import com.keystar.plane.inspection.utils.PhotoUtils;
+import com.keystar.plane.inspection.vo.PhotoMessageVo;
+import net.coobird.thumbnailator.Thumbnails;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
-import java.io.ByteArrayOutputStream;
-import java.io.FileInputStream;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Base64;
-import java.util.List;
+import java.io.*;
+import java.util.*;
 
 @Service
 public class PhotoResultServiceImpl extends ServiceImpl<PhotoResultMapper, PhotoResultEntity> implements PhotoResultService {
@@ -39,6 +38,9 @@ public class PhotoResultServiceImpl extends ServiceImpl<PhotoResultMapper, Photo
     @Autowired
     private PlanePhotoService planePhotoService;
 
+    @Autowired
+    private PhotoService photoService;
+
     @Override
     public PhotoBo queryResultByPhotoId(PhotoBo photoBo) {
         Long id = photoBo.getId();
@@ -61,13 +63,19 @@ public class PhotoResultServiceImpl extends ServiceImpl<PhotoResultMapper, Photo
 
             byteArrayOutputStream = new ByteArrayOutputStream();
 
+//            // 将图片按大小,质量压缩
+//            Thumbnails.of(inputStream)
+//                    .scale(1f) //图片大小(长宽)压缩比例 从0-1,1表示原图
+//                    .outputQuality(0.5f)//图片质量压缩比例 从0-1,越接近1质量越好
+//                    .toOutputStream(byteArrayOutputStream);
+
             byte[] bytes = new byte[10240];
             int mReadLength = 0;
 
             while ((mReadLength = inputStream.read(bytes)) != -1) {
                 byteArrayOutputStream.write(bytes, 0, mReadLength);
             }
-
+            // return "data:image/jpeg;base64," + Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray());
             return Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray());
         }catch (Exception e) {
 
@@ -135,20 +143,20 @@ public class PhotoResultServiceImpl extends ServiceImpl<PhotoResultMapper, Photo
     }
 
     @Override
-    public List<PlaneInspectionResultBo> listInspectionResult() {
+    public List<PlaneInspectionResultBo> listInspectionResult() throws IOException {
         //查库组装巡检结果集合传入函数即可
         List<PlaneInspectionResultBo> planeInspectionResultBoList = new ArrayList<>();
 
         //查询有效航线中的最新架次
         List<PlanePhotoEntity> photoEntityList = planePhotoService.queryNewRecordByMission();
         log.debug("*******************photoEntityList Size: " + photoEntityList.size());
+        int detailNum = 0;
         for (PlanePhotoEntity photoEntity : photoEntityList){
 
             // 根据架次获取图片和异常信息
             List<PlanePhotoEntity> photoList = planePhotoMapper.queryPhotoByRecordId(photoEntity.getRecordId());
             log.debug("*******************photoList Size: " + photoList.size());
             for (PlanePhotoEntity photo : photoList){
-                int detailNum = 0;
                 PlaneInspectionResultBo planeInspectionResultBo = new PlaneInspectionResultBo();
                 planeInspectionResultBo.setPics(new ArrayList<>());
                 planeInspectionResultBo.setDetails(new ArrayList<>());
@@ -157,7 +165,11 @@ public class PhotoResultServiceImpl extends ServiceImpl<PhotoResultMapper, Photo
                 planeInspectionResultBo.setId(String.valueOf(photo.getId()));
                 PlaneInspectionPicBo planeInspectionPicBo = new PlaneInspectionPicBo();
 //                planeInspectionPicBo.setVisible(pic2Base64FromPath("F:\\photo\\" + photo.getVisibleImagePath()));
-                planeInspectionPicBo.setInfrared(pic2Base64FromPath("F:\\photo\\" +photo.getInfraredImagePath()));
+                planeInspectionPicBo.setInfraredId(photo.getId() + "1");
+                // 将图片画框处理,将图片压缩
+                planeInspectionPicBo.setInfrared(photoService.addBorderToBase64(photo));
+//                planeInspectionPicBo.setInfrared(pic2Base64FromMinio(photo.getInfraredImagePath()));
+                planeInspectionPicBo.setVisibleId(photo.getId() + "2");
                 planeInspectionPicBo.setVisible("");
                 planeInspectionResultBo.getPics().add(planeInspectionPicBo);
 
@@ -177,8 +189,23 @@ public class PhotoResultServiceImpl extends ServiceImpl<PhotoResultMapper, Photo
                     }
                 }
                 PlaneInspectionResultDetailBo planeInspectionResultDetailBo = new PlaneInspectionResultDetailBo();
-                planeInspectionResultDetailBo.setNum(String.valueOf(detailNum+1));
-                planeInspectionResultDetailBo.setName(photo.getPvName());
+                planeInspectionResultDetailBo.setNum(String.valueOf(detailNum++));
+//                // 取最接近图片中心的组串作为名字
+//                PhotoMessageVo photoMessage = PhotoUtils.getPhotoMessage( );
+//                String[]  pvNameArray = photo.getPvName().split(",");
+//                ArrayList<String> arrayList = new ArrayList<>(pvNameArray.length);
+//                Collections.addAll(arrayList,pvNameArray);
+//                String name = "";
+//                double distance = 100.0;
+//                for (String pvName : arrayList){
+//                    Map<String, List<Location>> pz = LocationConstant.PVLocation.get(pvName.split("HL")[0]);
+//                    Location centerPoint = GisCheckUtils.getCenterPoint(pz.get(pvName));
+//                    // 判断那个组串中心点坐标距离图片中心点最近
+////                    double d = GisCheckUtils.GetDistance(centerPoint, location);
+//
+//                }
+
+                planeInspectionResultDetailBo.setName(photo.getCenterPvName());
                 planeInspectionResultDetailBo.setDioe(String.valueOf(detailDioe));
                 planeInspectionResultDetailBo.setHtspte(String.valueOf(detailHtspte));
                 planeInspectionResultDetailBo.setOce(String.valueOf(detailOce));

+ 107 - 22
src/main/java/com/keystar/plane/inspection/service/impl/PhotoServiceImpl.java

@@ -1,42 +1,34 @@
 package com.keystar.plane.inspection.service.impl;
 
 import com.drew.imaging.jpeg.JpegProcessingException;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
 import com.keystar.plane.inspection.bo.Location;
 import com.keystar.plane.inspection.bo.PhotoBo;
-import com.keystar.plane.inspection.bo.PhotoMqttMessageBo;
 import com.keystar.plane.inspection.bo.PvNameBo;
 import com.keystar.plane.inspection.constant.LocationConstant;
-import com.keystar.plane.inspection.dao.PhotoMessageVo;
-import com.keystar.plane.inspection.dao.PhotoResultVo;
-import com.keystar.plane.inspection.dao.PlanePhotoVo;
+import com.keystar.plane.inspection.service.PhotoResultService;
+import com.keystar.plane.inspection.vo.PhotoMessageVo;
+import com.keystar.plane.inspection.vo.PhotoResultVo;
+import com.keystar.plane.inspection.vo.PlanePhotoVo;
 import com.keystar.plane.inspection.entity.PhotoResultEntity;
 import com.keystar.plane.inspection.entity.PlanePhotoEntity;
 import com.keystar.plane.inspection.mapper.PhotoResultMapper;
 import com.keystar.plane.inspection.mapper.PlanePhotoMapper;
 import com.keystar.plane.inspection.service.PhotoService;
 import com.keystar.plane.inspection.service.PlanePhotoService;
-import com.keystar.plane.inspection.utils.FileUtil;
 import com.keystar.plane.inspection.utils.GisCheckUtils;
 import com.keystar.plane.inspection.utils.PhotoUtils;
 import lombok.extern.slf4j.Slf4j;
-import org.eclipse.paho.client.mqttv3.MqttAsyncClient;
-import org.eclipse.paho.client.mqttv3.MqttException;
-import org.eclipse.paho.client.mqttv3.MqttMessage;
-import org.junit.jupiter.params.shadow.com.univocity.parsers.conversions.LowerCaseConversion;
+import net.coobird.thumbnailator.Thumbnails;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
-import org.springframework.util.ResourceUtils;
 
 
 import javax.annotation.Resource;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
+import javax.imageio.ImageIO;
+import javax.imageio.stream.ImageOutputStream;
+import java.awt.image.BufferedImage;
+import java.io.*;
+import java.util.*;
 
 
 @Slf4j
@@ -57,6 +49,9 @@ public class PhotoServiceImpl implements PhotoService {
     @Autowired
     PlanePhotoService planePhotoService;
 
+    @Autowired
+    PhotoResultService photoResultService;
+
 
     @Override
     public PlanePhotoVo queryPhoto(String filePath) throws IOException, JpegProcessingException {
@@ -83,10 +78,13 @@ public class PhotoServiceImpl implements PhotoService {
 //                planePhotoVo.setPZName(pzMap.getKey());
 //            }
 
-            // 当图片与光伏区的重合面积大于图片本身面积的百分之80才判断图片属于这个光伏区
+            // 当图片与光伏区的重合面积大于图片本身面积的百分之60才判断图片属于这个光伏区
             double photoArea = GisCheckUtils.planarPolygonAreaMeters(degrees);
-            if (GisCheckUtils.CoincidentArea(degrees, value) >= photoArea * 0.6){
+            double pzArea = GisCheckUtils.CoincidentArea(degrees, value);
+            if (pzArea >= photoArea * 0.6){
                 planePhotoVo.setPZName(pzMap.getKey());
+                log.info("====判断出来无人机图片属于的光伏区是:" + pzMap.getKey());
+                log.info("====光伏区与图片的重合面积是:" + pzArea);
             }
         }
 
@@ -95,6 +93,9 @@ public class PhotoServiceImpl implements PhotoService {
             String pzName = planePhotoVo.getPZName();
             Map<String, List<Location>> stringListMap = LocationConstant.PVLocation.get(pzName.split("FZ")[1]);
             List<String> pvNameList = new ArrayList<>();
+
+            String centerPvName = "";
+            double distance = 50.0;
             for (Map.Entry<String, List<Location>> pvMap : stringListMap.entrySet()){
                 // 判断第一个多边形是否存在一个点在第二个多边形内
 //                if (GisCheckUtils.isPolygonInPolygon(pvMap.getValue(), degrees)){
@@ -105,12 +106,27 @@ public class PhotoServiceImpl implements PhotoService {
 //                    pvNameList.add(pvMap.getKey());
 //                }
 
-                // 当图片与的支架重合面积大于支架本身面积的百分之80才判断这个支架属于这个图片
+                // 当图片与的支架重合面积大于支架本身面积的百分之60才判断这个支架属于这个图片
                 double pvArea = GisCheckUtils.planarPolygonAreaMeters(pvMap.getValue());
-                if (GisCheckUtils.CoincidentArea(degrees, pvMap.getValue()) >= pvArea * 0.6){
+                double coincidentArea = GisCheckUtils.CoincidentArea(degrees, pvMap.getValue());
+                if (coincidentArea >= pvArea * 0.6){
                     pvNameList.add(pvMap.getKey());
+                    log.info("====判断出来无人机图片包涵的组串是:" + pvMap.getKey());
+                    log.info("====组串与图片的重合面积是:" + coincidentArea);
+                }
+
+                // 获取组串中心点的坐标
+                Location centerPoint = GisCheckUtils.getCenterPoint(pvMap.getValue());
+                // 判断那个组串中心点坐标距离图片中心点最近
+                double d = GisCheckUtils.GetDistance(centerPoint, location);
+                if (d < distance){
+                    distance = d;
+                    centerPvName = pvMap.getKey();
                 }
             }
+            log.info("=====组串的名字是:" + centerPvName  );
+            log.info("=====与图片中心点相差的距离是:" + distance);
+            planePhotoVo.setCenterPvName(centerPvName);
             planePhotoVo.setPVNames(pvNameList);
         }
 
@@ -142,6 +158,75 @@ public class PhotoServiceImpl implements PhotoService {
         return photoResultVo;
     }
 
+    @Override
+    public PlanePhotoVo queryPhoto(PhotoMessageVo photoMessage, Location location) throws IOException, JpegProcessingException {
+        PlanePhotoVo planePhotoVo = new PlanePhotoVo();
+        // 根据图片信息,获取图片四个角的经纬度,判断图片在哪个光伏区
+        List<Location> degrees = PhotoUtils.getDegrees(photoMessage);
+        for ( Map.Entry<String, List<Location>> pzMap : LocationConstant.PZLocation.entrySet()){
+            List<Location> value = pzMap.getValue();
+
+            // 当图片与光伏区的重合面积大于图片本身面积的百分之60才判断图片属于这个光伏区
+            double photoArea = GisCheckUtils.planarPolygonAreaMeters(degrees);
+            double pzArea = GisCheckUtils.CoincidentArea(degrees, value);
+            if (pzArea >= photoArea * 0.6){
+                planePhotoVo.setPZName(pzMap.getKey());
+                log.info("====判断出来无人机图片属于的光伏区是:" + pzMap.getKey());
+                log.info("====光伏区与图片的重合面积是:" + pzArea);
+            }
+        }
+
+        // 判断坐标点在那个组串上
+        if (planePhotoVo.getPZName() != null){
+            String pzName = planePhotoVo.getPZName();
+            Map<String, List<Location>> stringListMap = LocationConstant.PVLocation.get(pzName.split("FZ")[1]);
+            List<String> pvNameList = new ArrayList<>();
+            for (Map.Entry<String, List<Location>> pvMap : stringListMap.entrySet()){
+                if (GisCheckUtils.isPointInPolygon(location, pvMap.getValue())){
+                    pvNameList.add(pvMap.getKey());
+                }
+            }
+            planePhotoVo.setPVNames(pvNameList);
+        }
+
+
+        return planePhotoVo;
+    }
+
+    /**
+     *  将minio图片画框并转成base64
+     **/
+    @Override
+    public String addBorderToBase64(PlanePhotoEntity photo) throws IOException {
+        // 获取图片(base64)
+        String photoBase64 = photoResultService.pic2Base64FromMinio(photo.getInfraredImagePath());
+        // base64 转 BufferedImage
+        BufferedImage bufferedImage = PhotoUtils.base64ToBufferedImage(photoBase64);
+        // 画框
+        String arrayBox = photo.getArrayBox();
+        String[] array = arrayBox.split(";");
+        ArrayList<String> arrayList = new ArrayList<>(array.length);
+        Collections.addAll(arrayList,array);
+        for (String str : arrayList){
+            String[] pvArray = str.split(",");
+            int width = Integer.parseInt(pvArray[2]) - Integer.parseInt(pvArray[0]);
+            int height = Integer.parseInt(pvArray[3]) - Integer.parseInt(pvArray[1]);
+            bufferedImage = PhotoUtils.addBorders(bufferedImage, Integer.parseInt(pvArray[0]), Integer.parseInt(pvArray[1]), width, height);
+        }
+        // BufferedImage 转 inputStream
+        ByteArrayOutputStream bs = new ByteArrayOutputStream();
+        ImageOutputStream imOut = ImageIO.createImageOutputStream(bs);
+        ImageIO.write(bufferedImage, "jpg", imOut);
+        InputStream inputStream = new ByteArrayInputStream(bs.toByteArray());
+        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+        // 然后将图片进行压缩再转成base64
+        Thumbnails.of(inputStream)
+                .scale(1f) //图片大小(长宽)压缩比例 从0-1,1表示原图
+                .outputQuality(0.5f)//图片质量压缩比例 从0-1,越接近1质量越好
+                .toOutputStream(byteArrayOutputStream);
+
+        return Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray());
+    }
 
 
 }

+ 20 - 0
src/main/java/com/keystar/plane/inspection/service/impl/PlanePhotoServiceImpl.java

@@ -112,4 +112,24 @@ public class PlanePhotoServiceImpl extends ServiceImpl<PlanePhotoMapper, PlanePh
         return photoList;
     }
 
+    @Override
+    public List<Integer> getEffectiveMission() throws ParseException {
+        DateBo monthDay = Utils.getMonthDay();
+        List<PlanePhotoEntity> photoEntityList = planePhotoMapper.queryEffectiveMission(monthDay);
+        List<Integer> missionList = new ArrayList<>();
+        for (PlanePhotoEntity photoEntity : photoEntityList){
+            if (ArrayUtil.contains(MissionConstant.MISSION_ID, photoEntity.getMissionId())){
+                missionList.add(photoEntity.getMissionId());
+            }
+        }
+        return missionList;
+    }
+
+    @Override
+    public List<PlanePhotoEntity> queryNewRecordMonth() throws ParseException {
+        DateBo monthDay = Utils.getMonthDay();
+        List<PlanePhotoEntity> photoEntityList = planePhotoMapper.queryEffectiveMission(monthDay);
+        return null;
+    }
+
 }

+ 56 - 0
src/main/java/com/keystar/plane/inspection/service/impl/PlaneTaskServiceImpl.java

@@ -0,0 +1,56 @@
+package com.keystar.plane.inspection.service.impl;
+
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.keystar.plane.inspection.bo.DateBo;
+import com.keystar.plane.inspection.entity.PlaneTaskEntity;
+import com.keystar.plane.inspection.mapper.PlaneTaskMapper;
+import com.keystar.plane.inspection.service.PlaneTaskService;
+import com.keystar.plane.inspection.vo.PlaneTaskVo;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+@RequiredArgsConstructor
+public class PlaneTaskServiceImpl extends ServiceImpl<PlaneTaskMapper, PlaneTaskEntity> implements PlaneTaskService{
+
+    @Autowired
+    PlaneTaskMapper planeTaskMapper;
+
+    /**
+     * 插入任务
+     **/
+    @Override
+    public void insertTask(PlaneTaskEntity planeTaskEntity) {
+        planeTaskMapper.insert(planeTaskEntity);
+    }
+
+
+    /**
+     *  查询全部任务
+     **/
+    @Override
+    public int queryAllTask() {
+        return planeTaskMapper.queryAllTask();
+    }
+
+    /**
+     *  查询完成的任务
+     **/
+    @Override
+    public int queryFinishedTask(DateBo dateBo) {
+        List<PlaneTaskVo> planeTaskVos = planeTaskMapper.queryFinishedTask(dateBo);
+        int count = 0;
+        for (PlaneTaskVo planeTaskVo : planeTaskVos){
+            if (planeTaskVo.getNumRecords() != 0){
+                count += 1;
+            }
+        }
+        return count;
+    }
+
+
+}

+ 119 - 48
src/main/java/com/keystar/plane/inspection/service/impl/ReportServiceImpl.java

@@ -6,23 +6,36 @@ package com.keystar.plane.inspection.service.impl;
  * @Describe 报告接口实现类
  */
 
+import cn.hutool.core.util.ArrayUtil;
 import com.keystar.plane.inspection.bo.PlaneInspectionResultBo;
+import com.keystar.plane.inspection.config.MinIoConfig;
+import com.keystar.plane.inspection.constant.MissionConstant;
 import com.keystar.plane.inspection.entity.PlanePhotoEntity;
 import com.keystar.plane.inspection.mapper.PhotoResultMapper;
 import com.keystar.plane.inspection.service.IReportService;
 import com.keystar.plane.inspection.service.PhotoResultService;
 import com.keystar.plane.inspection.service.PlanePhotoService;
 import com.keystar.plane.inspection.service.TangyangDataService;
+import com.keystar.plane.inspection.vo.UploadVo;
 import freemarker.cache.ClassTemplateLoader;
 import freemarker.template.Configuration;
 import freemarker.template.Template;
 import freemarker.template.Version;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.fileupload.disk.DiskFileItemFactory;
+import org.apache.commons.io.IOUtils;
+
+import org.apache.commons.fileupload.FileItem;
+
 import org.springframework.aop.framework.AopContext;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.cloud.context.config.annotation.RefreshScope;
 import org.springframework.context.annotation.EnableAspectJAutoProxy;
+import org.springframework.http.MediaType;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.commons.CommonsMultipartFile;
 
 import javax.annotation.Resource;
 import java.io.*;
@@ -33,6 +46,7 @@ import java.util.*;
 
 @Service
 @Slf4j
+@RefreshScope
 //@EnableAspectJAutoProxy(exposeProxy = true)
 public class ReportServiceImpl implements IReportService {
 
@@ -50,6 +64,9 @@ public class ReportServiceImpl implements IReportService {
     @Autowired
     private PhotoResultService photoResultService;
 
+    @Value("${report.bucket}")
+    private String bucket;
+
     @Autowired
     public ReportServiceImpl(MinioService minioService) {
         this.minioService = minioService;
@@ -105,7 +122,7 @@ public class ReportServiceImpl implements IReportService {
             Template template = configuration.getTemplate("report.ftl", StandardCharsets.UTF_8.toString());
 
             //todo: 记得修改路径和名字(这里后面确定路径后要挂载目录)
-            mFile = new File("F:\\temp\\1.doc");
+            mFile = new File("唐阳_"+ new SimpleDateFormat("yyyy年MM月").format(mCalendar.getTime()) +"_无人机月度巡检报告.doc");
 
             fileOutputStream = new FileOutputStream(mFile);
 
@@ -114,6 +131,27 @@ public class ReportServiceImpl implements IReportService {
             template.process(mValueMap, outputStreamWriter);
 
             outputStreamWriter.flush();
+
+            // 将生成的报告上传到minio上面
+            DiskFileItemFactory factory = new DiskFileItemFactory(16, null);
+            FileItem fileItem = factory.createItem("file", MediaType.APPLICATION_OCTET_STREAM_VALUE,
+                    true, mFile.getName());
+            fileItem.getOutputStream();// 不知道为啥代码不会自动初始化outputstream只能多加这一行
+
+            try(InputStream is = new FileInputStream(mFile);
+                OutputStream os = fileItem.getOutputStream()){
+                IOUtils.copy(is, os);
+            }catch (Exception e){
+                mFile.delete();
+                throw e;
+            }
+
+            UploadVo fileVo = new UploadVo();
+            fileVo.setFile(new CommonsMultipartFile(fileItem));
+            fileVo.setBucketName(bucket);
+            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
+            fileVo.setResourcePath(simpleDateFormat.format(new Date()));
+            minioService.upload(fileVo);
         }catch (Exception e) {
             //生成失败删除垃圾文件
             if (mFile != null) {
@@ -141,13 +179,13 @@ public class ReportServiceImpl implements IReportService {
     }
 
     @Override
-    public void getMonthReport() throws ParseException {
+    public void getMonthReport() throws ParseException, IOException {
         //((ReportServiceImpl)AopContext.currentProxy()).genMonthReport();
         genMonthReport();
     }
 
     @Async
-    public void genMonthReport() throws ParseException {
+    public void genMonthReport() throws ParseException, IOException {
 
         Map<String, String> mFlyCountMap = new HashMap<>();
 
@@ -165,41 +203,48 @@ public class ReportServiceImpl implements IReportService {
         mSummaryMap.put("TotalPVString", "4624");
         //光伏板总数(124848不需要修改)
         mSummaryMap.put("TotalPVPanel", "124848");
-        //无人机巡检覆盖方阵数
-        mSummaryMap.put("CoveredFZ", "16");
-        //无人机巡检覆盖方阵百分比
-        mSummaryMap.put("CoveredFZPct", "100%");
-        //本月巡检覆盖组串总数
-        mSummaryMap.put("CoveredPVString", "4624");
-        //本月巡检覆盖组串百分比
-        mSummaryMap.put("CoveredPVStringPct", "100%");
-        //本月巡检覆盖光伏板总数
-        mSummaryMap.put("CoveredPVPanel", "124848");
-        //本月巡检覆盖光伏板百分比
-        mSummaryMap.put("CoveredPVPanelPct", "100%");
-        //无人机未巡检方阵数
-        mSummaryMap.put("UncoveredFZ", "0");
-        //无人机未巡检方阵百分比
-        mSummaryMap.put("UnCoveredFZPct", "0");
-        //本月未巡检组串总数
-        mSummaryMap.put("UncoveredPVString", "0");
-        //本月未巡检组串百分比
-        mSummaryMap.put("UncoveredPVStringPct", "0");
-        //本月未巡检光伏板总数
-        mSummaryMap.put("UncoveredPVPanel", "0");
-        //本月未巡检光伏板百分比
-        mSummaryMap.put("UncoveredPVPanelPct", "0");
+        // 判断无人机任务是否全部覆盖
+        List<Integer> effectiveMission = planePhotoService.getEffectiveMission();
+        if (effectiveMission.size() == 3){
+            //无人机巡检覆盖方阵数
+            mSummaryMap.put("CoveredFZ", "16");
+            //无人机巡检覆盖方阵百分比
+            mSummaryMap.put("CoveredFZPct", "100%");
+            //本月巡检覆盖组串总数
+            mSummaryMap.put("CoveredPVString", "4624");
+            //本月巡检覆盖组串百分比
+            mSummaryMap.put("CoveredPVStringPct", "100%");
+            //本月巡检覆盖光伏板总数
+            mSummaryMap.put("CoveredPVPanel", "124848");
+            //本月巡检覆盖光伏板百分比
+            mSummaryMap.put("CoveredPVPanelPct", "100%");
+            //无人机未巡检方阵数
+            mSummaryMap.put("UncoveredFZ", "0");
+            //无人机未巡检方阵百分比
+            mSummaryMap.put("UnCoveredFZPct", "0%");
+            //本月未巡检组串总数
+            mSummaryMap.put("UncoveredPVString", "0");
+            //本月未巡检组串百分比
+            mSummaryMap.put("UncoveredPVStringPct", "0%");
+            //本月未巡检光伏板总数
+            mSummaryMap.put("UncoveredPVPanel", "0");
+            //本月未巡检光伏板百分比
+            mSummaryMap.put("UncoveredPVPanelPct", "0%");
+        }
 
-        //存在异常方阵数
-        Integer FltFZ =  planePhotoService.getFltFZ();
-        mSummaryMap.put("FltFZ", FltFZ.toString());
-        double FltFZPct = (FltFZ.doubleValue() / 16.0) * 100.0;
-        //存在异常方阵百分比
-        mSummaryMap.put("FltFZPct", Double.toString(FltFZPct));
+//        //查询本月存在异常方阵数
+//        Integer FltFZ =  planePhotoService.getFltFZ();
+//        mSummaryMap.put("FltFZ", FltFZ.toString());
+//        double FltFZPct = (FltFZ.doubleValue() / 16.0) * 100.0;
+//        String format = String.format("%.2f", FltFZPct);
+//        //存在异常方阵百分比
+//        mSummaryMap.put("FltFZPct", format + "%");
 
+        // 获取固定的三条航线下的最新架次id
+        List<PlanePhotoEntity> photoEntityList = planePhotoService.queryNewRecordByMission();
 
+        // 二极管故障
         Integer DioFZ = 0,DioPVString = 0,DioPVPanel = 0;
-        List<PlanePhotoEntity> photoEntityList = planePhotoService.queryNewRecordByMission();
         for (PlanePhotoEntity photoEntity : photoEntityList){
             Integer recordId = photoEntity.getRecordId();
             DioFZ = DioFZ + photoResultMapper.queryFltPz(recordId, "diodeFault").size();
@@ -209,15 +254,15 @@ public class ReportServiceImpl implements IReportService {
         //存在二极管故障的方阵数
         mSummaryMap.put("DioFZ", Integer.toString(DioFZ));
         //存在二极管故障的方阵百分比
-        mSummaryMap.put("DioFZPct", Double.toString((FltFZ.doubleValue() / 16.0) * 100.0));
+        mSummaryMap.put("DioFZPct", String.format("%.2f",(DioFZ.doubleValue() / 16.0) * 100.0) + "%");
         //存在二极管故障的组串总数
         mSummaryMap.put("DioPVString", Integer.toString(DioPVString));
         //存在二极管故障的组串百分比
-        mSummaryMap.put("DioPVStringPct", Double.toString((DioPVString.doubleValue() / 4624.0) * 100.0));
+        mSummaryMap.put("DioPVStringPct", String.format("%.2f",(DioPVString.doubleValue() / 4624.0) * 100.0) + "%");
         //存在二极管故障的光伏板总数
         mSummaryMap.put("DioPVPanel", Integer.toString(DioPVPanel));
         //存在二极管故障的光伏板百分比
-        mSummaryMap.put("DioPVPanelPct", Double.toString((DioPVPanel.doubleValue() / 124848.0) * 100.0));
+        mSummaryMap.put("DioPVPanelPct", String.format("%.2f",(DioPVPanel.doubleValue() / 124848.0) * 100.0) + "%");
 
 
         Integer HtsptFZ = 0,HtsptPVString = 0,HtsptPVPanel = 0;
@@ -230,15 +275,20 @@ public class ReportServiceImpl implements IReportService {
         //存在热斑的方阵数
         mSummaryMap.put("HtsptFZ", Integer.toString(HtsptFZ));
         //存在热斑的方阵百分比
-        mSummaryMap.put("HtsptFZPct", Double.toString((HtsptFZ.doubleValue() / 16.0) * 100.0));
+        if (HtsptFZ > 16){
+            mSummaryMap.put("HtsptFZPct", "100.0" + "%");
+        }else {
+            mSummaryMap.put("HtsptFZPct", String.format("%.2f", (HtsptFZ.doubleValue() / 16.0) * 100.0) + "%" );
+        }
         //存在热斑的组串总数
         mSummaryMap.put("HtsptPVString", Integer.toString(HtsptPVString));
         //存在热斑的组串百分比
-        mSummaryMap.put("HtsptPVStringPct", Double.toString((HtsptPVString.doubleValue() / 4624.0) * 100.0));
+        mSummaryMap.put("HtsptPVStringPct", String.format("%.2f", (HtsptPVString.doubleValue() / 4624.0) * 100.0) + "%");
         //存在热斑的光伏板总数
         mSummaryMap.put("HtsptPVPanel", Integer.toString(HtsptPVPanel));
         //存在热斑的光伏板百分比
-        mSummaryMap.put("HtsptPVPanelPct", Double.toString((HtsptPVPanel.doubleValue() / 124848.0) * 100.0));
+        mSummaryMap.put("HtsptPVPanelPct", String.format("%.2f", (HtsptPVPanel.doubleValue() / 124848.0) * 100.0) + "%");
+
 
         //存在掉串的方阵数
         mSummaryMap.put("OcFZ", "0");
@@ -253,18 +303,39 @@ public class ReportServiceImpl implements IReportService {
         //存在掉串的光伏板百分比
         mSummaryMap.put("OcPVPanelPct", "0%");
 
-
+//        //存在异常组串总数
+//        Integer FltPVString = DioPVString + HtsptPVString;
+//        mSummaryMap.put("FltPVString", String.valueOf(FltPVString));
+//        //存在异常组串百分比
+//        mSummaryMap.put("FltPVStringPct", String.format("%.2f", (FltPVString.doubleValue() / 4624.0) * 100.0) + "%");
+//
+//        //存在异常光伏板总数
+//        Integer FltPVPanel = DioPVPanel + HtsptPVPanel;
+//        mSummaryMap.put("FltPVPanel", String.valueOf(FltPVPanel));
+//        //存在异常光伏板百分比
+//        mSummaryMap.put("FltPVPanelPct", String.format("%.2f", (FltPVPanel.doubleValue() / 124848.0) * 100.0) + "%");
+
+
+        // 存在异常
+        Integer FltFZ = 0, FltPVString = 0, FltPVPanel = 0;
+        for (PlanePhotoEntity photoEntity : photoEntityList){
+            Integer recordId = photoEntity.getRecordId();
+            FltFZ = FltFZ + photoResultMapper.queryFltPz(recordId, null).size();
+            FltPVString = FltPVString + photoResultMapper.queryFltPVString(recordId, null).size();
+            FltPVPanel = FltPVPanel + photoResultMapper.queryFltPVPanel(recordId, null).size();
+        }
+        //存在异常方阵数
+        mSummaryMap.put("FltFZ", Integer.toString(FltFZ));
+        //存在异常方阵百分比
+        mSummaryMap.put("FltFZPct", String.format("%.2f", (FltFZ.doubleValue() / 16.0) * 100.0) + "%");
         //存在异常组串总数
-        Integer FltPVString = DioPVString + HtsptPVString;
-        mSummaryMap.put("FltPVString", String.valueOf(FltPVString));
+        mSummaryMap.put("FltPVString", Integer.toString(FltPVString));
         //存在异常组串百分比
-        mSummaryMap.put("FltPVStringPct", Double.toString((FltPVString.doubleValue() / 4624.0) * 100.0));
-
+        mSummaryMap.put("FltPVStringPct", String.format("%.2f", (FltPVString.doubleValue() / 4624.0) * 100.0) + "%");
         //存在异常光伏板总数
-        Integer FltPVPanel = DioPVPanel + HtsptPVPanel;
-        mSummaryMap.put("FltPVPanel", String.valueOf(FltPVPanel));
+        mSummaryMap.put("FltPVPanel", Integer.toString(FltPVPanel));
         //存在异常光伏板百分比
-        mSummaryMap.put("FltPVPanelPct", Double.toString((FltPVPanel.doubleValue() / 124848.0) * 100.0));
+        mSummaryMap.put("FltPVPanelPct", String.format("%.2f", (FltPVPanel.doubleValue() / 124848.0) * 100.0) + "%");
 
         //下面这些可能要宇峰那边帮忙算
         //二极管故障损失量

+ 50 - 0
src/main/java/com/keystar/plane/inspection/utils/FileUtil.java

@@ -10,7 +10,10 @@ import com.keystar.plane.inspection.bo.NewFileBo;
 import com.keystar.plane.inspection.constant.LocationConstant;
 import lombok.extern.slf4j.Slf4j;
 
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletResponse;
 import java.io.*;
+import java.net.URLEncoder;
 import java.nio.charset.StandardCharsets;
 import java.util.*;
 
@@ -448,4 +451,51 @@ public class FileUtil {
         return recordName;
     }
 
+    /**
+     *  下载文件
+     **/
+    public static void download(HttpServletResponse response, String filePath) throws UnsupportedEncodingException {
+
+        String filename = URLEncoder.encode("无人机巡检报告.doc", "UTF-8");
+
+        response.setContentType("application/x-download");
+        response.setHeader("Content-Disposition", "attachment;filename=" + filename);//浏览器上提示下载时默认的文件名
+
+        try (ServletOutputStream out = response.getOutputStream();
+             InputStream stream = new FileInputStream(filePath)){//读取服务器上的文件
+
+            byte buff[] = new byte[1024];
+            int length = 0;
+            while ((length = stream.read(buff)) > 0) {
+                out.write(buff,0,length);
+            }
+            stream.close();
+            out.close();
+            out.flush();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 从输入流中获取数据
+     *
+     * @param inStream
+     *            输入流
+     * @return
+     * @throws Exception
+     */
+    public static byte[] readInputStream(InputStream inStream) throws IOException {
+        if(inStream == null){
+            return new byte[]{};
+        }
+        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+        byte[] buffer = new byte[10240];
+        int len = 0;
+        while ((len = inStream.read(buffer)) != -1) {
+            outStream.write(buffer, 0, len);
+        }
+        inStream.close();
+        return outStream.toByteArray();
+    }
 }

+ 68 - 68
src/main/java/com/keystar/plane/inspection/utils/FileUtils.java

@@ -11,77 +11,77 @@ import java.util.List;
 import java.util.Map;
 
 public class FileUtils {
-    /**
-     * 从json文件中读取数据
-     */
-    public static String getDataFromJsonFile() throws FileNotFoundException {
-
-        StringBuilder jsonString = new StringBuilder();
-        File file = ResourceUtils.getFile("classpath:pv.json");
-        if (file.exists()) {
-            BufferedReader bufferedReader = null;
-            try {
+//    /**
+//     * 从json文件中读取数据
+//     */
+//    public static String getDataFromJsonFile() throws FileNotFoundException {
+//
+//        StringBuilder jsonString = new StringBuilder();
+//        File file = ResourceUtils.getFile("classpath:pv.json");
+//        if (file.exists()) {
+//            BufferedReader bufferedReader = null;
+//            try {
+////                bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8));
+////                char[] chars = new char[100000];
+////                int length;
+////                while ((length = bufferedReader.read(chars)) != -1) {
+////                    String temp = new String(chars, 0, length);
+////                    jsonString.append(temp);
+////                }
 //                bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8));
-//                char[] chars = new char[100000];
-//                int length;
-//                while ((length = bufferedReader.read(chars)) != -1) {
-//                    String temp = new String(chars, 0, length);
+//                char[] chars =  new char[1000];
+//                while (bufferedReader.read(chars, 0, chars.length) > 0){
+//                    String temp = new String(chars, 0, chars.length);
 //                    jsonString.append(temp);
 //                }
-                bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8));
-                char[] chars =  new char[1000];
-                while (bufferedReader.read(chars, 0, chars.length) > 0){
-                    String temp = new String(chars, 0, chars.length);
-                    jsonString.append(temp);
-                }
-            } catch (IOException e) {
-                System.out.println("=====获取数据异常=====" + e);
-            } finally {
-                if (null != bufferedReader) {
-                    try {
-                        bufferedReader.close();
-                    } catch (IOException ex) {
-                        System.out.println("=======获取数据时,关闭流异常=======" + ex);
-                    }
-                }
-            }
-        }
-        return jsonString.toString();
-    }
-
-
-
-    /**
-     *  读取json文件
-     **/
-    public static String getPVJson() throws IOException {
-        File file = ResourceUtils.getFile("classpath:pv.json");
-        try(FileInputStream fileInputStream = new FileInputStream(file)) {
-            int size = fileInputStream.available();
-            StringBuilder jsonString = new StringBuilder();
-            for (int i = 0; i <= size; i+=1000) {
-                byte[] buffer = new byte[1000];
-                fileInputStream.read(buffer);
-                String str = new String(buffer, StandardCharsets.UTF_8);
-                jsonString.append(str);
-            }
-            return jsonString.toString();
-        }
-    }
-
-    public static Map<String, List> jsonTransData (String payload){
-        JSONObject jsonObject = JSON.parseObject(payload);
-        List<JSONObject> featureList = (List<JSONObject>)jsonObject.get("features");
-        Map<String,List> result = new HashMap<>();
-        for (int i = 0; i<featureList.size(); i++){
-            JSONObject object1 = featureList.get(i);
-            List<List> coordinatesAll = (List<List>) object1.get("coordinates");
-            List<List> coordinates = coordinatesAll.get(0);
-            JSONObject properties = (JSONObject) object1.get("properties");
-            result.put((String) properties.get("名称"),coordinates);
-        }
-        return result;
-    }
+//            } catch (IOException e) {
+//                System.out.println("=====获取数据异常=====" + e);
+//            } finally {
+//                if (null != bufferedReader) {
+//                    try {
+//                        bufferedReader.close();
+//                    } catch (IOException ex) {
+//                        System.out.println("=======获取数据时,关闭流异常=======" + ex);
+//                    }
+//                }
+//            }
+//        }
+//        return jsonString.toString();
+//    }
+//
+//
+//
+//    /**
+//     *  读取json文件
+//     **/
+//    public static String getPVJson() throws IOException {
+//        File file = ResourceUtils.getFile("classpath:pv.json");
+//        try(FileInputStream fileInputStream = new FileInputStream(file)) {
+//            int size = fileInputStream.available();
+//            StringBuilder jsonString = new StringBuilder();
+//            for (int i = 0; i <= size; i+=1000) {
+//                byte[] buffer = new byte[1000];
+//                fileInputStream.read(buffer);
+//                String str = new String(buffer, StandardCharsets.UTF_8);
+//                jsonString.append(str);
+//            }
+//            return jsonString.toString();
+//        }
+//    }
+//
+//    public static Map<String, List> jsonTransData (String payload){
+//        JSONObject jsonObject = JSON.parseObject(payload);
+//        List<JSONObject> featureList = (List<JSONObject>)jsonObject.get("features");
+//        Map<String,List> result = new HashMap<>();
+//        for (int i = 0; i<featureList.size(); i++){
+//            JSONObject object1 = featureList.get(i);
+//            List<List> coordinatesAll = (List<List>) object1.get("coordinates");
+//            List<List> coordinates = coordinatesAll.get(0);
+//            JSONObject properties = (JSONObject) object1.get("properties");
+//            result.put((String) properties.get("名称"),coordinates);
+//        }
+//        return result;
+//    }
 
 
 }

+ 79 - 3
src/main/java/com/keystar/plane/inspection/utils/GisCheckUtils.java

@@ -515,7 +515,7 @@ public class GisCheckUtils {
 
 //            double area = GisCheckUtils.calculatePolygonArea(sortLocation(areaList));
             double area = GisCheckUtils.planarPolygonAreaMeters(sortLocation(areaList));
-            log.info("重合区域面积为: " + area + "平方米");
+//            log.info("重合区域面积为: " + area + "平方米");
             return area;
         }
         //如果不相交判断是否包含-由于没有相交线段只要存在点在多边形内就说明包含
@@ -524,7 +524,7 @@ public class GisCheckUtils {
         if (isPointInPolygon) {
 //            double area = GisCheckUtils.calculatePolygonArea(circleList);
             double area = GisCheckUtils.planarPolygonAreaMeters(circleList);
-            log.info("重合区域面积为: " + area + "平方米");
+//            log.info("重合区域面积为: " + area + "平方米");
             return area;
         }
         //如果不相交判断是否包含-由于没有相交线段只要存在点在多边形内就说明包含
@@ -533,7 +533,7 @@ public class GisCheckUtils {
         if (isPointInPolygon) {
 //            double area = GisCheckUtils.calculatePolygonArea(locationList);
             double area = GisCheckUtils.planarPolygonAreaMeters(locationList);
-            log.info("重合区域面积为: " + area + "平方米");
+//            log.info("重合区域面积为: " + area + "平方米");
             return area;
         }
         return  0;
@@ -739,6 +739,82 @@ public class GisCheckUtils {
         // 转化为正数
         return Math.abs(a / 2);
     }
+    
+    /**
+     *  获取多边形中心点的坐标
+     **/
+    public static Location getCenterPoint(List<Location> locationList) {
+        int total = locationList.size();
+        double X = 0, Y = 0, Z = 0;
+
+//        while(!locationList.isEmpty()) {
+//            Location g = locationList.pollFirst();
+//            if(g != null) {
+//                double lat, lon, x, y, z;
+//                lat = g.getLat() * Math.PI / 180;
+//                lon = g.getLon() * Math.PI / 180;
+//                x = Math.cos(lat) * Math.cos(lon);
+//                y = Math.cos(lat) * Math.sin(lon);
+//                z = Math.sin(lat);
+//                X += x;
+//                Y += y;
+//                Z += z;
+//            }
+//        }
+        for ( Location location : locationList){
+            double lat, lon, x, y, z;
+            lat = location.getLat() * Math.PI / 180;
+            lon = location.getLon() * Math.PI / 180;
+            x = Math.cos(lat) * Math.cos(lon);
+            y = Math.cos(lat) * Math.sin(lon);
+            z = Math.sin(lat);
+            X += x;
+            Y += y;
+            Z += z;
+        }
+
+
+        X = X / total;
+        Y = Y / total;
+        Z = Z / total;
+        double Lon = Math.atan2(Y, X);
+        double Hyp = Math.sqrt(X * X + Y * Y);
+        double Lat = Math.atan2(Z, Hyp);
+        double longitude = Lon * 180 / Math.PI;
+        double latitude = Lat * 180 / Math.PI;
+//        System.out.println("中心点经度:"+longitude);
+//        System.out.println("中心点纬度:"+latitude);
+        Location location = new Location();
+        location.setLat(latitude);
+        location.setLon(longitude);
+        return location;
+    }
+
+    /**
+     *  计算两个坐标点直之间的距离
+     **/
+//    public static double GetDistance(double lon1,double lat1,double lon2, double lat2) {
+//        double radLat1 = rad(lat1);
+//        double radLat2 = rad(lat2);
+//        double a = radLat1 - radLat2;
+//        double b = rad(lon1) - rad(lon2);
+//        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
+//        s = s * EARTH_RADIUS;
+//        s = Math.round(s * 10000) / 10000;
+//        return s;
+//    }
+//
+    public static double GetDistance(Location location1, Location location2){
+        double radLat1 = location1.getLat() * radiansPerDegree;
+        double radLat2 = location2.getLat() * radiansPerDegree;
+        double a = radLat1 - radLat2;
+        double radLon1 = location1.getLon() * radiansPerDegree;
+        double radLon2 = location2.getLon() * radiansPerDegree;
+        double b = radLon1 - radLon2;
+        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
+        s = s * earthRadiusMeters;
+        return Math.round(s * 10000.0) / 10000.0;
+    }
 
 
 }

+ 72 - 2
src/main/java/com/keystar/plane/inspection/utils/PhotoUtils.java

@@ -8,14 +8,24 @@ import com.drew.metadata.Metadata;
 import com.drew.metadata.Tag;
 import com.drew.metadata.exif.GpsDirectory;
 import com.keystar.plane.inspection.bo.Location;
-import com.keystar.plane.inspection.dao.DegreesVo;
-import com.keystar.plane.inspection.dao.PhotoMessageVo;
+import com.keystar.plane.inspection.entity.PlanePhotoEntity;
+import com.keystar.plane.inspection.service.PhotoResultService;
+import com.keystar.plane.inspection.vo.DegreesVo;
+import com.keystar.plane.inspection.vo.PhotoMessageVo;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.util.ResourceUtils;
+import sun.misc.BASE64Encoder;
 
+import javax.imageio.ImageIO;
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.util.ArrayList;
+import java.util.Base64;
 import java.util.Collection;
 import java.util.List;
 
@@ -230,4 +240,64 @@ public class PhotoUtils {
     }
 
 
+    /**
+     * base64 编码转换为 BufferedImage
+     */
+    public static BufferedImage base64ToBufferedImage(String base64) {
+        Base64.Decoder decoder = Base64.getDecoder();
+        try {
+            byte[] bytes = decoder.decode(base64);
+            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
+            return ImageIO.read(byteArrayInputStream);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * 添加边框
+     *
+     * @param image   BufferedImage
+     * @param x 原点x坐标(原点一般在左上角)
+     * @param y 原点y坐标(原点一般在左上角)
+     * @param  width 框宽
+     * @param height 框高
+     * @return
+     */
+    public static BufferedImage addBorders(BufferedImage image, int x, int y, int width, int height) {
+        if (image == null) {
+            return null;
+        }
+        Graphics2D g2 = image.createGraphics();
+        //画笔颜色
+        g2.setColor(Color.RED);
+        //设置画笔粗细
+        BasicStroke stokeLine = new BasicStroke(5.0f);
+        g2.setStroke(stokeLine);
+        //矩形框(原点x坐标,原点y坐标,矩形的长,矩形的宽)
+        g2.drawRect(x, y, width, height);
+        g2.dispose();
+        return image;
+    }
+
+    /**
+     * BufferedImage 编码转换为 base64
+     */
+    public static String bufferedImageToBase64(BufferedImage bufferedImage) {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();//io流
+        try {
+            ImageIO.write(bufferedImage, "png", baos);//写入流中
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        byte[] bytes = baos.toByteArray();//转换成字节
+        BASE64Encoder encoder = new BASE64Encoder();
+        String png_base64 = encoder.encodeBuffer(bytes).trim();//转换成base64串
+        png_base64 = png_base64.replaceAll("\n", "").replaceAll("\r", "");//删除 \r\n
+//        return "data:image/jpg;base64," + png_base64;
+        return png_base64;
+    }
+
+
 }

+ 1 - 3
src/main/java/com/keystar/plane/inspection/dao/DegreesVo.java → src/main/java/com/keystar/plane/inspection/vo/DegreesVo.java

@@ -1,8 +1,6 @@
-package com.keystar.plane.inspection.dao;
+package com.keystar.plane.inspection.vo;
 
 import lombok.Data;
-import lombok.Getter;
-import lombok.Setter;
 
 @Data
 public class DegreesVo {

+ 1 - 1
src/main/java/com/keystar/plane/inspection/dao/LoginVo.java → src/main/java/com/keystar/plane/inspection/vo/LoginVo.java

@@ -1,4 +1,4 @@
-package com.keystar.plane.inspection.dao;
+package com.keystar.plane.inspection.vo;
 
 
 import lombok.Data;

+ 1 - 1
src/main/java/com/keystar/plane/inspection/dao/NestStatusVo.java → src/main/java/com/keystar/plane/inspection/vo/NestStatusVo.java

@@ -1,4 +1,4 @@
-package com.keystar.plane.inspection.dao;
+package com.keystar.plane.inspection.vo;
 
 import lombok.Data;
 

+ 1 - 1
src/main/java/com/keystar/plane/inspection/dao/PhotoMessageVo.java → src/main/java/com/keystar/plane/inspection/vo/PhotoMessageVo.java

@@ -1,4 +1,4 @@
-package com.keystar.plane.inspection.dao;
+package com.keystar.plane.inspection.vo;
 
 import lombok.Data;
 

+ 1 - 1
src/main/java/com/keystar/plane/inspection/dao/PhotoResultVo.java → src/main/java/com/keystar/plane/inspection/vo/PhotoResultVo.java

@@ -1,4 +1,4 @@
-package com.keystar.plane.inspection.dao;
+package com.keystar.plane.inspection.vo;
 
 import com.keystar.plane.inspection.bo.PhotoBo;
 import lombok.Data;

+ 6 - 2
src/main/java/com/keystar/plane/inspection/dao/PlanePhotoVo.java → src/main/java/com/keystar/plane/inspection/vo/PlanePhotoVo.java

@@ -1,8 +1,7 @@
-package com.keystar.plane.inspection.dao;
+package com.keystar.plane.inspection.vo;
 
 import lombok.Data;
 
-import java.util.Date;
 import java.util.List;
 
 @Data
@@ -17,4 +16,9 @@ public class PlanePhotoVo {
      *  光伏板名字
      **/
     private List<String> PVNames;
+
+    /**
+     *  图片中心组串的名字
+     **/
+    private String centerPvName;
 }

+ 10 - 0
src/main/java/com/keystar/plane/inspection/vo/PlaneTaskVo.java

@@ -0,0 +1,10 @@
+package com.keystar.plane.inspection.vo;
+
+import com.keystar.plane.inspection.entity.PlaneTaskEntity;
+import lombok.Data;
+
+@Data
+public class PlaneTaskVo extends PlaneTaskEntity {
+
+    private int numRecords;
+}

+ 31 - 0
src/main/java/com/keystar/plane/inspection/vo/UploadVo.java

@@ -0,0 +1,31 @@
+package com.keystar.plane.inspection.vo;
+
+import cn.hutool.core.util.StrUtil;
+import lombok.Data;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * @author KR0111
+ * @program third-party
+ * @className UploadVo
+ * @description 上传vo对象
+ * @create 2021-10-29 16:08
+ */
+@Data
+public class UploadVo {
+    @NotNull(message = "文件不能为空")
+    private MultipartFile file;
+    @NotNull(message = "储存目录不能为空")
+    private String bucketName;
+    private String resourcePath;
+    private String resourceName;
+
+    public String getPath(){
+        if (StrUtil.isEmpty(resourcePath)){
+            return  resourceName;
+        }
+        return  resourcePath+"/"+resourceName;
+    }
+}

+ 0 - 87
src/main/java/com/keystar/plane/inspection/websocket/BaseWebsocketClient.java

@@ -1,87 +0,0 @@
-//package com.keystar.plane.inspection.websocket;
-//
-//
-//import lombok.extern.slf4j.Slf4j;
-//import org.java_websocket.client.WebSocketClient;
-//import org.java_websocket.drafts.Draft_6455;
-//import org.java_websocket.handshake.ServerHandshake;
-//import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
-//
-//import java.net.URI;
-//import java.util.Map;
-//
-//@Slf4j
-//public class BaseWebsocketClient extends WebSocketClient{
-//    //客户端标识
-//    private String clientName;
-//    //客户端连接状态
-//    private boolean isConnect = false;
-//    //spring包下的线程池类
-//    private ThreadPoolTaskExecutor workPoolScheduler;
-//
-//    public BaseWebsocketClient(URI serverUri) {
-//        super(serverUri);
-//    }
-//
-//    public BaseWebsocketClient(URI serverUri, Map<String, String> httpHeaders,
-//                               String clientName,
-//                               ThreadPoolTaskExecutor workPoolScheduler) {
-//        super(serverUri, new Draft_6455(), httpHeaders, 0);
-//        this.clientName = clientName;
-//        this.workPoolScheduler = workPoolScheduler;
-//    }
-//
-//    @Override
-//    public void onOpen(ServerHandshake serverHandshake) {
-//    }
-//
-//    @Override
-//    public void onMessage(String s) {
-//    }
-//    /***检测到连接关闭之后,会更新连接状态以及尝试重新连接***/
-//    @Override
-//    public void onClose(int i, String s, boolean b) {
-//        log.info("-------连接关闭------");
-//        setConnectState(false);
-//        recontact();
-//    }
-//    /***检测到错误,更新连接状态***/
-//    @Override
-//    public void onError(Exception e) {
-//        log.info("-------连接失败------");
-//        setConnectState(false);
-//    }
-//
-//    public void setConnectState(boolean isConnect) {
-//        this.isConnect = isConnect;
-//    }
-//
-//    public boolean getConnectState(){
-//        return this.isConnect;
-//    }
-//
-//    public ThreadPoolTaskExecutor getWorkPoolScheduler() {
-//        return workPoolScheduler;
-//    }
-//
-//    /**
-//     * 重连
-//     */
-//    public void recontact() {
-//        workPoolScheduler.execute(() -> {
-//            Thread.currentThread().setName( "ReconnectThread-" + Thread.currentThread().getId() );
-//            try {
-//                Thread.sleep(5000);
-//                log.info("重连开始");
-//                if (isConnect) {
-//                    log.info("{} 重连停止", clientName);
-//                    return;
-//                }
-//                this.reconnect();
-//                log.info("重连结束");
-//            } catch (Exception e) {
-//                log.info("{} 重连失败", clientName);
-//            }
-//        });
-//    }
-//}

+ 0 - 44
src/main/java/com/keystar/plane/inspection/websocket/DeviceWebsocketClient.java

@@ -1,44 +0,0 @@
-//package com.keystar.plane.inspection.websocket;
-//
-//import com.fasterxml.jackson.databind.ObjectMapper;
-//
-//import com.keystar.plane.inspection.service.DeviceService;
-//import lombok.extern.slf4j.Slf4j;
-//import org.java_websocket.handshake.ServerHandshake;
-//import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
-//
-//import java.net.URI;
-//import java.util.Map;
-//
-//@Slf4j
-//public class DeviceWebsocketClient extends BaseWebsocketClient{
-//
-//    private static final String clientName = "deviceWebsocketClient";
-//    /*这个订阅格式是实现约定好的,可以具体情况具体分析*/
-//    private String sendStr = "/70ddc6e4-1b3e-4da9-9952-16c04ec5c415/status/media";
-//
-//    public DeviceWebsocketClient(URI serverUri, Map<String, String> httpHeaders, ThreadPoolTaskExecutor workPoolScheduler, DeviceService deviceService) {
-//        super(serverUri, httpHeaders, clientName, workPoolScheduler);
-//    }
-//
-//    public DeviceWebsocketClient(URI serverUri){
-//        super(serverUri);
-//    }
-//
-//    @Override
-//    public void onOpen(ServerHandshake serverHandshake) {
-//        log.info("--------打开连接-------");
-////        this.send(sendStr);
-//        setConnectState(true);
-//    }
-//
-//    @Override
-//    public void onMessage(String msg) {
-//        log.info("-------收到消息---------");
-//        // 收到消息
-//        System.out.println("收到的消息:"+ msg);
-//
-//
-//
-//    }
-//}

+ 31 - 3
src/main/resources/mapper/PlanePhotoMapper.xml

@@ -34,6 +34,8 @@
             kr_plane_photo AS p
         WHERE
             p.pv_name LIKE concat(concat("%",#{pvName}),"%")
+        AND
+            p.array_box != ""
         ORDER BY p.time DESC
         <if test="startIndex != null">
             LIMIT #{startIndex}, #{pageSize}
@@ -74,9 +76,9 @@
         WHERE
             p.id = r.photo_id
         AND
-            `time` >= #{startTime}
+            p.time >= #{startTime}
         AND
-            `time` &lt;= #{endTime}
+            p.time &lt;= #{endTime}
         GROUP BY p.pz_name
     </select>
 
@@ -95,11 +97,37 @@
         SELECT
         *
         FROM
-            `kr_plane_photo`
+            `kr_plane_photo` AS p,
+            `kr_photo_result` AS r
         WHERE
+		    p.id = r.photo_id
+		AND
+			p.center_pv_name != ""
+		AND
             record_id = #{recordId}
+		GROUP BY photo_id
     </select>
 
+    <select id="queryEffectiveMission" resultType="com.keystar.plane.inspection.entity.PlanePhotoEntity" parameterType="com.keystar.plane.inspection.bo.DateBo">
+        SELECT DISTINCT
+            mission_id
+        FROM
+			`kr_plane_photo`
+        WHERE
+			`time` >= #{startTime}
+        AND
+            `time` &lt;= #{endTime}
+    </select>
 
+    <select id="queryMonthRecord" resultType="com.keystar.plane.inspection.entity.PlanePhotoEntity" parameterType="com.keystar.plane.inspection.bo.DateBo">
+        SELECT DISTINCT
+            mission_id, record_id
+        FROM
+			`kr_plane_photo`
+        WHERE
+			`time` >= #{startTime}
+        AND
+            `time` &lt;= #{endTime}
+    </select>
 
 </mapper>

+ 24 - 0
src/main/resources/mapper/PlaneTaskMapper.xml

@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+
+<mapper namespace="com.keystar.plane.inspection.mapper.PlaneTaskMapper">
+
+    <select id="queryAllTask"  resultType="int">
+        SELECT
+            COUNT(DISTINCT mission_id)
+        FROM
+            kr_plane_task
+    </select>
+
+    <select id="queryFinishedTask"  resultType="com.keystar.plane.inspection.vo.PlaneTaskVo" parameterType="com.keystar.plane.inspection.bo.DateBo">
+        SELECT
+            mission_id, COUNT(*) AS num_records
+        FROM
+            kr_plane_task
+        WHERE
+            data BETWEEN #{startTime} AND #{endTime}
+        GROUP BY
+            mission_id;
+    </select>
+
+</mapper>

+ 190 - 26
src/test/java/com/keystar/plane/inspection/PlaneInspectionApplicationTests.java

@@ -1,6 +1,6 @@
 package com.keystar.plane.inspection;
 
-import com.baomidou.mybatisplus.annotation.TableField;
+import cn.hutool.core.util.IdUtil;
 import com.drew.imaging.jpeg.JpegProcessingException;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.jcraft.jsch.JSchException;
@@ -8,11 +8,11 @@ import com.jcraft.jsch.SftpException;
 import com.keystar.plane.inspection.bo.*;
 //import com.keystar.plane.inspection.config.MinIoConfig;
 import com.keystar.plane.inspection.constant.LocationConstant;
-import com.keystar.plane.inspection.constant.MissionConstant;
-import com.keystar.plane.inspection.dao.DegreesVo;
-import com.keystar.plane.inspection.dao.PhotoMessageVo;
-import com.keystar.plane.inspection.dao.PhotoResultVo;
-import com.keystar.plane.inspection.dao.PlanePhotoVo;
+import com.keystar.plane.inspection.entity.PlaneTaskEntity;
+import com.keystar.plane.inspection.mapper.PlaneTaskMapper;
+import com.keystar.plane.inspection.vo.PhotoMessageVo;
+import com.keystar.plane.inspection.vo.PhotoResultVo;
+import com.keystar.plane.inspection.vo.PlanePhotoVo;
 import com.keystar.plane.inspection.entity.PhotoResultEntity;
 import com.keystar.plane.inspection.entity.PlanePhotoEntity;
 import com.keystar.plane.inspection.mapper.PhotoResultMapper;
@@ -20,23 +20,22 @@ import com.keystar.plane.inspection.mapper.PlanePhotoMapper;
 import com.keystar.plane.inspection.mqtt.PlaneMqttHandler;
 import com.keystar.plane.inspection.service.*;
 import com.keystar.plane.inspection.service.impl.MinioService;
-import com.keystar.plane.inspection.service.impl.ReportServiceImpl;
 import com.keystar.plane.inspection.utils.*;
+import com.keystar.plane.inspection.vo.PlaneTaskVo;
 import io.minio.messages.Item;
+import net.coobird.thumbnailator.Thumbnails;
 import org.junit.jupiter.api.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.util.ResourceUtils;
 
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
+import java.awt.image.BufferedImage;
+import java.io.*;
 import java.math.BigDecimal;
 import java.nio.charset.Charset;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.*;
-import java.util.stream.Collectors;
 
 @SpringBootTest
 class PlaneInspectionApplicationTests {
@@ -73,6 +72,13 @@ class PlaneInspectionApplicationTests {
 
 	@Autowired
     PlanePhotoService planePhotoService;
+
+    @Autowired
+    PlaneTaskService planeTaskService;
+
+    @Autowired
+    PlaneTaskMapper planeTaskMapper;
+
 //
 //	@Test
 //	void contextLoads() {
@@ -349,16 +355,6 @@ class PlaneInspectionApplicationTests {
         System.out.println(Charset.defaultCharset());
     }
 
-    /**
-     * 根据图片中的某个坐标求解出对应的经纬度坐标
-     **/
-    @Test
-    public void testPhoto() throws IOException, JpegProcessingException {
-        // 获取图片中的信息
-        PhotoMessageVo photoMessage = PhotoUtils.getPhotoMessage("F:\\1871\\1871\\方阵13-16巡检任务0224-2023-02-26-15-21-02-DJI_20230226144408_0040_THRM.jpg");
-        Location pointLocation = PhotoUtils.getPointLocation(569.0,409.0 , photoMessage);
-        System.out.println(""+ pointLocation.toString());
-    }
 
     @Test
     public void testMapper(){
@@ -436,17 +432,185 @@ class PlaneInspectionApplicationTests {
     }
 
     @Test
-    public void testgetHour(){
+    public void testgetHour() throws IOException {
         List<PlaneInspectionResultBo> planeInspectionResultBos = photoResultService.listInspectionResult();
         System.out.println(planeInspectionResultBos);
     }
 
-    /*@Test
+    @Test
     public void testFile(){
-        String url = "F:/photo" + "/nest/photo/2420/1887/方阵13-16巡检任务0224-2023-03-04-11-04-02-DJI_20230304103720_0025_Z.JPG";
-        String s = reportService.pic2Base64FromPath(url);
+        String t = photoResultService.pic2Base64FromMinio("/nest/photo/2420/1872/方阵13-16巡检任务0224-2023-02-26-15-18-29-DJI_20230226144300_0006_THRM.jpg");
+        System.out.println(t);
+        String z = photoResultService.pic2Base64FromMinio("/nest/photo/2420/1872/方阵13-16巡检任务0224-2023-02-26-15-18-34-DJI_20230226144302_0006_ZOOM.jpg");
+        System.out.println(z);
+    }
+
+    @Test
+    public void removeExif() throws IOException {
+//        try (
+//                FileInputStream is = new FileInputStream(new File("/path/to/photo.jpg"));
+//                FileOutputStream os = new FileOutputStream(new File("/path/to/photo_without.jpg"))) {
+//
+//            new ExifRewriter().removeExifMetadata(is, os);
+//        }
+//        catch (IOException | ImageWriteException | ImageReadException e) {
+//            System.err.println(e);
+//        }
+
+//        BufferedImage image = ImageIO.read(new File("C:\\Users\\KR0282\\Desktop\\1872\\方阵13-16巡检任务0224-2023-02-26-15-18-29-DJI_20230226144300_0006_THRM.png"));
+//        ImageIO.write(image, "png", new File("C:\\Users\\KR0282\\Desktop\\output.png"));
+
+        Thumbnails.of(new File("C:\\Users\\KR0282\\Desktop\\1872\\方阵13-16巡检任务0224-2023-02-26-15-18-29-DJI_20230226144300_0006_THRM.png"))
+                .scale(1f) //图片大小(长宽)压缩比例 从0-1,1表示原图
+                .outputQuality(0.25f) //图片质量压缩比例 从0-1,越接近1质量越好
+                .toOutputStream(new FileOutputStream("C:\\Users\\KR0282\\Desktop\\1872\\output.png"));
+    }
+
+    @Test
+    public void testM(){
+        List<PlanePhotoEntity> photoEntityList = planePhotoMapper.queryPhotoByRecordId(1887);
+        System.out.println(photoEntityList.size());
+    }
+
+    /**
+     * 根据图片中的某个坐标求解出对应的经纬度坐标
+     **/
+    @Test
+    public void testPhoto() throws IOException, JpegProcessingException {
+        // 获取图片中的信息
+        PhotoMessageVo photoMessage = PhotoUtils.getPhotoMessage("F:\\photo\\nest\\photo\\2420\\1889\\方阵13-16巡检任务0224-2023-03-05-09-59-08-DJI_20230305093644_0054_T.JPG");
+        Location pointLocation = PhotoUtils.getPointLocation(370.0,342.0 , photoMessage);
+        PlanePhotoVo planePhotoVo = photoService.queryPhoto(photoMessage, pointLocation);
+        System.out.println(planePhotoVo.toString());
+        // PlanePhotoVo(PZName=FZ15, PVNames=[15HL02-03    15HL02-04])
+    }
+
+    /**
+     *  测试获取多边形的中心点坐标
+     **/
+    @Test
+    public void testUtil(){
+        Map<String, List<Location>> fz15 = LocationConstant.PVLocation.get("15");
+        List<Location> locations = fz15.get("15HL05-03    15HL05-04");
+        System.out.println(locations.toString());
+        Location centerPoint = GisCheckUtils.getCenterPoint(locations);
+    }
+
+    /**
+     *  测试计算两个坐标点的距离
+     **/
+    @Test
+    public void testDistance() throws IOException, JpegProcessingException {
+        PhotoMessageVo photoMessage = PhotoUtils.getPhotoMessage("F:\\photo\\nest\\photo\\2420\\1889\\方阵13-16巡检任务0224-2023-03-05-09-59-08-DJI_20230305093644_0054_T.JPG");
+        Location pointLocation = PhotoUtils.getPointLocation(370.0,342.0 , photoMessage);
+        Location location = new Location();
+        location.setLat(photoMessage.getLatitude());
+        location.setLon(photoMessage.getLongitude());
+        double v = GisCheckUtils.GetDistance(pointLocation, location);
+        System.out.println(v);
+    }
+
+    /**
+     *  测试在图片上画框
+     **/
+    @Test
+    public void testDrawPhoto(){
+        // 获取图片(base64)
+        String photo = photoResultService.pic2Base64FromMinio("/nest/photo/2420/1889/方阵13-16巡检任务0224-2023-03-05-10-01-20-DJI_20230305093732_0078_T.JPG");
+        // base64 转 BufferedImage
+        BufferedImage bufferedImage = PhotoUtils.base64ToBufferedImage(photo);
+        // 画框
+        bufferedImage  = PhotoUtils.addBorders(bufferedImage, 70, 90, 529, 83);
+        bufferedImage = PhotoUtils.addBorders(bufferedImage, 65, 208, 532, 122);
+        bufferedImage = PhotoUtils.addBorders(bufferedImage, 67, 328, 526, 122);
+        // BufferedImage 转 base64
+        String s = PhotoUtils.bufferedImageToBase64(bufferedImage);
         System.out.println(s);
-    }*/
 
+    }
+    /**
+     *  测试在图片上画框2
+     **/
+    @Test
+    public void testDrawPhoto2() throws IOException {
+        PlanePhotoEntity photo = planePhotoService.getById(1636282722097131520L);
+        String s = photoService.addBorderToBase64(photo);
+        System.out.println(s);
+    }
+
+    /**
+     *  获取全部光伏板的异常数
+     **/
+    @Test
+    public void abnormalPanel(){
+        List<PhotoResultEntity> covered = photoResultMapper.queryFltPVPanel(1889, "diodeFault");
+        System.out.println(covered.size());
+    }
+
+    /**
+     *  查询本月飞过的航线
+     **/
+    @Test
+    public void effectiveMission() throws ParseException {
+        DateBo monthDay = Utils.getMonthDay();
+        List<PlanePhotoEntity> photoEntityList = planePhotoMapper.queryEffectiveMission(monthDay);
+        System.out.println(photoEntityList.size());
+    }
+
+    /**
+     *  测试报告异常数
+     **/
+    @Test
+    public void reportAbnormal() throws ParseException {
+        Integer FltFZ =  planePhotoService.getFltFZ();
+    }
 
+    @Test
+    public void testQueryRecord() throws ParseException {
+        DateBo monthDay = new DateBo();
+        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        String start = "2023-03-01 00:00:00";
+        String end = "2023-03-30 23:59:59";
+        monthDay.setStartTime(dateFormat.parse(start));
+        monthDay.setEndTime(dateFormat.parse(end));
+        List<PlanePhotoEntity> photoEntityList = planePhotoMapper.queryMonthRecord(monthDay);
+        System.out.println(photoEntityList.size());
+    }
+
+    @Test
+    public void addTask(){
+        PlaneTaskEntity planeTaskEntity = new PlaneTaskEntity();
+        planeTaskEntity.setId(IdUtil.getSnowflake().nextId());
+        planeTaskEntity.setMissionId(1111);
+        planeTaskEntity.setRecordId(22222);
+        planeTaskEntity.setData(new Date());
+        planeTaskService.insertTask(planeTaskEntity);
+    }
+
+    @Test
+    public void TaskMapper() throws ParseException {
+        int i = planeTaskMapper.queryAllTask();
+        System.out.println(i);
+
+        DateBo monthDay = new DateBo();
+        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        String start = "2023-05-08 00:00:00";
+        String end = "2023-05-09 23:59:59";
+        monthDay.setStartTime(dateFormat.parse(start));
+        monthDay.setEndTime(dateFormat.parse(end));
+        List<PlaneTaskVo> planeTaskVoList = planeTaskMapper.queryFinishedTask(monthDay);
+        System.out.println(planeTaskVoList);
+    }
+
+    @Test
+    public void setPlaneTaskService() throws Exception {
+        DateBo monthDay = new DateBo();
+        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        String start = "2023-05-08 00:00:00";
+        String end = "2023-05-11 23:59:59";
+        monthDay.setStartTime(dateFormat.parse(start));
+        monthDay.setEndTime(dateFormat.parse(end));
+        PlaneInspectionBo inspection = nestService.getInspection(monthDay);
+        System.out.println(inspection);
+    }
 }