package com.ard.work.service.impl;
|
|
import com.ard.common.utils.DateUtils;
|
import com.ard.common.utils.StringUtils;
|
import com.ard.common.utils.file.MimeTypeUtils;
|
import com.ard.common.utils.uuid.IdUtils;
|
import com.ard.oss.service.IOssService;
|
import com.ard.oss.service.impl.OssServiceContext;
|
import com.ard.work.component.forest.TyClient;
|
import com.ard.work.domain.dto.BoxHistoryDTO;
|
import com.ard.work.domain.dto.BoxPhotosDTO;
|
import com.ard.work.domain.entity.ArdFlightTask;
|
import com.ard.work.domain.entity.ArdMedia;
|
import com.ard.work.domain.receiver.BoxHistoryReceiver;
|
import com.ard.work.domain.receiver.BoxPhotosReceiver;
|
import com.ard.work.domain.receiver.TyHttpCommonReceiver;
|
import com.ard.work.mapper.ArdFlightTaskMapper;
|
import com.ard.work.mapper.ArdMediaMapper;
|
import com.ard.work.service.IArdFlightTaskService;
|
import com.ard.work.service.IArdServerInfoService;
|
import org.apache.commons.io.FilenameUtils;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.scheduling.annotation.Async;
|
import org.springframework.scheduling.annotation.Scheduled;
|
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
import org.springframework.stereotype.Service;
|
import org.springframework.web.multipart.MultipartFile;
|
|
import javax.annotation.Resource;
|
import javax.net.ssl.*;
|
import java.io.InputStream;
|
import java.net.URL;
|
import java.util.Date;
|
import java.util.List;
|
import java.util.Objects;
|
import java.util.concurrent.CompletableFuture;
|
|
@Service
|
public class ArdFlightTaskServiceServiceImpl implements IArdFlightTaskService {
|
|
@Resource
|
private ArdFlightTaskMapper ardFlightTaskMapper;
|
@Resource
|
private ArdMediaMapper ardMediaMapper;
|
@Resource
|
private IArdServerInfoService ardServerInfoService;
|
@Resource
|
private TyClient tyClient;
|
@Resource
|
private OssServiceContext ossServiceContext;
|
|
@Resource
|
private ThreadPoolTaskExecutor threadPoolTaskExecutor; // 使用线程池执行异步任务
|
|
@Override
|
public List<ArdFlightTask> selectArdFlightTask(ArdFlightTask ardFlightTask) {
|
return ardFlightTaskMapper.selectArdFlightTask(ardFlightTask);
|
}
|
|
// 同步所有服务的飞行历史
|
@Scheduled(fixedDelay = 10000)
|
public void syncAllFlightHistory() {
|
List<String> serverIds = ardServerInfoService.getServerIdsList();
|
for (String serverId : serverIds) {
|
// 获取上次同步的时间(即数据库中最大 startTime)
|
Date lastSyncTime = getLastSyncTimeForServer(serverId);
|
// 根据上次同步时间同步飞行历史
|
syncFlightHistory(serverId, lastSyncTime);
|
}
|
}
|
|
// 获取上次同步时间(获取最大 startTime)
|
private Date getLastSyncTimeForServer(String serverId) {
|
Date maxStartTime = ardFlightTaskMapper.findMaxStartTimeByServerId(serverId);
|
return maxStartTime != null ? maxStartTime : new Date(0); // 如果没有数据,返回 Unix 纪元时间作为起点
|
}
|
|
// 调用接口获取飞行历史数据
|
// 根据上次同步时间同步飞行历史
|
public void syncFlightHistory(String serverId, Date lastSyncTime) {
|
// 创建查询条件 BoxHistoryDTO,并设置 startTime 作为过滤条件
|
BoxHistoryDTO boxHistoryDTO = new BoxHistoryDTO();
|
boxHistoryDTO.setStartTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, lastSyncTime)); // 传递 lastSyncTime 参数
|
|
// 获取飞行历史
|
List<BoxHistoryReceiver> historyList = getBoxHistory(serverId, boxHistoryDTO);
|
|
// 如果获取到数据,处理并同步到本地数据库
|
if (historyList != null && !historyList.isEmpty()) {
|
for (BoxHistoryReceiver boxHistory : historyList) {
|
syncToLocalDatabase(serverId, boxHistory);
|
}
|
}
|
}
|
|
// 调用接口获取飞行历史数据
|
private List<BoxHistoryReceiver> getBoxHistory(String serverId, BoxHistoryDTO boxHistoryDTO) {
|
TyHttpCommonReceiver<List<BoxHistoryReceiver>> boxHistory = tyClient.getBoxHistory(serverId, boxHistoryDTO);
|
return boxHistory.getContent();
|
}
|
|
// 将数据同步到本地数据库
|
private void syncToLocalDatabase(String serverId, BoxHistoryReceiver boxHistoryReceiver) {
|
// 创建FlightTask实体对象并填充数据
|
ArdFlightTask flightTask = new ArdFlightTask();
|
flightTask.setTaskId(boxHistoryReceiver.getTaskId());
|
flightTask.setBoxSn(boxHistoryReceiver.getBoxSn());
|
flightTask.setBoxName(boxHistoryReceiver.getBoxName());
|
flightTask.setTaskName(boxHistoryReceiver.getTaskName());
|
|
Integer photoCount = Integer.parseInt(boxHistoryReceiver.getPhotoCount());
|
flightTask.setPhotoCount(photoCount);
|
|
Integer videoCount = (boxHistoryReceiver.getVideoPathList() != null) ?
|
boxHistoryReceiver.getVideoPathList().size() : 0;
|
flightTask.setVideoCount(videoCount);
|
|
flightTask.setVideoPath(boxHistoryReceiver.getVideoPath());
|
flightTask.setServerId(serverId);
|
|
Date startTime = DateUtils.dateTime(DateUtils.YYYY_MM_DD_HH_MM_SS, boxHistoryReceiver.getStartTime());
|
flightTask.setStartTime(startTime);
|
|
Date endTime = DateUtils.dateTime(DateUtils.YYYY_MM_DD_HH_MM_SS, boxHistoryReceiver.getEndTime());
|
flightTask.setEndTime(endTime);
|
|
flightTask.setCreateTime(DateUtils.getNowDate());
|
|
// 检查是否已经存在相同任务ID的记录
|
ArdFlightTask ardFlightTaskById = ardFlightTaskMapper.getArdFlightTaskById(flightTask.getTaskId());
|
if (ardFlightTaskById != null) {
|
return;
|
}
|
|
System.out.println("Syncing task " + boxHistoryReceiver.getTaskId());
|
|
// 插入新记录
|
int rows = ardFlightTaskMapper.insertArdFlightTask(flightTask);
|
if (rows > 0) {
|
// 删除旧的媒体记录,防止重复插入
|
ardMediaMapper.deleteArdMediaByTaskId(flightTask.getTaskId());
|
|
// 插入视频
|
syncVideoToDatabase(flightTask, boxHistoryReceiver.getVideoPathList());
|
|
// 插入图片
|
syncPhotoToDatabase(flightTask, serverId, boxHistoryReceiver.getBoxSn());
|
}
|
}
|
|
// 插入视频记录
|
private void syncVideoToDatabase(ArdFlightTask flightTask, List<String> videoPathList) {
|
if (videoPathList != null && !videoPathList.isEmpty()) {
|
for (String videoPath : videoPathList) {
|
|
ArdMedia ardMedia = new ArdMedia();
|
ardMedia.setId(IdUtils.simpleUUID());
|
ardMedia.setTaskId(flightTask.getTaskId());
|
ardMedia.setMediaType(1); // 1表示视频
|
ardMedia.setSourceUrl(videoPath);
|
// 异步上传文件到OSS,并在上传完成后插入数据库
|
CompletableFuture.supplyAsync(() -> uploadFileToOss(flightTask.getBoxSn(), videoPath, "record",
|
MimeTypeUtils.VIDEO_MP4), threadPoolTaskExecutor)
|
.thenAccept(url -> {
|
ardMedia.setMediaUrl(url); // 获取上传后的文件 URL
|
ardMedia.setCreateTime(new Date());
|
ardMediaMapper.insertArdMedia(ardMedia); // 插入数据库
|
});
|
}
|
}
|
}
|
|
// 插入图片记录
|
private void syncPhotoToDatabase(ArdFlightTask flightTask, String serverId, String boxSn) {
|
// 查询图片
|
BoxPhotosDTO boxPhotosDTO = new BoxPhotosDTO();
|
boxPhotosDTO.setTaskId(flightTask.getTaskId());
|
boxPhotosDTO.setBoxSn(boxSn);
|
boxPhotosDTO.setPageIndex(1);
|
boxPhotosDTO.setPageSize(1000);
|
|
TyHttpCommonReceiver<List<BoxPhotosReceiver>> boxPhotos = tyClient.getBoxPhotos(serverId, boxPhotosDTO);
|
List<BoxPhotosReceiver> photoList = boxPhotos.getContent();
|
|
if (photoList != null && !photoList.isEmpty()) {
|
for (BoxPhotosReceiver photo : photoList) {
|
ArdMedia ardMedia = new ArdMedia();
|
ardMedia.setId(IdUtils.simpleUUID());
|
ardMedia.setTaskId(flightTask.getTaskId());
|
ardMedia.setMediaType(0); // 0表示图片
|
ardMedia.setFileSize(photo.getFileSize());
|
ardMedia.setFileMd5(photo.getFileMd5());
|
ardMedia.setSourceUrl(photo.getImgUrl());
|
// 异步上传文件到OSS,并在上传完成后插入数据库
|
CompletableFuture.supplyAsync(() -> uploadFileToOss(flightTask.getBoxSn(), photo.getImgUrl(), "pic",
|
MimeTypeUtils.IMAGE_JPG), threadPoolTaskExecutor)
|
.thenAccept(url -> {
|
ardMedia.setMediaUrl(url); // 获取上传后的文件 URL
|
ardMedia.setCreateTime(new Date());
|
ardMediaMapper.insertArdMedia(ardMedia); // 插入数据库
|
});
|
}
|
}
|
}
|
|
// 通用的上传方法,支持视频和图片等文件上传
|
public String uploadFileToOss(String boxSn, String fileUrl, String bucket, String contentType) {
|
InputStream fileInputStream = null;
|
String fileOssUrl = "";
|
try {
|
// 创建信任所有证书的SSLContext
|
TrustManager[] trustAllCerts = new TrustManager[]{
|
new X509TrustManager() {
|
@Override
|
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
|
return null;
|
}
|
|
@Override
|
public void checkClientTrusted(
|
java.security.cert.X509Certificate[] certs, String authType) {
|
}
|
|
@Override
|
public void checkServerTrusted(
|
java.security.cert.X509Certificate[] certs, String authType) {
|
}
|
}
|
};
|
|
SSLContext sc = SSLContext.getInstance("SSL");
|
sc.init(null, trustAllCerts, new java.security.SecureRandom());
|
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
|
|
// 创建所有主机名都信任的HostnameVerifier
|
HostnameVerifier allHostsValid = new HostnameVerifier() {
|
@Override
|
public boolean verify(String hostname, SSLSession session) {
|
return true;
|
}
|
};
|
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
|
|
// 现在可以正常访问
|
|
// 从URL创建InputStream
|
URL url = new URL(fileUrl);
|
fileInputStream = url.openStream();
|
|
// 文件名
|
String fileName = boxSn + "/" + IdUtils.fastSimpleUUID() + "." + MimeTypeUtils.getExtension(contentType);
|
|
// 调用OSS服务上下文进行文件上传
|
fileOssUrl = ossServiceContext.upload(bucket, fileName, fileInputStream, contentType);
|
|
} catch (Exception e) {
|
e.printStackTrace();
|
// 异常处理,可以选择记录日志或者抛出业务异常
|
} finally {
|
// 关闭InputStream
|
if (fileInputStream != null) {
|
try {
|
fileInputStream.close();
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
}
|
}
|
|
return fileOssUrl; // 返回上传后的文件OSS URL
|
}
|
|
}
|