package com.xiaopeng.itinerary.service.impl; import com.alibaba.fastjson2.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.xiaopeng.api.dto.order.OrderChangeDto; import com.xiaopeng.api.feignClient.map.XpMapClient; import com.xiaopeng.api.feignClient.operation.XpPointClient; import com.xiaopeng.api.feignClient.order.XpOrderClient; 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.XpRoutePlan; import com.xiaopeng.api.model.order.XpOrder; 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.exception.ServiceException; 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.*; 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 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; /* public void getRouteAndFareParamValidate(RouteAndFareDto routeAndFareDto, String userId) { //获取订单信息 R xpOrderR = xpOrderClient.queryOrderById(routeAndFareDto.getOrderId()); if (xpOrderR.getCode() != R.SUCCESS || xpOrderR.getData() == null) { throw new ServiceException("订单不存在"); } // 1. 基础数据查询 Map 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().eq(XpPricing::getCityId, routeAndFareDto.getOpenCityId())); if (xpPricing == null) { throw new ServiceException("当前区域未开通服务", I18nKeyConstant.NO_CURRENT_REGION); } routeAndFareDto.setRoutePlanRule(xpOrderR.getData().getRoutePlanRule()); // 算距离 R 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 xpOrderR = xpOrderClient.queryOrderById(dto.getOrderId()); if (xpOrderR.getCode() != R.SUCCESS || xpOrderR.getData() == null) { throw new ServiceException("订单不存在"); } Integer orderChange = 2;//todo yyy 从配置文件读取 修改订单目的地次数 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()); XpRoutePlan xpRoutePlan = xpRoutePlanMapper.selectOne(new LambdaQueryWrapper().eq(XpRoutePlan::getAuditStatus, 2).eq(XpRoutePlan::getCityCode, order.getCityCode())); final Integer planRuleForQueue = dto.getSelectedRoutePlanRule() != null ? dto.getSelectedRoutePlanRule() : (xpRoutePlan != null ? xpRoutePlan.getRoutePlanRule() : null); // order.getId() + "_" + xpPoint.getPointLon() + "," + xpPoint.getPointLat() + "_0" + "_" + uid + "_" + order.getOrderNumber() + "_" + dto.getDistance() + "_" + dto.getDuration() + "_" + null 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); } /** * 获取距离和时间 * @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); } }