调度费用计算

This commit is contained in:
attiya 2025-04-21 11:55:20 +08:00
parent 13d1c7535f
commit 596ccfdfa7
3 changed files with 102 additions and 17 deletions

View File

@ -28,11 +28,6 @@ public class ResFeignEbikeSysRcostsetDto {
*/
private Character chargingMode;
/**
* 免费时长模式
*/
private Character freeDurationMode;
/**
* 免费时长
*/

View File

@ -0,0 +1,22 @@
package com.cdzy.orders.enums;
/**
* @author attiya
* @since 2025-04-21
*/
public interface TimeDivisionCharging {
/**
* 关闭
*/
char CLOSE = '1';
/**
* 时间段
*/
char TIME_SLOT = '2';
/**
* 周计费
*/
char WEEK = '3';
}

View File

@ -5,10 +5,7 @@ import com.cdzy.common.enums.Code;
import com.cdzy.common.model.JsonResult;
import com.cdzy.common.model.ResGPSDto;
import com.cdzy.orders.component.EbikeCoreHandler;
import com.cdzy.orders.enums.CmdCode;
import com.cdzy.orders.enums.EbikeRegionInOperation;
import com.cdzy.orders.enums.OrderStatus;
import com.cdzy.orders.enums.OrderType;
import com.cdzy.orders.enums.*;
import com.cdzy.orders.mapper.UserOrdersMapper;
import com.cdzy.orders.model.dto.req.ReqBikeDto;
import com.cdzy.orders.model.dto.req.ReqOrderDto;
@ -36,6 +33,7 @@ import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import static com.cdzy.orders.enums.TimeDivisionCharging.*;
import static com.cdzy.orders.model.entity.table.UserOrdersTableDef.USER_ORDERS;
/**
@ -144,14 +142,8 @@ public class UserOrdersServiceImpl extends ServiceImpl<UserOrdersMapper, UserOrd
}
FeignEbikeRegionDto regionDto = regionResult.getData();
//是否在运营区内
boolean pointInOperation = bikeInOperation(resGpsDto.getLongitude(), resGpsDto.getLatitude(), regionDto.getOrgId(), regionDto.getRegionId());
boolean pointInParking = redisUtil.isPointInParking(resGpsDto.getLongitude(), resGpsDto.getLatitude(), regionDto.getOrgId());
//是否在停车区内
long minutes = TimeUtils.betweenMinutes(userOrders.getStartTime(), LocalDateTime.now());
//TODO:时间校验根据规则做时间校验判断收费多少.需要支付则为待支付状态不需要则为取消状态
userOrders.setStatus(OrderStatus.PENDING_PAYMENT);
userOrders.setTotalAmount(BigDecimal.ZERO);
ResFeignEbikeSysRcostsetDto feignEbikeSysRcostsetDto = operateJsonResult.getData();
costCalculation(feignEbikeSysRcostsetDto,resGpsDto,regionDto,userOrders);
userOrdersMapper.update(userOrders);
//关锁,并且等待结果
CompletableFuture<String> stringCompletableFuture = ebikeCoreHandler.executeCommand(ecuInfo, CmdCode.LOCK, Long.valueOf(bikeInfoDto.getBikeId()), userId);
@ -201,4 +193,80 @@ public class UserOrdersServiceImpl extends ServiceImpl<UserOrdersMapper, UserOrd
boolean bikeInOperation(double lng, double lat, Long orgId, Long regionId) {
return redisUtil.isPointInOperation(lng, lat, orgId, regionId);
}
/**
* 计算费用
* @param feignEbikeSysRcostsetDto 计费规则
* @param resGpsDto 定位信息
* @param regionDto 运营区域信息
* @param userOrders 订单信息
*/
void costCalculation(ResFeignEbikeSysRcostsetDto feignEbikeSysRcostsetDto, ResGPSDto resGpsDto,FeignEbikeRegionDto regionDto,UserOrders userOrders){
BigDecimal totalAmount = new BigDecimal(0);
//是否在运营区内
boolean pointInOperation = bikeInOperation(resGpsDto.getLongitude(), resGpsDto.getLatitude(), regionDto.getOrgId(), regionDto.getRegionId());
boolean pointInParking = redisUtil.isPointInParking(resGpsDto.getLongitude(), resGpsDto.getLatitude(), regionDto.getOrgId());
//是否在停车区内
long minutes = TimeUtils.betweenMinutes(userOrders.getStartTime(), userOrders.getEndTime());
//是否取消订单
if (pointInOperation && pointInParking && minutes < feignEbikeSysRcostsetDto.getFreeDuration()){
userOrders.setStatus(OrderStatus.CANCELLED);
return;
}
//计算调度费用
if (pointInOperation && !pointInParking){
//停车区调度费用
BigDecimal parkingAreaOutDispatchFee = feignEbikeSysRcostsetDto.getParkingAreaOutDispatchFee();
totalAmount = totalAmount.add(parkingAreaOutDispatchFee);
}else if (!pointInOperation){
//运营区调度费用
BigDecimal dispatchFeeOutOperateArea = feignEbikeSysRcostsetDto.getDispatchFeeOutOperateArea();
totalAmount = totalAmount.add(dispatchFeeOutOperateArea);
}
//时长费用计算
Character timeDivisionCharging = feignEbikeSysRcostsetDto.getTimeDivisionCharging();
totalAmount = switch (timeDivisionCharging) {
case TIME_SLOT -> timeSlotCostCalculation(totalAmount, minutes, userOrders, feignEbikeSysRcostsetDto);
case WEEK -> weekCostCalculation(totalAmount, minutes, userOrders, feignEbikeSysRcostsetDto);
default -> defaultCostCalculation(totalAmount, minutes, feignEbikeSysRcostsetDto);
};
userOrders.setStatus(OrderStatus.PENDING_PAYMENT);
userOrders.setTotalAmount(totalAmount);
}
/**
* 按照特殊时间段计费
* @param totalAmount 当前金额时间段计费前
* @param minutes 骑行总分钟
* @param userOrders 订单信息
* @param feignEbikeSysRcostsetDto 计费规则
* @return 计费后总金额
*/
BigDecimal timeSlotCostCalculation(BigDecimal totalAmount,long minutes,UserOrders userOrders,ResFeignEbikeSysRcostsetDto feignEbikeSysRcostsetDto){
return totalAmount;
}
/**
* 按照时间段计费
* @param totalAmount 当前金额时间段计费前
* @param minutes 骑行总分钟
* @param userOrders 订单信息
* @param feignEbikeSysRcostsetDto 计费规则
* @return 计费后总金额
*/
BigDecimal weekCostCalculation(BigDecimal totalAmount,long minutes,UserOrders userOrders,ResFeignEbikeSysRcostsetDto feignEbikeSysRcostsetDto){
return totalAmount;
}
/**
* 按照时间段计费(默认
* @param totalAmount 当前金额时间段计费前
* @param minutes 骑行总分钟
* @param feignEbikeSysRcostsetDto 计费规则
* @return 计费后总金额
*/
BigDecimal defaultCostCalculation(BigDecimal totalAmount,long minutes,ResFeignEbikeSysRcostsetDto feignEbikeSysRcostsetDto){
return totalAmount;
}
}