手机辅助定位
This commit is contained in:
parent
c3f3b02a06
commit
b9cfc3ef88
|
@ -155,6 +155,10 @@ public class Device extends BaseEntity implements IotDevice, LogBizParam
|
|||
@ApiModelProperty("最近一次下单用户ID")
|
||||
private Long lastUserId;
|
||||
|
||||
@Excel(name = "定位类型")
|
||||
@ApiModelProperty("定位类型(1设备定位 2手机定位)")
|
||||
private String locationType;
|
||||
|
||||
@Override
|
||||
public String mac() {
|
||||
return this.mac;
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
package com.ruoyi.bst.device.domain.dto;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import com.ruoyi.iot.domain.IotDeviceSysInfo;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class DeviceBltUploadDTO {
|
||||
|
||||
@ApiModelProperty("设备MAC")
|
||||
@NotBlank(message = "设备MAC不能为空")
|
||||
private String mac;
|
||||
|
||||
@ApiModelProperty("系统数据")
|
||||
@NotNull(message = "系统数据不能为空")
|
||||
private IotDeviceSysInfo sys;
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package com.ruoyi.bst.device.domain.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum DeviceLocationType {
|
||||
DEVICE("1", "设备定位"),
|
||||
PHONE("2", "手机定位");
|
||||
|
||||
private String code;
|
||||
private String name;
|
||||
|
||||
}
|
|
@ -44,6 +44,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
bd.last_online_time,
|
||||
bd.order_device_id,
|
||||
bd.software_version,
|
||||
bd.location_type,
|
||||
mch.nick_name as mch_name,
|
||||
mch.point as mch_point,
|
||||
bm.name as model_name,
|
||||
|
@ -129,6 +130,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="query.orderUserPhone != null and query.orderUserPhone != ''">and suo.user_name like concat('%', #{query.orderUserPhone}, '%')</if>
|
||||
<if test="query.lastTimeEnd != null">and bd.last_location_time <= #{query.lastTimeEnd}</if>
|
||||
<if test="query.lastTimeStart != null">and bd.last_location_time >= #{query.lastTimeStart}</if>
|
||||
<if test="query.locationType != null and query.locationType != ''">and bd.location_type = #{query.locationType}</if>
|
||||
<if test="query.keyword != null and query.keyword != ''">
|
||||
and (
|
||||
bd.sn like concat('%', #{query.keyword}, '%')
|
||||
|
@ -234,6 +236,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="lastOnlineTime != null">last_online_time,</if>
|
||||
<if test="orderDeviceId != null">order_device_id,</if>
|
||||
<if test="softwareVersion != null">software_version,</if>
|
||||
<if test="locationType != null">location_type,</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="modelId != null">#{modelId},</if>
|
||||
|
@ -268,6 +271,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="lastOnlineTime != null">#{lastOnlineTime},</if>
|
||||
<if test="orderDeviceId != null">#{orderDeviceId},</if>
|
||||
<if test="softwareVersion != null">#{softwareVersion},</if>
|
||||
<if test="locationType != null">#{locationType},</if>
|
||||
</trim>
|
||||
</insert>
|
||||
|
||||
|
@ -312,6 +316,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="data.lastOnlineTime != null">bd.last_online_time = #{data.lastOnlineTime},</if>
|
||||
<if test="data.orderDeviceId != null">bd.order_device_id = #{data.orderDeviceId},</if>
|
||||
<if test="data.softwareVersion != null">bd.software_version = #{data.softwareVersion},</if>
|
||||
<if test="data.locationType != null">bd.location_type = #{data.locationType},</if>
|
||||
</sql>
|
||||
|
||||
<delete id="deleteDeviceById" parameterType="Long">
|
||||
|
|
|
@ -5,6 +5,7 @@ import java.util.List;
|
|||
|
||||
import com.ruoyi.bst.device.domain.Device;
|
||||
import com.ruoyi.bst.device.domain.DeviceVO;
|
||||
import com.ruoyi.bst.device.domain.dto.DeviceBltUploadDTO;
|
||||
import com.ruoyi.bst.device.domain.enums.DeviceUnLockType;
|
||||
import com.ruoyi.bst.device.domain.vo.DeviceIotVO;
|
||||
|
||||
|
@ -146,4 +147,11 @@ public interface DeviceIotService {
|
|||
*/
|
||||
int updateIot(Device device);
|
||||
|
||||
/**
|
||||
* 蓝牙上传
|
||||
* @param dto
|
||||
* @return
|
||||
*/
|
||||
int bltUpload(DeviceBltUploadDTO dto);
|
||||
|
||||
}
|
||||
|
|
|
@ -14,6 +14,8 @@ import org.springframework.transaction.support.TransactionTemplate;
|
|||
import com.ruoyi.bst.device.domain.Device;
|
||||
import com.ruoyi.bst.device.domain.DeviceQuery;
|
||||
import com.ruoyi.bst.device.domain.DeviceVO;
|
||||
import com.ruoyi.bst.device.domain.dto.DeviceBltUploadDTO;
|
||||
import com.ruoyi.bst.device.domain.enums.DeviceLocationType;
|
||||
import com.ruoyi.bst.device.domain.enums.DeviceLockStatus;
|
||||
import com.ruoyi.bst.device.domain.enums.DeviceQuality;
|
||||
import com.ruoyi.bst.device.domain.enums.DeviceStatus;
|
||||
|
@ -23,8 +25,12 @@ import com.ruoyi.bst.device.mapper.DeviceMapper;
|
|||
import com.ruoyi.bst.device.service.DeviceIotService;
|
||||
import com.ruoyi.bst.device.service.DeviceService;
|
||||
import com.ruoyi.bst.device.utils.DeviceUtil;
|
||||
import com.ruoyi.bst.locationLog.domain.LocationLog;
|
||||
import com.ruoyi.bst.locationLog.service.LocationLogConverter;
|
||||
import com.ruoyi.bst.orderDevice.domain.enums.OrderDeviceStatus;
|
||||
import com.ruoyi.common.constant.CacheConstants;
|
||||
import com.ruoyi.common.constants.ServiceCode;
|
||||
import com.ruoyi.common.core.redis.RedisCache;
|
||||
import com.ruoyi.common.core.redis.RedisLock;
|
||||
import com.ruoyi.common.utils.MathUtils;
|
||||
import com.ruoyi.common.utils.ServiceUtil;
|
||||
|
@ -59,9 +65,15 @@ public class DeviceIotServiceImpl implements DeviceIotService {
|
|||
@Autowired
|
||||
private ScheduledExecutorService scheduledExecutorService;
|
||||
|
||||
@Autowired
|
||||
private LocationLogConverter locationLogConverter;
|
||||
|
||||
@Autowired
|
||||
private RedisLock redisLock;
|
||||
|
||||
@Autowired
|
||||
private RedisCache redisCache;
|
||||
|
||||
private final static Integer SUB_FAST = 5; // 上报频率(快)
|
||||
private final static Integer SUB_SLOW = 300; // 上报频率(慢)
|
||||
|
||||
|
@ -275,7 +287,7 @@ public class DeviceIotServiceImpl implements DeviceIotService {
|
|||
}
|
||||
|
||||
// 异步发送命令,强制设备上报数据
|
||||
scheduledExecutorService.schedule(() -> {
|
||||
scheduledExecutorService.execute(() -> {
|
||||
for (DeviceVO device : deviceList) {
|
||||
try {
|
||||
if (onlineType != null) {
|
||||
|
@ -285,7 +297,7 @@ public class DeviceIotServiceImpl implements DeviceIotService {
|
|||
log.error("强制设备{}上报数据失败", device.getSn(), e);
|
||||
}
|
||||
}
|
||||
}, 0, TimeUnit.SECONDS);
|
||||
});
|
||||
}
|
||||
|
||||
private void setOnlineStatus(DeviceVO device, String onlineStatus) {
|
||||
|
@ -433,4 +445,27 @@ public class DeviceIotServiceImpl implements DeviceIotService {
|
|||
|
||||
return vo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int bltUpload(DeviceBltUploadDTO dto) {
|
||||
ServiceUtil.assertion(dto == null, "数据不能为空");
|
||||
|
||||
DeviceVO device = deviceService.selectByMac(dto.getMac());
|
||||
ServiceUtil.assertion(device == null, "设备不存在");
|
||||
|
||||
// 更新设备信息
|
||||
DeviceUtil.setIotSysInfo(device, dto.getSys(), LocalDateTime.now(), true);
|
||||
device.setLocationType(DeviceLocationType.PHONE.getCode());
|
||||
int rows = this.updateIot(device);
|
||||
|
||||
// 创建定位日志
|
||||
if (rows > 0) {
|
||||
LocationLog locationLog = locationLogConverter.toPo(device);
|
||||
if (locationLog != null) {
|
||||
redisCache.rightPush(CacheConstants.LOCATION_LOG_QUEUE, locationLog);
|
||||
}
|
||||
}
|
||||
|
||||
return rows;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import java.time.LocalDateTime;
|
|||
import java.util.List;
|
||||
|
||||
import com.ruoyi.bst.device.domain.DeviceVO;
|
||||
import com.ruoyi.bst.device.domain.enums.DeviceLocationType;
|
||||
import com.ruoyi.bst.orderDevice.domain.enums.OrderDeviceStatus;
|
||||
import com.ruoyi.common.utils.MathUtils;
|
||||
import com.ruoyi.common.utils.map.GpsCoordinateUtils;
|
||||
|
@ -19,26 +20,26 @@ public class DeviceUtil {
|
|||
* @param device 设备
|
||||
* @param sys 设备信息
|
||||
*/
|
||||
public static void setIotSysInfo(DeviceVO device, IotDeviceSysInfo sys, LocalDateTime at) {
|
||||
public static void setIotSysInfo(DeviceVO device, IotDeviceSysInfo sys, LocalDateTime at, boolean setNull) {
|
||||
if (device == null || sys == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 转换经纬度坐标系并赋值
|
||||
// 只有定位是正常的才认为是有获取到定位
|
||||
if (sys.getLon() != null && sys.getLat() != null
|
||||
&& !MathUtils.equals(sys.getLon(), BigDecimal.ZERO)
|
||||
&& !MathUtils.equals(sys.getLat(), BigDecimal.ZERO)) {
|
||||
if (DeviceUtil.validLocation(sys.getLon(), sys.getLat())) {
|
||||
List<BigDecimal> coordinates = GpsCoordinateUtils.coordinateConvert(sys.getLon(), sys.getLat());
|
||||
if (coordinates != null && coordinates.size() >= 2) {
|
||||
device.setLongitude(coordinates.get(1));
|
||||
device.setLatitude(coordinates.get(0));
|
||||
device.setLastLocationTime(at);
|
||||
device.setLocationType(DeviceLocationType.DEVICE.getCode());
|
||||
}
|
||||
} else {
|
||||
} else if (setNull) {
|
||||
device.setLongitude(null);
|
||||
device.setLatitude(null);
|
||||
device.setLastLocationTime(null);
|
||||
device.setLocationType(null);
|
||||
}
|
||||
|
||||
device.setLastTime(at);
|
||||
|
@ -62,7 +63,7 @@ public class DeviceUtil {
|
|||
|
||||
IotDeviceSysInfo sys = iot.getSys();
|
||||
if (sys != null) {
|
||||
setIotSysInfo(device, sys, iot.getAt());
|
||||
setIotSysInfo(device, sys, iot.getAt(), false);
|
||||
}
|
||||
device.setSoftwareVersion(iot.getVer());
|
||||
}
|
||||
|
@ -75,4 +76,16 @@ public class DeviceUtil {
|
|||
public static boolean isOrderUsing(DeviceVO device) {
|
||||
return device != null && device.getOrderDeviceId() != null && OrderDeviceStatus.inUse().contains(device.getOrderDeviceStatus());
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断经纬度是否有效
|
||||
* @param lon 经度
|
||||
* @param lat 纬度
|
||||
* @return 是否有效
|
||||
*/
|
||||
public static boolean validLocation(BigDecimal lon, BigDecimal lat) {
|
||||
return lon != null && lat != null
|
||||
&& !MathUtils.equals(lon, BigDecimal.ZERO)
|
||||
&& !MathUtils.equals(lat, BigDecimal.ZERO);
|
||||
}
|
||||
}
|
|
@ -84,4 +84,9 @@ public class LocationLog extends BaseEntity
|
|||
@Excel(name = "订单ID")
|
||||
@ApiModelProperty("订单ID")
|
||||
private Long orderId;
|
||||
|
||||
@Excel(name = "类型")
|
||||
@ApiModelProperty("类型(1设备定位 2手机定位)")
|
||||
private String type;
|
||||
|
||||
}
|
||||
|
|
|
@ -23,7 +23,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
bll.quality,
|
||||
bll.iot_status,
|
||||
bll.device_id,
|
||||
bll.order_id
|
||||
bll.order_id,
|
||||
bll.type
|
||||
<include refid="searchTables"/>
|
||||
</sql>
|
||||
|
||||
|
@ -48,6 +49,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="query.orderId != null "> and bll.order_id = #{query.orderId}</if>
|
||||
<if test="query.startTime != null"> and bll.at >= #{query.startTime}</if>
|
||||
<if test="query.endTime != null"> and bll.at <= #{query.endTime}</if>
|
||||
<if test="query.type != null and query.type != ''"> and bll.type = #{query.type}</if>
|
||||
<if test="query.timeRange != null and query.timeRange.size() > 1">
|
||||
and bll.at >= #{query.timeRange[0]}
|
||||
and bll.at <= #{query.timeRange[1]}
|
||||
|
@ -103,6 +105,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="iotStatus != null">iot_status,</if>
|
||||
<if test="deviceId != null">device_id,</if>
|
||||
<if test="orderId != null">order_id,</if>
|
||||
<if test="type != null">type,</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="mac != null and mac != ''">#{mac},</if>
|
||||
|
@ -120,6 +123,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="iotStatus != null">#{iotStatus},</if>
|
||||
<if test="deviceId != null">#{deviceId},</if>
|
||||
<if test="orderId != null">#{orderId},</if>
|
||||
<if test="type != null">#{type},</if>
|
||||
</trim>
|
||||
</insert>
|
||||
|
||||
|
@ -140,7 +144,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
quality,
|
||||
iot_status,
|
||||
device_id,
|
||||
order_id
|
||||
order_id,
|
||||
type
|
||||
</trim>
|
||||
values
|
||||
<foreach collection="list" item="i" separator=",">
|
||||
|
@ -175,6 +180,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="i.deviceId == null ">default,</if>
|
||||
<if test="i.orderId != null ">#{i.orderId},</if>
|
||||
<if test="i.orderId == null ">default,</if>
|
||||
<if test="i.type != null ">#{i.type},</if>
|
||||
<if test="i.type == null ">default,</if>
|
||||
</trim>
|
||||
</foreach>
|
||||
</insert>
|
||||
|
@ -203,6 +210,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="data.iotStatus != null">iot_status = #{data.iotStatus},</if>
|
||||
<if test="data.deviceId != null">device_id = #{data.deviceId},</if>
|
||||
<if test="data.orderId != null">order_id = #{data.orderId},</if>
|
||||
<if test="data.type != null">type = #{data.type},</if>
|
||||
</sql>
|
||||
|
||||
<delete id="deleteLocationLogByIds" parameterType="String">
|
||||
|
|
|
@ -2,7 +2,6 @@ package com.ruoyi.bst.locationLog.service;
|
|||
|
||||
import com.ruoyi.bst.device.domain.DeviceVO;
|
||||
import com.ruoyi.bst.locationLog.domain.LocationLog;
|
||||
import com.ruoyi.iot.domain.ReceiveMsg;
|
||||
|
||||
public interface LocationLogConverter {
|
||||
|
||||
|
|
|
@ -1,35 +1,16 @@
|
|||
package com.ruoyi.bst.locationLog.service.impl;
|
||||
|
||||
import com.ruoyi.bst.order.domain.enums.OrderStatus;
|
||||
import com.ruoyi.bst.orderDevice.domain.enums.OrderDeviceStatus;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.ruoyi.bst.device.domain.DeviceVO;
|
||||
import com.ruoyi.bst.device.service.DeviceIotService;
|
||||
import com.ruoyi.bst.device.service.DeviceService;
|
||||
import com.ruoyi.bst.device.utils.DeviceUtil;
|
||||
import com.ruoyi.bst.locationLog.domain.LocationLog;
|
||||
import com.ruoyi.bst.locationLog.service.LocationLogConverter;
|
||||
import com.ruoyi.common.utils.DateUtils;
|
||||
import com.ruoyi.bst.orderDevice.domain.enums.OrderDeviceStatus;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.iot.domain.IotDeviceSysInfo;
|
||||
import com.ruoyi.iot.domain.ReceiveMsg;
|
||||
import com.ruoyi.iot.service.IotConverter;
|
||||
import com.ruoyi.iot.util.IotUtil;
|
||||
|
||||
@Service
|
||||
public class LocationLogConverterImpl implements LocationLogConverter {
|
||||
|
||||
@Autowired
|
||||
private DeviceService deviceService;
|
||||
|
||||
@Autowired
|
||||
private DeviceIotService deviceIotService;
|
||||
|
||||
@Autowired
|
||||
private IotConverter iotConverter;
|
||||
|
||||
@Override
|
||||
public LocationLog toPo(DeviceVO device) {
|
||||
if (device == null || StringUtils.isBlank(device.getMac())) {
|
||||
|
@ -51,6 +32,7 @@ public class LocationLogConverterImpl implements LocationLogConverter {
|
|||
po.setLatitude(device.getLatitude());
|
||||
po.setAt(device.getLastLocationTime());
|
||||
po.setDeviceId(device.getId());
|
||||
po.setType(device.getLocationType());
|
||||
if (OrderDeviceStatus.inUse().contains(device.getOrderDeviceStatus())) {
|
||||
po.setOrderId(device.getOrderId());
|
||||
}
|
||||
|
|
|
@ -22,6 +22,8 @@ public class OrderVO extends Order implements IotDevice {
|
|||
private String deviceSn;
|
||||
@ApiModelProperty("当前设备车牌号")
|
||||
private String deviceVehicleNum;
|
||||
@ApiModelProperty("当前设备状态")
|
||||
private String deviceStatus;
|
||||
@ApiModelProperty("当前设备所属用户ID")
|
||||
private Long deviceMchId;
|
||||
@ApiModelProperty("结束子区域ID")
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
package com.ruoyi.bst.order.domain.dto;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 订单开锁请求参数
|
||||
*/
|
||||
@Data
|
||||
public class OrderOpenDeviceDTO {
|
||||
@ApiModelProperty("订单id")
|
||||
@NotNull(message = "订单id不能为空")
|
||||
private Long orderId;
|
||||
|
||||
@ApiModelProperty("手机定位经度")
|
||||
private BigDecimal lon;
|
||||
|
||||
@ApiModelProperty("手机定位纬度")
|
||||
private BigDecimal lat;
|
||||
|
||||
@ApiModelProperty("IOT是否必须成功")
|
||||
private Boolean requiredIot;
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package com.ruoyi.bst.order.domain.query;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class OrderRankQuery {
|
||||
|
||||
@ApiModelProperty("日期范围")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
||||
private List<LocalDate> dateRange;
|
||||
|
||||
}
|
|
@ -83,7 +83,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
bod.return_lon,
|
||||
bod.return_lat,
|
||||
bd.longitude as current_lon,
|
||||
bd.latitude as current_lat
|
||||
bd.latitude as current_lat,
|
||||
bd.status as device_status
|
||||
from <include refid="searchTables"/>
|
||||
</sql>
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ import com.ruoyi.bst.order.domain.dto.OrderChangeDeviceDTO;
|
|||
import com.ruoyi.bst.order.domain.dto.OrderCloseDeviceDTO;
|
||||
import com.ruoyi.bst.order.domain.dto.OrderCreateDTO;
|
||||
import com.ruoyi.bst.order.domain.dto.OrderEndDTO;
|
||||
import com.ruoyi.bst.order.domain.dto.OrderOpenDeviceDTO;
|
||||
import com.ruoyi.bst.order.domain.dto.OrderRefundDTO;
|
||||
import com.ruoyi.bst.order.domain.dto.OrderVerifyDTO;
|
||||
import com.ruoyi.bst.order.domain.vo.OrderEndVO;
|
||||
|
@ -158,7 +159,7 @@ public interface OrderService {
|
|||
* @param requiredIot 是否必须成功
|
||||
* @return 结果
|
||||
*/
|
||||
public DeviceIotVO openDevice(OrderVO order, boolean requiredIot);
|
||||
public DeviceIotVO openDevice(OrderOpenDeviceDTO dto);
|
||||
|
||||
/**
|
||||
* 操作订单设备关闭
|
||||
|
|
|
@ -23,14 +23,17 @@ import com.ruoyi.bst.bonus.service.BonusConverter;
|
|||
import com.ruoyi.bst.bonus.service.BonusService;
|
||||
import com.ruoyi.bst.device.domain.Device;
|
||||
import com.ruoyi.bst.device.domain.DeviceVO;
|
||||
import com.ruoyi.bst.device.domain.enums.DeviceLocationType;
|
||||
import com.ruoyi.bst.device.domain.enums.DeviceUnLockType;
|
||||
import com.ruoyi.bst.device.domain.vo.DeviceIotVO;
|
||||
import com.ruoyi.bst.device.service.DeviceIotService;
|
||||
import com.ruoyi.bst.device.service.DeviceService;
|
||||
import com.ruoyi.bst.device.service.impl.DeviceValidatorImpl;
|
||||
import com.ruoyi.bst.device.utils.DeviceUtil;
|
||||
import com.ruoyi.bst.fault.domain.Fault;
|
||||
import com.ruoyi.bst.fault.service.FaultConverter;
|
||||
import com.ruoyi.bst.fault.service.FaultService;
|
||||
import com.ruoyi.bst.locationLog.domain.LocationLog;
|
||||
import com.ruoyi.bst.locationLog.service.LocationLogConverter;
|
||||
import com.ruoyi.bst.locationLog.utils.LocationLogUtil;
|
||||
import com.ruoyi.bst.order.domain.Order;
|
||||
import com.ruoyi.bst.order.domain.OrderQuery;
|
||||
|
@ -43,6 +46,7 @@ import com.ruoyi.bst.order.domain.dto.OrderChangeDeviceDTO;
|
|||
import com.ruoyi.bst.order.domain.dto.OrderCloseDeviceDTO;
|
||||
import com.ruoyi.bst.order.domain.dto.OrderCreateDTO;
|
||||
import com.ruoyi.bst.order.domain.dto.OrderEndDTO;
|
||||
import com.ruoyi.bst.order.domain.dto.OrderOpenDeviceDTO;
|
||||
import com.ruoyi.bst.order.domain.dto.OrderRefundDTO;
|
||||
import com.ruoyi.bst.order.domain.dto.OrderVerifyDTO;
|
||||
import com.ruoyi.bst.order.domain.enums.OrderReturnType;
|
||||
|
@ -59,7 +63,6 @@ import com.ruoyi.bst.orderDevice.domain.OrderDevice;
|
|||
import com.ruoyi.bst.orderDevice.domain.OrderDeviceVO;
|
||||
import com.ruoyi.bst.orderDevice.domain.enums.OrderDeviceReason;
|
||||
import com.ruoyi.bst.orderDevice.domain.enums.OrderDeviceStatus;
|
||||
import com.ruoyi.bst.orderDevice.service.OrderDeviceConverter;
|
||||
import com.ruoyi.bst.orderDevice.service.OrderDeviceService;
|
||||
import com.ruoyi.bst.pay.domain.Pay;
|
||||
import com.ruoyi.bst.pay.domain.dto.PayRefundDTO;
|
||||
|
@ -69,6 +72,8 @@ import com.ruoyi.bst.pay.service.PayConverter;
|
|||
import com.ruoyi.bst.pay.service.PayService;
|
||||
import com.ruoyi.bst.refund.domain.enums.RefundType;
|
||||
import com.ruoyi.bst.sms.service.SmsService;
|
||||
import com.ruoyi.common.constant.CacheConstants;
|
||||
import com.ruoyi.common.core.redis.RedisCache;
|
||||
import com.ruoyi.common.core.redis.RedisLock;
|
||||
import com.ruoyi.common.core.redis.enums.RedisLockKey;
|
||||
import com.ruoyi.common.utils.DateUtils;
|
||||
|
@ -90,8 +95,6 @@ import lombok.extern.slf4j.Slf4j;
|
|||
@Service
|
||||
@Slf4j
|
||||
public class OrderServiceImpl implements OrderService {
|
||||
|
||||
private final DeviceValidatorImpl deviceValidatorImpl;
|
||||
@Autowired
|
||||
private OrderMapper orderMapper;
|
||||
|
||||
|
@ -144,7 +147,7 @@ public class OrderServiceImpl implements OrderService {
|
|||
private FaultService faultService;
|
||||
|
||||
@Autowired
|
||||
private OrderDeviceConverter orderDeviceConverter;
|
||||
private LocationLogConverter locationLogConverter;
|
||||
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
|
@ -152,9 +155,8 @@ public class OrderServiceImpl implements OrderService {
|
|||
@Autowired
|
||||
private SmsService smsService;
|
||||
|
||||
OrderServiceImpl(DeviceValidatorImpl deviceValidatorImpl) {
|
||||
this.deviceValidatorImpl = deviceValidatorImpl;
|
||||
}
|
||||
@Autowired
|
||||
private RedisCache redisCache;
|
||||
|
||||
/**
|
||||
* 查询订单
|
||||
|
@ -413,10 +415,8 @@ public class OrderServiceImpl implements OrderService {
|
|||
OrderDeviceVO orderDevice = bo.getOrderDevice();
|
||||
DeviceVO device = bo.getDevice();
|
||||
|
||||
// 处理其他线程操作
|
||||
scheduledExecutorService.execute(() -> {
|
||||
this.handleDeviceLocation(device, dto);
|
||||
});
|
||||
// 异步使用手机定位更新设备定位
|
||||
this.handleDeviceLocationAsync(device, dto.getLon(), dto.getLat());
|
||||
|
||||
// 设置订单数据
|
||||
order.setEndTime(LocalDateTime.now()); // 结束时间
|
||||
|
@ -471,19 +471,35 @@ public class OrderServiceImpl implements OrderService {
|
|||
return vo;
|
||||
}
|
||||
|
||||
// 使用手机定位设置设备定位
|
||||
private void handleDeviceLocation(DeviceVO device, OrderEndDTO dto) {
|
||||
if (dto.getLon() != null && dto.getLat() != null
|
||||
&& dto.getLon().compareTo(BigDecimal.ZERO) != 0
|
||||
&& dto.getLat().compareTo(BigDecimal.ZERO) != 0) {
|
||||
// 异步使用手机定位更新设备定位
|
||||
private void handleDeviceLocationAsync(DeviceVO device, BigDecimal lon, BigDecimal lat) {
|
||||
if (device != null && device.getId() != null && DeviceUtil.validLocation(lon, lat)) {
|
||||
scheduledExecutorService.execute(() -> {
|
||||
device.setLongitude(lon);
|
||||
device.setLatitude(lat);
|
||||
device.setLocationType(DeviceLocationType.PHONE.getCode());
|
||||
|
||||
// 更新设备定位
|
||||
Device data = new Device();
|
||||
data.setId(device.getId());
|
||||
data.setLongitude(dto.getLon());
|
||||
data.setLatitude(dto.getLat());
|
||||
data.setLongitude(device.getLongitude());
|
||||
data.setLatitude(device.getLatitude());
|
||||
data.setLocationType(device.getLocationType());
|
||||
int rows = deviceService.updateDevice(data);
|
||||
if (rows != 1) {
|
||||
log.error("通过手机定位修改设备定位失败deviceId={}", device.getId());
|
||||
}
|
||||
|
||||
// 转为定位日志
|
||||
LocationLog locationLog = locationLogConverter.toPo(device);
|
||||
if (locationLog == null) {
|
||||
log.error("转换定位日志失败: {}", device.getMac());
|
||||
return;
|
||||
}
|
||||
// 暂存到Redis缓存
|
||||
redisCache.rightPush(CacheConstants.LOCATION_LOG_QUEUE, locationLog);
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -648,8 +664,11 @@ public class OrderServiceImpl implements OrderService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DeviceIotVO openDevice(OrderVO order, boolean requiredIot) {
|
||||
ServiceUtil.assertion(order == null, "参数错误,order不允许为空");
|
||||
public DeviceIotVO openDevice(OrderOpenDeviceDTO dto) {
|
||||
ServiceUtil.assertion(dto == null, "参数错误,dto不允许为空");
|
||||
|
||||
OrderVO order = this.selectOrderById(dto.getOrderId());
|
||||
ServiceUtil.assertion(order == null, "ID为%s的订单不存在", dto.getOrderId());
|
||||
ServiceUtil.assertion(!OrderStatus.inUse().contains(order.getStatus()), "ID为%s的订单当前状态并非使用中,无法操作设备",
|
||||
order.getId());
|
||||
|
||||
|
@ -658,8 +677,16 @@ public class OrderServiceImpl implements OrderService {
|
|||
ServiceUtil.assertion(!OrderDeviceStatus.inUse().contains(orderDevice.getStatus()),
|
||||
"ID为%s的订单设备当前状态并非使用中,无法操作设备", order.getId());
|
||||
|
||||
return deviceIotService.unlock(orderDevice.getDeviceId(), DeviceUnLockType.USER, "订单开锁:" + order.getNo(),
|
||||
requiredIot);
|
||||
// 查询设备
|
||||
DeviceVO device = deviceService.selectDeviceById(orderDevice.getDeviceId());
|
||||
ServiceUtil.assertion(device == null, "ID为%s的设备不存在", orderDevice.getDeviceId());
|
||||
|
||||
// 异步使用手机定位更新设备定位
|
||||
this.handleDeviceLocationAsync(device, dto.getLon(), dto.getLat());
|
||||
|
||||
// 发送命令开锁
|
||||
return deviceIotService.unlock(device, DeviceUnLockType.USER, "订单开锁:" + order.getNo(),
|
||||
dto.getRequiredIot());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -688,6 +715,10 @@ public class OrderServiceImpl implements OrderService {
|
|||
ServiceUtil.assertion(inParkingVO.getInNoParking() != null && inParkingVO.getInNoParking(), "禁止在禁停区内停车");
|
||||
}
|
||||
|
||||
// 异步使用手机定位更新设备定位
|
||||
this.handleDeviceLocationAsync(device, dto.getLon(), dto.getLat());
|
||||
|
||||
// 发送命令锁车
|
||||
return deviceIotService.lock(device, false, "订单锁车:" + order.getNo(), dto.getRequiredIot());
|
||||
}
|
||||
|
||||
|
@ -711,6 +742,10 @@ public class OrderServiceImpl implements OrderService {
|
|||
OrderDevice newOrderDevice = bo.getNewOrderDevice();
|
||||
OrderVO order = bo.getOrder();
|
||||
OrderInParkingVO inParkingVO = bo.getInParkingVO();
|
||||
DeviceVO oldDevice = bo.getOldDevice();
|
||||
|
||||
// 异步使用手机定位更新设备定位
|
||||
this.handleDeviceLocationAsync(oldDevice, dto.getLon(), dto.getLat());
|
||||
|
||||
// 操作数据库
|
||||
Integer result = transactionTemplate.execute(status -> {
|
||||
|
|
|
@ -106,4 +106,12 @@ public interface IotService {
|
|||
* @return 结果
|
||||
*/
|
||||
CommandResponse setMusic(IotDevice device, String music, String reason);
|
||||
|
||||
/**
|
||||
* 上传数据
|
||||
* @param device 设备
|
||||
* @param reason 原因
|
||||
* @return 结果
|
||||
*/
|
||||
CommandResponse uploadData(IotDevice device, String reason);
|
||||
}
|
||||
|
|
|
@ -90,7 +90,7 @@ public class IotReceiveServiceImpl implements IotReceiveService {
|
|||
log.info("收到sys数据:{}", msg.getValue());
|
||||
IotDeviceSysInfo sys = IotUtil.toSysInfo(msg.getValue());
|
||||
LocalDateTime at = DateUtils.toLocalDateTime(msg.getAt());
|
||||
DeviceUtil.setIotSysInfo(device, sys, at);
|
||||
DeviceUtil.setIotSysInfo(device, sys, at, true);
|
||||
|
||||
// 更新设备信息
|
||||
device.setOnlineStatus(DeviceOnlineStatus.ONLINE.getStatus());
|
||||
|
|
|
@ -319,7 +319,8 @@ public class IotServiceImpl implements IotService {
|
|||
commandLogService.addLog(po, loginUser);
|
||||
}
|
||||
|
||||
private CommandResponse uploadData(IotDevice device, String reason) {
|
||||
@Override
|
||||
public CommandResponse uploadData(IotDevice device, String reason) {
|
||||
return sendCommand(device, IotConstants.COMMAND_UPLOAD_DATA, reason);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,12 +3,15 @@ package com.ruoyi.web.app;
|
|||
import java.math.BigDecimal;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.ruoyi.bst.device.domain.DeviceVO;
|
||||
import com.ruoyi.bst.device.domain.dto.DeviceBltUploadDTO;
|
||||
import com.ruoyi.bst.device.service.DeviceIotService;
|
||||
import com.ruoyi.bst.device.service.DeviceService;
|
||||
import com.ruoyi.common.annotation.Log;
|
||||
|
@ -58,4 +61,11 @@ public class AppDeviceIotController extends BaseController {
|
|||
|
||||
return toAjax(deviceIotService.play(device, IotConstants.PLAY_WARNING, "用户响铃寻车", true));
|
||||
}
|
||||
|
||||
@ApiOperation("蓝牙上传设备信息")
|
||||
@PutMapping("/bltUpload")
|
||||
@Log(title = "蓝牙上传设备信息", businessType = BusinessType.OTHER, bizType = LogBizType.DEVICE)
|
||||
public AjaxResult bltUpload(@RequestBody @Validated DeviceBltUploadDTO dto) {
|
||||
return toAjax(deviceIotService.bltUpload(dto));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import com.ruoyi.bst.order.domain.dto.OrderChangeDeviceDTO;
|
|||
import com.ruoyi.bst.order.domain.dto.OrderCloseDeviceDTO;
|
||||
import com.ruoyi.bst.order.domain.dto.OrderCreateDTO;
|
||||
import com.ruoyi.bst.order.domain.dto.OrderEndDTO;
|
||||
import com.ruoyi.bst.order.domain.dto.OrderOpenDeviceDTO;
|
||||
import com.ruoyi.bst.order.domain.enums.OrderReturnType;
|
||||
import com.ruoyi.bst.order.domain.enums.OrderStatus;
|
||||
import com.ruoyi.bst.order.domain.vo.OrderEndVO;
|
||||
|
@ -98,9 +99,9 @@ public class AppOrderController extends BaseController {
|
|||
return success(orderService.createOrder(dto));
|
||||
}
|
||||
|
||||
@ApiOperation("结束本人订单(还车)")
|
||||
@ApiOperation("结束订单(还车)")
|
||||
@PutMapping("/end")
|
||||
@Log(title = "结束本人订单(还车)", businessType = BusinessType.OTHER, bizIdName = "arg0", bizType = LogBizType.ORDER)
|
||||
@Log(title = "结束订单(还车)", businessType = BusinessType.OTHER, bizIdName = "arg0", bizType = LogBizType.ORDER)
|
||||
public AjaxResult endOrder(@RequestBody @Validated OrderEndDTO dto) {
|
||||
OrderVO order = orderService.selectOrderById(dto.getOrderId());
|
||||
ServiceUtil.assertion(!orderValidator.canEnd(order, getUserId()), "您无权结束ID为%s的订单", order.getId());
|
||||
|
@ -125,12 +126,13 @@ public class AppOrderController extends BaseController {
|
|||
@ApiOperation("订单开锁")
|
||||
@PutMapping("/openDevice")
|
||||
@Log(title = "订单开锁", businessType = BusinessType.OTHER, bizIdName = "arg0", bizType = LogBizType.ORDER)
|
||||
public AjaxResult openDevice(Long orderId) {
|
||||
OrderVO order = orderService.selectOrderById(orderId);
|
||||
public AjaxResult openDevice(@Validated OrderOpenDeviceDTO dto) {
|
||||
OrderVO order = orderService.selectOrderById(dto.getOrderId());
|
||||
ServiceUtil.assertion(order == null, "订单不存在");
|
||||
ServiceUtil.assertion(!orderValidator.canOpenDevice(order, getUserId()), "您无权操作ID为%s的订单设备开启", order.getId());
|
||||
ServiceUtil.assertion(orderValidator.isTimeout(order), "当前订单已超时,请在安全的区域还车");
|
||||
return success(orderService.openDevice(order, true));
|
||||
dto.setRequiredIot(true);
|
||||
return success(orderService.openDevice(dto));
|
||||
}
|
||||
|
||||
@ApiOperation("临时锁车")
|
||||
|
|
|
@ -2,9 +2,9 @@ package com.ruoyi.web.common;
|
|||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
import com.ruoyi.common.utils.ServiceUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
@ -20,6 +20,7 @@ import com.ruoyi.common.core.domain.model.LoginBody;
|
|||
import com.ruoyi.common.core.domain.model.WxLoginBody;
|
||||
import com.ruoyi.common.core.domain.vo.UserVO;
|
||||
import com.ruoyi.common.utils.SecurityUtils;
|
||||
import com.ruoyi.common.utils.ServiceUtil;
|
||||
import com.ruoyi.dashboard.constants.StatKeys;
|
||||
import com.ruoyi.dashboard.domain.stat.StatQuery;
|
||||
import com.ruoyi.dashboard.domain.stat.StatVO;
|
||||
|
@ -55,6 +56,9 @@ public class LoginController
|
|||
@Value("${ruoyi.loginById}")
|
||||
private Boolean loginById;
|
||||
|
||||
@Value("${ruoyi.loginByIdSecret}")
|
||||
private String loginByIdSecret;
|
||||
|
||||
/**
|
||||
* 登录方法
|
||||
*
|
||||
|
@ -86,8 +90,9 @@ public class LoginController
|
|||
// ID登录(测试)
|
||||
@PostMapping("/loginById")
|
||||
@Anonymous
|
||||
public AjaxResult loginById(Long userId) {
|
||||
public AjaxResult loginById(Long userId, String secret) {
|
||||
ServiceUtil.assertion(!loginById, "接口不可用");
|
||||
ServiceUtil.assertion(!Objects.equals(loginByIdSecret, secret), "接口不可用");
|
||||
AjaxResult ajax = AjaxResult.success();
|
||||
// 生成令牌
|
||||
String token = loginService.loginById(userId);
|
||||
|
|
|
@ -38,6 +38,8 @@ ruoyi:
|
|||
captchaType: math
|
||||
# 允许使用ID登录
|
||||
loginById: true
|
||||
# ID登录密钥
|
||||
loginByIdSecret: 123456
|
||||
|
||||
# 支付配置
|
||||
pay:
|
||||
|
|
Loading…
Reference in New Issue
Block a user