车辆实时计费
This commit is contained in:
parent
bcd0a46d87
commit
304aed9f8b
@ -6,11 +6,11 @@ import com.cdzy.user.model.dto.EbikeUserCyclingDto;
|
||||
import com.cdzy.user.model.dto.EbikeUserCyclingEndDto;
|
||||
import com.cdzy.user.model.entity.EbikeOrder;
|
||||
import com.cdzy.user.model.vo.EbikeBikeInfoVo;
|
||||
import com.cdzy.user.model.vo.EbikeBikeRealInfoVo;
|
||||
import com.cdzy.user.model.vo.EbikeRevenueStatisticsVo;
|
||||
import com.cdzy.user.model.vo.EbikeUserAllOrdersVo;
|
||||
import com.cdzy.user.service.EbikeOrderService;
|
||||
import com.ebike.feign.model.dto.FeignEbikeDto;
|
||||
import com.ebike.feign.model.dto.FeignEbikeUserBikeInfo;
|
||||
import com.ebike.feign.model.vo.FeignEbikeBikeRadiusVo;
|
||||
import com.mybatisflex.core.paginate.Page;
|
||||
import jakarta.annotation.Resource;
|
||||
@ -131,4 +131,15 @@ public class EbikeOrderController {
|
||||
List<EbikeRevenueStatisticsVo> revenueStatistics = ebikeOrderService.getRevenueStatistics();
|
||||
return JsonResult.success(revenueStatistics);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询车辆实时信息
|
||||
*
|
||||
* @return 车辆实时信息
|
||||
*/
|
||||
@GetMapping("getBikeRealTimeInfo")
|
||||
public JsonResult<?> getBikeRealTimeInfo(@RequestParam("orderId") Long orderId) {
|
||||
EbikeBikeRealInfoVo revenueStatistics = ebikeOrderService.getBikeRealTimeInfo(orderId);
|
||||
return JsonResult.success(revenueStatistics);
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,26 @@
|
||||
package com.cdzy.user.model.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 车辆实时信息
|
||||
*
|
||||
* @author yanglei
|
||||
* @since 2025-12-26 11:03
|
||||
*/
|
||||
@Data
|
||||
public class EbikeBikeRealInfoVo implements Serializable {
|
||||
|
||||
/**
|
||||
* 当前费用
|
||||
*/
|
||||
private BigDecimal cost;
|
||||
|
||||
/**
|
||||
* 车辆可用里程
|
||||
*/
|
||||
private Long mileage;
|
||||
}
|
||||
@ -5,10 +5,10 @@ import com.cdzy.user.model.dto.EbikeUserCyclingDto;
|
||||
import com.cdzy.user.model.dto.EbikeUserCyclingEndDto;
|
||||
import com.cdzy.user.model.entity.EbikeOrder;
|
||||
import com.cdzy.user.model.vo.EbikeBikeInfoVo;
|
||||
import com.cdzy.user.model.vo.EbikeBikeRealInfoVo;
|
||||
import com.cdzy.user.model.vo.EbikeRevenueStatisticsVo;
|
||||
import com.cdzy.user.model.vo.EbikeUserAllOrdersVo;
|
||||
import com.ebike.feign.model.dto.FeignEbikeDto;
|
||||
import com.ebike.feign.model.dto.FeignEbikeUserBikeInfo;
|
||||
import com.ebike.feign.model.dto.FeignOrderPaymentDto;
|
||||
import com.ebike.feign.model.vo.FeignEbikeBikeRadiusVo;
|
||||
import com.mybatisflex.core.paginate.Page;
|
||||
@ -128,4 +128,12 @@ public interface EbikeOrderService extends IService<EbikeOrder> {
|
||||
* @return 营收统计
|
||||
*/
|
||||
List<EbikeRevenueStatisticsVo> getRevenueStatistics();
|
||||
|
||||
/**
|
||||
* 查询车辆实时信息
|
||||
*
|
||||
* @param orderId 订单id
|
||||
* @return 车辆实时信息
|
||||
*/
|
||||
EbikeBikeRealInfoVo getBikeRealTimeInfo(Long orderId);
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@ import com.cdzy.user.model.entity.EbikeOrder;
|
||||
import com.cdzy.user.model.entity.EbikeOrderDetail;
|
||||
import com.cdzy.user.model.entity.EbikePayment;
|
||||
import com.cdzy.user.model.vo.EbikeBikeInfoVo;
|
||||
import com.cdzy.user.model.vo.EbikeBikeRealInfoVo;
|
||||
import com.cdzy.user.model.vo.EbikeRevenueStatisticsVo;
|
||||
import com.cdzy.user.model.vo.EbikeUserAllOrdersVo;
|
||||
import com.cdzy.user.service.EbikeOrderDetailService;
|
||||
@ -88,10 +89,10 @@ public class EbikeOrderServiceImpl extends ServiceImpl<EbikeOrderMapper, EbikeOr
|
||||
}
|
||||
}
|
||||
// 校验用户是否已进行实名认证
|
||||
boolean userIsVerify = ebikeUserRealInfoService.checkUserIsVerify(userId);
|
||||
if (!userIsVerify) {
|
||||
throw new EbikeException("请先完成实名认证");
|
||||
}
|
||||
// boolean userIsVerify = ebikeUserRealInfoService.checkUserIsVerify(userId);
|
||||
// if (!userIsVerify) {
|
||||
// throw new EbikeException("请先完成实名认证");
|
||||
// }
|
||||
EbikeBikeInfoVo bikeInfo = queryBikeInfo(orderDto.getBikeCode());
|
||||
// 创建订单
|
||||
EbikeOrder order = EbikeOrder.builder()
|
||||
@ -326,6 +327,76 @@ public class EbikeOrderServiceImpl extends ServiceImpl<EbikeOrderMapper, EbikeOr
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算订单当前实时费用
|
||||
*/
|
||||
@Override
|
||||
public EbikeBikeRealInfoVo getBikeRealTimeInfo(Long orderId) {
|
||||
QueryWrapper queryWrapper = QueryWrapper.create()
|
||||
.select(
|
||||
EBIKE_ORDER.ORDER_STATUS,
|
||||
EBIKE_ORDER.START_TIME,
|
||||
EBIKE_ORDER.FREE_DURATION_MINUTES,
|
||||
EBIKE_ORDER.BASE_FEE,
|
||||
EBIKE_ORDER.DURATION_FEE,
|
||||
EBIKE_ORDER.MAX_FEE_AMOUNT,
|
||||
EBIKE_ORDER.BIKE_CODE
|
||||
)
|
||||
.where(EBIKE_ORDER.ORDER_ID.eq(orderId));
|
||||
EbikeOrder ebikeOrder = this.mapper.selectOneByQuery(queryWrapper);
|
||||
if (Objects.isNull(ebikeOrder)) {
|
||||
throw new EbikeException("当前订单不存在");
|
||||
}
|
||||
// 查询车辆信息
|
||||
EbikeBikeInfoVo bikeInfo = queryBikeInfo(ebikeOrder.getBikeCode());
|
||||
// 计算实时费用(包含封顶)
|
||||
BigDecimal cost = calculateRealTimeCost(ebikeOrder, bikeInfo);
|
||||
|
||||
// 计算可用里程:剩余电量 × 0.7 (公里)
|
||||
Float soc = bikeInfo.getSoc();
|
||||
long mileage = (long) Math.floor(Math.max(GlobalConstants.NUMBER_ZERO, soc * 0.7));
|
||||
|
||||
EbikeBikeRealInfoVo result = new EbikeBikeRealInfoVo();
|
||||
result.setCost(cost);
|
||||
result.setMileage(mileage);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 辅助方法:计算订单当前实时费用(含封顶金额限制)
|
||||
*/
|
||||
private BigDecimal calculateRealTimeCost(EbikeOrder order, EbikeBikeInfoVo bikeInfo) {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
Duration duration = Duration.between(order.getStartTime(), now);
|
||||
long totalSeconds = duration.getSeconds();
|
||||
int currentMinutes = (int) ((totalSeconds + 59) / 60);
|
||||
|
||||
Integer freeMinutes = bikeInfo.getFreeDurationMinutes();
|
||||
if (freeMinutes == null) {
|
||||
freeMinutes = 0;
|
||||
}
|
||||
|
||||
if (currentMinutes <= freeMinutes) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
return computeTotalFee(bikeInfo, currentMinutes - freeMinutes);
|
||||
}
|
||||
|
||||
private BigDecimal computeTotalFee(EbikeBikeInfoVo bikeInfo, int chargeableMinutes) {
|
||||
BigDecimal baseFee = Objects.requireNonNullElse(bikeInfo.getBaseFee(), BigDecimal.ZERO);
|
||||
BigDecimal durationFee = Objects.requireNonNullElse(bikeInfo.getDurationFee(), BigDecimal.ZERO);
|
||||
|
||||
BigDecimal totalFee = baseFee.add(durationFee.multiply(BigDecimal.valueOf(chargeableMinutes)))
|
||||
.setScale(2, RoundingMode.HALF_UP);
|
||||
|
||||
BigDecimal maxFee = bikeInfo.getMaxFeeAmount();
|
||||
if (maxFee != null && maxFee.compareTo(BigDecimal.ZERO) > 0 && totalFee.compareTo(maxFee) > 0) {
|
||||
totalFee = maxFee;
|
||||
}
|
||||
return totalFee;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算增长率并格式化为百分比字符串
|
||||
*
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user