Merge remote-tracking branch 'origin/main'
This commit is contained in:
commit
fb78f577b7
@ -4,15 +4,51 @@ import cn.dev33.satoken.stp.StpUtil;
|
||||
import com.cdzy.common.ex.EbikeException;
|
||||
import com.cdzy.common.model.dto.ResGPSDto;
|
||||
import com.cdzy.common.model.request.PageParam;
|
||||
import com.cdzy.operations.enums.*;
|
||||
import com.cdzy.operations.mapper.*;
|
||||
import com.cdzy.operations.enums.BatteryStatus;
|
||||
import com.cdzy.operations.enums.BikeOrderType;
|
||||
import com.cdzy.operations.enums.BikeQrStatus;
|
||||
import com.cdzy.operations.enums.BikeStatus;
|
||||
import com.cdzy.operations.enums.BikeUsageStatus;
|
||||
import com.cdzy.operations.enums.OrderDispatchState;
|
||||
import com.cdzy.operations.enums.OrderHandleState;
|
||||
import com.cdzy.operations.enums.RegionStatus;
|
||||
import com.cdzy.operations.enums.SpecialBillingConfigurationType;
|
||||
import com.cdzy.operations.mapper.EbiekSpecialDayMapper;
|
||||
import com.cdzy.operations.mapper.EbiekSpecialTimeMapper;
|
||||
import com.cdzy.operations.mapper.EbikeBatteryInfoMapper;
|
||||
import com.cdzy.operations.mapper.EbikeBikeInfoMapper;
|
||||
import com.cdzy.operations.mapper.EbikeBikeOrderMapper;
|
||||
import com.cdzy.operations.mapper.EbikeBikeQrMapper;
|
||||
import com.cdzy.operations.mapper.EbikeDefaultBillingConfigurationMapper;
|
||||
import com.cdzy.operations.mapper.EbikeRegionMapper;
|
||||
import com.cdzy.operations.mapper.EbikeSiteMapper;
|
||||
import com.cdzy.operations.mapper.EbikeSpecialBillingConfigurationMapper;
|
||||
import com.cdzy.operations.model.dto.EbikeBikeInfoDto;
|
||||
import com.cdzy.operations.model.dto.EbikeDto;
|
||||
import com.cdzy.operations.model.dto.EbikeUserBikeInfo;
|
||||
import com.cdzy.operations.model.dto.EbikeUserLockDto;
|
||||
import com.cdzy.operations.model.entity.*;
|
||||
import com.cdzy.operations.model.vo.*;
|
||||
import com.cdzy.operations.service.*;
|
||||
import com.cdzy.operations.model.entity.EbikeBatteryInfo;
|
||||
import com.cdzy.operations.model.entity.EbikeBikeInfo;
|
||||
import com.cdzy.operations.model.entity.EbikeBikeOrder;
|
||||
import com.cdzy.operations.model.entity.EbikeBikeQr;
|
||||
import com.cdzy.operations.model.entity.EbikeDefaultBillingConfiguration;
|
||||
import com.cdzy.operations.model.entity.EbikeDispatchConfiguration;
|
||||
import com.cdzy.operations.model.entity.EbikeEcuInfo;
|
||||
import com.cdzy.operations.model.entity.EbikeInventoryRecord;
|
||||
import com.cdzy.operations.model.entity.EbikeRegion;
|
||||
import com.cdzy.operations.model.entity.EbikeSpecialBillingConfiguration;
|
||||
import com.cdzy.operations.model.entity.EbikeSpecialDay;
|
||||
import com.cdzy.operations.model.entity.EbikeSpecialTime;
|
||||
import com.cdzy.operations.model.vo.EbikeBatchLaunchVo;
|
||||
import com.cdzy.operations.model.vo.EbikeBatchUnLaunchVo;
|
||||
import com.cdzy.operations.model.vo.EbikeBikeBindVo;
|
||||
import com.cdzy.operations.model.vo.EbikeBikeRadiusVo;
|
||||
import com.cdzy.operations.model.vo.EbikeInventoryVo;
|
||||
import com.cdzy.operations.service.EbikeBikeInfoService;
|
||||
import com.cdzy.operations.service.EbikeDispatchConfigurationService;
|
||||
import com.cdzy.operations.service.EbikeEcuInfoService;
|
||||
import com.cdzy.operations.service.EbikeInventoryRecordService;
|
||||
import com.cdzy.operations.service.EbikeInventoryService;
|
||||
import com.cdzy.operations.utils.RedisUtil;
|
||||
import com.ebike.feign.model.vo.EbikeLockVo;
|
||||
import com.mybatisflex.core.paginate.Page;
|
||||
@ -365,6 +401,8 @@ public class EbikeBikeInfoServiceImpl extends ServiceImpl<EbikeBikeInfoMapper, E
|
||||
bikeOrder.setHandleState(OrderHandleState.VOIDED);
|
||||
orderMapper.update(bikeOrder);
|
||||
}
|
||||
// 删除redis中的 车辆多长时间无单生成调度工单
|
||||
redisUtil.deleteNoDocument(bikeCode);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -488,7 +488,7 @@ public class RedisUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据库2专用:存储 辆多长时间无单生成调度工单 并设置过期时间
|
||||
* 数据库2专用:删除 车辆多长时间无单生成调度工单
|
||||
*/
|
||||
public void deleteNoDocument(String bikeCode) {
|
||||
delete(Database.DB2, BIKE_NO_DOCUMENT_PREFIX + bikeCode);
|
||||
|
||||
@ -19,9 +19,6 @@ import java.time.LocalDateTime;
|
||||
@Data
|
||||
public class EbikeOrderDetailVo {
|
||||
|
||||
/**
|
||||
* 订单表主键ID
|
||||
*/
|
||||
private Long orderId;
|
||||
|
||||
/**
|
||||
@ -177,4 +174,24 @@ public class EbikeOrderDetailVo {
|
||||
* 是否免费订单 true-免费 false-收费
|
||||
*/
|
||||
private Boolean isFreeOrder;
|
||||
|
||||
/**
|
||||
* 用户花费时长费用
|
||||
*/
|
||||
private BigDecimal userDurationFee;
|
||||
|
||||
/**
|
||||
* 用户花费起步费用
|
||||
*/
|
||||
private BigDecimal userBaseFee;
|
||||
|
||||
/**
|
||||
* 用户花费调度费用
|
||||
*/
|
||||
private BigDecimal userDispatchFee;
|
||||
|
||||
/**
|
||||
* 用户头盔费用
|
||||
*/
|
||||
private BigDecimal userHelmetFee;
|
||||
}
|
||||
|
||||
@ -310,28 +310,13 @@ public class EbikeOrderServiceImpl extends ServiceImpl<EbikeOrderMapper, EbikeOr
|
||||
public EbikeOrderDetailVo getInfo(Long orderId) {
|
||||
QueryWrapper queryWrapper = QueryWrapper.create()
|
||||
.select(
|
||||
EBIKE_ORDER.ORDER_ID,
|
||||
EBIKE_ORDER.USER_ID,
|
||||
EBIKE_ORDER.OPERATOR_ID,
|
||||
EBIKE_ORDER.BIKE_CODE,
|
||||
EBIKE_ORDER.ORDER_TYPE,
|
||||
EBIKE_ORDER.ORDER_STATUS,
|
||||
EBIKE_ORDER.TOTAL_AMOUNT,
|
||||
EBIKE_ORDER.ACTUAL_AMOUNT,
|
||||
EBIKE_ORDER.START_TIME,
|
||||
EBIKE_ORDER.END_TIME,
|
||||
EBIKE_ORDER.PAYMENT_TIME,
|
||||
EBIKE_ORDER.PAYMENT_METHOD,
|
||||
EBIKE_ORDER.BASE_DURATION_MINUTES,
|
||||
EBIKE_ORDER.FREE_DURATION_MINUTES,
|
||||
EBIKE_ORDER.CHARGE_DURATION_MINUTES,
|
||||
EBIKE_ORDER.MAX_FEE_AMOUNT,
|
||||
EBIKE_ORDER.START_LOCATION,
|
||||
EBIKE_ORDER.END_LOCATION,
|
||||
EBIKE_ORDER.IS_FREE_ORDER
|
||||
EBIKE_ORDER.ALL_COLUMNS
|
||||
)
|
||||
.where(EBIKE_ORDER.ORDER_ID.eq(orderId));
|
||||
EbikeOrderDetailVo ebikeOrderDetailVo = this.mapper.selectOneByQueryAs(queryWrapper, EbikeOrderDetailVo.class);
|
||||
if (Objects.isNull(ebikeOrderDetailVo)) {
|
||||
throw new EbikeException("订单不存在");
|
||||
}
|
||||
//获取费用详情
|
||||
List<EbikePaymentCostDetailVo> details = ebikeOrderDetailService.getOrderDetailsByOrderId(orderId);
|
||||
if (Objects.nonNull(details)) {
|
||||
@ -340,27 +325,27 @@ public class EbikeOrderServiceImpl extends ServiceImpl<EbikeOrderMapper, EbikeOr
|
||||
switch (payDetailVo.getDetailType()) {
|
||||
case 1 -> {
|
||||
BigDecimal current = payDetailVo.getDetailAmount();
|
||||
ebikeOrderDetailVo.setDurationFee((current != null ? current : BigDecimal.ZERO));
|
||||
ebikeOrderDetailVo.setUserDurationFee((current != null ? current : BigDecimal.ZERO));
|
||||
}
|
||||
case 2 -> {
|
||||
BigDecimal current = payDetailVo.getDetailAmount();
|
||||
ebikeOrderDetailVo.setBaseFee((current != null ? current : BigDecimal.ZERO));
|
||||
ebikeOrderDetailVo.setUserBaseFee((current != null ? current : BigDecimal.ZERO));
|
||||
}
|
||||
case 3 -> {
|
||||
BigDecimal current = payDetailVo.getDetailAmount();
|
||||
ebikeOrderDetailVo.setOutOfServiceAreaFee((current != null ? current : BigDecimal.ZERO));
|
||||
ebikeOrderDetailVo.setUserDispatchFee((current != null ? current : BigDecimal.ZERO));
|
||||
}
|
||||
case 4 -> {
|
||||
BigDecimal current = payDetailVo.getDetailAmount();
|
||||
ebikeOrderDetailVo.setOutOfParkingAreaFee((current != null ? current : BigDecimal.ZERO));
|
||||
ebikeOrderDetailVo.setUserDispatchFee((current != null ? current : BigDecimal.ZERO));
|
||||
}
|
||||
case 5 -> {
|
||||
BigDecimal current = payDetailVo.getDetailAmount();
|
||||
ebikeOrderDetailVo.setNoParkingZoneFee((current != null ? current : BigDecimal.ZERO));
|
||||
ebikeOrderDetailVo.setUserDispatchFee((current != null ? current : BigDecimal.ZERO));
|
||||
}
|
||||
case 6 -> {
|
||||
BigDecimal current = payDetailVo.getDetailAmount();
|
||||
ebikeOrderDetailVo.setHelmetManagementFee((current != null ? current : BigDecimal.ZERO));
|
||||
ebikeOrderDetailVo.setUserHelmetFee((current != null ? current : BigDecimal.ZERO));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -459,61 +444,68 @@ public class EbikeOrderServiceImpl extends ServiceImpl<EbikeOrderMapper, EbikeOr
|
||||
* @return 订单费用
|
||||
*/
|
||||
private EbikeCostDetailDto costCalculation(LocalDateTime endTime,
|
||||
EbikeOrder order, FeignEbikeUserLockDto data) {
|
||||
// 基础费用计算
|
||||
EbikeOrder order,
|
||||
FeignEbikeUserLockDto data) {
|
||||
EbikeCostDetailDto dto = new EbikeCostDetailDto();
|
||||
|
||||
// 1. 基础参数
|
||||
BigDecimal baseFee = Objects.requireNonNullElse(order.getBaseFee(), BigDecimal.ZERO);
|
||||
BigDecimal durationFee = Objects.requireNonNullElse(order.getDurationFee(), BigDecimal.ZERO);
|
||||
Integer freeDurationMinutes = order.getFreeDurationMinutes();
|
||||
Integer chargeDurationMinutes = order.getChargeDurationMinutes();
|
||||
// 获取总骑行时长(秒)
|
||||
Integer freeDurationMinutes = Objects.requireNonNullElse(order.getFreeDurationMinutes(), 0);
|
||||
Integer baseDurationMinutes = Objects.requireNonNullElse(order.getBaseDurationMinutes(), 0);
|
||||
int chargeDurationMinutes = Objects.requireNonNullElse(order.getChargeDurationMinutes(), 1);
|
||||
|
||||
// 2. 计算总骑行时长(秒)
|
||||
long totalRideSeconds = Duration.between(order.getStartTime(), endTime).toSeconds();
|
||||
// 免费时间(秒)
|
||||
long freeDurationSeconds = freeDurationMinutes * GlobalConstants.LONG_SIXTY;
|
||||
// 如果骑行时长小于等于免费时长,不收费
|
||||
BigDecimal baseCost;
|
||||
EbikeCostDetailDto ebikeCostDetailDto = new EbikeCostDetailDto();
|
||||
// 起步费用
|
||||
ebikeCostDetailDto.setBaseFee(baseFee);
|
||||
if (totalRideSeconds <= freeDurationSeconds) {
|
||||
ebikeCostDetailDto.setTotalCost(BigDecimal.ZERO);
|
||||
return ebikeCostDetailDto;
|
||||
} else {
|
||||
long totalRoundedMinutes = (totalRideSeconds + GlobalConstants.NUMBER_FIFTY_NINE) / GlobalConstants.NUMBER_SIXTY;
|
||||
// 可计费分钟数 = 向上取整后的总分钟 - 免费分钟
|
||||
long chargeableMinutes = totalRoundedMinutes - freeDurationMinutes;
|
||||
long chargeUnits = (chargeableMinutes + chargeDurationMinutes - 1) / chargeDurationMinutes;
|
||||
BigDecimal durationCost = durationFee.multiply(BigDecimal.valueOf(chargeUnits));
|
||||
// 时长费用
|
||||
ebikeCostDetailDto.setDurationFee(durationCost);
|
||||
// 总基础费用
|
||||
baseCost = baseFee.add(durationCost);
|
||||
// 向上取整为分钟
|
||||
long totalRideMinutes = (totalRideSeconds + 59) / 60;
|
||||
|
||||
// 3. 免费阶段:总时长 <= 免费时长
|
||||
if (totalRideMinutes <= freeDurationMinutes) {
|
||||
dto.setTotalCost(BigDecimal.ZERO);
|
||||
return dto;
|
||||
}
|
||||
// 计算调度费(按优先级判断附加费用:运营区 > 停车区外 > 禁停区)
|
||||
|
||||
// 4. 起步阶段:免费之后,但未超出起步时长 只收起步费
|
||||
long includedInBaseMinutes = freeDurationMinutes + baseDurationMinutes;
|
||||
if (totalRideMinutes <= includedInBaseMinutes) {
|
||||
dto.setBaseFee(baseFee);
|
||||
dto.setTotalCost(baseFee);
|
||||
return dto;
|
||||
}
|
||||
|
||||
// 5. 超出起步阶段:计算额外时长费用
|
||||
long extraMinutes = totalRideMinutes - includedInBaseMinutes;
|
||||
long chargeUnits = (extraMinutes + chargeDurationMinutes - 1) / chargeDurationMinutes;
|
||||
BigDecimal durationCost = durationFee.multiply(BigDecimal.valueOf(chargeUnits));
|
||||
|
||||
dto.setBaseFee(baseFee);
|
||||
dto.setDurationFee(durationCost);
|
||||
BigDecimal baseCost = baseFee.add(durationCost);
|
||||
|
||||
// 6. 调度费用
|
||||
BigDecimal additionalFee = BigDecimal.ZERO;
|
||||
if (data != null) {
|
||||
// 运营区
|
||||
if (Boolean.FALSE.equals(data.getBikeInRegion())) {
|
||||
additionalFee = order.getOutOfServiceAreaFee() != null ? order.getOutOfServiceAreaFee() : BigDecimal.ZERO;
|
||||
ebikeCostDetailDto.setOutOfServiceAreaFee(additionalFee);
|
||||
additionalFee = Objects.requireNonNullElse(order.getOutOfServiceAreaFee(), BigDecimal.ZERO);
|
||||
dto.setOutOfServiceAreaFee(additionalFee);
|
||||
} else if (Boolean.FALSE.equals(data.getBikeInParking())) {
|
||||
// 不在运营区内但在停车区内
|
||||
additionalFee = order.getOutOfParkingAreaFee() != null ? order.getOutOfParkingAreaFee() : BigDecimal.ZERO;
|
||||
ebikeCostDetailDto.setOutOfParkingAreaFee(additionalFee);
|
||||
} else if (Boolean.FALSE.equals(data.getBikeInNoParking())) {
|
||||
// 不在运营区内也不在停车区内,但在禁停区内
|
||||
additionalFee = order.getNoParkingZoneFee() != null ? order.getNoParkingZoneFee() : BigDecimal.ZERO;
|
||||
ebikeCostDetailDto.setNoParkingZoneFee(additionalFee);
|
||||
additionalFee = Objects.requireNonNullElse(order.getOutOfParkingAreaFee(), BigDecimal.ZERO);
|
||||
dto.setOutOfParkingAreaFee(additionalFee);
|
||||
} else if (Boolean.TRUE.equals(data.getBikeInNoParking())) {
|
||||
additionalFee = Objects.requireNonNullElse(order.getNoParkingZoneFee(), BigDecimal.ZERO);
|
||||
dto.setNoParkingZoneFee(additionalFee);
|
||||
}
|
||||
}
|
||||
// 计算总费用
|
||||
|
||||
// 7. 总费用 + 封顶
|
||||
BigDecimal totalCost = baseCost.add(additionalFee);
|
||||
// 检查是否超过封顶金额
|
||||
BigDecimal maxFee = order.getMaxFeeAmount();
|
||||
if (maxFee != null && totalCost.compareTo(maxFee) > 0) {
|
||||
totalCost = maxFee;
|
||||
}
|
||||
ebikeCostDetailDto.setTotalCost(totalCost);
|
||||
return ebikeCostDetailDto;
|
||||
dto.setTotalCost(totalCost);
|
||||
return dto;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user