|
@@ -1,5 +1,6 @@
|
|
|
package com.ylx.order.service.impl;
|
|
package com.ylx.order.service.impl;
|
|
|
|
|
|
|
|
|
|
+import cn.hutool.core.bean.BeanUtil;
|
|
|
import cn.hutool.core.collection.CollUtil;
|
|
import cn.hutool.core.collection.CollUtil;
|
|
|
import cn.hutool.core.util.ObjectUtil;
|
|
import cn.hutool.core.util.ObjectUtil;
|
|
|
import cn.hutool.core.util.StrUtil;
|
|
import cn.hutool.core.util.StrUtil;
|
|
@@ -35,14 +36,12 @@ import com.ylx.order.domain.vo.OrderDetailVO;
|
|
|
import com.ylx.order.domain.vo.OrderStatusFlowVO;
|
|
import com.ylx.order.domain.vo.OrderStatusFlowVO;
|
|
|
import com.ylx.order.domain.vo.RecentMerchantVO;
|
|
import com.ylx.order.domain.vo.RecentMerchantVO;
|
|
|
import com.ylx.order.domain.vo.merchant.MerchantCancelOrderDTO;
|
|
import com.ylx.order.domain.vo.merchant.MerchantCancelOrderDTO;
|
|
|
|
|
+import com.ylx.order.domain.vo.merchant.MerchantOrderDetailVO;
|
|
|
import com.ylx.order.domain.vo.merchant.OrderCustomerPhoneVO;
|
|
import com.ylx.order.domain.vo.merchant.OrderCustomerPhoneVO;
|
|
|
import com.ylx.order.domain.vo.merchant.OrderPageVO;
|
|
import com.ylx.order.domain.vo.merchant.OrderPageVO;
|
|
|
import com.ylx.order.enums.*;
|
|
import com.ylx.order.enums.*;
|
|
|
import com.ylx.order.mapper.TOrderMapper;
|
|
import com.ylx.order.mapper.TOrderMapper;
|
|
|
-import com.ylx.order.service.IAfterSaleDisplay;
|
|
|
|
|
-import com.ylx.order.service.IAfterSalesServiceService;
|
|
|
|
|
-import com.ylx.order.service.OrderStatusFlowService;
|
|
|
|
|
-import com.ylx.order.service.TOrderService;
|
|
|
|
|
|
|
+import com.ylx.order.service.*;
|
|
|
import com.ylx.project.domain.Project;
|
|
import com.ylx.project.domain.Project;
|
|
|
import com.ylx.project.service.ProjectService;
|
|
import com.ylx.project.service.ProjectService;
|
|
|
import com.ylx.shopingfundsdetail.domain.vo.ShoppingFundsDetailAddDto;
|
|
import com.ylx.shopingfundsdetail.domain.vo.ShoppingFundsDetailAddDto;
|
|
@@ -893,6 +892,8 @@ public class TOrderServiceImpl extends ServiceImpl<TOrderMapper, TOrder> impleme
|
|
|
Integer tagCode = calcCustomerTagCode(vo, merchantId, now);
|
|
Integer tagCode = calcCustomerTagCode(vo, merchantId, now);
|
|
|
vo.setCustomerTagCode(tagCode);
|
|
vo.setCustomerTagCode(tagCode);
|
|
|
vo.setCustomerTagDesc(CustomerTagEnum.getDescByCode(tagCode));
|
|
vo.setCustomerTagDesc(CustomerTagEnum.getDescByCode(tagCode));
|
|
|
|
|
+
|
|
|
|
|
+ this.fillCurrentAfterSaleInfo(vo, vo.getId());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return page;
|
|
return page;
|
|
@@ -1026,7 +1027,7 @@ public class TOrderServiceImpl extends ServiceImpl<TOrderMapper, TOrder> impleme
|
|
|
.set(TOrder::getCancelledReason, cancelReason)
|
|
.set(TOrder::getCancelledReason, cancelReason)
|
|
|
.set(TOrder::getUpdateTime, LocalDateTime.now())
|
|
.set(TOrder::getUpdateTime, LocalDateTime.now())
|
|
|
.set(TOrder::getUpdateBy, loginUser.getCNickName())
|
|
.set(TOrder::getUpdateBy, loginUser.getCNickName())
|
|
|
- .set(TOrder::getDispatchedStatus,DispatchedStatusEnum.UN_DISPATCHED.getCode())
|
|
|
|
|
|
|
+ .set(TOrder::getDispatchedStatus, DispatchedStatusEnum.UN_DISPATCHED.getCode())
|
|
|
.eq(TOrder::getId, orderId)
|
|
.eq(TOrder::getId, orderId)
|
|
|
.eq(TOrder::getStatus, statusCode);
|
|
.eq(TOrder::getStatus, statusCode);
|
|
|
int row = baseMapper.update(null, updateWrapper);
|
|
int row = baseMapper.update(null, updateWrapper);
|
|
@@ -1213,6 +1214,48 @@ public class TOrderServiceImpl extends ServiceImpl<TOrderMapper, TOrder> impleme
|
|
|
return page;
|
|
return page;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public MerchantOrderDetailVO getMerchantOrderDetail(MerchantOrderDetailDTO dto) {
|
|
|
|
|
+
|
|
|
|
|
+ // 1. 根据ID查询订单主表
|
|
|
|
|
+ TOrder order = this.baseMapper.selectById(dto.getOrderId());
|
|
|
|
|
+ if (ObjectUtil.isNull(order)) {
|
|
|
|
|
+ throw new ServiceException("订单不存在");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (ObjectUtil.notEqual(order.getIsDelete(), NOT_DELETE)) {
|
|
|
|
|
+ throw new ServiceException("订单已被删除");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ MerchantOrderDetailVO vo = new MerchantOrderDetailVO<>();
|
|
|
|
|
+
|
|
|
|
|
+ // 2. 基础字段映射 (使用 BeanUtil 或手动 set)
|
|
|
|
|
+ BeanUtil.copyProperties(order, vo);
|
|
|
|
|
+ vo.setOrderStatus(order.getStatus());
|
|
|
|
|
+ vo.setOrderStatusName(OrderStatusEnum.getInfoByCode(order.getStatus()));
|
|
|
|
|
+
|
|
|
|
|
+ // 特殊处理 ID 转 String (前端 Long 精度丢失问题)
|
|
|
|
|
+ vo.setOrderId(String.valueOf(order.getId()));
|
|
|
|
|
+
|
|
|
|
|
+ // 格式化时间范围 (例如: 5月12日 16:00-18:00)
|
|
|
|
|
+ vo.setAppointmentTimeRange(formatTimeRange(order.getAppointmentStartTime(), order.getProjectDuration()));
|
|
|
|
|
+
|
|
|
|
|
+ // 3. 联系信息脱敏处理
|
|
|
|
|
+ vo.setContactPhoneNumber(PhoneUtils.maskPhoneNumber(order.getContactPhoneNumber()));
|
|
|
|
|
+
|
|
|
|
|
+ // 4. 计算距离与告警提示 (依赖地理围栏表 t_geo_fence)
|
|
|
|
|
+ List<TGeoFence> validFenceList = geoFenceService.selectValidFences(dto.getCityCode());
|
|
|
|
|
+ List<TGeoFence> usableFence = filterUsableFence(validFenceList);
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ // 5. 查询关联的售后信息 (如果有)
|
|
|
|
|
+ fillCurrentAfterSaleInfo(vo, order.getId());
|
|
|
|
|
+ // 6. 计算高风险围栏信息
|
|
|
|
|
+ calcOrderGeoFenceInfo(vo, usableFence);
|
|
|
|
|
+
|
|
|
|
|
+ return vo;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
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).orderByDesc(AfterSalesService::getCreateTime).last("LIMIT 1");
|
|
wrapper.eq(AfterSalesService::getOrderId, orderId).orderByDesc(AfterSalesService::getCreateTime).last("LIMIT 1");
|
|
@@ -1434,7 +1477,7 @@ public class TOrderServiceImpl extends ServiceImpl<TOrderMapper, TOrder> impleme
|
|
|
/**
|
|
/**
|
|
|
* 计算单条订单围栏距离、是否高风险区域、围栏备注
|
|
* 计算单条订单围栏距离、是否高风险区域、围栏备注
|
|
|
*/
|
|
*/
|
|
|
- private void calcOrderGeoFenceInfo(OrderPageVO orderVO, List<TGeoFence> usableFence) {
|
|
|
|
|
|
|
+ private void calcOrderGeoFenceInfo(IGeoRiskInfo orderVO, List<TGeoFence> usableFence) {
|
|
|
// 用户坐标为空直接标记非风险
|
|
// 用户坐标为空直接标记非风险
|
|
|
BigDecimal userLat = orderVO.getUserLatitude();
|
|
BigDecimal userLat = orderVO.getUserLatitude();
|
|
|
BigDecimal userLon = orderVO.getUserLongitude();
|
|
BigDecimal userLon = orderVO.getUserLongitude();
|
|
@@ -1474,4 +1517,37 @@ public class TOrderServiceImpl extends ServiceImpl<TOrderMapper, TOrder> impleme
|
|
|
orderVO.setFenceIntro(nearestFence.getFenceIntro());
|
|
orderVO.setFenceIntro(nearestFence.getFenceIntro());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 格式化预约时间范围
|
|
|
|
|
+ * 示例输出: "5月12日 16:00-18:00"
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param startTime 预约开始时间
|
|
|
|
|
+ * @param durationMinutes 项目时长(分钟)
|
|
|
|
|
+ * @return 格式化后的时间范围字符串
|
|
|
|
|
+ */
|
|
|
|
|
+ private String formatTimeRange(LocalDateTime startTime, Integer durationMinutes) {
|
|
|
|
|
+ if (startTime == null || durationMinutes == null || durationMinutes <= 0) {
|
|
|
|
|
+ return "";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ LocalDateTime endTime = startTime.plusMinutes(durationMinutes);
|
|
|
|
|
+ DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("M月d日", Locale.CHINA);
|
|
|
|
|
+ DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm");
|
|
|
|
|
+
|
|
|
|
|
+ String dateStr = dateFormatter.format(startTime);
|
|
|
|
|
+ String startTimeStr = timeFormatter.format(startTime);
|
|
|
|
|
+ String endTimeStr = timeFormatter.format(endTime);
|
|
|
|
|
+
|
|
|
|
|
+ // 判断是否跨天
|
|
|
|
|
+ if (!startTime.toLocalDate().isEqual(endTime.toLocalDate())) {
|
|
|
|
|
+ // 跨天场景:在结束时间前加上日期
|
|
|
|
|
+ String endDateStr = dateFormatter.format(endTime);
|
|
|
|
|
+ return String.format("%s %s-%s %s", dateStr, startTimeStr, endDateStr, endTimeStr);
|
|
|
|
|
+ // 输出示例: "5月12日 23:00-5月13日 01:00"
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 同天场景:正常拼接
|
|
|
|
|
+ return String.format("%s %s-%s", dateStr, startTimeStr, endTimeStr);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
}
|
|
}
|