更新订单超时逻辑,不断电

This commit is contained in:
磷叶 2025-04-30 10:38:36 +08:00
parent 4f63af8214
commit f5dbfb9057
13 changed files with 88 additions and 13 deletions

View File

@ -188,6 +188,10 @@ public class Area extends BaseEntity implements LogBizParam
@ApiModelProperty("响铃寻车是否必须在范围内") @ApiModelProperty("响铃寻车是否必须在范围内")
private Boolean requiredRingRadius; private Boolean requiredRingRadius;
@Excel(name = "超时是否自动断电")
@ApiModelProperty("超时是否自动断电")
private Boolean timeoutLock;
@Override @Override
public Object logBizId() { public Object logBizId() {
return id; return id;

View File

@ -48,6 +48,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
ba.outage_distance, ba.outage_distance,
ba.ring_radius, ba.ring_radius,
ba.required_ring_radius, ba.required_ring_radius,
ba.timeout_lock,
su.nick_name as user_name, su.nick_name as user_name,
su.agent_id as agent_id, su.agent_id as agent_id,
su.user_name as user_phone, su.user_name as user_phone,
@ -85,6 +86,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="query.userName != null and query.userName != ''"> and su.nick_name like concat('%', #{query.userName}, '%')</if> <if test="query.userName != null and query.userName != ''"> and su.nick_name like concat('%', #{query.userName}, '%')</if>
<if test="query.createName != null and query.createName != ''"> and suc.nick_name like concat('%', #{query.createName}, '%')</if> <if test="query.createName != null and query.createName != ''"> and suc.nick_name like concat('%', #{query.createName}, '%')</if>
<if test="query.userPhone != null and query.userPhone != ''"> and su.user_name like concat('%', #{query.userPhone}, '%')</if> <if test="query.userPhone != null and query.userPhone != ''"> and su.user_name like concat('%', #{query.userPhone}, '%')</if>
<if test="query.timeoutLock != null "> and ba.timeout_lock = #{query.timeoutLock}</if>
<if test="query.ids != null and query.ids.size() > 0"> <if test="query.ids != null and query.ids.size() > 0">
and ba.id in and ba.id in
<foreach collection="query.ids" item="item" open="(" separator="," close=")"> <foreach collection="query.ids" item="item" open="(" separator="," close=")">
@ -166,6 +168,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="outageDistance != null">outage_distance,</if> <if test="outageDistance != null">outage_distance,</if>
<if test="ringRadius != null">ring_radius,</if> <if test="ringRadius != null">ring_radius,</if>
<if test="requiredRingRadius != null">required_ring_radius,</if> <if test="requiredRingRadius != null">required_ring_radius,</if>
<if test="timeoutLock != null">timeout_lock,</if>
</trim> </trim>
<trim prefix="values (" suffix=")" suffixOverrides=","> <trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="userId != null">#{userId},</if> <if test="userId != null">#{userId},</if>
@ -204,6 +207,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="outageDistance != null">#{outageDistance},</if> <if test="outageDistance != null">#{outageDistance},</if>
<if test="ringRadius != null">#{ringRadius},</if> <if test="ringRadius != null">#{ringRadius},</if>
<if test="requiredRingRadius != null">#{requiredRingRadius},</if> <if test="requiredRingRadius != null">#{requiredRingRadius},</if>
<if test="timeoutLock != null">#{timeoutLock},</if>
</trim> </trim>
</insert> </insert>
@ -252,6 +256,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="data.outageDistance != null">outage_distance = #{data.outageDistance},</if> <if test="data.outageDistance != null">outage_distance = #{data.outageDistance},</if>
<if test="data.ringRadius != null">ring_radius = #{data.ringRadius},</if> <if test="data.ringRadius != null">ring_radius = #{data.ringRadius},</if>
<if test="data.requiredRingRadius != null">required_ring_radius = #{data.requiredRingRadius},</if> <if test="data.requiredRingRadius != null">required_ring_radius = #{data.requiredRingRadius},</if>
<if test="data.timeoutLock != null">timeout_lock = #{data.timeoutLock},</if>
</sql> </sql>
<delete id="deleteAreaById" parameterType="Long"> <delete id="deleteAreaById" parameterType="Long">

View File

@ -32,6 +32,7 @@ public class AreaConverterImpl implements AreaConverter {
po.setAreaOutOutage(data.getAreaOutOutage()); po.setAreaOutOutage(data.getAreaOutOutage());
po.setBoundaryDistance(data.getBoundaryDistance()); po.setBoundaryDistance(data.getBoundaryDistance());
po.setOutageDistance(data.getOutageDistance()); po.setOutageDistance(data.getOutageDistance());
po.setTimeoutLock(data.getTimeoutLock());
// 还车设置 // 还车设置
po.setError(data.getError()); po.setError(data.getError());
@ -74,6 +75,7 @@ public class AreaConverterImpl implements AreaConverter {
po.setAreaOutOutage(data.getAreaOutOutage()); po.setAreaOutOutage(data.getAreaOutOutage());
po.setBoundaryDistance(data.getBoundaryDistance()); po.setBoundaryDistance(data.getBoundaryDistance());
po.setOutageDistance(data.getOutageDistance()); po.setOutageDistance(data.getOutageDistance());
po.setTimeoutLock(data.getTimeoutLock());
// 还车设置 // 还车设置
po.setError(data.getError()); po.setError(data.getError());

View File

@ -6,6 +6,7 @@ import java.util.List;
import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.Geometry;
import com.ruoyi.bst.areaSub.domain.AreaSubVO; import com.ruoyi.bst.areaSub.domain.AreaSubVO;
import com.ruoyi.bst.areaSub.domain.enums.AreaSubStatus;
import com.ruoyi.common.utils.collection.CollectionUtils; import com.ruoyi.common.utils.collection.CollectionUtils;
import com.ruoyi.common.utils.map.GeoUtils; import com.ruoyi.common.utils.map.GeoUtils;
@ -35,6 +36,9 @@ public class AreaSubUtil {
if (geometry == null) { if (geometry == null) {
continue; continue;
} }
if (AreaSubStatus.DISABLED.getCode().equals(area.getStatus())) {
continue;
}
if(area.getError() != null ){ if(area.getError() != null ){
tolerance = area.getError(); tolerance = area.getError();
} }
@ -67,6 +71,9 @@ public class AreaSubUtil {
if (geometry == null) { if (geometry == null) {
continue; continue;
} }
if (AreaSubStatus.DISABLED.getCode().equals(area.getStatus())) {
continue;
}
if (area.getError() != null) { if (area.getError() != null) {
tolerance = area.getError(); tolerance = area.getError();
} }

View File

@ -10,7 +10,7 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
@Data @Data
public class OrderQuery extends OrderVO { public class OrderQuery extends OrderVO {
@ApiModelProperty("id列表") @ApiModelProperty("id列表")
private List<Long> ids; private List<Long> ids;

View File

@ -5,12 +5,13 @@ import java.time.LocalDateTime;
import java.util.List; import java.util.List;
import com.ruoyi.bst.orderDevice.domain.OrderDeviceVO; import com.ruoyi.bst.orderDevice.domain.OrderDeviceVO;
import com.ruoyi.iot.interfaces.IotDevice;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
@Data @Data
public class OrderVO extends Order { public class OrderVO extends Order implements IotDevice {
// 订单设备 // 订单设备
@ApiModelProperty("当前设备ID") @ApiModelProperty("当前设备ID")
@ -33,6 +34,10 @@ public class OrderVO extends Order {
private BigDecimal returnLon; private BigDecimal returnLon;
@ApiModelProperty("还车纬度") @ApiModelProperty("还车纬度")
private BigDecimal returnLat; private BigDecimal returnLat;
@ApiModelProperty("当前经度")
private BigDecimal currentLon;
@ApiModelProperty("当前纬度")
private BigDecimal currentLat;
@ApiModelProperty("订单设备列表") @ApiModelProperty("订单设备列表")
private List<OrderDeviceVO> orderDeviceList; private List<OrderDeviceVO> orderDeviceList;
@ -65,4 +70,18 @@ public class OrderVO extends Order {
private BigDecimal payAdminRefund; private BigDecimal payAdminRefund;
@Override
public String mac() {
return this.deviceMac;
}
@Override
public BigDecimal longitude() {
return this.currentLon;
}
@Override
public BigDecimal latitude() {
return this.currentLat;
}
} }

View File

@ -10,6 +10,9 @@ import lombok.Data;
@Data @Data
public class OrderInParkingVO { public class OrderInParkingVO {
@ApiModelProperty("停车区数量")
private Integer parkingCount;
@ApiModelProperty("手机定位所在停车区") @ApiModelProperty("手机定位所在停车区")
private AreaSubVO mobileAreaSub; private AreaSubVO mobileAreaSub;

View File

@ -72,7 +72,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
bod.end_area_sub_name, bod.end_area_sub_name,
bod.return_mode, bod.return_mode,
bod.return_lon, bod.return_lon,
bod.return_lat bod.return_lat,
bd.longitude as current_lon,
bd.latitude as current_lat
from <include refid="searchTables"/> from <include refid="searchTables"/>
</sql> </sql>
@ -82,6 +84,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
left join sys_user su on bo.user_id = su.user_id left join sys_user su on bo.user_id = su.user_id
left join bst_pay bp on bo.pay_id = bp.id left join bst_pay bp on bo.pay_id = bp.id
left join bst_order_device bod on bod.id = bo.order_device_id left join bst_order_device bod on bod.id = bo.order_device_id
left join bst_device bd on bod.device_id = bd.id
</sql> </sql>
<sql id="searchCondition"> <sql id="searchCondition">

View File

@ -90,4 +90,11 @@ public interface OrderValidator {
*/ */
boolean canOperate(Long orderId); boolean canOperate(Long orderId);
/**
* 校验订单是否超时
* @param order 订单
* @return 是否超时
*/
boolean isTimeout(OrderVO order);
} }

View File

@ -1,5 +1,6 @@
package com.ruoyi.bst.order.service.impl; package com.ruoyi.bst.order.service.impl;
import java.time.LocalDateTime;
import java.time.LocalTime; import java.time.LocalTime;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
@ -165,6 +166,12 @@ public class OrderValidatorImpl implements OrderValidator{
public void checkInParking(AreaVO area, OrderInParkingVO inParkingVO) { public void checkInParking(AreaVO area, OrderInParkingVO inParkingVO) {
log.info("【还车定位校验】运营区:{},定位数据:{}", area.getName(), inParkingVO); log.info("【还车定位校验】运营区:{},定位数据:{}", area.getName(), inParkingVO);
ServiceUtil.assertion(inParkingVO == null, "参数错误,停车点信息不存在"); ServiceUtil.assertion(inParkingVO == null, "参数错误,停车点信息不存在");
ServiceUtil.assertion(area == null, "参数错误,运营区信息不存在");
if (inParkingVO.getParkingCount() != null && inParkingVO.getParkingCount() == 0) {
log.warn("运营区{}的停车区数量为0无需校验停车区", area.getName());
return;
}
boolean mustInParking = area.getParkingReturn() != null && area.getParkingReturn(); boolean mustInParking = area.getParkingReturn() != null && area.getParkingReturn();
boolean inParking = inParkingVO.getInParking() != null && inParkingVO.getInParking(); boolean inParking = inParkingVO.getInParking() != null && inParkingVO.getInParking();
@ -224,4 +231,9 @@ public class OrderValidatorImpl implements OrderValidator{
List<Long> list = orderMapper.selectIdByQuery(query); List<Long> list = orderMapper.selectIdByQuery(query);
return new HashSet<>(list).containsAll(orderIds); return new HashSet<>(list).containsAll(orderIds);
} }
@Override
public boolean isTimeout(OrderVO order) {
return order != null && order.getMaxTime() != null && order.getMaxTime().isBefore(LocalDateTime.now());
}
} }

View File

@ -126,6 +126,9 @@ public class OrderUtil {
BigDecimal deviceLon = device.getLongitude(); BigDecimal deviceLon = device.getLongitude();
BigDecimal deviceLat = device.getLatitude(); BigDecimal deviceLat = device.getLatitude();
// 停车区数量
vo.setParkingCount(parkingList.size());
// 通过设备定位获取所在停车点 // 通过设备定位获取所在停车点
AreaSubVO deviceAreaSub = AreaSubUtil.getInAreaSub(parkingList, deviceLon, deviceLat, areaError); AreaSubVO deviceAreaSub = AreaSubUtil.getInAreaSub(parkingList, deviceLon, deviceLat, areaError);
vo.setDeviceAreaSub(deviceAreaSub); vo.setDeviceAreaSub(deviceAreaSub);

View File

@ -9,18 +9,19 @@ import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner; import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import com.ruoyi.bst.device.service.DeviceIotService;
import com.ruoyi.bst.locationLog.domain.vo.LocationLogPositionVO; import com.ruoyi.bst.locationLog.domain.vo.LocationLogPositionVO;
import com.ruoyi.bst.locationLog.service.LocationLogService; import com.ruoyi.bst.locationLog.service.LocationLogService;
import com.ruoyi.bst.locationLog.utils.LocationLogUtil; import com.ruoyi.bst.locationLog.utils.LocationLogUtil;
import com.ruoyi.bst.order.domain.OrderQuery; import com.ruoyi.bst.order.domain.OrderQuery;
import com.ruoyi.bst.order.domain.OrderVO; import com.ruoyi.bst.order.domain.OrderVO;
import com.ruoyi.bst.order.domain.dto.OrderEndDTO;
import com.ruoyi.bst.order.domain.enums.OrderReturnType;
import com.ruoyi.bst.order.domain.enums.OrderStatus; import com.ruoyi.bst.order.domain.enums.OrderStatus;
import com.ruoyi.bst.order.mapper.OrderMapper; import com.ruoyi.bst.order.mapper.OrderMapper;
import com.ruoyi.bst.order.service.OrderService; import com.ruoyi.bst.order.service.OrderService;
import com.ruoyi.common.utils.ServiceUtil; import com.ruoyi.common.utils.ServiceUtil;
import com.ruoyi.common.utils.collection.CollectionUtils; import com.ruoyi.common.utils.collection.CollectionUtils;
import com.ruoyi.iot.constants.IotConstants;
import com.ruoyi.iot.service.IotService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -37,6 +38,11 @@ public class OrderTask implements ApplicationRunner {
@Autowired @Autowired
private LocationLogService locationLogService; private LocationLogService locationLogService;
@Autowired
private DeviceIotService deviceIotService;
@Autowired
private IotService iotService;
@Override @Override
public void run(ApplicationArguments args) throws Exception { public void run(ApplicationArguments args) throws Exception {
@ -55,9 +61,9 @@ public class OrderTask implements ApplicationRunner {
} }
/** /**
* 关闭超过最大可用时间的订单 * 处理超过最大可用时间的订单
*/ */
public void closeExpireMaxTimeOrder() { public void handleExpireMaxTimeOrder() {
// 查询超过最大可用时间的订单 // 查询超过最大可用时间的订单
OrderQuery query = new OrderQuery(); OrderQuery query = new OrderQuery();
query.setStatusList(OrderStatus.inUse()); query.setStatusList(OrderStatus.inUse());
@ -71,11 +77,12 @@ public class OrderTask implements ApplicationRunner {
for (OrderVO order : orderList) { for (OrderVO order : orderList) {
try { try {
OrderEndDTO dto = new OrderEndDTO(); // OrderEndDTO dto = new OrderEndDTO();
dto.setReturnType(OrderReturnType.SYSTEM.getCode()); // dto.setReturnType(OrderReturnType.SYSTEM.getCode());
dto.setOrderId(order.getId()); // dto.setOrderId(order.getId());
dto.setEndReason("超时系统自动结束"); // dto.setEndReason("超时系统自动结束");
orderService.endOrder(dto); // orderService.endOrder(dto);
iotService.play(order, IotConstants.PLAY_END, "超时系统警告");
} catch (Exception e) { } catch (Exception e) {
log.error("结束订单失败订单ID{}", order.getId(), e); log.error("结束订单失败订单ID{}", order.getId(), e);
} }

View File

@ -129,6 +129,7 @@ public class AppOrderController extends BaseController {
OrderVO order = orderService.selectOrderById(orderId); OrderVO order = orderService.selectOrderById(orderId);
ServiceUtil.assertion(order == null, "订单不存在"); ServiceUtil.assertion(order == null, "订单不存在");
ServiceUtil.assertion(!orderValidator.canOpenDevice(order, getUserId()), "您无权操作ID为%s的订单设备开启", order.getId()); ServiceUtil.assertion(!orderValidator.canOpenDevice(order, getUserId()), "您无权操作ID为%s的订单设备开启", order.getId());
ServiceUtil.assertion(orderValidator.isTimeout(order), "当前订单已超时,请在安全的区域还车");
return success(orderService.openDevice(order, true)); return success(orderService.openDevice(order, true));
} }
@ -139,6 +140,7 @@ public class AppOrderController extends BaseController {
OrderVO order = orderService.selectOrderById(dto.getOrderId()); OrderVO order = orderService.selectOrderById(dto.getOrderId());
ServiceUtil.assertion(order == null, "订单不存在"); ServiceUtil.assertion(order == null, "订单不存在");
ServiceUtil.assertion(!orderValidator.canCloseDevice(order, getUserId()), "您无权操作ID为%s的订单设备关闭", order.getId()); ServiceUtil.assertion(!orderValidator.canCloseDevice(order, getUserId()), "您无权操作ID为%s的订单设备关闭", order.getId());
ServiceUtil.assertion(orderValidator.isTimeout(order), "当前订单已超时,请在安全的区域还车");
dto.setRequiredIot(true); dto.setRequiredIot(true);
return success(orderService.closeDevice(dto)); return success(orderService.closeDevice(dto));
} }
@ -149,6 +151,7 @@ public class AppOrderController extends BaseController {
public AjaxResult changeDevice(@RequestBody @Validated OrderChangeDeviceDTO dto) { public AjaxResult changeDevice(@RequestBody @Validated OrderChangeDeviceDTO dto) {
OrderVO order = orderService.selectOrderById(dto.getOrderId()); OrderVO order = orderService.selectOrderById(dto.getOrderId());
ServiceUtil.assertion(!orderValidator.canChangeDevice(order, getUserId()), "您无权操作ID为%s的订单换车", order.getId()); ServiceUtil.assertion(!orderValidator.canChangeDevice(order, getUserId()), "您无权操作ID为%s的订单换车", order.getId());
ServiceUtil.assertion(orderValidator.isTimeout(order), "当前订单已超时,请在安全的区域还车");
dto.setUserId(getUserId()); dto.setUserId(getUserId());
dto.setUserName(getNickName()); dto.setUserName(getNickName());
return toAjax(orderService.changeDevice(dto)); return toAjax(orderService.changeDevice(dto));