Compare commits
2 Commits
62724b62d7
...
5fa9515ed9
| Author | SHA1 | Date | |
|---|---|---|---|
| 5fa9515ed9 | |||
| 58c06997f0 |
@ -4,6 +4,7 @@ import com.cdzy.common.model.JsonResult;
|
|||||||
import com.cdzy.common.model.PageParam;
|
import com.cdzy.common.model.PageParam;
|
||||||
import com.cdzy.orders.model.dto.req.ReqBikeDto;
|
import com.cdzy.orders.model.dto.req.ReqBikeDto;
|
||||||
import com.cdzy.orders.model.dto.req.ReqOrderDto;
|
import com.cdzy.orders.model.dto.req.ReqOrderDto;
|
||||||
|
import com.cdzy.orders.model.dto.res.RspOrderDetailsInfo;
|
||||||
import com.ebike.feign.model.res.ResFeignOrderPaymentDto;
|
import com.ebike.feign.model.res.ResFeignOrderPaymentDto;
|
||||||
import com.cdzy.orders.model.dto.res.RspBikeDto;
|
import com.cdzy.orders.model.dto.res.RspBikeDto;
|
||||||
import com.cdzy.orders.model.entity.EbikeUserOrders;
|
import com.cdzy.orders.model.entity.EbikeUserOrders;
|
||||||
@ -167,7 +168,17 @@ public class EbikeUserOrdersController {
|
|||||||
boolean inParking = userOrdersService.checkBikeInParking(bikeCode);
|
boolean inParking = userOrdersService.checkBikeInParking(bikeCode);
|
||||||
return JsonResult.success(inParking);
|
return JsonResult.success(inParking);
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 根据ID获取订单计费详情。
|
||||||
|
*
|
||||||
|
* @param orderId 用户订单表主键
|
||||||
|
* @ 用户订单表详情
|
||||||
|
*/
|
||||||
|
@GetMapping("orderDetailsInfo")
|
||||||
|
public JsonResult<?> OrderDetailsInfo(@RequestParam("orderId") Long orderId) {
|
||||||
|
RspOrderDetailsInfo info = userOrdersService.orderDetailsInfo(orderId);
|
||||||
|
return JsonResult.success(info);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据用户订单表主键获取详细信。
|
* 根据用户订单表主键获取详细信。
|
||||||
|
|||||||
@ -0,0 +1,124 @@
|
|||||||
|
package com.cdzy.orders.model.dto.res;
|
||||||
|
|
||||||
|
import com.cdzy.orders.model.entity.EbikeOrderDetails;
|
||||||
|
import com.mybatisflex.annotation.Column;
|
||||||
|
import com.mybatisflex.annotation.Id;
|
||||||
|
import com.mybatisflex.annotation.RelationOneToMany;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author attiya
|
||||||
|
* @since 2025-04-28
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class RspOrderDetailsInfo {
|
||||||
|
/**
|
||||||
|
* 分布式ID(雪花算法或业务前缀+序列)
|
||||||
|
*/
|
||||||
|
@Id
|
||||||
|
private Long orderId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户ID,关联用户表
|
||||||
|
*/
|
||||||
|
private String userId;
|
||||||
|
|
||||||
|
private String bikeId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单类型:1-单次骑行 2-骑行卡购买 3-会员卡续费
|
||||||
|
*/
|
||||||
|
private Integer orderType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态:0-进行中 1-已取消 2-待支付 3-已支付 4-退款中 5-已退款
|
||||||
|
*/
|
||||||
|
@Column(onInsertValue = "0")
|
||||||
|
private Integer status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单总金额(单位:元)
|
||||||
|
*/
|
||||||
|
private BigDecimal totalAmount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实付金额(扣除卡券优惠后)
|
||||||
|
*/
|
||||||
|
private BigDecimal actualAmount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 骑行开始时间(仅骑行订单有效)
|
||||||
|
*/
|
||||||
|
private LocalDateTime startTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 骑行结束时间(仅骑行订单有效)
|
||||||
|
*/
|
||||||
|
private LocalDateTime endTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付成功时间
|
||||||
|
*/
|
||||||
|
private LocalDateTime paymentTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付方式:wechat/alipay/balance
|
||||||
|
*/
|
||||||
|
private String paymentMethod;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用卡券ID集合(JSON数组)
|
||||||
|
*/
|
||||||
|
private String couponIds;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 优惠明细(结构化存储,便于对账)
|
||||||
|
*/
|
||||||
|
private String discountDetails;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 骑行设备编号(仅骑行订单有效)
|
||||||
|
*/
|
||||||
|
private String bikeCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 地理位置GeoHash编码(用于区域优惠分析)
|
||||||
|
*/
|
||||||
|
private String geoHash;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
@Column(onInsertValue = "now()")
|
||||||
|
private LocalDateTime createdAt;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新时间
|
||||||
|
*/
|
||||||
|
private LocalDateTime updatedAt;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 骑行起始点
|
||||||
|
*/
|
||||||
|
private String ridePoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 骑行结束点
|
||||||
|
*/
|
||||||
|
private String returnPoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 0-未临时锁车 -1临时锁车
|
||||||
|
*/
|
||||||
|
private Integer tempLock;
|
||||||
|
|
||||||
|
@Column(isLogicDelete = true,onInsertValue = "0")
|
||||||
|
private Integer isDelete;
|
||||||
|
|
||||||
|
@RelationOneToMany(selfField = "orderId", targetField = "orderId")
|
||||||
|
List<EbikeOrderDetails> details;
|
||||||
|
}
|
||||||
@ -2,6 +2,7 @@ package com.cdzy.orders.service;
|
|||||||
|
|
||||||
import com.cdzy.orders.model.dto.req.ReqBikeDto;
|
import com.cdzy.orders.model.dto.req.ReqBikeDto;
|
||||||
import com.cdzy.orders.model.dto.req.ReqOrderDto;
|
import com.cdzy.orders.model.dto.req.ReqOrderDto;
|
||||||
|
import com.cdzy.orders.model.dto.res.RspOrderDetailsInfo;
|
||||||
import com.ebike.feign.model.res.ResFeignOrderPaymentDto;
|
import com.ebike.feign.model.res.ResFeignOrderPaymentDto;
|
||||||
import com.cdzy.orders.model.dto.res.RspBikeDto;
|
import com.cdzy.orders.model.dto.res.RspBikeDto;
|
||||||
import com.mybatisflex.core.service.IService;
|
import com.mybatisflex.core.service.IService;
|
||||||
@ -93,8 +94,9 @@ public interface UserOrdersService extends IService<EbikeUserOrders> {
|
|||||||
void doneRefund(Long orderId);
|
void doneRefund(Long orderId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 车辆详情
|
* 获取订单详情
|
||||||
* @param ecuSn scusn
|
* @param orderId 订单id
|
||||||
|
* @return 详情
|
||||||
*/
|
*/
|
||||||
List<RspBikeDto> bikeInfo(String ecuSn);
|
RspOrderDetailsInfo orderDetailsInfo(Long orderId);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,6 +12,7 @@ import com.cdzy.orders.model.dto.req.ReqBikeDto;
|
|||||||
import com.cdzy.orders.model.dto.req.ReqOrderDto;
|
import com.cdzy.orders.model.dto.req.ReqOrderDto;
|
||||||
import com.cdzy.orders.model.dto.res.RedisPoint;
|
import com.cdzy.orders.model.dto.res.RedisPoint;
|
||||||
import com.cdzy.orders.model.dto.res.RspBikeDto;
|
import com.cdzy.orders.model.dto.res.RspBikeDto;
|
||||||
|
import com.cdzy.orders.model.dto.res.RspOrderDetailsInfo;
|
||||||
import com.cdzy.orders.model.dto.res.TimeSegment;
|
import com.cdzy.orders.model.dto.res.TimeSegment;
|
||||||
import com.cdzy.orders.model.entity.EbikeOrderDetails;
|
import com.cdzy.orders.model.entity.EbikeOrderDetails;
|
||||||
import com.cdzy.orders.model.entity.EbikeUserOrders;
|
import com.cdzy.orders.model.entity.EbikeUserOrders;
|
||||||
@ -36,6 +37,7 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.LocalTime;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
@ -310,8 +312,8 @@ public class UserOrdersServiceImpl extends ServiceImpl<UserOrdersMapper, EbikeUs
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<RspBikeDto> bikeInfo(String ecuSn) {
|
public RspOrderDetailsInfo orderDetailsInfo(Long orderId) {
|
||||||
return List.of();
|
return this.mapper.selectOneWithRelationsByIdAs(orderId,RspOrderDetailsInfo.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -397,9 +399,43 @@ public class UserOrdersServiceImpl extends ServiceImpl<UserOrdersMapper, EbikeUs
|
|||||||
*/
|
*/
|
||||||
BigDecimal timeSlotCostCalculation(List<EbikeOrderDetails> list, EbikeUserOrders userOrders, ResFeignEbikeSysRcostsetDto feignEbikeSysRcostsetDto) {
|
BigDecimal timeSlotCostCalculation(List<EbikeOrderDetails> list, EbikeUserOrders userOrders, ResFeignEbikeSysRcostsetDto feignEbikeSysRcostsetDto) {
|
||||||
BigDecimal decimal = new BigDecimal(0);
|
BigDecimal decimal = new BigDecimal(0);
|
||||||
List<ResFeignEbikeSysRcostsetTimePeriodDto> ebikeSysRcostsetTimePeriodDtos = feignEbikeSysRcostsetDto.getEbikeSysRcostsetTimePeriodDtos();
|
|
||||||
List<TimeSegment> timeSegments = TimeUtils.splitByDays(userOrders.getStartTime(), userOrders.getEndTime());
|
List<TimeSegment> timeSegments = TimeUtils.splitByDays(userOrders.getStartTime(), userOrders.getEndTime());
|
||||||
//TODO:时间划分不同自然时间段,每一段才判断在高峰时间段内有多长时间收费多少,非高峰期多长时间收费多少
|
//TODO:时间划分不同自然时间段,每一段才判断在高峰时间段内有多长时间收费多少,非高峰期多长时间收费多少
|
||||||
|
for (TimeSegment timeSegment : timeSegments) {
|
||||||
|
BigDecimal timeFee = timeFee(timeSegment, feignEbikeSysRcostsetDto, list, userOrders.getOrderId());
|
||||||
|
decimal = decimal.add(timeFee);
|
||||||
|
}
|
||||||
|
return decimal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据自然时间段计算出现费用(高峰时段
|
||||||
|
*
|
||||||
|
* @param timeSegment 自然时间段(按天划分
|
||||||
|
* @param feignEbikeSysRcostsetDto 计算规则
|
||||||
|
* @param list 订单详细列表
|
||||||
|
* @param orderId 订单编号
|
||||||
|
* @return 当前时间段收取金额
|
||||||
|
*/
|
||||||
|
BigDecimal timeFee(TimeSegment timeSegment, ResFeignEbikeSysRcostsetDto feignEbikeSysRcostsetDto, List<EbikeOrderDetails> list, long orderId) {
|
||||||
|
BigDecimal decimal = new BigDecimal(0);
|
||||||
|
LocalDateTime start = timeSegment.getStart();
|
||||||
|
LocalDateTime end = timeSegment.getEnd();
|
||||||
|
LocalTime orderStartupTime = LocalTime.of(start.getHour(), start.getMinute(), start.getSecond());
|
||||||
|
LocalTime orderEndTime = LocalTime.of(end.getHour(), end.getMinute(), end.getSecond());
|
||||||
|
List<ResFeignEbikeSysRcostsetTimePeriodDto> ebikeSysRcostsetTimePeriodDtos = feignEbikeSysRcostsetDto.getEbikeSysRcostsetTimePeriodDtos();
|
||||||
|
//收集订单所满足计费条件的所有时段费用
|
||||||
|
for (ResFeignEbikeSysRcostsetTimePeriodDto timePeriodDto : ebikeSysRcostsetTimePeriodDtos) {
|
||||||
|
LocalTime timePeriodDtoStartupTime = timePeriodDto.getStartupTime();
|
||||||
|
LocalTime timePeriodDtoEndTime = timePeriodDto.getEndTime();
|
||||||
|
boolean createBeforeTimePeriodDtoEndTime = orderStartupTime.isBefore(timePeriodDtoEndTime);
|
||||||
|
boolean createAfterTimePeriodDtoStartupTime = orderEndTime.isAfter(timePeriodDtoStartupTime);
|
||||||
|
//满足计费条件,进行计费
|
||||||
|
if (createBeforeTimePeriodDtoEndTime && createAfterTimePeriodDtoStartupTime) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//计算常规费用
|
||||||
return decimal;
|
return decimal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package com.cdzy.orders.uitls;
|
|||||||
import com.cdzy.orders.model.dto.res.TimeSegment;
|
import com.cdzy.orders.model.dto.res.TimeSegment;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.LocalTime;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import java.time.temporal.ChronoUnit;
|
import java.time.temporal.ChronoUnit;
|
||||||
@ -81,12 +82,22 @@ public class TimeUtils {
|
|||||||
return ChronoUnit.MINUTES.between(start, end);
|
return ChronoUnit.MINUTES.between(start, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算两个时间之间的分钟差
|
||||||
|
*/
|
||||||
|
public static long betweenMinutes(LocalTime start, LocalTime end) {
|
||||||
|
Objects.requireNonNull(start, "开始时间不能为空");
|
||||||
|
Objects.requireNonNull(end, "结束时间不能为空");
|
||||||
|
return ChronoUnit.MINUTES.between(start, end);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 计算两个时间之间的秒数差
|
* 计算两个时间之间的秒数差
|
||||||
*/
|
*/
|
||||||
public static long betweenSeconds(LocalDateTime start, LocalDateTime end) {
|
public static long betweenSeconds(LocalDateTime start, LocalDateTime end) {
|
||||||
Objects.requireNonNull(start, "start time must not be null");
|
Objects.requireNonNull(start, "开始时间不能为空");
|
||||||
Objects.requireNonNull(end, "end time must not be null");
|
Objects.requireNonNull(end, "结束时间不能为空");
|
||||||
return ChronoUnit.SECONDS.between(start, end);
|
return ChronoUnit.SECONDS.between(start, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user