|
@@ -35,10 +35,7 @@ import com.ylx.massage.utils.OrderNumberGenerator;
|
|
|
import com.ylx.order.domain.AfterSalesService;
|
|
import com.ylx.order.domain.AfterSalesService;
|
|
|
import com.ylx.order.domain.OrderStatusFlow;
|
|
import com.ylx.order.domain.OrderStatusFlow;
|
|
|
import com.ylx.order.domain.TOrder;
|
|
import com.ylx.order.domain.TOrder;
|
|
|
-import com.ylx.order.domain.dto.OrderCancleDTO;
|
|
|
|
|
-import com.ylx.order.domain.dto.OrderDateQueryDTO;
|
|
|
|
|
-import com.ylx.order.domain.dto.OrderSubmitDTO;
|
|
|
|
|
-import com.ylx.order.domain.dto.OrderUpdateStatusDTO;
|
|
|
|
|
|
|
+import com.ylx.order.domain.dto.*;
|
|
|
import com.ylx.order.domain.vo.OrderDateQueryVo;
|
|
import com.ylx.order.domain.vo.OrderDateQueryVo;
|
|
|
import com.ylx.order.domain.vo.OrderDetailVO;
|
|
import com.ylx.order.domain.vo.OrderDetailVO;
|
|
|
import com.ylx.order.domain.vo.OrderStatusFlowVO;
|
|
import com.ylx.order.domain.vo.OrderStatusFlowVO;
|
|
@@ -83,7 +80,9 @@ public class TOrderServiceImpl extends ServiceImpl<TOrderMapper, TOrder> impleme
|
|
|
private final DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("M月d日");
|
|
private final DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("M月d日");
|
|
|
private final DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm");
|
|
private final DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm");
|
|
|
|
|
|
|
|
- /** 仅允许取消的状态:待付款(0) */
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 仅允许取消的状态:待付款(0)
|
|
|
|
|
+ */
|
|
|
private static final List<Integer> ALLOWED_CANCEL_STATUS = Collections.singletonList(0);
|
|
private static final List<Integer> ALLOWED_CANCEL_STATUS = Collections.singletonList(0);
|
|
|
@Resource
|
|
@Resource
|
|
|
private ProjectService projectService;
|
|
private ProjectService projectService;
|
|
@@ -113,6 +112,7 @@ public class TOrderServiceImpl extends ServiceImpl<TOrderMapper, TOrder> impleme
|
|
|
@Resource
|
|
@Resource
|
|
|
private IAfterSalesServiceService afterSalesServiceService;
|
|
private IAfterSalesServiceService afterSalesServiceService;
|
|
|
private static final String DICT_TYPE = "unit_type";
|
|
private static final String DICT_TYPE = "unit_type";
|
|
|
|
|
+ private static final int BUFFER_MINUTES = 30; // 30分钟缓冲期
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
public TOrder addOrder(TOrder order) {
|
|
public TOrder addOrder(TOrder order) {
|
|
@@ -419,6 +419,7 @@ public class TOrderServiceImpl extends ServiceImpl<TOrderMapper, TOrder> impleme
|
|
|
/**
|
|
/**
|
|
|
*
|
|
*
|
|
|
* 更新订单状态(修改订单表状态必须使用此接口)
|
|
* 更新订单状态(修改订单表状态必须使用此接口)
|
|
|
|
|
+ *
|
|
|
* @param dto
|
|
* @param dto
|
|
|
*/
|
|
*/
|
|
|
@Override
|
|
@Override
|
|
@@ -630,6 +631,7 @@ public class TOrderServiceImpl extends ServiceImpl<TOrderMapper, TOrder> impleme
|
|
|
// 3. 组装VO
|
|
// 3. 组装VO
|
|
|
return buildOrderDetailVO(order, flowList);
|
|
return buildOrderDetailVO(order, flowList);
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* 将订单实体和流转记录转换为详情VO
|
|
* 将订单实体和流转记录转换为详情VO
|
|
|
*/
|
|
*/
|
|
@@ -723,8 +725,10 @@ public class TOrderServiceImpl extends ServiceImpl<TOrderMapper, TOrder> impleme
|
|
|
|
|
|
|
|
return vo;
|
|
return vo;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* 格式化预约时间范围
|
|
* 格式化预约时间范围
|
|
|
|
|
+ *
|
|
|
* @param start 预约开始时间
|
|
* @param start 预约开始时间
|
|
|
* @param end 预约结束时间
|
|
* @param end 预约结束时间
|
|
|
* @return 示例:5月12日 16:00-18:00
|
|
* @return 示例:5月12日 16:00-18:00
|
|
@@ -742,6 +746,7 @@ public class TOrderServiceImpl extends ServiceImpl<TOrderMapper, TOrder> impleme
|
|
|
String endTime = (end != null) ? end.format(timeFormatter) : "";
|
|
String endTime = (end != null) ? end.format(timeFormatter) : "";
|
|
|
return dateStr + " " + startTime + "-" + endTime;
|
|
return dateStr + " " + startTime + "-" + endTime;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* 构建联系信息(姓名 + 脱敏手机号)
|
|
* 构建联系信息(姓名 + 脱敏手机号)
|
|
|
* 示例:王先生,188****5555
|
|
* 示例:王先生,188****5555
|
|
@@ -819,6 +824,48 @@ public class TOrderServiceImpl extends ServiceImpl<TOrderMapper, TOrder> impleme
|
|
|
return rows;
|
|
return rows;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public Boolean bookingCheck(BookingCheckDTO dto) {
|
|
|
|
|
+
|
|
|
|
|
+ // 1. 根据 projectId 获取项目时长
|
|
|
|
|
+ Project project = projectService.getById(dto.getProjectId());
|
|
|
|
|
+ if (ObjectUtil.isNull(project)) {
|
|
|
|
|
+ throw new ServiceException("项目不存在");
|
|
|
|
|
+ }
|
|
|
|
|
+ Integer duration = convertToMinutes(project.getStandardDuration(), project.getUnitType());
|
|
|
|
|
+
|
|
|
|
|
+ // 2. 组装目标时间段
|
|
|
|
|
+ LocalDateTime newStart = LocalDateTime.of(dto.getAppointmentDate(), dto.getStartTime());
|
|
|
|
|
+ LocalDateTime actualEnd = newStart.plusMinutes(duration); // 实际服务结束时间
|
|
|
|
|
+ LocalDateTime newEndWithBuffer = actualEnd.plusMinutes(BUFFER_MINUTES); // 含30分钟缓冲的结束时间
|
|
|
|
|
+
|
|
|
|
|
+ // 3. 查询该商户当天的【有效占用】订单
|
|
|
|
|
+ LocalDateTime dayStart = dto.getAppointmentDate().atStartOfDay();
|
|
|
|
|
+ LocalDateTime dayEnd = dto.getAppointmentDate().atTime(LocalTime.MAX);
|
|
|
|
|
+
|
|
|
|
|
+ List<TOrder> validOrders = this.baseMapper.selectValidOrdersByMerchantAndDate(
|
|
|
|
|
+ dto.getMerchantId(),
|
|
|
|
|
+ dto.getProjectId(),
|
|
|
|
|
+ dayStart,
|
|
|
|
|
+ dayEnd
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ // 4. 内存中遍历判断重叠
|
|
|
|
|
+ for (TOrder order : validOrders) {
|
|
|
|
|
+ LocalDateTime existStart = order.getAppointmentStartTime();
|
|
|
|
|
+ LocalDateTime existEnd = order.getAppointmentEndTime();
|
|
|
|
|
+
|
|
|
|
|
+ // 核心重叠算法:
|
|
|
|
|
+ // 新订单开始时间 < 已有订单结束时间 且 新订单结束时间(含30min缓冲) > 已有订单开始时间
|
|
|
|
|
+ if (newStart.isBefore(existEnd) && newEndWithBuffer.isAfter(existStart)) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 5. 没有任何冲突,可以预约
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
private void fillCurrentAfterSaleInfo(IAfterSaleDisplay vo, Long orderId) {
|
|
private void fillCurrentAfterSaleInfo(IAfterSaleDisplay vo, Long orderId) {
|
|
|
LambdaQueryWrapper<AfterSalesService> wrapper = new LambdaQueryWrapper<>();
|
|
LambdaQueryWrapper<AfterSalesService> wrapper = new LambdaQueryWrapper<>();
|
|
|
wrapper.eq(AfterSalesService::getOrderId, orderId)
|
|
wrapper.eq(AfterSalesService::getOrderId, orderId)
|
|
@@ -843,6 +890,7 @@ public class TOrderServiceImpl extends ServiceImpl<TOrderMapper, TOrder> impleme
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* 根据单位类型将时长转换为分钟
|
|
* 根据单位类型将时长转换为分钟
|
|
|
|
|
+ *
|
|
|
* @param duration 原始时长
|
|
* @param duration 原始时长
|
|
|
* @param unitType 单位类型 (对应字典表: 1-分钟, 2-小时, 3-小时/次)
|
|
* @param unitType 单位类型 (对应字典表: 1-分钟, 2-小时, 3-小时/次)
|
|
|
* @return 转换后的分钟数
|
|
* @return 转换后的分钟数
|