定位区域判断更新,更加准确

This commit is contained in:
磷叶 2025-04-11 15:35:25 +08:00
parent 578adc465c
commit 6336f41a79
25 changed files with 255 additions and 108 deletions

View File

@ -100,11 +100,14 @@ public class CacheConstants
* 运营区禁行区列表
*/
public static final String NO_RIDING_AREA_SUB_LIST = "no_riding_area_sub_list:";
/**
* 运营区停车区列表
*/
public static final String PARKING_AREA_SUB_LIST = "parking_area_sub_list:";
/**
* 运营区禁停区列表
*/
public static final String NO_PARKING_AREA_SUB_LIST = "no_parking_area_sub_list:";
/**
* 设备运营区处理状态

View File

@ -71,7 +71,7 @@ public class AreaUtil {
// 靠近运营区边界时的播报距离
BigDecimal boundaryDistance = area.getBoundaryDistance();
// 是否在禁行区内
// 是否靠近禁行区
AreaSubVO nearAreaSub = AreaSubUtil.getNearAreaSub(noRidingList, lon, lat, area.getError(), boundaryDistance);
vo.setNearNoRidingArea(nearAreaSub);
vo.setIsNearNoRidingArea(nearAreaSub != null);

View File

@ -215,7 +215,8 @@ public class AreaSubServiceImpl implements AreaSubService
if (areaId == null) {
return;
}
String key = CacheConstants.NO_RIDING_AREA_SUB_LIST + areaId;
redisCache.deleteObject(key);
redisCache.deleteObject(CacheConstants.NO_RIDING_AREA_SUB_LIST + areaId);
redisCache.deleteObject(CacheConstants.PARKING_AREA_SUB_LIST + areaId);
redisCache.deleteObject(CacheConstants.NO_PARKING_AREA_SUB_LIST + areaId);
}
}

View File

@ -20,7 +20,11 @@ public interface BalanceLogService
* @param id 余额日志主键
* @return 余额日志
*/
public BalanceLogVO selectBalanceLogById(Long id);
public BalanceLogVO selectBalanceLogById(Long id, boolean scope);
default BalanceLogVO selectBalanceLogById(Long id) {
return this.selectBalanceLogById(id, false);
}
/**
* 查询余额日志列表

View File

@ -5,12 +5,14 @@ import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.github.pagehelper.PageHelper;
import com.ruoyi.bst.balanceLog.domain.BalanceLog;
import com.ruoyi.bst.balanceLog.domain.BalanceLogQuery;
import com.ruoyi.bst.balanceLog.domain.BalanceLogVO;
import com.ruoyi.bst.balanceLog.mapper.BalanceLogMapper;
import com.ruoyi.bst.balanceLog.service.BalanceLogService;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.collection.CollectionUtils;
/**
* 余额日志Service业务层处理
@ -31,9 +33,21 @@ public class BalanceLogServiceImpl implements BalanceLogService
* @return 余额日志
*/
@Override
public BalanceLogVO selectBalanceLogById(Long id)
{
return balanceLogMapper.selectBalanceLogById(id);
public BalanceLogVO selectBalanceLogById(Long id, boolean scope) {
if (id == null) {
return null;
}
BalanceLogQuery query = new BalanceLogQuery();
query.setId(id);
query.setScope(scope);
return this.selectOne(query);
}
private BalanceLogVO selectOne(BalanceLogQuery query) {
PageHelper.startPage(1, 1);
List<BalanceLogVO> list = balanceLogMapper.selectBalanceLogList(query);
return CollectionUtils.firstElement(list);
}
/**

View File

@ -145,18 +145,6 @@ public class Order extends BaseEntity
@ApiModelProperty("套餐区间计费规则json")
private List<SuitIntervalFeeRule> suitIntervalRule;
@Excel(name = "还车定位方式", readConverterExp = "1=设备定位,2=手机定位")
@ApiModelProperty("还车定位方式")
private String returnMode;
@Excel(name = "还车经度")
@ApiModelProperty("还车经度")
private BigDecimal returnLon;
@Excel(name = "还车纬度")
@ApiModelProperty("还车纬度")
private BigDecimal returnLat;
@Excel(name = "取消备注")
@ApiModelProperty("取消备注")
private String cancelRemark;
@ -179,10 +167,6 @@ public class Order extends BaseEntity
@ApiModelProperty("开始子区域ID")
private Long startAreaSubId;
@Excel(name = "结束子区域ID")
@ApiModelProperty("结束子区域ID")
private Long endAreaSubId;
@Excel(name = "开始子区域名称")
@ApiModelProperty("开始子区域名称")
private String startAreaSubName;

View File

@ -59,4 +59,20 @@ public class OrderVO extends Order {
@ApiModelProperty("订单设备列表")
private List<OrderDeviceVO> orderDeviceList;
@ApiModelProperty("结束子区域ID")
private Long endAreaSubId;
@ApiModelProperty("结束子区域名称")
private String endAreaSubName;
@ApiModelProperty("还车定位方式")
private String returnMode;
@ApiModelProperty("还车经度")
private BigDecimal returnLon;
@ApiModelProperty("还车纬度")
private BigDecimal returnLat;
}

View File

@ -1,5 +1,8 @@
package com.ruoyi.bst.order.domain.dto;
import java.math.BigDecimal;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
@ -20,4 +23,8 @@ public class OrderVerifyDTO {
@ApiModelProperty("审核备注")
@Size(max = 200, message = "审核备注不能超过200个字符")
private String remark;
@ApiModelProperty("车损费")
@Min(value = 0, message = "车损费不允许小于0")
private BigDecimal deductionFee;
}

View File

@ -136,4 +136,12 @@ public interface OrderMapper
*/
List<StringIntegerVO> selectStatusCount(@Param("query") OrderQuery query);
/**
* 增加车损费
* @param id
* @param deductionFee
* @return
*/
int addDeductionFee(@Param("id") Long id, @Param("deductionFee") BigDecimal deductionFee);
}

View File

@ -38,18 +38,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
bo.suit_rental_unit,
bo.suit_riding_rule,
bo.suit_start_rule,
bo.return_mode,
bo.suit_interval_rule,
bo.return_lon,
bo.return_lat,
bo.pay_amount,
bo.pay_expire_time,
bo.max_time,
bo.suit_seconds,
bo.start_area_sub_id,
bo.end_area_sub_id,
bo.start_area_sub_name,
bo.end_area_sub_name,
bo.end_reason,
bo.order_device_id,
bo.area_return_verify,
@ -70,7 +65,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
bod.device_mac,
bod.device_sn,
bod.device_vehicle_num,
bod.device_mch_id
bod.device_mch_id,
bod.end_area_sub_id,
bod.end_area_sub_name,
bod.return_mode,
bod.return_lon,
bod.return_lat
from <include refid="searchTables"/>
</sql>
@ -88,9 +88,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="query.suitType != null and query.suitType != ''"> and bo.suit_type = #{query.suitType}</if>
<if test="query.areaId != null "> and bo.area_id = #{query.areaId}</if>
<if test="query.userId != null "> and bo.user_id = #{query.userId}</if>
<if test="query.deviceId != null "> and bo.device_id = #{query.deviceId}</if>
<if test="query.deviceMac != null and query.deviceMac != ''"> and bo.device_mac like concat('%', #{query.deviceMac}, '%')</if>
<if test="query.deviceSn != null and query.deviceSn != ''"> and bo.device_sn like concat('%', #{query.deviceSn}, '%')</if>
<if test="query.deviceId != null "> and bod.device_id = #{query.deviceId}</if>
<if test="query.deviceMac != null and query.deviceMac != ''"> and bod.device_mac like concat('%', #{query.deviceMac}, '%')</if>
<if test="query.deviceSn != null and query.deviceSn != ''"> and bod.device_sn like concat('%', #{query.deviceSn}, '%')</if>
<if test="query.payId != null "> and bo.pay_id = #{query.payId}</if>
<if test="query.mark != null and query.mark != ''"> and bo.mark like concat('%', #{query.mark}, '%')</if>
<if test="query.status != null and query.status != ''"> and bo.status = #{query.status}</if>
@ -98,21 +98,21 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="query.suitId != null "> and bo.suit_id = #{query.suitId}</if>
<if test="query.suitRentalUnit != null and query.suitRentalUnit != ''"> and bo.suit_rental_unit = #{query.suitRentalUnit}</if>
<if test="query.suitRidingRule != null and query.suitRidingRule != ''"> and bo.suit_riding_rule = #{query.suitRidingRule}</if>
<if test="query.returnMode != null and query.returnMode != ''"> and bo.return_mode = #{query.returnMode}</if>
<if test="query.returnMode != null and query.returnMode != ''"> and bod.return_mode = #{query.returnMode}</if>
<if test="query.suitName != null and query.suitName != ''"> and bo.suit_name like concat('%', #{query.suitName}, '%')</if>
<if test="query.areaName != null and query.areaName != ''"> and ba.name like concat('%', #{query.areaName}, '%')</if>
<if test="query.userName != null and query.userName != ''"> and su.nick_name like concat('%', #{query.userName}, '%')</if>
<if test="query.deviceVehicleNum != null and query.deviceVehicleNum != ''"> and bo.device_vehicle_num like concat('%', #{query.deviceVehicleNum}, '%')</if>
<if test="query.deviceVehicleNum != null and query.deviceVehicleNum != ''"> and bod.device_vehicle_num like concat('%', #{query.deviceVehicleNum}, '%')</if>
<if test="query.payNo != null and query.payNo != ''"> and bp.no like concat('%', #{query.payNo}, '%')</if>
<if test="query.userPhone != null and query.userPhone != ''"> and su.user_name like concat('%', #{query.userPhone}, '%')</if>
<if test="query.eqNo != null and query.eqNo != ''"> and bo.no = #{query.eqNo}</if>
<if test="query.startAreaSubId != null "> and bo.start_area_sub_id = #{query.startAreaSubId}</if>
<if test="query.endAreaSubId != null "> and bo.end_area_sub_id = #{query.endAreaSubId}</if>
<if test="query.endAreaSubId != null "> and bod.end_area_sub_id = #{query.endAreaSubId}</if>
<if test="query.startAreaSubName != null and query.startAreaSubName != ''"> and bo.start_area_sub_name like concat('%', #{query.startAreaSubName}, '%')</if>
<if test="query.endAreaSubName != null and query.endAreaSubName != ''"> and bo.end_area_sub_name like concat('%', #{query.endAreaSubName}, '%')</if>
<if test="query.endAreaSubName != null and query.endAreaSubName != ''"> and bod.end_area_sub_name like concat('%', #{query.endAreaSubName}, '%')</if>
<if test="query.maxTimeStart != null"> and bo.max_time &gt;= #{query.maxTimeStart}</if>
<if test="query.maxTimeEnd != null"> and bo.max_time &lt;= #{query.maxTimeEnd}</if>
<if test="query.deviceMchId != null "> and bo.device_mch_id = #{query.deviceMchId}</if>
<if test="query.deviceMchId != null "> and bod.device_mch_id = #{query.deviceMchId}</if>
<if test="query.endReason != null and query.endReason != ''"> and bo.end_reason like concat('%', #{query.endReason}, '%')</if>
<if test="query.orderDeviceId != null "> and bo.order_device_id = #{query.orderDeviceId}</if>
<if test="query.areaReturnVerify != null "> and bo.area_return_verify = #{query.areaReturnVerify}</if>
@ -201,18 +201,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="suitRentalUnit != null">suit_rental_unit,</if>
<if test="suitRidingRule != null">suit_riding_rule,</if>
<if test="suitStartRule != null">suit_start_rule,</if>
<if test="returnMode != null">return_mode,</if>
<if test="suitIntervalRule != null">suit_interval_rule,</if>
<if test="returnLon != null">return_lon,</if>
<if test="returnLat != null">return_lat,</if>
<if test="payAmount != null">pay_amount,</if>
<if test="payExpireTime != null">pay_expire_time,</if>
<if test="maxTime != null">max_time,</if>
<if test="suitSeconds != null">suit_seconds,</if>
<if test="startAreaSubId != null">start_area_sub_id,</if>
<if test="endAreaSubId != null">end_area_sub_id,</if>
<if test="startAreaSubName != null">start_area_sub_name,</if>
<if test="endAreaSubName != null">end_area_sub_name,</if>
<if test="endReason != null">end_reason,</if>
<if test="orderDeviceId != null">order_device_id,</if>
<if test="areaReturnVerify != null">area_return_verify,</if>
@ -247,18 +242,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="suitRentalUnit != null">#{suitRentalUnit},</if>
<if test="suitRidingRule != null">#{suitRidingRule},</if>
<if test="suitStartRule != null">#{suitStartRule, typeHandler=com.ruoyi.bst.suit.mapper.typehanlder.SuitStartFeeRuleJsonTypeHandler},</if>
<if test="returnMode != null">#{returnMode},</if>
<if test="suitIntervalRule != null">#{suitIntervalRule, typeHandler=com.ruoyi.bst.suit.mapper.typehanlder.SuitIntervalFeeRuleJsonListTypeHandler},</if>
<if test="returnLon != null">#{returnLon},</if>
<if test="returnLat != null">#{returnLat},</if>
<if test="payAmount != null">#{payAmount},</if>
<if test="payExpireTime != null">#{payExpireTime},</if>
<if test="maxTime != null">#{maxTime},</if>
<if test="suitSeconds != null">#{suitSeconds},</if>
<if test="startAreaSubId != null">#{startAreaSubId},</if>
<if test="endAreaSubId != null">#{endAreaSubId},</if>
<if test="startAreaSubName != null">#{startAreaSubName},</if>
<if test="endAreaSubName != null">#{endAreaSubName},</if>
<if test="endReason != null">#{endReason},</if>
<if test="orderDeviceId != null">#{orderDeviceId},</if>
<if test="areaReturnVerify != null">#{areaReturnVerify},</if>
@ -303,18 +293,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="data.suitRentalUnit != null">suit_rental_unit = #{data.suitRentalUnit},</if>
<if test="data.suitRidingRule != null">suit_riding_rule = #{data.suitRidingRule},</if>
<if test="data.suitStartRule != null">suit_start_rule = #{data.suitStartRule, typeHandler=com.ruoyi.bst.suit.mapper.typehanlder.SuitStartFeeRuleJsonTypeHandler},</if>
<if test="data.returnMode != null">return_mode = #{data.returnMode},</if>
<if test="data.suitIntervalRule != null">suit_interval_rule = #{data.suitIntervalRule, typeHandler=com.ruoyi.bst.suit.mapper.typehanlder.SuitIntervalFeeRuleJsonListTypeHandler},</if>
<if test="data.returnLon != null">return_lon = #{data.returnLon},</if>
<if test="data.returnLat != null">return_lat = #{data.returnLat},</if>
<if test="data.payAmount != null">pay_amount = #{data.payAmount},</if>
<if test="data.payExpireTime != null">pay_expire_time = #{data.payExpireTime},</if>
<if test="data.maxTime != null">max_time = #{data.maxTime},</if>
<if test="data.suitSeconds != null">suit_seconds = #{data.suitSeconds},</if>
<if test="data.startAreaSubId != null">start_area_sub_id = #{data.startAreaSubId},</if>
<if test="data.endAreaSubId != null">end_area_sub_id = #{data.endAreaSubId},</if>
<if test="data.startAreaSubName != null">start_area_sub_name = #{data.startAreaSubName},</if>
<if test="data.endAreaSubName != null">end_area_sub_name = #{data.endAreaSubName},</if>
<if test="data.endReason != null">end_reason = #{data.endReason},</if>
<if test="data.orderDeviceId != null">order_device_id = #{data.orderDeviceId},</if>
<if test="data.areaReturnVerify != null">area_return_verify = #{data.areaReturnVerify},</if>
@ -451,5 +436,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</where>
group by `key`
</select>
<!-- addDeductionFee -->
<update id="addDeductionFee">
update bst_order bo
set bo.deduction_fee = bo.deduction_fee + #{deductionFee},
bo.total_fee = bo.total_fee + #{deductionFee}
where bo.id = #{id} and bo.total_fee + #{deductionFee} &lt;= bo.deposit_fee
</update>
</mapper>

View File

@ -137,7 +137,7 @@ public class OrderConverterImpl implements OrderConverter{
// 查询设备所属人的加盟信息
AreaJoinVO areaJoin = areaJoinService.selectByUserArea(device.getMchId(), device.getAreaId());
bo.setAreaJoin(areaJoin);
// 查询运营区的合伙人列表
List<AreaJoinVO> partners = areaJoinService.selectListByAreaId(device.getAreaId(), AreaJoinType.PARTNER.getCode());
bo.setPartners(partners);
@ -176,7 +176,7 @@ public class OrderConverterImpl implements OrderConverter{
// 生成订单设备
OrderDevice orderDevice = this.generateOrderDevice(bo);
bo.setOrderDevice(orderDevice);
return bo;
}
@ -317,12 +317,8 @@ public class OrderConverterImpl implements OrderConverter{
data.setRidingFee(order.getRidingFee());
data.setTotalFee(order.getTotalFee());
data.setEndTime(order.getEndTime());
data.setEndAreaSubId(order.getEndAreaSubId());
data.setDuration(order.getDuration());
data.setDistance(order.getDistance());
data.setReturnLon(order.getReturnLon());
data.setReturnLat(order.getReturnLat());
data.setReturnMode(order.getReturnMode());
data.setReturnType(order.getReturnType());
data.setEndAreaSubName(order.getEndAreaSubName());
data.setEndReason(order.getEndReason());
@ -399,7 +395,7 @@ public class OrderConverterImpl implements OrderConverter{
newDevice = deviceService.selectDeviceBySn(dto.getDeviceSn());
ServiceUtil.assertion(newDevice == null, "SN为%s的设备不存在", dto.getDeviceSn());
} else {
throw new RuntimeException("参数错误,deviceId和deviceSn不能同时为空");
throw new RuntimeException("参数错误,请选择需要更换的车辆。");
}
bo.setNewDevice(newDevice);

View File

@ -40,7 +40,6 @@ import com.ruoyi.bst.order.domain.dto.OrderCreateDTO;
import com.ruoyi.bst.order.domain.dto.OrderEndDTO;
import com.ruoyi.bst.order.domain.dto.OrderRefundDTO;
import com.ruoyi.bst.order.domain.dto.OrderVerifyDTO;
import com.ruoyi.bst.order.domain.enums.OrderReturnMode;
import com.ruoyi.bst.order.domain.enums.OrderReturnType;
import com.ruoyi.bst.order.domain.enums.OrderStatus;
import com.ruoyi.bst.order.domain.vo.OrderFeeVO;
@ -394,49 +393,25 @@ public class OrderServiceImpl implements OrderService
// 转为BO对象
OrderEndBO bo = orderConverter.toEndBO(dto);
// 校验参数
boolean ignoreInParking = dto.getIsAdmin() != null && dto.getIsAdmin();
orderValidator.validate(bo, ignoreInParking);
boolean isAdmin = dto.getIsAdmin() != null && dto.getIsAdmin();
orderValidator.validate(bo, isAdmin);
OrderVO order = bo.getOrder();
OrderInParkingVO inParkingVO = bo.getInParkingVO();
AreaVO area = bo.getArea();
OrderDeviceVO orderDevice = bo.getOrderDevice();
// 设置订单数据
order.setEndTime(LocalDateTime.now()); // 结束时间
order.setDuration(Duration.between(order.getStartTime(), order.getEndTime()).getSeconds());
order.setDistance(LocationLogUtil.calcDistance(bo.getPositionList()));
order.setEndReason(dto.getEndReason());
// 实际还车点
if (inParkingVO != null ) {
if (inParkingVO.getActualAreaSub() != null) {
AreaSubVO areaSub = inParkingVO.getActualAreaSub();
order.setEndAreaSubId(areaSub.getId());
order.setEndAreaSubName(areaSub.getName());
}
order.setReturnLon(inParkingVO.getActualLon());
order.setReturnLat(inParkingVO.getActualLat());
if (inParkingVO.getDeviceInArea() != null) {
order.setReturnMode(OrderReturnMode.DEVICE.getCode());
} else {
order.setReturnMode(OrderReturnMode.MOBILE.getCode());
}
}
// 还车类型
order.setReturnType(ignoreInParking ? OrderReturnType.AUXILIARY.getCode() : OrderReturnType.NORMAL.getCode());
// 根据是否需要审核设置订单状态
if (order.getAreaReturnVerify() != null && order.getAreaReturnVerify() && !ignoreInParking) {
// 更新订单状态为待审核
order.setStatus(OrderStatus.WAIT_VERIFY.getCode());
} else {
// 更新订单状态为已完成
order.setStatus(OrderStatus.FINISHED.getCode());
}
order.setReturnType(isAdmin ? OrderReturnType.AUXILIARY.getCode() : OrderReturnType.NORMAL.getCode());
// 订单状态
this.setOrderStatus(order, isAdmin);
// 订单费用
OrderFeeVO orderFee = OrderUtil.calcOrderFee(order, area, inParkingVO, order.getEndTime());
order.setManageFee(orderFee.getManageFee());
order.setDispatchFee(orderFee.getDispatchFee());
order.setRidingFee(orderFee.getRidingFee());
order.setTotalFee(orderFee.getTotalFee());
this.setOrderFee(order, area, inParkingVO);
Integer result = transactionTemplate.execute(status -> {
// 更新订单数据
@ -458,8 +433,7 @@ public class OrderServiceImpl implements OrderService
}
// 结束订单设备
OrderDeviceVO orderDevice = bo.getOrderDevice();
int finish = orderDeviceService.finish(orderDevice, dto.getPicture());
int finish = orderDeviceService.finish(orderDevice, dto.getPicture(), inParkingVO);
ServiceUtil.assertion(finish != 1, "结束ID为%s的订单设备失败", orderDevice.getId());
// 设备上锁必须放最后因为会操作设备
@ -472,6 +446,27 @@ public class OrderServiceImpl implements OrderService
return result == null ? 0 : 1;
}
// 设置订单状态
private void setOrderStatus(OrderVO order, boolean isAdmin) {
// 根据是否需要审核设置订单状态
if (order.getAreaReturnVerify() != null && order.getAreaReturnVerify() && !isAdmin) {
// 更新订单状态为待审核
order.setStatus(OrderStatus.WAIT_VERIFY.getCode());
} else {
// 更新订单状态为已完成
order.setStatus(OrderStatus.FINISHED.getCode());
}
}
// 设置订单费用
private void setOrderFee(OrderVO order, AreaVO area, OrderInParkingVO inParkingVO) {
OrderFeeVO orderFee = OrderUtil.calcOrderFee(order, area, inParkingVO, order.getEndTime());
order.setManageFee(orderFee.getManageFee());
order.setDispatchFee(orderFee.getDispatchFee());
order.setRidingFee(orderFee.getRidingFee());
order.setTotalFee(orderFee.getTotalFee());
}
// 退还剩余金额
private int refundRemainAmount(Long orderId) {
// 查询订单
@ -613,11 +608,12 @@ public class OrderServiceImpl implements OrderService
OrderDeviceVO oldOrderDevice = bo.getOldOrderDevice();
OrderDevice newOrderDevice = bo.getNewOrderDevice();
OrderVO order = bo.getOrder();
OrderInParkingVO inParkingVO = bo.getInParkingVO();
// 操作数据库
Integer result = transactionTemplate.execute(status -> {
// 结束当前订单设备
int finish = orderDeviceService.finish(oldOrderDevice, dto.getFaultPicture());
int finish = orderDeviceService.finish(oldOrderDevice, dto.getFaultPicture(), inParkingVO);
ServiceUtil.assertion(finish != 1, "结束当前订单设备失败");
// 创建故障信息
@ -670,6 +666,14 @@ public class OrderServiceImpl implements OrderService
int rows = orderMapper.updateByQuery(data, query);
ServiceUtil.assertion(rows != 1, "ID为%s的订单审核失败", dto.getId());
// 更新车损费
if (dto.getDeductionFee() != null && dto.getDeductionFee().compareTo(BigDecimal.ZERO) > 0) {
BigDecimal max = MathUtils.subtractDecimal(order.getDepositFee(), order.getTotalFee());
ServiceUtil.assertion(MathUtils.biggerThan(dto.getDeductionFee(), max), "ID为%s的订单车损费不允许超过%s", dto.getId(), max);
int add = orderMapper.addDeductionFee(order.getId(), dto.getDeductionFee());
ServiceUtil.assertion(add != 1, "ID为%s的订单增加车损费失败请刷新后重试", order.getId());
}
// 若审核通过则退还剩余金额
if (pass && rows > 0) {
int refund = this.refundRemainAmount(order.getId());
@ -685,4 +689,5 @@ public class OrderServiceImpl implements OrderService
return result == null ? 0 : result;
}
}

View File

@ -3,6 +3,7 @@ package com.ruoyi.bst.order.service.impl;
import java.util.List;
import java.util.Objects;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -34,6 +35,7 @@ import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.collection.CollectionUtils;
@Service
@Slf4j
public class OrderValidatorImpl implements OrderValidator{
@Autowired
@ -144,6 +146,7 @@ public class OrderValidatorImpl implements OrderValidator{
@Override
public void checkInParking(AreaVO area, OrderInParkingVO inParkingVO) {
log.info("【还车定位校验】运营区:{},定位数据:{}", area.getName(), inParkingVO);
ServiceUtil.assertion(inParkingVO == null, "参数错误,停车点信息不存在");
boolean mustInParking = area.getParkingReturn() != null && area.getParkingReturn();
@ -169,8 +172,8 @@ public class OrderValidatorImpl implements OrderValidator{
if (order != null) {
DeviceQuery query = OrderUtil.toChangeDeviceQuery(order);
List<DeviceVO> list = deviceService.selectDeviceList(query);
ServiceUtil.assertion(CollectionUtils.isEmptyElement(list), "ID为%s的车辆当前状态不可使用", device.getId());
ServiceUtil.assertion(!CollectionUtils.map(list, DeviceVO::getId).contains(device.getId()), "ID为%s的车辆不可在当前订单上使用", device.getId());
ServiceUtil.assertion(CollectionUtils.isEmptyElement(list), "当前订单无法使用ID为%s的车辆请换一辆车或者重新下单。", device.getId());
ServiceUtil.assertion(!CollectionUtils.map(list, DeviceVO::getId).contains(device.getId()), "当前订单无法使用ID为%s的车辆请换一辆车或者重新下单。", device.getId());
}
}
@ -180,6 +183,6 @@ public class OrderValidatorImpl implements OrderValidator{
ServiceUtil.assertion(order != null
&& order.getAreaReturnVerify() != null
&& order.getAreaReturnVerify()
&& StringUtils.isBlank(picture), "请上传还车图片");
&& StringUtils.isBlank(picture), "请上传还车视频");
}
}

View File

@ -115,8 +115,6 @@ public class OrderUtil {
return vo;
}
/**
* 获取在停车点信息
* @param area 运营区

View File

@ -82,4 +82,29 @@ public class OrderDevice extends BaseEntity
@ApiModelProperty("还车图片")
private String finishPicture;
@Excel(name = "开始子区域ID")
@ApiModelProperty("开始子区域ID")
private Long startAreaSubId;
@Excel(name = "结束子区域ID")
@ApiModelProperty("结束子区域ID")
private Long endAreaSubId;
@Excel(name = "开始子区域名称")
@ApiModelProperty("开始子区域名称")
private String startAreaSubName;
@Excel(name = "结束子区域名称")
@ApiModelProperty("结束子区域名称")
private String endAreaSubName;
@Excel(name = "还车定位方式", readConverterExp = "1=设备定位,2=手机定位")
@ApiModelProperty("还车定位方式1设备定位 2手机定位")
private String returnMode;
@ApiModelProperty("还车经度")
private BigDecimal returnLon;
@ApiModelProperty("还车纬度")
private BigDecimal returnLat;
}

View File

@ -23,6 +23,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
bod.device_mch_id,
bod.device_model_full_endurance,
bod.finish_picture,
bod.start_area_sub_id,
bod.end_area_sub_id,
bod.start_area_sub_name,
bod.end_area_sub_name,
bod.return_mode,
bod.return_lon,
bod.return_lat,
bo.no as order_no,
bo.user_id as order_user_id,
bo.start_time as order_start_time,
@ -58,6 +65,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="query.deviceLockStatus != null and query.deviceLockStatus != ''"> and bd.lock_status = #{query.deviceLockStatus}</if>
<if test="query.orderUserName != null and query.orderUserName != ''"> and su.nick_name like concat('%', #{query.orderUserName}, '%')</if>
<if test="query.deviceMchName != null and query.deviceMchName != ''"> and mch.nick_name like concat('%', #{query.deviceMchName}, '%')</if>
<if test="query.startAreaSubId != null"> and bod.start_area_sub_id = #{query.startAreaSubId}</if>
<if test="query.endAreaSubId != null"> and bod.end_area_sub_id = #{query.endAreaSubId}</if>
<if test="query.startAreaSubName != null and query.startAreaSubName != ''"> and bod.start_area_sub_name like concat('%', #{query.startAreaSubName}, '%')</if>
<if test="query.endAreaSubName != null and query.endAreaSubName != ''"> and bod.end_area_sub_name like concat('%', #{query.endAreaSubName}, '%')</if>
<if test="query.returnMode != null and query.returnMode != ''"> and bod.return_mode = #{query.returnMode}</if>
<if test="query.statusList != null and query.statusList.size() > 0">
and bod.status in
<foreach item="item" collection="query.statusList" separator="," open="(" close=")">
@ -110,6 +122,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="deviceMchId != null">device_mch_id,</if>
<if test="deviceModelFullEndurance != null">device_model_full_endurance,</if>
<if test="finishPicture != null and finishPicture != ''">finish_picture,</if>
<if test="startAreaSubId != null">start_area_sub_id,</if>
<if test="endAreaSubId != null">end_area_sub_id,</if>
<if test="startAreaSubName != null and startAreaSubName != ''">start_area_sub_name,</if>
<if test="endAreaSubName != null and endAreaSubName != ''">end_area_sub_name,</if>
<if test="returnMode != null and returnMode != ''">return_mode,</if>
<if test="returnLon != null ">return_lon,</if>
<if test="returnLat != null">return_lat,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">#{id},</if>
@ -127,6 +146,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="deviceMchId != null">#{deviceMchId},</if>
<if test="deviceModelFullEndurance != null">#{deviceModelFullEndurance},</if>
<if test="finishPicture != null and finishPicture != ''">#{finishPicture},</if>
<if test="startAreaSubId != null">#{startAreaSubId},</if>
<if test="endAreaSubId != null">#{endAreaSubId},</if>
<if test="startAreaSubName != null and startAreaSubName != ''">#{startAreaSubName},</if>
<if test="endAreaSubName != null and endAreaSubName != ''">#{endAreaSubName},</if>
<if test="returnMode != null and returnMode != ''">#{returnMode},</if>
<if test="returnLon != null">#{returnLon},</if>
<if test="returnLat != null">#{returnLat},</if>
</trim>
</insert>
@ -153,6 +179,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="data.deviceMchId != null">device_mch_id = #{data.deviceMchId},</if>
<if test="data.deviceModelFullEndurance != null">device_model_full_endurance = #{data.deviceModelFullEndurance},</if>
<if test="data.finishPicture != null and data.finishPicture != ''">finish_picture = #{data.finishPicture},</if>
<if test="data.startAreaSubId != null">start_area_sub_id = #{data.startAreaSubId},</if>
<if test="data.endAreaSubId != null">end_area_sub_id = #{data.endAreaSubId},</if>
<if test="data.startAreaSubName != null and data.startAreaSubName != ''">start_area_sub_name = #{data.startAreaSubName},</if>
<if test="data.endAreaSubName != null and data.endAreaSubName != ''">end_area_sub_name = #{data.endAreaSubName},</if>
<if test="data.returnMode != null and data.returnMode != ''">return_mode = #{data.returnMode},</if>
<if test="data.returnLon != null">return_lon = #{data.returnLon},</if>
<if test="data.returnLat != null">return_lat = #{data.returnLat},</if>
</sql>
<delete id="deleteOrderDeviceById" parameterType="Long">

View File

@ -2,6 +2,7 @@ package com.ruoyi.bst.orderDevice.service;
import java.util.List;
import com.ruoyi.bst.order.domain.vo.OrderInParkingVO;
import com.ruoyi.bst.orderDevice.domain.OrderDevice;
import com.ruoyi.bst.orderDevice.domain.OrderDeviceQuery;
import com.ruoyi.bst.orderDevice.domain.OrderDeviceVO;
@ -92,7 +93,7 @@ public interface OrderDeviceService
* @param orderDevice 订单设备
* @return 结果
*/
public int finish(OrderDeviceVO orderDevice, String picture);
public int finish(OrderDeviceVO orderDevice, String picture, OrderInParkingVO inParkingVO);
/**
* 开始订单设备

View File

@ -8,8 +8,11 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;
import com.github.pagehelper.PageHelper;
import com.ruoyi.bst.areaSub.domain.AreaSubVO;
import com.ruoyi.bst.device.service.DeviceIotService;
import com.ruoyi.bst.device.service.DeviceService;
import com.ruoyi.bst.order.domain.enums.OrderReturnMode;
import com.ruoyi.bst.order.domain.vo.OrderInParkingVO;
import com.ruoyi.bst.order.service.OrderService;
import com.ruoyi.bst.orderDevice.domain.OrderDevice;
import com.ruoyi.bst.orderDevice.domain.OrderDeviceQuery;
@ -183,16 +186,31 @@ public class OrderDeviceServiceImpl implements OrderDeviceService
}
@Override
public int finish(OrderDeviceVO orderDevice, String picture) {
public int finish(OrderDeviceVO orderDevice, String picture, OrderInParkingVO inParkingVO) {
ServiceUtil.assertion(orderDevice == null, "订单设备不能为空");
ServiceUtil.assertion(!OrderDeviceStatus.canFinish().contains(orderDevice.getStatus()), "订单设备状态不允许结束");
Integer result = transactionTemplate.execute(status -> {
// 修改状态
// 修改数据
OrderDevice data = new OrderDevice();
data.setStatus(OrderDeviceStatus.FINISHED.getCode());
data.setEndTime(LocalDateTime.now());
data.setFinishPicture(picture);
// 还车数据
if (inParkingVO != null) {
if (inParkingVO.getActualAreaSub() != null) {
AreaSubVO areaSub = inParkingVO.getActualAreaSub();
data.setEndAreaSubId(areaSub.getId());
data.setEndAreaSubName(areaSub.getName());
}
data.setReturnLon(inParkingVO.getActualLon());
data.setReturnLat(inParkingVO.getActualLat());
if (inParkingVO.getDeviceInArea() != null) {
data.setReturnMode(OrderReturnMode.DEVICE.getCode());
} else {
data.setReturnMode(OrderReturnMode.MOBILE.getCode());
}
}
OrderDeviceQuery query = new OrderDeviceQuery();
query.setId(orderDevice.getId());
query.setStatusList(OrderDeviceStatus.canFinish());

View File

@ -3,6 +3,7 @@ package com.ruoyi.bst.suit.domain;
import java.math.BigDecimal;
import java.util.List;
import javax.validation.Valid;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
@ -57,6 +58,7 @@ public class Suit extends BaseEntity
@Excel(name = "免费骑行时长(分钟)")
@ApiModelProperty("免费骑行时长(分钟)")
@NotNull(message = "免费骑行时长不能为空", groups = {ValidGroup.Create.class})
@Min(value = 0, message = "免费骑行时长不能小于0")
private Integer freeRideTime;
@Excel(name = "租赁单位", readConverterExp = "m=inutes分钟,h=ours小时,d=ay天")
@ -72,10 +74,12 @@ public class Suit extends BaseEntity
@Excel(name = "起步价计费规则")
@ApiModelProperty("起步价计费规则")
@Valid
private SuitStartFeeRule startRule;
@Excel(name = "区间计费规则")
@ApiModelProperty("区间计费规则")
@Valid
private List<SuitIntervalFeeRule> intervalRule;
@Excel(name = "骑行价格说明")

View File

@ -2,6 +2,8 @@ package com.ruoyi.bst.suit.domain.vo;
import java.math.BigDecimal;
import javax.validation.constraints.Min;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ -12,14 +14,18 @@ import lombok.Data;
public class SuitIntervalFeeRule {
@ApiModelProperty("区间开始时间")
@Min(value = 0, message = "区间开始时间不能小于0")
private Integer start;
@ApiModelProperty("区间结束时间")
@Min(value = 0, message = "区间结束时间不能小于0")
private Integer end;
@ApiModelProperty("计费间隔")
@Min(value = 1, message = "计费间隔不能小于1")
private Integer eachUnit;
@ApiModelProperty("费用")
@Min(value = 0, message = "费用不能小于0")
private BigDecimal fee;
}

View File

@ -2,6 +2,8 @@ package com.ruoyi.bst.suit.domain.vo;
import java.math.BigDecimal;
import javax.validation.constraints.Min;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ -11,14 +13,18 @@ import lombok.Data;
@Data
public class SuitStartFeeRule {
@ApiModelProperty("起步时长")
@Min(value = 0, message = "起步时长不能小于0")
private Integer startingTime;
@ApiModelProperty("起步价格(元)")
@Min(value = 0, message = "起步价格不能小于0")
private BigDecimal startingPrice;
@ApiModelProperty("超时时长")
@Min(value = 0, message = "超时时长不能小于0")
private Integer timeoutTime;
@ApiModelProperty("超时价格(元)")
@Min(value = 0, message = "超时价格不能小于0")
private BigDecimal timeoutPrice;
}

View File

@ -161,6 +161,7 @@ public class IotReceiveServiceImpl implements IotReceiveService {
boolean isInAreaMax = locationArea.getIsInAreaMax() != null && locationArea.getIsInAreaMax();
boolean isInNoRidingArea = locationArea.getIsInNoRidingArea() != null && locationArea.getIsInNoRidingArea();
boolean isNearNoRidingArea = locationArea.getIsNearNoRidingArea() != null && locationArea.getIsNearNoRidingArea();
boolean hasAreaBoundary = StringUtils.isNotBlank(area.getBoundary()); // 是否有运营区边界
// 在运营区内并且不在禁行区内并且车辆为强制断电状态为车辆上电
if (isInAreaMax && !isInNoRidingArea && isQLocked && !isOpen && hasOrder) {
@ -172,7 +173,7 @@ public class IotReceiveServiceImpl implements IotReceiveService {
if(isOpen) {
// 超出运营区域外的最大范围且车辆为开锁状态强制断电
boolean areaOutOutage = area.getAreaOutOutage() != null && area.getAreaOutOutage(); // 运营区外断电
if (areaOutOutage) {
if (areaOutOutage && hasAreaBoundary) {
// 超出运营区最大边界强制断电
if (!isInAreaMax) {
deviceIotService.qLock(device, "超出运营区外边界最大值,强制断电", false);

View File

@ -1,5 +1,6 @@
package com.ruoyi.web.app;
import com.ruoyi.common.annotation.Anonymous;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@ -24,6 +25,7 @@ public class AppSuitController extends BaseController {
@ApiOperation("获取车型可用套餐列表")
@GetMapping("/listByModel")
@Anonymous
public AjaxResult listByModel(SuitQuery query) {
if (query.getModelId() == null) {
return error("车型ID不能为空");
@ -32,7 +34,7 @@ public class AppSuitController extends BaseController {
query.setStatus(SuitStatus.ENABLED.getCode());
return success(suitService.selectSuitList(query));
}
@ApiOperation("获取套餐详情")
@GetMapping("/detail")
public AjaxResult detail(@RequestParam Long id) {

View File

@ -5,7 +5,12 @@ import java.util.List;
import javax.servlet.http.HttpServletResponse;
import com.ruoyi.bst.areaSub.domain.AreaSubVO;
import com.ruoyi.bst.areaSub.service.AreaSubService;
import com.ruoyi.bst.areaSub.utils.AreaSubUtil;
import com.ruoyi.bst.order.utils.OrderUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.OrderUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
@ -58,6 +63,9 @@ public class AreaController extends BaseController
@Autowired
private UserValidator userValidator;
@Autowired
private AreaSubService areaSubService;
/**
* 查询运营区列表
*/
@ -168,6 +176,14 @@ public class AreaController extends BaseController
@PreAuthorize("@ss.hasPermi('bst:area:locationArea')")
@GetMapping("/locationArea")
public AjaxResult locationArea(BigDecimal lon, BigDecimal lat, Long areaId) {
return success(areaService.selectLocationArea(lon, lat, areaId));
AjaxResult ajax = AjaxResult.success();
ajax.put("ride", areaService.selectLocationArea(lon, lat, areaId));
AreaVO area = areaService.selectAreaById(areaId);
List<AreaSubVO> areaSubList = areaSubService.selectParkingAreaByAreaId(areaId);
AreaSubVO deviceAreaSub = AreaSubUtil.getInAreaSub(areaSubList, lon, lat, area.getError());
ajax.put("return", deviceAreaSub);
return ajax;
}
}

View File

@ -44,6 +44,7 @@ public class BalanceLogController extends BaseController
{
startPage();
startOrderBy();
query.setScope(true);
List<BalanceLogVO> list = balanceLogService.selectBalanceLogList(query);
return getDataTable(list);
}
@ -56,6 +57,7 @@ public class BalanceLogController extends BaseController
@PostMapping("/export")
public void export(HttpServletResponse response, BalanceLogQuery query)
{
query.setScope(true);
List<BalanceLogVO> list = balanceLogService.selectBalanceLogList(query);
ExcelUtil<BalanceLogVO> util = new ExcelUtil<BalanceLogVO>(BalanceLogVO.class);
util.exportExcel(response, list, "余额日志数据");
@ -68,6 +70,6 @@ public class BalanceLogController extends BaseController
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id)
{
return success(balanceLogService.selectBalanceLogById(id));
return success(balanceLogService.selectBalanceLogById(id, true));
}
}