ruoyi-api/ruoyi-api-system/pom.xml
@@ -28,6 +28,12 @@ </exclusion> </exclusions> </dependency> <dependency> <groupId>cn.afterturn</groupId> <artifactId>easypoi-annotation</artifactId> <version>4.1.2</version> <scope>compile</scope> </dependency> </dependencies> </project> ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/model/Order.java
@@ -1,10 +1,11 @@ package com.ruoyi.system.api.model; import cn.afterturn.easypoi.excel.annotation.Excel; import cn.afterturn.easypoi.excel.annotation.ExcelTarget; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import com.ruoyi.common.core.annotation.Excel; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -19,6 +20,7 @@ @Data @ApiModel @TableName("t_order") @ExcelTarget(("order")) public class Order { /** * 主键 @@ -40,7 +42,7 @@ @ApiModelProperty(value = "车辆id") private Integer carId; @TableField(exist = false) @TableField("vehicle_number") @ApiModelProperty(value = "车牌号") @Excel(name = "车牌号", width = 30) private String vehicleNumber; ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/model/Warn.java
@@ -138,4 +138,9 @@ */ @TableField("object_id") private Integer objectId; /** * 车牌号 */ @TableField("vehicle_number") private String vehicleNumber; } ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/CarController.java
@@ -124,7 +124,7 @@ public R<RealVideoResp> getRealVideo(@PathVariable("id") Integer id) { Car car = carService.getById(id); if (null == car) { return R.fail("失败"); return R.fail("车辆信息获取失败"); } //手动加一次状态数据,避免定时任务结束任务线程 redisTemplate.opsForValue().set("live:" + id, true, 1, TimeUnit.MINUTES); @@ -280,8 +280,11 @@ public R<List<Car>> getMapCarList() { List<Car> list = carService.list(new LambdaQueryWrapper<Car>().eq(Car::getStatus, 1)); for (Car car : list) { Long s = (null == car.getDownlineTime() ? LocalDateTime.now() : car.getDownlineTime()).toEpochSecond(ZoneOffset.ofHours(8)) - car.getOnlineTime().toEpochSecond(ZoneOffset.ofHours(8)); car.setDrivingTime(s / 60); car.setDrivingTime(0L); if(null != car.getOnlineTime()){ Long s = (null == car.getDownlineTime() ? LocalDateTime.now() : car.getDownlineTime()).toEpochSecond(ZoneOffset.ofHours(8)) - car.getOnlineTime().toEpochSecond(ZoneOffset.ofHours(8)); car.setDrivingTime(s / 60); } GnssDataVo gnssDataVo = (GnssDataVo) redisTemplate.opsForValue().get("location:" + car.getVehicleNumber()); if (null != gnssDataVo) { car.setLongitude(new BigDecimal(gnssDataVo.getLon()).divide(new BigDecimal(1000000)).toString()); ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/query/CarWarnListResp.java
@@ -1,6 +1,7 @@ package com.ruoyi.system.query; import com.ruoyi.common.core.annotation.Excel; import cn.afterturn.easypoi.excel.annotation.Excel; import cn.afterturn.easypoi.excel.annotation.ExcelTarget; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -13,6 +14,7 @@ */ @Data @ApiModel @ExcelTarget(("carWarnListResp")) public class CarWarnListResp { @ApiModelProperty("车辆名称") @Excel(name = "车辆名称", width = 30) ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/query/ComplainListResp.java
@@ -1,6 +1,7 @@ package com.ruoyi.system.query; import cn.afterturn.easypoi.excel.annotation.Excel; import cn.afterturn.easypoi.excel.annotation.ExcelTarget; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -11,6 +12,7 @@ */ @Data @ApiModel @ExcelTarget("complainListResp") public class ComplainListResp { @ApiModelProperty("车辆名称") @Excel(name = "车辆名称", width = 30) ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ICarService.java
@@ -18,6 +18,11 @@ */ void taskSaveNewCar(); /** * 定时保存车辆的司机id */ void taskSaveDriverId(); /** * 获取车辆列表数据 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/IOrderService.java
@@ -16,6 +16,11 @@ */ void taskSaveNewOrder(); /** * 定时保存车辆id和司机id */ void taskSaveCarIdAndDriverId(); /** * 获取订单列表 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/IWarnService.java
@@ -22,6 +22,11 @@ void taskSaveNewWarn(); /** * 定时保存车辆id和司机id */ void taskSaveCarIdAndDriverId(); /** * 定时任务修改预警信息处理结果 */ void taskUpdateWarnStatus(); ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/CarServiceImpl.java
@@ -111,6 +111,22 @@ /** * 定时保存车辆司机id */ @Override public void taskSaveDriverId() { List<Driver> driverList = driverService.list(new LambdaQueryWrapper<Driver>().eq(Driver::getStatus, 1)); List<Car> list = this.list(new LambdaQueryWrapper<Car>().isNull(Car::getDriverId)); for (Car car : list) { Optional<Driver> optional = driverList.stream().filter(s -> s.getVehicleNumber().equals(car.getVehicleNumber())).findFirst(); if (optional.isPresent()) { car.setDriverId(optional.get().getId()); this.updateById(car); } } } /** * 获取车辆列表数据 * * @param carListReq @@ -136,7 +152,7 @@ if (car.getStatus() == 1) { updateWrapper.set(Car::getDownlineTime, LocalDateTime.now()); } updateWrapper.set(Car::getStatus, 4); updateWrapper.set(Car::getStatus, 3); this.update(updateWrapper); } else { String dateTime = gnssDataVo.getDate() + " " + gnssDataVo.getTime(); @@ -146,7 +162,7 @@ if (car.getStatus() == 1) { updateWrapper.set(Car::getDownlineTime, LocalDateTime.now()); } updateWrapper.set(Car::getStatus, 4); updateWrapper.set(Car::getStatus, 3); this.update(updateWrapper); } else { if (car.getStatus() != 1) { ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/OrderServiceImpl.java
@@ -81,6 +81,7 @@ order.setCreateTime(LocalDateTime.now()); order.setVehicleNumber(vo.getVehicleNo()); orders.add(order); } if (orders.size() > 0) { @@ -89,6 +90,29 @@ } /** * 定时保存车辆id和司机id */ @Override public void taskSaveCarIdAndDriverId() { List<Order> list = this.list(new LambdaQueryWrapper<Order>().isNull(Order::getCarId).or().isNull(Order::getDriverId)); List<Car> carList = carService.list(); List<Driver> driverList = driverService.list(new LambdaQueryWrapper<Driver>().eq(Driver::getStatus, 1)); for (Order order : list) { Optional<Driver> optional = driverList.stream().filter(s -> s.getVehicleNumber().equals(order.getVehicleNumber())).findFirst(); if (optional.isPresent()) { order.setDriverId(optional.get().getId()); this.updateById(order); } Optional<Car> optional1 = carList.stream().filter(s -> s.getVehicleNumber().equals(order.getVehicleNumber())).findFirst(); if (optional1.isPresent()) { order.setCarId(optional1.get().getId()); this.updateById(order); } } } /** * 获取订单列表 * ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/WarnServiceImpl.java
@@ -112,6 +112,7 @@ } warn.setCreateTime(LocalDateTime.now()); warn.setObjectId(vo.getInfoId()); warn.setVehicleNumber(vo.getVehicleNo()); warns.add(warn); } if (warns.size() > 0) { @@ -119,6 +120,28 @@ } } /** * 定时保存车辆id和司机id */ @Override public void taskSaveCarIdAndDriverId() { List<Warn> list = this.list(new LambdaQueryWrapper<Warn>().isNull(Warn::getCarId).or().isNull(Warn::getDriverId)); List<Car> carList = carService.list(); List<Driver> driverList = driverService.list(new LambdaQueryWrapper<Driver>().eq(Driver::getStatus, 1)); for (Warn warn : list) { Optional<Driver> optional = driverList.stream().filter(s -> s.getVehicleNumber().equals(warn.getVehicleNumber())).findFirst(); if (optional.isPresent()) { warn.setDriverId(optional.get().getId()); this.updateById(warn); } Optional<Car> optional1 = carList.stream().filter(s -> s.getVehicleNumber().equals(warn.getVehicleNumber())).findFirst(); if (optional1.isPresent()) { warn.setCarId(optional1.get().getId()); this.updateById(warn); } } } /** * 定时任务修改预警信息处理结果 @@ -158,7 +181,7 @@ */ @Override public PageInfo<CarWarnListResp> getCarWarnList(CarWarnListReq carWarnListReq) { PageInfo<CarWarnListResp> pageInfo = new PageInfo<>(carWarnListReq.getPageCurr(), carWarnListReq.getPageCurr()); PageInfo<CarWarnListResp> pageInfo = new PageInfo<>(carWarnListReq.getPageCurr(), carWarnListReq.getPageSize()); return this.baseMapper.getCarWarnList(pageInfo, carWarnListReq); } ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/util/TaskUtil.java
@@ -35,6 +35,7 @@ @Scheduled(fixedRate = 1000 * 60) public void taskSaveNewCar() { carService.taskSaveNewCar(); carService.taskSaveDriverId(); } @@ -53,6 +54,7 @@ @Scheduled(fixedRate = 1000 * 60) public void taskSaveNewWarn() { warnService.taskSaveNewWarn(); warnService.taskSaveCarIdAndDriverId(); } @@ -71,6 +73,7 @@ @Scheduled(fixedRate = 1000 * 60) public void taskSaveNewOrder() { orderService.taskSaveNewOrder(); orderService.taskSaveCarIdAndDriverId(); } ruoyi-modules/ruoyi-system/src/main/resources/mapping/system/DriverMapper.xml
@@ -5,7 +5,7 @@ <select id="getDriverList" resultType="com.ruoyi.system.query.DriverListResp"> select a.id, a.nameas driverName, a.name as driverName, b.name as enterpriseName, a.driving_license_number as drivingLicenseNumber, a.mailing_address as mailingAddress, ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/controller/RealVideoMsgController.java
@@ -84,21 +84,21 @@ vo.setUrl("http://" + vo.getServerIP() + ":" + vo.getServerPort() + "/" + encode + "." + vo.getVehicleColor() + ".1.0." + realVideo.getData()); return R.ok(vo); case 1: return R.fail("失败"); return R.fail("发起实时音视频失败"); case 2: return R.fail("不支持"); return R.fail("不支持实时音视频"); case 3: return R.fail("会话结束"); return R.fail("实时音视频会话结束"); case 4: return R.fail("失效口令错误"); return R.fail("实时音视频口令错误"); case 5: return R.fail("不满足跨域条件"); return R.fail("实时音视频不满足跨域条件"); default: return R.fail("失败"); return R.fail("发起实时音视频失败"); } } if (num >= 30) { return R.fail("失败"); return R.fail("发起实时音视频失败"); } } } ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/BaseMsg.java
New file @@ -0,0 +1,31 @@ package com.ruoyi.dataInterchange.model; import lombok.Data; /** * @author zhibing.pu * @Date 2025/4/17 10:43 */ @Data public class BaseMsg { /** * 车牌号 */ private String vehicleNo; /** * 车牌颜色 */ private int vehicleColor; /** * 子业务类型标识 */ private int dataType; /** * 后续数据长度 */ private int dataLength; /** * 数据部分 */ private byte[] data; } ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/GnssData.java
@@ -81,24 +81,28 @@ * 解析报文 */ public GnssData decode(ByteBuf byteBuf) { this.encrypt = byteBuf.readByte(); int d = byteBuf.readByte(); int m = byteBuf.readByte(); int y = byteBuf.readShort(); this.date = y + "-" + String.format("%02d", m) + "-" + String.format("%02d", d); int h = byteBuf.readByte(); int mi = byteBuf.readByte(); int s = byteBuf.readByte(); this.time = String.format("%02d", h) + ":" + String.format("%02d", mi) + ":" + String.format("%02d", s); this.lon = byteBuf.readInt(); this.lat = byteBuf.readInt(); this.vec1 = byteBuf.readShort(); this.vec2 = byteBuf.readShort(); this.vec3 = byteBuf.readInt(); this.direction = byteBuf.readShort(); this.altitude = byteBuf.readShort(); this.state = byteBuf.readInt(); this.alarm = byteBuf.readInt(); try { this.encrypt = byteBuf.readByte(); int d = byteBuf.readByte(); int m = byteBuf.readByte(); int y = byteBuf.readShort(); this.date = y + "-" + String.format("%02d", m) + "-" + String.format("%02d", d); int h = byteBuf.readByte(); int mi = byteBuf.readByte(); int s = byteBuf.readByte(); this.time = String.format("%02d", h) + ":" + String.format("%02d", mi) + ":" + String.format("%02d", s); this.lon = byteBuf.readInt(); this.lat = byteBuf.readInt(); this.vec1 = byteBuf.readShort(); this.vec2 = byteBuf.readShort(); this.vec3 = byteBuf.readInt(); this.direction = byteBuf.readShort(); this.altitude = byteBuf.readShort(); this.state = byteBuf.readInt(); this.alarm = byteBuf.readInt(); }catch (Exception e){ e.printStackTrace(); } return this; } } ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/model/UPBaseMsgVehicleAddedAck.java
@@ -1,6 +1,8 @@ package com.ruoyi.dataInterchange.model; import com.fasterxml.jackson.annotation.JsonProperty; import com.ruoyi.dataInterchange.util.jtt809.common.Jtt809Util; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import lombok.Data; /** @@ -13,36 +15,38 @@ /** * 车牌号码 */ @JsonProperty("VEHICLE_NO") private String vehicleNo; /** * 车牌颜色 */ @JsonProperty("VEHICLE_COLOR") private String vehicleColor; private int vehicleColor; /** * 子业务类型标识 */ @JsonProperty("DATA_TYPE") private String dataType; private int dataType; /** * 后续数据长度 */ @JsonProperty("DATA_LENGTH") private String dataLength; /** * 对应补报车辆静态信息请求消息源子业务类型标识 */ @JsonProperty("SOURCE_DATE_TYPE") private String sourceDateType; /** * 对应补报车辆静态信息请求消息源报文序列号 */ @JsonProperty("SOURCE_MSG_SN") private String sourceMsgSn; private int dataLength; /** * 车辆信息 */ @JsonProperty("CAR_INFO") private String carInfo; /** * 解析报文 */ public UPBaseMsgVehicleAddedAck decode(BaseMsg baseMsg) { byte[] data = baseMsg.getData(); ByteBuf byteBuf = Unpooled.wrappedBuffer(data); this.vehicleNo = baseMsg.getVehicleNo(); this.vehicleColor = baseMsg.getVehicleColor(); this.dataType = baseMsg.getDataType(); this.dataLength = baseMsg.getDataLength(); //车辆信息 this.carInfo = Jtt809Util.readGBKString(byteBuf, baseMsg.getDataLength()); return this; } } ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/server/BaseMsgService.java
@@ -1,13 +1,23 @@ package com.ruoyi.dataInterchange.server; import com.ruoyi.common.core.utils.bean.BeanUtils; import com.ruoyi.dataInterchange.dao.UPExgMsgRegisterDao; import com.ruoyi.dataInterchange.model.BaseMsg; import com.ruoyi.dataInterchange.model.UPBaseMsgVehicleAddedAck; import com.ruoyi.dataInterchange.model.UPExgMsgRegister; import com.ruoyi.dataInterchange.model.enu.DataType; import com.ruoyi.dataInterchange.util.jtt809.common.Jtt809Util; import com.ruoyi.dataInterchange.util.jtt809.packet.common.OuterPacket; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; import lombok.extern.slf4j.Slf4j; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.time.LocalDateTime; import java.time.ZoneOffset; /** * @author zhibing.pu @@ -20,6 +30,9 @@ @Resource private RedisTemplate redisTemplate; @Resource private UPExgMsgRegisterDao upExgMsgRegisterDao; public void up_base_msg(ChannelHandlerContext ctx, OuterPacket out) { if (!redisTemplate.hasKey("login:" + out.getGnsscenterId())) { @@ -27,13 +40,59 @@ ctx.close(); return; } DataType dataType = DataType.getDataType(out.getId()); BaseMsg baseMsg = getBaseMsg(out); DataType dataType = DataType.getDataType(baseMsg.getDataType()); switch (dataType) { case UP_BASE_MSG_VEHICLE_ADDED_ACK: log.info("补报车辆静态信息应答消息({}):{}", DataType.UP_BASE_MSG_VEHICLE_ADDED_ACK.getCode(), out); up_base_msg_vehicle_added_ack(ctx, out.getGnsscenterId(), baseMsg); break; default: break; } } /** * 解析子业务数据 * * @param out * @return */ public BaseMsg getBaseMsg(OuterPacket out) { byte[] body = out.getBody(); ByteBuf byteBuf = Unpooled.wrappedBuffer(body); //车牌号 String vehicleNo = Jtt809Util.readGBKString(byteBuf, 21); //车牌颜色 byte vehicleColor = byteBuf.readByte(); //子业务类型标识 int dataType = byteBuf.readUnsignedShort(); //后续数据长度 int dataLength = byteBuf.readInt(); //子业务数据包 byte[] data = new byte[byteBuf.readableBytes()]; byteBuf.readBytes(data); BaseMsg baseMsg = new BaseMsg(); baseMsg.setVehicleNo(vehicleNo); baseMsg.setVehicleColor(vehicleColor); baseMsg.setDataType(dataType); baseMsg.setDataLength(dataLength); baseMsg.setData(data); return baseMsg; } public void up_base_msg_vehicle_added_ack(ChannelHandlerContext ctx, int inferiorPlatformId, BaseMsg baseMsg){ UPBaseMsgVehicleAddedAck upBaseMsgVehicleAddedAck = new UPBaseMsgVehicleAddedAck().decode(baseMsg); UPExgMsgRegister upExgMsgRegister = new UPExgMsgRegister(); BeanUtils.copyProperties(upBaseMsgVehicleAddedAck, upExgMsgRegister); upExgMsgRegister.setInferiorPlatformId(inferiorPlatformId); upExgMsgRegister.setCreateTime(LocalDateTime.now().toEpochSecond(ZoneOffset.ofHours(8))); UPExgMsgRegister register = upExgMsgRegisterDao.findByVehicleNo(upExgMsgRegister.getVehicleNo()); if (null == register) { upExgMsgRegisterDao.save(upExgMsgRegister); } } } ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/server/ConnectReqService.java
@@ -97,7 +97,6 @@ public void downConnect(ChannelHandlerContext ctx, int inferiorPlatformId, String host, int port, int verifyCode) { try { boolean b = downConnect(inferiorPlatformId, host, port, verifyCode); } catch (Exception e) { downDisconnectInform(ctx, 0x00); throw new RuntimeException(e);