package com.xiaopeng.itinerary.service.impl;
|
|
|
import com.alibaba.fastjson2.JSON;
|
import com.alibaba.fastjson2.JSONObject;
|
import com.xiaopeng.api.dto.automaticPilot.PushOrderDto;
|
import com.xiaopeng.api.dto.operation.ReassignOrderDTO;
|
import com.xiaopeng.api.dto.order.OrderChangeDto;
|
import com.xiaopeng.api.feignClient.automaticPilot.OrderMissionClient;
|
import com.xiaopeng.api.feignClient.map.XpMapClient;
|
import com.xiaopeng.api.feignClient.operation.ReassignOrderClient;
|
import com.xiaopeng.api.feignClient.operation.XpPointClient;
|
import com.xiaopeng.api.feignClient.operation.XpSystemSettingClient;
|
import com.xiaopeng.api.feignClient.order.XpOrderClient;
|
import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient;
|
import com.xiaopeng.api.model.operation.XpElectronicFence;
|
import com.xiaopeng.api.model.operation.XpElectronicFenceArea;
|
import com.xiaopeng.api.model.operation.XpPoint;
|
import com.xiaopeng.api.model.operation.XpSystemSetting;
|
import com.xiaopeng.api.model.order.XpOrder;
|
import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
|
import com.xiaopeng.api.vo.automaticPilot.protobuf.OrderOperationType;
|
import com.xiaopeng.api.vo.operation.RouteOptionVo;
|
import com.xiaopeng.api.vo.operation.RouteVo;
|
import com.xiaopeng.common.core.constant.CacheConstants;
|
import com.xiaopeng.common.core.domain.R;
|
import com.xiaopeng.common.core.enums.OrderStatusEnum;
|
import com.xiaopeng.common.core.exception.ServiceException;
|
import com.xiaopeng.common.core.utils.StringUtils;
|
import com.xiaopeng.common.redis.service.RedisService;
|
import com.xiaopeng.itinerary.constant.I18nKeyConstant;
|
import com.xiaopeng.itinerary.mapper.XpElectronicFenceAreaMapper;
|
import com.xiaopeng.itinerary.mapper.XpElectronicFenceMapper;
|
import com.xiaopeng.itinerary.mapper.XpOpenCityMapper;
|
import com.xiaopeng.itinerary.mapper.XpRoutePlanMapper;
|
import com.xiaopeng.itinerary.navigation.MultiRouteSnapshotPayload;
|
import com.xiaopeng.itinerary.service.ActiveOrderService;
|
import com.xiaopeng.itinerary.service.XpPointService;
|
import com.xiaopeng.itinerary.service.XpPricingService;
|
import com.xiaopeng.itinerary.utils.map.GDMapGeocodingUtil;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Service;
|
|
import javax.annotation.Resource;
|
import java.time.LocalDateTime;
|
import java.util.StringJoiner;
|
import java.util.concurrent.TimeUnit;
|
|
|
@Slf4j
|
@Service
|
public class ActiveOrderServiceImpl implements ActiveOrderService {
|
|
|
@Resource
|
private GDMapGeocodingUtil gdMapGeocodingUtil;
|
@Resource
|
private XpOpenCityMapper xpOpenCityMapper;
|
@Resource
|
private XpOrderClient xpOrderClient;
|
@Resource
|
private XpSystemSettingClient xpSystemSettingClient;
|
@Resource
|
private XpPricingService xpPricingService;
|
@Resource
|
private XpMapClient xpMapClient;
|
@Resource
|
private XpElectronicFenceAreaMapper xpElectronicFenceAreaMapper;
|
@Autowired
|
private XpElectronicFenceMapper xpElectronicFenceMapper;
|
@Autowired
|
private XpPointService xpPointService;
|
@Resource
|
private XpPointClient xpPointClient;
|
@Resource
|
private RedisService redisService;
|
@Resource
|
private XpRoutePlanMapper xpRoutePlanMapper;
|
@Resource
|
private XpVehicleClient vehicleClient;
|
@Resource
|
private OrderMissionClient orderMissionClient;
|
|
|
/*
|
public void getRouteAndFareParamValidate(RouteAndFareDto routeAndFareDto, String userId) {
|
//获取订单信息
|
|
R<XpOrder> xpOrderR = xpOrderClient.queryOrderById(routeAndFareDto.getOrderId());
|
|
if (xpOrderR.getCode() != R.SUCCESS || xpOrderR.getData() == null) {
|
throw new ServiceException("订单不存在");
|
}
|
// 1. 基础数据查询
|
Map<String, String> geocode = gdMapGeocodingUtil.geocode(routeAndFareDto.getOrigin().getLongitude().toString(), routeAndFareDto.getOrigin().getLatitude().toString());
|
if(null == geocode){
|
throw new ServiceException("获取城市信息失败", I18nKeyConstant.CITY_NOT_FOUND);
|
}
|
Long cityCode = routeAndFareDto.getOpenCityId();
|
XpOpenCity openCities = xpOpenCityMapper.selectById(cityCode);
|
if (openCities == null ) {
|
throw new ServiceException("获取城市信息失败", I18nKeyConstant.CITY_NOT_FOUND);
|
}
|
XpPricing xpPricing = xpPricingService.getOne(new LambdaQueryWrapper<XpPricing>().eq(XpPricing::getCityId, routeAndFareDto.getOpenCityId()));
|
if (xpPricing == null) {
|
throw new ServiceException("当前区域未开通服务", I18nKeyConstant.NO_CURRENT_REGION);
|
}
|
|
routeAndFareDto.setRoutePlanRule(xpOrderR.getData().getRoutePlanRule());
|
// 算距离
|
R<RouteVo> distanceAndDuration = xpMapClient.getDistanceAndDuration(routeAndFareDto);
|
if (distanceAndDuration.getCode() != 200) {
|
throw new ServiceException("获取导肮信息失败", I18nKeyConstant.PATH_NOT_FOUND);
|
}
|
RouteVo routeVo = distanceAndDuration.getData();
|
}
|
*/
|
|
@Override
|
public void orderChange(OrderChangeDto dto, String uid){
|
|
//获取订单信息
|
R<XpOrder> xpOrderR = xpOrderClient.queryOrderById(dto.getOrderId());
|
if (xpOrderR.getCode() != R.SUCCESS || xpOrderR.getData() == null) {
|
throw new ServiceException("订单不存在");
|
}
|
|
//获取系统配置
|
XpSystemSetting systemSetting = xpSystemSettingClient.getSystemSettingOne().getData();
|
if(systemSetting == null){
|
throw new ServiceException("获取行程配置错误");
|
}
|
Integer orderChange = systemSetting.getXczCaCount();// 从配置文件读取 修改订单目的地次数
|
XpOrder order = xpOrderR.getData();
|
//判断订单修改的次数
|
if(order.getOrderChange() > orderChange){
|
throw new ServiceException("目的地修改次数已超上限");
|
}
|
|
// 是否在运营区域时间内
|
XpElectronicFenceArea xpElectronicFenceArea = xpElectronicFenceAreaMapper.selectById(order.getXpElectronicFenceAreaId());
|
XpElectronicFence xpElectronicFence = xpElectronicFenceMapper.selectById(xpElectronicFenceArea.getElectronicId());
|
String operationStrategy = xpElectronicFence.getOperationStrategy();
|
Boolean inOperationTime = xpPricingService.isInOperationTime(operationStrategy);
|
if (!inOperationTime && xpElectronicFence.getFailureType()!=1) {
|
log.info("当前区域暂未开通,下单失败 {}", uid);
|
throw new ServiceException("当前区域未开通服务", I18nKeyConstant.NO_CURRENT_REGION);
|
}
|
boolean inTime = xpPointClient.nowInTimePoint(dto.getEndPointId()).getData();
|
if (!inTime) {
|
throw new ServiceException("终点点位未开通服务", I18nKeyConstant.NO_CURRENT_REGION);
|
}
|
// 终点
|
XpPoint endXpPoint = xpPointService.getById(dto.getEndPointId());
|
if(endXpPoint ==null || endXpPoint.getOperationStatus()!=2){
|
throw new ServiceException("该站点已停止运营", 200,I18nKeyConstant.NO_CURRENT_POINT);
|
}
|
|
//修改订单数据
|
XpOrder xpOrder = new XpOrder();
|
xpOrder.setId(order.getId());
|
xpOrder.setEndLon(endXpPoint.getPointLon());
|
xpOrder.setEndLat(endXpPoint.getPointLat());
|
xpOrder.setEndAddress(endXpPoint.getPointAddress());
|
xpOrder.setEndPointId(dto.getEndPointId());
|
xpOrder.setEndPointName(endXpPoint.getPointName());
|
|
Long couponRef = dto.getCouponId();
|
xpOrder.setCouponId(couponRef != null && couponRef > 0L ? couponRef : null);
|
xpOrder.setUpdateTime(LocalDateTime.now());
|
xpOrder.setOrderChange(order.getOrderChange()+1);
|
xpOrderClient.updateOrder(xpOrder);
|
|
//获取距离和时间
|
this.getDD(uid,dto);
|
|
//将修改信息存入到redis,
|
// 获取起点经纬度
|
XpPoint xpPoint = xpPointService.getById(order.getStartPointId());
|
final Integer planRuleForQueue = dto.getSelectedRoutePlanRule();
|
|
StringJoiner points = new StringJoiner("_");
|
points.add(order.getId().toString());
|
points.add(xpPoint.getPointLon() + "," + xpPoint.getPointLat());
|
points.add("0");
|
points.add(uid);
|
points.add(order.getOrderNumber());
|
points.add(dto.getDistance()+"");
|
points.add(dto.getDuration()+"");
|
|
String key = CacheConstants.QUEUE_POINT_ID + "-" + xpPoint.getId() + "-" + xpPoint.getPointLon() + "," + xpPoint.getPointLat();
|
if (planRuleForQueue == null) {
|
redisService.addToTail(key,points+"_"+null);
|
} else {
|
redisService.addToTail(key,points+"_"+planRuleForQueue);
|
}
|
log.info("订单推单:{} {}", key, redisService.getCacheList(key));
|
xpOrder.setQueueName(key);
|
xpOrderClient.updateOrder(xpOrder);
|
//给车端推送修改目的地报文
|
XpVehicle xpVehicle = vehicleClient.queryById(xpOrder.getVehicleId()).getData();
|
PushOrderDto pushOrderDto = new PushOrderDto();
|
pushOrderDto.setOrderId(order.getId().toString());
|
pushOrderDto.setTaskId(order.getXpuTaskId());
|
pushOrderDto.setVin(xpVehicle.getVehicleVin());
|
pushOrderDto.setOperation_type(OrderOperationType.CLOUD_CHANGE_DESTINATION);
|
orderMissionClient.cancelOrder(pushOrderDto);
|
log.info("订单下发XPU修改目的地成功 {}", order.getId());
|
|
|
// 判断当前订单的车辆是否有连环派单,然后判断是都还满足连环派单的条件,不满足则需要重新派单
|
String json = redisService.getCacheObject(CacheConstants.nextOrder(order.getId().toString()));
|
if (StringUtils.isNotEmpty(json)){
|
JSONObject jsonObject = JSON.parseObject(json);
|
Long nextOrderId = jsonObject.getLong("orderId");
|
XpOrder nextOrder = xpOrderClient.queryOrderById(nextOrderId).getData();
|
if(null != nextOrder && nextOrder.getStatus() == OrderStatusEnum.PICK_UP.getCode()){
|
redisService.setCacheObject(CacheConstants.nextOrder(order.getId().toString()),null);
|
ReassignOrderDTO reassignOrderDTO = new ReassignOrderDTO();
|
reassignOrderDTO.setUid(xpOrder.getAppUserId().toString());
|
reassignOrderDTO.setOrderNo(xpOrder.getOrderNumber());
|
reassignOrderDTO.setCount(10);
|
reassignOrderDTO.setLongitude(xpOrder.getStartLon());
|
reassignOrderDTO.setLatitude(xpOrder.getStartLon());
|
reassignOrderClient.reassignOrder(reassignOrderDTO);
|
}
|
}
|
}
|
@Resource
|
private ReassignOrderClient reassignOrderClient;
|
/**
|
* 获取距离和时间
|
* @param uid
|
* @param dto
|
*/
|
public void getDD (String uid, OrderChangeDto dto ){
|
|
Integer distance = 0;
|
Integer duration = 0;
|
if (dto.getNavigationSnapshotId() != null && dto.getSelectedRouteId() != null) {
|
String snap = redisService.getCacheObject(CacheConstants.ORDER_MULTI_ROUTE_SNAPSHOT + uid + ":" + dto.getNavigationSnapshotId());
|
if (snap != null) {
|
MultiRouteSnapshotPayload snapPayload = JSON.parseObject(snap, MultiRouteSnapshotPayload.class);
|
RouteOptionVo opt = snapPayload.getRoutes().stream()
|
.filter(r2 -> dto.getSelectedRouteId().equals(r2.getPathFingerprint()))
|
.findFirst()
|
.orElse(null);
|
if (opt != null && opt.getRoute() != null) {
|
distance = opt.getRoute().getDistance();
|
duration = opt.getRoute().getDuration();
|
redisService.setCacheObject("ORDER_NAVIGATION_END_DATA:" + uid, JSON.toJSONString(opt.getRoute()), 24L, TimeUnit.HOURS);
|
if (dto.getSelectedRoutePlanRule() == null) {
|
dto.setSelectedRoutePlanRule(opt.getPrimaryRoutePlanRule());
|
}
|
}
|
}
|
}
|
if (distance == 0 && duration == 0) {
|
Object cacheObject = redisService.getCacheObject("ORDER_NAVIGATION_END_DATA:" + uid);
|
if (cacheObject != null) {
|
RouteVo routeVo = JSON.parseObject(cacheObject.toString(), RouteVo.class);
|
distance = routeVo.getDistance();
|
duration = routeVo.getDuration();
|
}
|
}
|
|
dto.setDistance(distance);
|
dto.setDuration(duration);
|
}
|
|
|
|
}
|