1. 计费方式跟着订单走,修改收费模版也不影响前面的订单

This commit is contained in:
邱贞招 2024-09-04 08:43:06 +08:00
parent 24383a9cd9
commit bb9e0de398
7 changed files with 126 additions and 47 deletions

View File

@ -185,6 +185,9 @@ public class AppVerifyController extends BaseController
if(order.getRuleId()==null){
return error("=============================================ruleId未传=============================================");
}
if(order.getUserId()==null){
return error("=============================================userId未传=============================================");
}
// 判断该订单是否已结束
EtOrder etOrder = etOrderService.selectEtOrderByOrderNo(order.getOrderNo());
if(ObjectUtil.isNotNull(etOrder)){

View File

@ -267,4 +267,37 @@ public class EtOrder extends BaseEntity
/** 锁单中: 0-否1-是 */
@Excel(name = "锁单中: 0-否1-是")
private String locking;
/** 还车结算___小时后自动退押金 */
@Excel(name = "还车结算___小时后自动退押金")
private Integer autoRefundDeposit;
/** 免费骑行时长(分钟) */
@Excel(name = "免费骑行时长(分钟)")
private Integer freeRideTime;
/** 租赁单位minutes-分钟hours-小时day-天 */
@Excel(name = "租赁单位")
private String rentalUnit;
/** 计费规则1-起步价计费 2-区间计费 */
@Excel(name = "计费规则")
private String ridingRule;
/** 计费规则json串*/
@Excel(name = "计费规则json")
private String ridingRuleJson;
/** 计费周期1-订单生成后__小时 2-自定义时刻 */
@Excel(name = "计费周期")
private String chargingCycle;
/** 计费周期值:*/
@Excel(name = "计费周期值")
private String chargingCycleValue;
/** 封顶金额*/
@Excel(name = "封顶金额")
private BigDecimal cappedAmount;
}

View File

@ -1910,38 +1910,33 @@ public class AsDeviceServiceImpl extends ServiceImpl<AsDeviceMapper, AsDevice> i
private EtOrder calculateOrderFee(EtOrder order,String isInParkingArea) {
String type = order.getType();
if(type.equals("1")){//骑行订单,正常骑行包含预约费计时收费根据开锁时间起步价和起步时长时长费和时长分钟等参数如果有预约还要加上预约费计算费用,还要判断封顶费用根据开锁时间
Long ruleId = order.getRuleId();
EtFeeRule rule = etFeeRuleService.selectEtFeeRuleByRuleIdIncludeDelete(ruleId);
if(ObjectUtil.isNull(rule)){
throw new ServiceException("计费规则不存在");
}
String rentalUnit = rule.getRentalUnit();//租赁单位
String rentalUnit = order.getRentalUnit();//租赁单位
//根据订单的开始时间和还车时间计算出在第几个计费周期在第一个计费周期内并没有超过封顶费用则根据规则算出骑行费
Integer cycle = null;
Date startTime = order.getUnlockTime();
Date endTime = order.getReturnTime();
String chargingCycle = rule.getChargingCycle();
String chargingCycleValue = rule.getChargingCycleValue();
String chargingCycle = order.getChargingCycle();
String chargingCycleValue = order.getChargingCycleValue();
if(ServiceConstants.CHARGING_CYCLE_HOUR.equals(chargingCycle)) {//订单生成后__小时 第几个
cycle = inHowManyChargingCycle(startTime, endTime, chargingCycleValue);
BigDecimal ridingFee;
if(cycle == 1){
order.setCycle(1);//在第几个计费周期内
ridingFee = calculateRidingFee(order.getUnlockTime(), order.getReturnTime(), rule, rule.getRidingRuleJson(), rentalUnit);
order.setCycle(1);//在第几个计费周期内 rule, rule.getRidingRuleJson(), rentalUnit
ridingFee = calculateRidingFee(order,order.getUnlockTime(), order.getReturnTime());
}else {
// 判断一个计费周期是否超过封顶费用如果超出 骑行费 = (第几个周期 - 1) * 封顶费用 + 骑行费
// 如果不超出骑行费 = 骑行费
Date oneCycleAfter = DateUtils.getTimeAfterXHours(order.getUnlockTime(), Integer.parseInt(chargingCycleValue));
if(isFeeExceedingCap(order.getUnlockTime(),oneCycleAfter, rule,rentalUnit)){
if(isFeeExceedingCap(order.getUnlockTime(),oneCycleAfter,order,order.getRentalUnit())){
// 如果超出 骑行费 = (第几个周期 - 1) * 封顶费用 + 骑行费
order.setCycle(cycle);
Date afterXHours = DateUtils.getTimeAfterXHours(order.getUnlockTime(), Integer.parseInt(chargingCycleValue)*(cycle-1));
BigDecimal remainingFee = calculateRidingFee(afterXHours, order.getReturnTime(), rule, rule.getRidingRuleJson(),rentalUnit);
ridingFee = new BigDecimal(cycle - 1).multiply(rule.getCappedAmount()).add(remainingFee);
BigDecimal remainingFee = calculateRidingFee(order,afterXHours,order.getReturnTime());
ridingFee = new BigDecimal(cycle - 1).multiply(order.getCappedAmount()).add(remainingFee);
}else{
ridingFee = calculateRidingFee(order.getUnlockTime(), order.getReturnTime(), rule, rule.getRidingRuleJson(), rentalUnit);
ridingFee = calculateRidingFee(order, order.getUnlockTime(), order.getReturnTime());
}
}
order.setRidingFee(ridingFee);
@ -1967,21 +1962,21 @@ public class AsDeviceServiceImpl extends ServiceImpl<AsDeviceMapper, AsDevice> i
BigDecimal ridingFee;
if (order.getUnlockTime().before(customCycleTime) && endTime.after(customCycleTime)) {//如果自定义时间在骑行时间段内分段计算骑行费用并考虑封顶费用
BigDecimal firstPeriodFee = calculateRidingFee(order.getUnlockTime(), customCycleTime, rule, rule.getRidingRuleJson(), rentalUnit);
BigDecimal secondPeriodFee = calculateRidingFee(customCycleTime, endTime, rule, rule.getRidingRuleJson(), rentalUnit);
BigDecimal firstPeriodFee = calculateRidingFee(order,order.getUnlockTime(), customCycleTime);
BigDecimal secondPeriodFee = calculateRidingFee(order,customCycleTime, endTime);
if (firstPeriodFee.compareTo(rule.getCappedAmount()) > 0) {
firstPeriodFee = rule.getCappedAmount();
if (firstPeriodFee.compareTo(order.getCappedAmount()) > 0) {
firstPeriodFee = order.getCappedAmount();
}
if (secondPeriodFee.compareTo(rule.getCappedAmount()) > 0) {
secondPeriodFee = rule.getCappedAmount();
if (secondPeriodFee.compareTo(order.getCappedAmount()) > 0) {
secondPeriodFee = order.getCappedAmount();
}
ridingFee = firstPeriodFee.add(secondPeriodFee);
} else {// 如果自定义时间不在骑行时间段内直接计算骑行费用并考虑封顶费用
ridingFee = calculateRidingFee(order.getUnlockTime(), endTime, rule, rule.getRidingRuleJson(), rentalUnit);
if (ridingFee.compareTo(rule.getCappedAmount()) > 0) {
ridingFee = rule.getCappedAmount();
ridingFee = calculateRidingFee(order,order.getUnlockTime(), endTime);
if (ridingFee.compareTo(order.getCappedAmount()) > 0) {
ridingFee = order.getCappedAmount();
}
}
@ -2042,9 +2037,9 @@ public class AsDeviceServiceImpl extends ServiceImpl<AsDeviceMapper, AsDevice> i
* 判断一个计费周期是否超过封顶费用
*/
@NotNull
private Boolean isFeeExceedingCap(Date startTime, Date endTime, EtFeeRule rule, String rentalUnit) {
private Boolean isFeeExceedingCap(Date startTime, Date endTime, EtOrder order, String rentalUnit) {
Integer minutes = DateUtils.timeDifferenceInMinutes(endTime,startTime);//计算相隔多少分钟
StartingRuleVo startingRule = JSONObject.parseObject(rule.getRidingRuleJson(), StartingRuleVo.class);
StartingRuleVo startingRule = JSONObject.parseObject(order.getRidingRuleJson(), StartingRuleVo.class);
String timeoutPrice = startingRule.getTimeoutPrice();//超时价格
Integer timeoutTime = Integer.parseInt(startingRule.getTimeoutTime());//超时时间
@ -2056,32 +2051,27 @@ public class AsDeviceServiceImpl extends ServiceImpl<AsDeviceMapper, AsDevice> i
double ceil = Math.ceil(minutes / timeoutTime) +1 ;
BigDecimal ridingFee = new BigDecimal(ceil * Double.parseDouble(timeoutPrice));
return ridingFee.compareTo(rule.getCappedAmount())>0;
return ridingFee.compareTo(order.getCappedAmount())>0;
}
/**
* 计算骑行费
* @param unlockTime 开锁时间
* @param returnTime 还车时间
* @param rule 计费规则
* @param ridingRuleJson 起步价规则
* @param rentalUnit 租赁单位
*/
@NotNull
private BigDecimal calculateRidingFee(Date unlockTime,Date returnTime, EtFeeRule rule, String ridingRuleJson,String rentalUnit) {
private BigDecimal calculateRidingFee(EtOrder order,Date unlockTime,Date returnTime) {
BigDecimal ridingFee = BigDecimal.ZERO;
//没有预约根据订单中的开锁时间计算费用骑行费用 ((还车时间-开锁时间转成分钟数)/ 时长分钟)-起步价分钟数 * 时长费 + 起步价
// Date returnTime = order.getReturnTime();//还车时间
String rentalUnit = order.getRentalUnit();
//在免费骑行时间内骑行费为0
Integer minutes = DateUtils.timeDifferenceInMinutes(returnTime,unlockTime);//计算相隔多少分钟
Integer freeRideTime = rule.getFreeRideTime();
Integer freeRideTime = order.getFreeRideTime();
if(freeRideTime!=0 && freeRideTime!=null && minutes<=freeRideTime){
return ridingFee;
}
if(rule.getRidingRule().equals(ServiceConstants.RIDING_RULE_STARTING_PRICE_MODE)){//1-起步价计费
StartingRuleVo startingRule = JSONObject.parseObject(ridingRuleJson, StartingRuleVo.class);
if(order.getRidingRule().equals(ServiceConstants.RIDING_RULE_STARTING_PRICE_MODE)){//1-起步价计费
StartingRuleVo startingRule = JSONObject.parseObject(order.getRidingRuleJson(), StartingRuleVo.class);
String startingPrice = startingRule.getStartingPrice();//起步价
Integer startingTime = Integer.parseInt(startingRule.getStartingTime());//起步时间
String timeoutPrice = startingRule.getTimeoutPrice();//超时价格
@ -2115,7 +2105,7 @@ public class AsDeviceServiceImpl extends ServiceImpl<AsDeviceMapper, AsDevice> i
}
}
}else{//2-区间计费
IntervalRuleVo intervalRuleVo = JSONObject.parseObject(ridingRuleJson, IntervalRuleVo.class);
IntervalRuleVo intervalRuleVo = JSONObject.parseObject(order.getRidingRuleJson(), IntervalRuleVo.class);
List<IntervalRuleVo.IntervalRule> rule1 = intervalRuleVo.getRule();
//骑行时长
Integer duration = DateUtils.timeDifferenceInMinutes(returnTime,unlockTime);//计算相隔多少分钟

View File

@ -523,8 +523,7 @@ public class CallbackServiceImpl implements CallbackService {
* 退还押金定时任务
*/
private void refundDeposit(String deposit, EtOrder order, AsUser asUser) {
EtFeeRule rule = etFeeRuleService.selectEtFeeRuleByRuleIdIncludeDelete(order.getRuleId());
Integer autoRefundDeposit = rule.getAutoRefundDeposit();
Integer autoRefundDeposit = order.getAutoRefundDeposit();
logger.info("【微信支付回调】进入退还押金");
if(autoRefundDeposit!=null){

View File

@ -1195,6 +1195,17 @@ public class EtOrderServiceImpl implements IEtOrderService
etOrder.setUserName(user.getUserName());
etOrder.setMark(order.getMark());
etOrder.setCreateTime(DateUtils.getNowDate());
if(ObjectUtil.isNotNull(order.getRuleId())){
EtFeeRule etFeeRule = etFeeRuleService.selectEtFeeRuleByRuleIdIncludeDelete(order.getRuleId());
etOrder.setAutoRefundDeposit(etFeeRule.getAutoRefundDeposit());
etOrder.setFreeRideTime(etFeeRule.getFreeRideTime());
etOrder.setRentalUnit(etFeeRule.getRentalUnit());
etOrder.setRidingRule(etFeeRule.getRidingRule());
etOrder.setRidingRuleJson(etFeeRule.getRidingRuleJson());
etOrder.setChargingCycle(etFeeRule.getChargingCycle());
etOrder.setChargingCycleValue(etFeeRule.getChargingCycleValue());
etOrder.setCappedAmount(etFeeRule.getCappedAmount());
}
etOrder.setRuleId(order.getRuleId());
etOrder.setAreaId(order.getAreaId());
/** 订单类型 1骑行 2预约 3套餐 4押金 根据类型不同下单的参数也不同,不同的参数有: 金额、类型、rule_id套餐id*/

View File

@ -94,7 +94,7 @@ public class EtTask {
@Autowired
private IEtModelService etModelService;
@Autowired
@Resource
private EtCouponClaimLogMapper etCouponClaimLogMapper;
@ -118,13 +118,13 @@ public class EtTask {
List<EtOrder> orders = etOrderMapper.selectUserListFinishOrder();
log.info("已完成的订单未退还押金的的订单 = " + JSON.toJSONString(orders));
for(EtOrder order:orders){
EtFeeRule rule = etFeeRuleService.selectEtFeeRuleByRuleIdIncludeDelete(order.getRuleId());
if(ObjectUtil.isNull(rule)){
throw new ServiceException("骑行订单:【"+order.getOrderNo()+"】未找到该套餐【"+order.getRuleId()+"");
}
// EtFeeRule rule = etFeeRuleService.selectEtFeeRuleByRuleIdIncludeDelete(order.getRuleId());
// if(ObjectUtil.isNull(rule)){
// throw new ServiceException("骑行订单:【"+order.getOrderNo()+"】未找到该套餐【"+order.getRuleId()+"");
// }
EtOperatingArea area = etOperatingAreaService.selectEtOperatingAreaByAreaId(order.getAreaId());
AsUser asUser = asUserMapper.selectUserById(order.getUserId());
Integer autoRefundDeposit = rule.getAutoRefundDeposit();
Integer autoRefundDeposit = order.getAutoRefundDeposit();
// 根据用户查询最后一次押金充值订单
EtOrder etOrder = new EtOrder();

View File

@ -47,6 +47,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="usedSn" column="used_sn" />
<result property="changeReason" column="change_reason" />
<result property="locking" column="locking" />
<result property="autoRefundDeposit" column="auto_refund_deposit" />
<result property="freeRideTime" column="free_ride_time" />
<result property="rentalUnit" column="rental_unit" />
<result property="ridingRule" column="riding_rule" />
<result property="ridingRuleJson" column="riding_rule_json" />
<result property="chargingCycle" column="charging_cycle" />
<result property="chargingCycleValue" column="charging_cycle_value" />
<result property="cappedAmount" column="capped_amount" />
</resultMap>
<sql id="selectEtOrderVo">
@ -54,7 +62,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
device_mac, sn, pay_time, paid, pay_type, type, total_fee, pay_fee, dispatch_fee,
manage_fee, riding_fee, appointment_fee, mark, duration, distance, status,
create_time, appointment_start_time, appointment_end_time,appointment_timeout, unlock_time,return_time,
rule_end_time, return_type, AsText(trip_route) trip_route,trip_route_str,cycle,deposit_deduction,video_url,upload_time,deduction_amount,audio_files,used_sn,change_reason,locking from et_order
rule_end_time, return_type, AsText(trip_route) trip_route,trip_route_str,cycle,deposit_deduction,video_url,
upload_time,deduction_amount,audio_files,used_sn,change_reason,locking,auto_refund_deposit,free_ride_time,
rental_unit,riding_rule,riding_rule_json,charging_cycle,charging_cycle_value,capped_amount from et_order
</sql>
<sql id="selectEtOrderVoNoRoute">
@ -62,7 +72,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
device_mac, sn, pay_time, paid, pay_type, type, total_fee, pay_fee, dispatch_fee,
manage_fee, riding_fee, appointment_fee, mark, duration, distance, status,
create_time, appointment_start_time, appointment_end_time,appointment_timeout, unlock_time,return_time,
rule_end_time, return_type, cycle,deposit_deduction,video_url,upload_time,deduction_amount,audio_files,used_sn,change_reason,locking from et_order
rule_end_time, return_type, cycle,deposit_deduction,video_url,upload_time,deduction_amount,audio_files,used_sn,change_reason,locking,auto_refund_deposit,free_ride_time,
rental_unit,riding_rule,riding_rule_json,charging_cycle,charging_cycle_value,capped_amountfrom et_order
</sql>
<select id="selectEtOrderList" parameterType="EtOrder" resultMap="EtOrderResult">
@ -817,6 +828,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="tripRoute != null">trip_route,</if>
<if test="tripRouteStr != null">trip_route_str,</if>
<if test="cycle != null">cycle,</if>
<if test="autoRefundDeposit != null">auto_refund_deposit,</if>
<if test="freeRideTime != null">free_ride_time,</if>
<if test="rentalUnit != null">rental_unit,</if>
<if test="ridingRule != null">riding_rule,</if>
<if test="ridingRuleJson != null">riding_rule_json,</if>
<if test="chargingCycle != null">charging_cycle,</if>
<if test="chargingCycleValue != null">charging_cycle_value,</if>
<if test="cappedAmount != null">capped_amount,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="orderId != null">#{orderId},</if>
@ -851,6 +870,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="tripRoute != null">GeomFromText(#{tripRoute}),</if>
<if test="tripRouteStr != null">#{tripRouteStr},</if>
<if test="cycle != null">#{cycle},</if>
<if test="autoRefundDeposit != null">#{autoRefundDeposit},</if>
<if test="freeRideTime != null">#{freeRideTime},</if>
<if test="rentalUnit != null">#{rentalUnit},</if>
<if test="ridingRule != null">#{ridingRule},</if>
<if test="ridingRuleJson != null">#{ridingRuleJson},</if>
<if test="chargingCycle != null">#{chargingCycle},</if>
<if test="chargingCycleValue != null">#{chargingCycleValue},</if>
<if test="cappedAmount != null">#{cappedAmount},</if>
</trim>
</insert>
@ -895,6 +922,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="usedSn != null">used_sn = #{usedSn},</if>
<if test="changeReason != null">change_reason = #{changeReason},</if>
<if test="locking != null">locking = #{locking},</if>
<if test="autoRefundDeposit != null">auto_refund_deposit = #{autoRefundDeposit},</if>
<if test="freeRideTime != null">free_ride_time = #{freeRideTime},</if>
<if test="rentalUnit != null">rental_unit = #{rentalUnit},</if>
<if test="ridingRule != null">riding_rule = #{ridingRule},</if>
<if test="ridingRuleJson != null">riding_rule_json = #{ridingRuleJson},</if>
<if test="chargingCycle != null">charging_cycle = #{chargingCycle},</if>
<if test="chargingCycleValue != null">charging_cycle_value = #{chargingCycleValue},</if>
<if test="cappedAmount != null">capped_amount = #{cappedAmount},</if>
</trim>
where order_id = #{orderId}
</update>
@ -940,6 +975,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="usedSn != null">used_sn = #{usedSn},</if>
<if test="changeReason != null">change_reason = #{changeReason},</if>
<if test="locking != null">locking = #{locking},</if>
<if test="autoRefundDeposit != null">auto_refund_deposit = #{autoRefundDeposit},</if>
<if test="freeRideTime != null">free_ride_time = #{freeRideTime},</if>
<if test="rentalUnit != null">rental_unit = #{rentalUnit},</if>
<if test="ridingRule != null">riding_rule = #{ridingRule},</if>
<if test="ridingRuleJson != null">riding_rule_json = #{ridingRuleJson},</if>
<if test="chargingCycle != null">charging_cycle = #{chargingCycle},</if>
<if test="chargingCycleValue != null">charging_cycle_value = #{chargingCycleValue},</if>
<if test="cappedAmount != null">capped_amount = #{cappedAmount},</if>
</trim>
where order_no = #{orderNo}
</update>