定位器
parent
dc4b0143e0
commit
ee1bcefc9f
|
|
@ -2,9 +2,9 @@ package com.njzscloud.common.localizer;
|
|||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.njzscloud.common.localizer.contant.LocalizerType;
|
||||
import com.njzscloud.common.mqtt.util.Mqtt;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
|
|
@ -19,7 +19,7 @@ public class DeviceStore {
|
|||
private static final Lock localizersReadLock = localizersLock.readLock();
|
||||
|
||||
public static void init() {
|
||||
Mqtt.publish("localizer/loader");
|
||||
// Mqtt.publish("localizer/loader");
|
||||
}
|
||||
|
||||
public static void setLocalizers(List<Localizer> list) {
|
||||
|
|
@ -61,4 +61,8 @@ public class DeviceStore {
|
|||
return null;
|
||||
}
|
||||
|
||||
public static Collection<Localizer> list() {
|
||||
return CollUtil.unmodifiable(localizers);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ public class TokenHandshakeInterceptor implements HandshakeInterceptor {
|
|||
try {
|
||||
HttpServletRequest req = ((ServletServerHttpRequest) request).getServletRequest();
|
||||
String authorization = req.getParameter(Authorization);
|
||||
if (StrUtil.isBlank(authorization)) return false;
|
||||
// if (StrUtil.isBlank(authorization)) return false;
|
||||
|
||||
Tuple2<Long, String> resolved = this.resolve(authorization);
|
||||
if (resolved == null) return false;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,226 @@
|
|||
package com.njzscloud.localizer.config;
|
||||
|
||||
import cn.hutool.core.thread.ThreadUtil;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.metadata.OrderItem;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.njzscloud.common.core.ex.ExceptionMsg;
|
||||
import com.njzscloud.common.core.thread.ThreadPool;
|
||||
import com.njzscloud.common.core.tuple.Tuple2;
|
||||
import com.njzscloud.common.core.utils.CoordinateConverter;
|
||||
import com.njzscloud.common.core.utils.R;
|
||||
import com.njzscloud.common.ws.support.Websocket;
|
||||
import com.njzscloud.common.ws.support.WsMsg;
|
||||
import com.njzscloud.localizer.device.service.LocalizerDeviceService;
|
||||
import com.njzscloud.localizer.track.pojo.entity.TruckLocationTrackEntity;
|
||||
import com.njzscloud.localizer.track.pojo.param.LocationTrackSearchParam;
|
||||
import com.njzscloud.localizer.track.service.TruckLocationTrackService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class OnStarted {
|
||||
private final LocalizerDeviceService localizerDeviceService;
|
||||
private final TruckLocationTrackService truckLocationTrackService;
|
||||
ThreadPoolExecutor threadPoolExecutor = ThreadPool.createThreadPool(
|
||||
"GPS 数据",
|
||||
10,
|
||||
200,
|
||||
60,
|
||||
1,
|
||||
1,
|
||||
new ThreadPoolExecutor.CallerRunsPolicy()
|
||||
);
|
||||
|
||||
@EventListener(ApplicationReadyEvent.class)
|
||||
public void onApplicationReady() {
|
||||
localizerDeviceService.loadDevice();
|
||||
Websocket.subscribe("up/truck_location_track/history", msg -> {
|
||||
WsMsg.User from = msg.getFrom();
|
||||
String cid = from.getCid();
|
||||
LocationTrackSearchParam param = msg.extractData(LocationTrackSearchParam.class);
|
||||
// String terminalId = param.getTerminalId();
|
||||
String licensePlate = param.getLicensePlate();
|
||||
LocalDateTime startTime = param.getStartTime();
|
||||
LocalDateTime endTime = param.getEndTime();
|
||||
Integer speed = param.getSpeed();
|
||||
CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
int currentPage = 1;
|
||||
// 分页查询,每次500条
|
||||
while (true) {
|
||||
// 检查是否被取消
|
||||
if (Thread.currentThread().isInterrupted()) {
|
||||
log.info("任务被取消");
|
||||
return;
|
||||
}
|
||||
|
||||
Page<TruckLocationTrackEntity> page = new Page<>(currentPage, 500);
|
||||
page.addOrder(OrderItem.asc("location_time"));
|
||||
|
||||
// 分页查询当前页数据
|
||||
IPage<TruckLocationTrackEntity> resultPage = truckLocationTrackService.page(page, Wrappers.lambdaQuery(TruckLocationTrackEntity.class)
|
||||
.eq(TruckLocationTrackEntity::getLicensePlate, licensePlate)
|
||||
.ge(startTime != null, TruckLocationTrackEntity::getLocationTime, startTime)
|
||||
.le(endTime != null, TruckLocationTrackEntity::getLocationTime, endTime));
|
||||
|
||||
List<TruckLocationTrackEntity> records = resultPage.getRecords();
|
||||
if (records.isEmpty()) {
|
||||
Websocket.publish(new WsMsg()
|
||||
.setEvent("down/truck_location_track/history")
|
||||
.setData(R.failed(ExceptionMsg.SYS_ERR_MSG, "数据发送完成"))
|
||||
.setTo(Collections.singletonList(new WsMsg.User().setCid(cid)))
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// 处理当前页数据,按时间间隔推送
|
||||
for (TruckLocationTrackEntity record : records) {
|
||||
if (Thread.currentThread().isInterrupted()) {
|
||||
log.info("任务被取消");
|
||||
return;
|
||||
}
|
||||
if (speed > 100) {
|
||||
if (!ThreadUtil.sleep(speed)) {
|
||||
log.info("任务被取消");
|
||||
Websocket.publish(new WsMsg()
|
||||
.setEvent("down/truck_location_track/history")
|
||||
.setData(R.failed(ExceptionMsg.SYS_ERR_MSG, "数据发送完成"))
|
||||
.setTo(Collections.singletonList(new WsMsg.User().setCid(cid)))
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
Tuple2<Double, Double> doubles = CoordinateConverter.wgs84ToGcj02(record.getLatitude(), record.getLongitude());
|
||||
record.setLatitude(doubles.get_0())
|
||||
.setLongitude(doubles.get_1());
|
||||
boolean publish = Websocket.publish(new WsMsg()
|
||||
.setEvent("down/truck_location_track/history")
|
||||
.setData(R.success(record))
|
||||
.setTo(Collections.singletonList(new WsMsg.User().setCid(cid)))
|
||||
);
|
||||
if (!publish) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 判断是否为最后一页
|
||||
if (currentPage >= resultPage.getPages()) {
|
||||
Websocket.publish(new WsMsg()
|
||||
.setEvent("down/truck_location_track/history")
|
||||
.setData(R.failed(ExceptionMsg.SYS_ERR_MSG, "数据发送完成"))
|
||||
.setTo(Collections.singletonList(new WsMsg.User().setCid(cid)))
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// 继续查询下一页
|
||||
currentPage++;
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
// 其他异常
|
||||
log.error("查询历史轨迹异常", e);
|
||||
}
|
||||
}, threadPoolExecutor);
|
||||
});
|
||||
|
||||
Websocket.subscribe("up/truck_location_track/realtime", msg -> {
|
||||
WsMsg.User from = msg.getFrom();
|
||||
String cid = from.getCid();
|
||||
LocationTrackSearchParam param = msg.extractData(LocationTrackSearchParam.class);
|
||||
// String terminalId = param.getTerminalId();
|
||||
String licensePlate = param.getLicensePlate();
|
||||
Integer speed = param.getSpeed();
|
||||
CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
LocalDateTime startTime = LocalDateTime.now().minusSeconds(300);
|
||||
int errCount = 0;
|
||||
while (true) {
|
||||
// 检查是否被取消
|
||||
if (Thread.currentThread().isInterrupted()) {
|
||||
log.info("任务被取消");
|
||||
return;
|
||||
}
|
||||
|
||||
Page<TruckLocationTrackEntity> page = new Page<>(1, 10);
|
||||
page.addOrder(OrderItem.asc("location_time"));
|
||||
|
||||
// 分页查询当前页数据
|
||||
IPage<TruckLocationTrackEntity> resultPage = truckLocationTrackService.page(page, Wrappers.lambdaQuery(TruckLocationTrackEntity.class)
|
||||
.eq(TruckLocationTrackEntity::getLicensePlate, licensePlate)
|
||||
.gt(TruckLocationTrackEntity::getLocationTime, startTime));
|
||||
|
||||
List<TruckLocationTrackEntity> records = resultPage.getRecords();
|
||||
if (records.isEmpty()) {
|
||||
if (errCount >= 200 * 5) {
|
||||
log.error("暂无实时数据, 车牌号: {}, 时间: {}", licensePlate, startTime);
|
||||
Websocket.publish(new WsMsg()
|
||||
.setEvent("down/truck_location_track/realtime")
|
||||
.setData(R.failed(ExceptionMsg.SYS_ERR_MSG, "暂无实时数据"))
|
||||
.setTo(Collections.singletonList(new WsMsg.User().setCid(cid)))
|
||||
);
|
||||
return;
|
||||
}
|
||||
errCount++;
|
||||
if (!ThreadUtil.sleep(300)) {
|
||||
log.info("任务被取消");
|
||||
return;
|
||||
} else {
|
||||
startTime = LocalDateTime.now();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
errCount = 0;
|
||||
|
||||
// 处理当前页数据,按时间间隔推送
|
||||
for (TruckLocationTrackEntity record : records) {
|
||||
if (Thread.currentThread().isInterrupted()) {
|
||||
log.info("任务被取消");
|
||||
return;
|
||||
}
|
||||
if (speed > 100) {
|
||||
if (!ThreadUtil.sleep(speed)) {
|
||||
log.info("任务被取消");
|
||||
Websocket.publish(new WsMsg()
|
||||
.setEvent("down/truck_location_track/realtime")
|
||||
.setData(R.failed(ExceptionMsg.SYS_ERR_MSG, "数据发送完成"))
|
||||
.setTo(Collections.singletonList(new WsMsg.User().setCid(cid)))
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
startTime = record.getLocationTime();
|
||||
Tuple2<Double, Double> doubles = CoordinateConverter.wgs84ToGcj02(record.getLatitude(), record.getLongitude());
|
||||
record.setLatitude(doubles.get_0())
|
||||
.setLongitude(doubles.get_1());
|
||||
boolean publish = Websocket.publish(new WsMsg()
|
||||
.setEvent("down/truck_location_track/realtime")
|
||||
.setData(R.success(record))
|
||||
.setTo(Collections.singletonList(new WsMsg.User().setCid(cid)))
|
||||
);
|
||||
if (!publish) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// 其他异常
|
||||
log.error("查询历史轨迹异常", e);
|
||||
}
|
||||
}, threadPoolExecutor);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
package com.njzscloud.localizer.device.controller;
|
||||
|
||||
import com.njzscloud.common.core.utils.R;
|
||||
import com.njzscloud.common.localizer.DeviceStore;
|
||||
import com.njzscloud.localizer.device.service.LocalizerDeviceService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.CrossOrigin;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@Slf4j
|
||||
@CrossOrigin
|
||||
@RestController
|
||||
@RequestMapping("/localizer_device")
|
||||
@RequiredArgsConstructor
|
||||
public class LocalizerDeviceController {
|
||||
private final LocalizerDeviceService localizerDeviceService;
|
||||
|
||||
@GetMapping("/load_device")
|
||||
public R<?> loadDevice() {
|
||||
localizerDeviceService.loadDevice();
|
||||
return R.success();
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
public R<?> list() {
|
||||
return R.success(DeviceStore.list());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
package com.njzscloud.localizer.device.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.njzscloud.localizer.device.pojo.entity.DeviceEntity;
|
||||
import com.njzscloud.localizer.device.pojo.entity.LocalizerDeviceEntity;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface DeviceMapper extends BaseMapper<DeviceEntity> {
|
||||
public interface LocalizerDeviceMapper extends BaseMapper<LocalizerDeviceEntity> {
|
||||
}
|
||||
|
|
@ -1,32 +1,52 @@
|
|||
package com.njzscloud.localizer.device.pojo.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.njzscloud.common.localizer.contant.LocalizerType;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@ToString
|
||||
@Accessors(chain = true)
|
||||
@TableName("localizer_device")
|
||||
public class DeviceEntity {
|
||||
public class LocalizerDeviceEntity {
|
||||
|
||||
/**
|
||||
* 设备 Id
|
||||
* Id
|
||||
*/
|
||||
protected String terminalId;
|
||||
/**
|
||||
* 设备类型
|
||||
*/
|
||||
protected LocalizerType localizerType;
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
private Long id;
|
||||
/**
|
||||
* 车牌
|
||||
*/
|
||||
private String licensePlate;
|
||||
/**
|
||||
* 设备 Id
|
||||
*/
|
||||
protected String terminalId;
|
||||
|
||||
/**
|
||||
* 设备类型
|
||||
*/
|
||||
protected LocalizerType localizerType;
|
||||
|
||||
/**
|
||||
* 速度阈值
|
||||
*/
|
||||
private Integer speedThreshold;
|
||||
/**
|
||||
* 是否可用; 0-->否、1-->是
|
||||
*/
|
||||
private Boolean canuse;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private LocalDateTime createTime;
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
package com.njzscloud.localizer.device.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.njzscloud.localizer.device.mapper.DeviceMapper;
|
||||
import com.njzscloud.localizer.device.pojo.entity.DeviceEntity;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class DeviceService extends ServiceImpl<DeviceMapper, DeviceEntity> implements IService<DeviceEntity> {
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package com.njzscloud.localizer.device.service;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.njzscloud.common.localizer.DeviceStore;
|
||||
import com.njzscloud.common.localizer.Localizer;
|
||||
import com.njzscloud.localizer.device.mapper.LocalizerDeviceMapper;
|
||||
import com.njzscloud.localizer.device.pojo.entity.LocalizerDeviceEntity;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class LocalizerDeviceService extends ServiceImpl<LocalizerDeviceMapper, LocalizerDeviceEntity> implements IService<LocalizerDeviceEntity> {
|
||||
|
||||
public void loadDevice() {
|
||||
List<LocalizerDeviceEntity> list = this.list();
|
||||
List<Localizer> localizers = list.stream().map(it -> BeanUtil.copyProperties(it, Localizer.class)).collect(Collectors.toList());
|
||||
if (CollUtil.isEmpty(localizers)) return;
|
||||
DeviceStore.setLocalizers(localizers);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
package com.njzscloud.localizer.track.controller;
|
||||
|
||||
import com.njzscloud.common.core.utils.R;
|
||||
import com.njzscloud.common.localizer.tuqiang.Tuqiang;
|
||||
import com.njzscloud.localizer.track.service.TruckLocationTrackService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.CrossOrigin;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
* 车辆定位数据
|
||||
|
|
@ -19,4 +19,23 @@ public class TruckLocationTrackController {
|
|||
|
||||
private final TruckLocationTrackService truckLocationTrackService;
|
||||
|
||||
@GetMapping("/start")
|
||||
public R<?> startTrack(@RequestParam("licensePlate") String licensePlate) {
|
||||
truckLocationTrackService.startTrack(licensePlate);
|
||||
return R.success();
|
||||
}
|
||||
|
||||
@GetMapping("/stop")
|
||||
public R<?> stopTrack(@RequestParam("licensePlate") String licensePlate) {
|
||||
truckLocationTrackService.stopTrack(licensePlate);
|
||||
return R.success();
|
||||
}
|
||||
|
||||
@GetMapping("/send")
|
||||
public R<?> send(@RequestParam("terminalId") String terminalId,
|
||||
@RequestParam("directive") String directive) {
|
||||
Tuqiang.sendDirective(terminalId, directive);
|
||||
return R.success();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,43 +1,20 @@
|
|||
package com.njzscloud.localizer.track.service;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.thread.ThreadUtil;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.metadata.OrderItem;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.njzscloud.common.core.ex.ExceptionMsg;
|
||||
import com.njzscloud.common.core.thread.ThreadPool;
|
||||
import com.njzscloud.common.core.tuple.Tuple2;
|
||||
import com.njzscloud.common.core.utils.CoordinateConverter;
|
||||
import com.njzscloud.common.core.utils.R;
|
||||
import com.njzscloud.common.localizer.DeviceStore;
|
||||
import com.njzscloud.common.localizer.Localizer;
|
||||
import com.njzscloud.common.localizer.mqtt.result.RealtimeLocationResult;
|
||||
import com.njzscloud.common.localizer.service.LocalizerService;
|
||||
import com.njzscloud.common.ws.support.Websocket;
|
||||
import com.njzscloud.common.ws.support.WsMsg;
|
||||
import com.njzscloud.localizer.device.pojo.entity.DeviceEntity;
|
||||
import com.njzscloud.localizer.device.service.DeviceService;
|
||||
import com.njzscloud.localizer.track.mapper.TruckLocationTrackMapper;
|
||||
import com.njzscloud.localizer.track.pojo.entity.TruckLocationTrackEntity;
|
||||
import com.njzscloud.localizer.track.pojo.param.LocationTrackSearchParam;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* 车辆定位数据
|
||||
|
|
@ -46,206 +23,10 @@ import java.util.stream.Collectors;
|
|||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class TruckLocationTrackService extends ServiceImpl<TruckLocationTrackMapper, TruckLocationTrackEntity> implements LocalizerService, IService<TruckLocationTrackEntity> {
|
||||
private final DeviceService deviceService;
|
||||
ThreadPoolExecutor threadPoolExecutor = ThreadPool.createThreadPool(
|
||||
"GPS 数据",
|
||||
10,
|
||||
200,
|
||||
60,
|
||||
1,
|
||||
1,
|
||||
new ThreadPoolExecutor.CallerRunsPolicy()
|
||||
);
|
||||
|
||||
@EventListener(ApplicationReadyEvent.class)
|
||||
public void onApplicationReady() {
|
||||
List<DeviceEntity> list = deviceService.list();
|
||||
List<Localizer> localizers = list.stream().map(it -> BeanUtil.copyProperties(it, Localizer.class)).collect(Collectors.toList());
|
||||
DeviceStore.setLocalizers(localizers);
|
||||
Websocket.subscribe("up/truck_location_track/history", msg -> {
|
||||
WsMsg.User from = msg.getFrom();
|
||||
String cid = from.getCid();
|
||||
LocationTrackSearchParam param = msg.extractData(LocationTrackSearchParam.class);
|
||||
// String terminalId = param.getTerminalId();
|
||||
String licensePlate = param.getLicensePlate();
|
||||
LocalDateTime startTime = param.getStartTime();
|
||||
LocalDateTime endTime = param.getEndTime();
|
||||
Integer speed = param.getSpeed();
|
||||
CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
int currentPage = 1;
|
||||
// 分页查询,每次500条
|
||||
while (true) {
|
||||
// 检查是否被取消
|
||||
if (Thread.currentThread().isInterrupted()) {
|
||||
log.info("任务被取消");
|
||||
return;
|
||||
}
|
||||
|
||||
Page<TruckLocationTrackEntity> page = new Page<>(currentPage, 500);
|
||||
page.addOrder(OrderItem.asc("location_time"));
|
||||
|
||||
// 分页查询当前页数据
|
||||
IPage<TruckLocationTrackEntity> resultPage = this.page(page, Wrappers.lambdaQuery(TruckLocationTrackEntity.class)
|
||||
.eq(TruckLocationTrackEntity::getLicensePlate, licensePlate)
|
||||
.ge(startTime != null, TruckLocationTrackEntity::getLocationTime, startTime)
|
||||
.le(endTime != null, TruckLocationTrackEntity::getLocationTime, endTime));
|
||||
|
||||
List<TruckLocationTrackEntity> records = resultPage.getRecords();
|
||||
if (records.isEmpty()) {
|
||||
Websocket.publish(new WsMsg()
|
||||
.setEvent("down/truck_location_track/history")
|
||||
.setData(R.failed(ExceptionMsg.SYS_ERR_MSG, "数据发送完成"))
|
||||
.setTo(Collections.singletonList(new WsMsg.User().setCid(cid)))
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// 处理当前页数据,按时间间隔推送
|
||||
for (TruckLocationTrackEntity record : records) {
|
||||
if (Thread.currentThread().isInterrupted()) {
|
||||
log.info("任务被取消");
|
||||
return;
|
||||
}
|
||||
if (speed > 100) {
|
||||
if (!ThreadUtil.sleep(speed)) {
|
||||
log.info("任务被取消");
|
||||
Websocket.publish(new WsMsg()
|
||||
.setEvent("down/truck_location_track/history")
|
||||
.setData(R.failed(ExceptionMsg.SYS_ERR_MSG, "数据发送完成"))
|
||||
.setTo(Collections.singletonList(new WsMsg.User().setCid(cid)))
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
Tuple2<Double, Double> doubles = CoordinateConverter.wgs84ToGcj02(record.getLatitude(), record.getLongitude());
|
||||
record.setLatitude(doubles.get_0())
|
||||
.setLongitude(doubles.get_1());
|
||||
boolean publish = Websocket.publish(new WsMsg()
|
||||
.setEvent("down/truck_location_track/history")
|
||||
.setData(R.success(record))
|
||||
.setTo(Collections.singletonList(new WsMsg.User().setCid(cid)))
|
||||
);
|
||||
if (!publish) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 判断是否为最后一页
|
||||
if (currentPage >= resultPage.getPages()) {
|
||||
Websocket.publish(new WsMsg()
|
||||
.setEvent("down/truck_location_track/history")
|
||||
.setData(R.failed(ExceptionMsg.SYS_ERR_MSG, "数据发送完成"))
|
||||
.setTo(Collections.singletonList(new WsMsg.User().setCid(cid)))
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// 继续查询下一页
|
||||
currentPage++;
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
// 其他异常
|
||||
log.error("查询历史轨迹异常", e);
|
||||
}
|
||||
}, threadPoolExecutor);
|
||||
});
|
||||
|
||||
Websocket.subscribe("up/truck_location_track/realtime", msg -> {
|
||||
WsMsg.User from = msg.getFrom();
|
||||
String cid = from.getCid();
|
||||
LocationTrackSearchParam param = msg.extractData(LocationTrackSearchParam.class);
|
||||
// String terminalId = param.getTerminalId();
|
||||
String licensePlate = param.getLicensePlate();
|
||||
Integer speed = param.getSpeed();
|
||||
CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
LocalDateTime startTime = LocalDateTime.now().minusSeconds(1);
|
||||
int errCount = 0;
|
||||
while (true) {
|
||||
// 检查是否被取消
|
||||
if (Thread.currentThread().isInterrupted()) {
|
||||
log.info("任务被取消");
|
||||
return;
|
||||
}
|
||||
|
||||
Page<TruckLocationTrackEntity> page = new Page<>(1, 10);
|
||||
page.addOrder(OrderItem.asc("location_time"));
|
||||
|
||||
// 分页查询当前页数据
|
||||
IPage<TruckLocationTrackEntity> resultPage = this.page(page, Wrappers.lambdaQuery(TruckLocationTrackEntity.class)
|
||||
.eq(TruckLocationTrackEntity::getLicensePlate, licensePlate)
|
||||
.gt(TruckLocationTrackEntity::getLocationTime, startTime));
|
||||
|
||||
List<TruckLocationTrackEntity> records = resultPage.getRecords();
|
||||
if (records.isEmpty()) {
|
||||
if (errCount >= 200) {
|
||||
log.error("暂无实时数据, 车牌号: {}, 时间: {}", licensePlate, startTime);
|
||||
Websocket.publish(new WsMsg()
|
||||
.setEvent("down/truck_location_track/realtime")
|
||||
.setData(R.failed(ExceptionMsg.SYS_ERR_MSG, "暂无实时数据"))
|
||||
.setTo(Collections.singletonList(new WsMsg.User().setCid(cid)))
|
||||
);
|
||||
return;
|
||||
}
|
||||
errCount++;
|
||||
if (!ThreadUtil.sleep(300)) {
|
||||
log.info("任务被取消");
|
||||
return;
|
||||
} else {
|
||||
startTime = LocalDateTime.now();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
errCount = 0;
|
||||
|
||||
// 处理当前页数据,按时间间隔推送
|
||||
for (TruckLocationTrackEntity record : records) {
|
||||
if (Thread.currentThread().isInterrupted()) {
|
||||
log.info("任务被取消");
|
||||
return;
|
||||
}
|
||||
if (speed > 100) {
|
||||
if (!ThreadUtil.sleep(speed)) {
|
||||
log.info("任务被取消");
|
||||
Websocket.publish(new WsMsg()
|
||||
.setEvent("down/truck_location_track/realtime")
|
||||
.setData(R.failed(ExceptionMsg.SYS_ERR_MSG, "数据发送完成"))
|
||||
.setTo(Collections.singletonList(new WsMsg.User().setCid(cid)))
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
startTime = record.getLocationTime();
|
||||
Tuple2<Double, Double> doubles = CoordinateConverter.wgs84ToGcj02(record.getLatitude(), record.getLongitude());
|
||||
record.setLatitude(doubles.get_0())
|
||||
.setLongitude(doubles.get_1());
|
||||
boolean publish = Websocket.publish(new WsMsg()
|
||||
.setEvent("down/truck_location_track/realtime")
|
||||
.setData(R.success(record))
|
||||
.setTo(Collections.singletonList(new WsMsg.User().setCid(cid)))
|
||||
);
|
||||
if (!publish) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// 其他异常
|
||||
log.error("查询历史轨迹异常", e);
|
||||
}
|
||||
}, threadPoolExecutor);
|
||||
});
|
||||
|
||||
/* 川SXJ070 12082962846
|
||||
|
||||
川SB070Z 12083145045
|
||||
|
||||
川SYV011 12082915117
|
||||
|
||||
川SYE909 12082855453 */
|
||||
}
|
||||
private static final ConcurrentHashMap<String, Boolean> TRACK_FLAG = new ConcurrentHashMap<>();
|
||||
@Value("${trackFlag}")
|
||||
boolean trackFlag = false;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
|
|
@ -254,6 +35,10 @@ public class TruckLocationTrackService extends ServiceImpl<TruckLocationTrackMap
|
|||
if (realtimeLocationResult == null) {
|
||||
return;
|
||||
}
|
||||
String licensePlate = realtimeLocationResult.getLicensePlate();
|
||||
if (trackFlag && !TRACK_FLAG.getOrDefault(licensePlate, Boolean.FALSE)) {
|
||||
return;
|
||||
}
|
||||
String time = realtimeLocationResult.getTime();
|
||||
double latitude = realtimeLocationResult.getLatitude();
|
||||
double longitude = realtimeLocationResult.getLongitude();
|
||||
|
|
@ -263,7 +48,7 @@ public class TruckLocationTrackService extends ServiceImpl<TruckLocationTrackMap
|
|||
}
|
||||
|
||||
TruckLocationTrackEntity entity = new TruckLocationTrackEntity()
|
||||
.setLicensePlate(realtimeLocationResult.getLicensePlate())
|
||||
.setLicensePlate(licensePlate)
|
||||
.setTerminalId(realtimeLocationResult.getTerminalId())
|
||||
.setLatitude(latitude)
|
||||
.setLongitude(longitude)
|
||||
|
|
@ -276,4 +61,12 @@ public class TruckLocationTrackService extends ServiceImpl<TruckLocationTrackMap
|
|||
this.save(entity);
|
||||
}
|
||||
}
|
||||
|
||||
public void startTrack(String licensePlate) {
|
||||
TRACK_FLAG.put(licensePlate, Boolean.TRUE);
|
||||
}
|
||||
|
||||
public void stopTrack(String licensePlate) {
|
||||
TRACK_FLAG.put(licensePlate, Boolean.FALSE);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,24 @@
|
|||
spring:
|
||||
servlet:
|
||||
multipart:
|
||||
location: D:\ProJects\gov_manage\njzscloud-supervisory-svr\logs\temp
|
||||
datasource:
|
||||
url: jdbc:mysql://localhost:33061/green_frog?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true&allowPublicKeyRetrieval=true&allowMultiQueries=true
|
||||
username: dbard01
|
||||
password: mik9uvNZ
|
||||
trackFlag: false
|
||||
mybatis-plus:
|
||||
tunnel:
|
||||
enable: false
|
||||
ssh:
|
||||
host: 121.43.155.83
|
||||
port: 22
|
||||
user: root
|
||||
credentials: D:/W/首炬/dzsj.pem
|
||||
localPort: 33061
|
||||
db:
|
||||
host: rm-bp1w3397b718u1882.mysql.rds.aliyuncs.com
|
||||
port: 3306
|
||||
mqtt:
|
||||
enabled: true
|
||||
broker: tcp://139.224.54.144:1883
|
||||
|
|
|
|||
|
|
@ -1,6 +1,15 @@
|
|||
spring:
|
||||
application:
|
||||
name: localizer
|
||||
servlet:
|
||||
multipart:
|
||||
location: D:\ProJects\gov_manage\njzscloud-supervisory-svr\logs\temp
|
||||
datasource:
|
||||
url: jdbc:mysql://localhost:33061/green_frog?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true&allowPublicKeyRetrieval=true&allowMultiQueries=true
|
||||
username: dbard01
|
||||
password: mik9uvNZ
|
||||
|
||||
trackFlag: false
|
||||
|
||||
mqtt:
|
||||
enabled: true
|
||||
|
|
|
|||
|
|
@ -388,7 +388,7 @@
|
|||
const authorization = wsAuthorizationInput.value.trim();
|
||||
try {
|
||||
// 创建WebSocket连接
|
||||
url = `${url}?authorization=${authorization}`;
|
||||
url = `${url}`;
|
||||
websocket = new WebSocket(url);
|
||||
|
||||
// 连接成功
|
||||
|
|
|
|||
Loading…
Reference in New Issue