Browse Source

面积统计任务

master
zhangyeguang 2 months ago
parent
commit
48471f4170
  1. 36
      social/src/main/java/com/jiagutech/ams/listener/JobFinishListener.java
  2. 116
      social/src/main/java/com/jiagutech/ams/scheduled/JobScheduled.java
  3. 2
      social/src/main/java/com/jiagutech/ams/service/JobService.java
  4. 1
      social/src/main/java/com/jiagutech/ams/service/JobServiceImpl.java
  5. 3
      system/src/main/java/com/jiagutech/ams/controller/CommonController.java
  6. 2
      web/src/main/java/com/jiagutech/ams/SocialApplication.java

36
social/src/main/java/com/jiagutech/ams/listener/JobFinishListener.java

@ -7,6 +7,7 @@ import com.jiagutech.ams.mapper.JobMapper;
import com.jiagutech.ams.model.TrackItem;
import com.jiagutech.ams.model.dto.DeviceDTO;
import com.jiagutech.ams.model.dto.JobDTO;
import com.jiagutech.ams.scheduled.JobScheduled;
import com.jiagutech.ams.service.JobService;
import com.jiagutech.ams.utils.FlightTrackerUtils;
import lombok.RequiredArgsConstructor;
@ -20,6 +21,9 @@ import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* @ClassName JobFinishListener
@ -35,7 +39,8 @@ public class JobFinishListener {
private final JobService jobService;
private final JobMapper jobMapper;
private final DeviceMapper deviceMapper;
private final ScheduledExecutorService taskScheduler = Executors.newScheduledThreadPool(1);
private final JobScheduled jobScheduled;
@Async
@EventListener(JobFinishEvent.class)
public void finishJob(JobFinishEvent event) {
@ -48,39 +53,12 @@ public class JobFinishListener {
Instant instant2 = Instant.ofEpochMilli(endTime);
Duration duration = Duration.between(instant1, instant2);
jobDTO.setDuration((int) duration.toSeconds());
List<TrackItem> trackList = jobService.getTrackList(event.getJobId());
if (CollectionUtil.isNotEmpty(trackList)) {
jobDTO.setArea(calculateArea(trackList));
TrackItem trackItem = trackList.get(trackList.size() - 1);
jobDTO.setLat(trackItem.getLat()).setLng(trackItem.getLng());
DeviceDTO deviceDTO = new DeviceDTO().setId(jobDTO.getDeviceId()).setLat(trackItem.getLat()).setLng(trackItem.getLng()).setUpdateTime(trackItem.getTimestamp());
deviceMapper.updateById(deviceDTO);
}
jobMapper.updateById(jobDTO);
jobScheduled.handleArea(jobDTO, 0);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public float calculateArea(List<TrackItem> trackList) {
try {
if (CollectionUtil.isEmpty(trackList)) {
return 0.0f;
}
List<FlightTrackerUtils.PointTemp> pointTemps = trackList.stream().map(item -> {
LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(item.getTimestamp()), ZoneId.systemDefault());
int speed = Math.round(item.getVelocity() * 5 / 18);
return new FlightTrackerUtils.PointTemp(localDateTime, item.getLat(), item.getLng(), speed);
}).toList();
if (CollectionUtil.isEmpty(pointTemps)) {
return 0.0f;
}
return (float) FlightTrackerUtils.calculateArea(pointTemps);
} catch (Exception e) {
log.error("calculate area error", e);
return 0.0f;
}
}
}

116
social/src/main/java/com/jiagutech/ams/scheduled/JobScheduled.java

@ -0,0 +1,116 @@
package com.jiagutech.ams.scheduled;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.jiagutech.ams.mapper.DeviceMapper;
import com.jiagutech.ams.mapper.JobMapper;
import com.jiagutech.ams.model.TrackItem;
import com.jiagutech.ams.model.common.PageRequest;
import com.jiagutech.ams.model.common.PageResult;
import com.jiagutech.ams.model.dto.DeviceDTO;
import com.jiagutech.ams.model.dto.JobDTO;
import com.jiagutech.ams.model.request.JobPageRequest;
import com.jiagutech.ams.model.response.JobItem;
import com.jiagutech.ams.service.JobService;
import com.jiagutech.ams.utils.FlightTrackerUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.*;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@Slf4j
@Component
@RequiredArgsConstructor
public class JobScheduled {
private final JobService jobService;
private final JobMapper jobMapper;
private final DeviceMapper deviceMapper;
private final ScheduledExecutorService taskScheduler = Executors.newScheduledThreadPool(1);
@Scheduled(cron = "0 20 0 * * ?")
public void cronTask() {
log.info("定时任务执行");
// 获取当天零点
LocalDate today = LocalDate.now();
LocalDateTime todayStart = today.atStartOfDay();
long jobQueryEndTime = todayStart.toEpochSecond(ZoneOffset.ofHours(8)) * 1000;
// 获取前一天零点
LocalDate yesterday = today.minusDays(1);
LocalDateTime yesterdayStart = yesterday.atStartOfDay();
long jobQueryStartTime = yesterdayStart.toEpochSecond(ZoneOffset.ofHours(8)) * 1000;
QueryWrapper<JobDTO> queryWrapper = Wrappers.query();
queryWrapper.between("start_time", jobQueryStartTime, jobQueryEndTime);
queryWrapper.eq("status", 2);
queryWrapper.eq("area", 0);
List<JobDTO> jobDTOS = jobMapper.selectList(queryWrapper);
for (JobDTO jobDTO : jobDTOS) {
Long startTime = jobDTO.getStartTime();
Long endTime = System.currentTimeMillis();
Instant instant1 = Instant.ofEpochMilli(startTime);
Instant instant2 = Instant.ofEpochMilli(endTime);
List<TrackItem> trackList = jobService.getTrackList(jobDTO.getId());
if (CollectionUtil.isEmpty(trackList)) {
continue;
}
update(jobDTO, trackList);
}
}
public void handleArea(JobDTO jobDTO, int retryCount) {
log.info("job:{}去获取轨迹计算作业面积,当前重试次数:{}", jobDTO.getId(), retryCount);
List<TrackItem> trackList = jobService.getTrackList(jobDTO.getId());
if (CollectionUtil.isNotEmpty(trackList)) {
update(jobDTO, trackList);
} else {
if (retryCount < 3) {
int[] retryDelays = {60, 120, 300};
int delay = retryDelays[retryCount];
taskScheduler.schedule(() -> handleArea(jobDTO, retryCount + 1), delay, TimeUnit.SECONDS);
} else {
log.info("job:{}达到最大重试次数,面积计算未成功,终止任务", jobDTO.getId());
}
}
}
private void update(JobDTO jobDTO, List<TrackItem> trackList) {
jobDTO.setArea(calculateArea(trackList));
TrackItem trackItem = trackList.get(trackList.size() - 1);
jobDTO.setLat(trackItem.getLat()).setLng(trackItem.getLng());
DeviceDTO deviceDTO = new DeviceDTO().setId(jobDTO.getDeviceId()).setLat(trackItem.getLat()).setLng(trackItem.getLng()).setUpdateTime(trackItem.getTimestamp());
deviceMapper.updateById(deviceDTO);
jobMapper.updateById(jobDTO);
}
private float calculateArea(List<TrackItem> trackList) {
try {
if (CollectionUtil.isEmpty(trackList)) {
return 0.0f;
}
List<FlightTrackerUtils.PointTemp> pointTemps = trackList.stream().map(item -> {
LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(item.getTimestamp()), ZoneId.systemDefault());
int speed = Math.round(item.getVelocity() * 5 / 18);
return new FlightTrackerUtils.PointTemp(localDateTime, item.getLat(), item.getLng(), speed);
}).toList();
if (CollectionUtil.isEmpty(pointTemps)) {
return 0.0f;
}
return (float) FlightTrackerUtils.calculateArea(pointTemps);
} catch (Exception e) {
log.error("calculate area error", e);
return 0.0f;
}
}
}

2
social/src/main/java/com/jiagutech/ams/service/JobService.java

@ -32,4 +32,6 @@ public interface JobService {
List<TrackItem> getTrackList(Long jobId);
void saveJobImages(TrackImageVO trackImageDTO);
}

1
social/src/main/java/com/jiagutech/ams/service/JobServiceImpl.java

@ -169,6 +169,7 @@ public class JobServiceImpl implements JobService {
QueryWrapper<DeviceDTO> query = Wrappers.query();
DeviceDTO deviceDTO = deviceMapper.selectOne(query.eq("box_num", trackImageDTO.getBoxNum()));
if (ObjectUtil.isNotEmpty(deviceDTO)) {
log.info("去保存作业图片,boxNum:{}", deviceDTO.getBoxNum());
trackImageDTO.setDeviceId(deviceDTO.getId());
trackImageMapper.insert(trackImageDTO);
}

3
system/src/main/java/com/jiagutech/ams/controller/CommonController.java

@ -12,6 +12,7 @@ import com.jiagutech.ams.model.response.CaptchaVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@ -31,6 +32,7 @@ import java.time.Duration;
@RestController
@RequiredArgsConstructor
@Tag(name = "基础", description = "基础功能")
@Slf4j
public class CommonController {
private final RedisTemplate redisTemplate;
@ -46,6 +48,7 @@ public class CommonController {
String code = RandomUtil.randomNumbers(4);
Image image = lineCaptcha.createImage(code);
String base64 = ImgUtil.toBase64(image, "jpg");
log.info("验证码:{}", code);
redisTemplate.opsForValue().set(verifyKey, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION));
captchaVo.setUuid(uuid);
captchaVo.setImg(base64);

2
web/src/main/java/com/jiagutech/ams/SocialApplication.java

@ -3,6 +3,7 @@ package com.jiagutech.ams;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
/**
* @ClassName SocialApplication
@ -12,6 +13,7 @@ import org.springframework.scheduling.annotation.EnableAsync;
* @description:
**/
@EnableAsync
@EnableScheduling
@SpringBootApplication
public class SocialApplication {
public static void main(String[] args) {

Loading…
Cancel
Save