|
|
@@ -554,6 +554,9 @@ public class StoreReservationServiceImpl extends ServiceImpl<StoreReservationMap
|
|
|
throw new RuntimeException("订单状态为" + statusText + ",不允许删除。只有已取消、已退款、已完成状态的订单可以删除");
|
|
|
}
|
|
|
|
|
|
+ // 已完成订单:仅当当前时间 > 预约结束时间 + 3小时才允许删除
|
|
|
+ validateCompletedReservationDeleteTimeWindow(reservation, orderStatus);
|
|
|
+
|
|
|
// 删除订单记录(逻辑删除)
|
|
|
boolean orderDeleteResult = userReservationOrderService.removeById(order.getId());
|
|
|
if (!orderDeleteResult) {
|
|
|
@@ -571,6 +574,75 @@ public class StoreReservationServiceImpl extends ServiceImpl<StoreReservationMap
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 删除校验:已完成状态的预订,需满足“当前时间 > 结束时间 + 3小时”。
|
|
|
+ */
|
|
|
+ private void validateCompletedReservationDeleteTimeWindow(UserReservation reservation, Integer orderStatus) {
|
|
|
+ // 仅校验已完成状态
|
|
|
+ if (orderStatus == null || orderStatus != 2) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ Date reservationEndTime = parseReservationEndDateTime(reservation);
|
|
|
+ if (reservationEndTime == null) {
|
|
|
+ throw new RuntimeException("预约结束时间异常,暂不可删除");
|
|
|
+ }
|
|
|
+
|
|
|
+ Calendar calendar = Calendar.getInstance();
|
|
|
+ calendar.setTime(reservationEndTime);
|
|
|
+ calendar.add(Calendar.HOUR_OF_DAY, 3);
|
|
|
+ Date endPlusThreeHours = calendar.getTime();
|
|
|
+
|
|
|
+ if (!new Date().after(endPlusThreeHours)) {
|
|
|
+ throw new RuntimeException("已完成订单需在结束3小时后才可删除");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 解析预约结束时间,兼容两种场景:
|
|
|
+ * 1) endTime 已是完整时间(yyyy-MM-dd HH:mm[:ss])
|
|
|
+ * 2) endTime 仅为时分秒(HH:mm[:ss]),需与 reservationDate 拼接
|
|
|
+ */
|
|
|
+ private Date parseReservationEndDateTime(UserReservation reservation) {
|
|
|
+ if (reservation == null || !StringUtils.hasText(reservation.getEndTime())) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ String endTime = reservation.getEndTime().trim();
|
|
|
+
|
|
|
+ // 场景1:endTime 已是完整日期时间
|
|
|
+ String normalizedFullDateTime = normalizeDateTime(endTime);
|
|
|
+ if (normalizedFullDateTime != null) {
|
|
|
+ try {
|
|
|
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
|
+ sdf.setLenient(false);
|
|
|
+ return sdf.parse(normalizedFullDateTime);
|
|
|
+ } catch (ParseException e) {
|
|
|
+ log.warn("解析完整结束时间失败,reservationId={}, endTime={}", reservation.getId(), endTime, e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 场景2:endTime 仅时间,拼接 reservationDate 再解析
|
|
|
+ if (reservation.getReservationDate() == null) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
|
|
|
+ String datePart = dateFormat.format(reservation.getReservationDate());
|
|
|
+ String mergedDateTime = datePart + " " + endTime;
|
|
|
+ String normalizedMergedDateTime = normalizeDateTime(mergedDateTime);
|
|
|
+ if (normalizedMergedDateTime == null) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
|
+ sdf.setLenient(false);
|
|
|
+ return sdf.parse(normalizedMergedDateTime);
|
|
|
+ } catch (ParseException e) {
|
|
|
+ log.warn("解析拼接结束时间失败,reservationId={}, reservationDate={}, endTime={}",
|
|
|
+ reservation.getId(), datePart, endTime, e);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
@Override
|
|
|
public boolean addTimeByStore(Integer reservationId, String addTimeStart, Integer addTimeMinutes) {
|
|
|
log.info("StoreReservationServiceImpl.addTimeByStore?reservationId={}, addTimeStart={}, addTimeMinutes={}",
|