| | |
| | | //package com.xiaopeng.order.service.impl; |
| | | // |
| | | //import cn.hutool.core.bean.BeanUtil; |
| | | //import cn.hutool.core.collection.CollUtil; |
| | | //import cn.hutool.json.JSONUtil; |
| | | //import com.alibaba.fastjson2.JSON; |
| | | //import com.alibaba.fastjson2.JSONArray; |
| | | //import com.alibaba.fastjson2.JSONObject; |
| | | //import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | //import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | //import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | //import com.google.common.collect.ImmutableMap; |
| | | //import com.xiaopeng.api.dto.account.GetUserCouponDto; |
| | | //import com.xiaopeng.api.dto.account.UcUserInfo; |
| | | //import com.xiaopeng.api.dto.account.UseUserCouponDto; |
| | | //import com.xiaopeng.api.dto.automaticPilot.PushOrderDto; |
| | | //import com.xiaopeng.api.dto.order.GetOrderNumDto; |
| | | //import com.xiaopeng.api.dto.order.HistoryEndPointsDto; |
| | | //import com.xiaopeng.api.dto.order.HistoryStartPointsDto; |
| | | //import com.xiaopeng.api.dto.order.PopOrderDto; |
| | | //import com.xiaopeng.api.dto.pushMessage.SendMessageDTO; |
| | | //import com.xiaopeng.api.dto.statistics.DailyCountDTO; |
| | | //import com.xiaopeng.api.dto.statistics.OrderStatisticsDTO; |
| | | //import com.xiaopeng.api.dto.statistics.StatisticsQueryDTO; |
| | | //import com.xiaopeng.api.dto.vehicleConvoy.BaseVehicleUserDto; |
| | | //import com.xiaopeng.api.feignClient.account.UserResourcesClient; |
| | | //import com.xiaopeng.api.feignClient.account.XpAppUserCouponClient; |
| | | //import com.xiaopeng.api.feignClient.automaticPilot.OrderMissionClient; |
| | | //import com.xiaopeng.api.feignClient.maintenance.XpTaskRuleClient; |
| | | //import com.xiaopeng.api.feignClient.operation.XpCruisePlanClient; |
| | | //import com.xiaopeng.api.feignClient.operation.XpPointClient; |
| | | //import com.xiaopeng.api.feignClient.operation.XpPricingClient; |
| | | //import com.xiaopeng.api.feignClient.operation.XpSystemSettingClient; |
| | | //import com.xiaopeng.api.feignClient.pushMessage.XpPushMessageClient; |
| | | //import com.xiaopeng.api.feignClient.vehicleConvoy.UserVehicleClient; |
| | | //import com.xiaopeng.api.feignClient.vehicleConvoy.XpFleetClient; |
| | | //import com.xiaopeng.api.feignClient.vehicleConvoy.XpFleetVehicleClient; |
| | | //import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient; |
| | | //import com.xiaopeng.api.model.maintenance.XpTaskRule; |
| | | //import com.xiaopeng.api.model.operation.*; |
| | | //import com.xiaopeng.api.model.order.*; |
| | | //import com.xiaopeng.api.model.vehicleConvoy.XpFleet; |
| | | //import com.xiaopeng.api.model.vehicleConvoy.XpVehicle; |
| | | //import com.xiaopeng.api.vo.OrderType; |
| | | //import com.xiaopeng.api.vo.account.UserCouponVo; |
| | | //import com.xiaopeng.api.vo.automaticPilot.VehiclePosition; |
| | | //import com.xiaopeng.api.vo.operation.RouteVo; |
| | | //import com.xiaopeng.api.vo.order.*; |
| | | //import com.xiaopeng.api.vo.vehicleConvoy.AddTaxiPassengerVo; |
| | | //import com.xiaopeng.api.vo.vehicleConvoy.CancelTaxiPassengerVo; |
| | | //import com.xiaopeng.common.core.constant.CacheConstants; |
| | | //import com.xiaopeng.common.core.constant.Constants; |
| | | //import com.xiaopeng.common.core.constant.HttpStatus; |
| | | //import com.xiaopeng.common.core.domain.R; |
| | | //import com.xiaopeng.common.core.enums.OrderStatusEnum; |
| | | //import com.xiaopeng.common.core.enums.PushMessageTypeEnum; |
| | | //import com.xiaopeng.common.core.exception.ServiceException; |
| | | //import com.xiaopeng.common.core.utils.DateUtils; |
| | | //import com.xiaopeng.common.core.utils.GeodesyUtil; |
| | | //import com.xiaopeng.common.core.utils.StringUtils; |
| | | //import com.xiaopeng.common.core.web.domain.BaseModel; |
| | | //import com.xiaopeng.common.core.web.page.PageInfo; |
| | | //import com.xiaopeng.common.redis.service.RedisService; |
| | | //import com.xiaopeng.common.security.utils.SecurityUtils; |
| | | //import com.xiaopeng.order.constant.I18nKeyConstant; |
| | | //import com.xiaopeng.order.dto.MileageDto; |
| | | //import com.xiaopeng.order.job.base.QuartzManager; |
| | | //import com.xiaopeng.order.job.base.TimeJobType; |
| | | //import com.xiaopeng.order.job.jobs.AddCruiseMissionJob; |
| | | //import com.xiaopeng.order.job.jobs.EndTripJob; |
| | | //import com.xiaopeng.order.job.jobs.OrderCancelJob; |
| | | //import com.xiaopeng.order.mangodb.model.OrderTrajectory; |
| | | //import com.xiaopeng.order.mangodb.service.OrderTrajectoryService; |
| | | //import com.xiaopeng.order.mapper.*; |
| | | //import com.xiaopeng.order.model.dto.XpOrderCommentDto; |
| | | //import com.xiaopeng.order.model.dto.XpOrderPayDto; |
| | | //import com.xiaopeng.order.model.query.XpHistoryOrderListQuery; |
| | | //import com.xiaopeng.order.model.query.XpOrderExcelQuery; |
| | | //import com.xiaopeng.order.model.query.XpOrderPageQuery; |
| | | //import com.xiaopeng.order.model.query.XpTestOrderPageQuery; |
| | | //import com.xiaopeng.order.model.vo.*; |
| | | //import com.xiaopeng.order.service.*; |
| | | //import com.xiaopeng.order.utils.GDMapGeocodingUtil; |
| | | //import com.xiaopeng.order.utils.RegionCodeFilterUtil; |
| | | //import com.xiaopeng.order.utils.TaxiPricingDemoService; |
| | | //import com.xiaopeng.order.utils.XpPricingUtil; |
| | | //import com.xiaopeng.order.utils.holiday.HolidayUtil; |
| | | //import com.xiaopeng.order.vo.OrderDetailVo; |
| | | //import lombok.RequiredArgsConstructor; |
| | | //import lombok.extern.slf4j.Slf4j; |
| | | //import org.apache.shardingsphere.transaction.annotation.ShardingSphereTransactionType; |
| | | //import org.apache.shardingsphere.transaction.core.TransactionType; |
| | | //import org.springframework.beans.BeanUtils; |
| | | //import org.springframework.beans.factory.annotation.Autowired; |
| | | //import org.springframework.beans.factory.annotation.Value; |
| | | //import org.springframework.context.annotation.Lazy; |
| | | //import org.springframework.data.domain.Sort; |
| | | //import org.springframework.data.mongodb.core.MongoTemplate; |
| | | //import org.springframework.data.mongodb.core.geo.GeoJsonPoint; |
| | | //import org.springframework.data.mongodb.core.query.Criteria; |
| | | //import org.springframework.data.mongodb.core.query.Query; |
| | | //import org.springframework.stereotype.Service; |
| | | //import org.springframework.transaction.annotation.Transactional; |
| | | //import org.springframework.util.CollectionUtils; |
| | | // |
| | | //import java.math.BigDecimal; |
| | | //import java.math.RoundingMode; |
| | | //import java.text.SimpleDateFormat; |
| | | //import java.time.*; |
| | | //import java.util.*; |
| | | //import java.util.concurrent.LinkedBlockingQueue; |
| | | //import java.util.concurrent.ThreadPoolExecutor; |
| | | //import java.util.concurrent.TimeUnit; |
| | | //import java.util.function.Function; |
| | | //import java.util.stream.Collectors; |
| | | // |
| | | ///** |
| | | // * <p> |
| | | // * 订单 服务实现类 |
| | | // * </p> |
| | | // * |
| | | // * @author mitao |
| | | // * @since 2026-02-03 |
| | | // */ |
| | | //@Slf4j |
| | | //@Service |
| | | //@RequiredArgsConstructor(onConstructor_ = @Lazy) |
| | | //public class XpTestOrderServiceImpl extends ServiceImpl<XpTestOrderMapper, XpTestOrder> implements IXpTestOrderService { |
| | | // |
| | | // private final UserResourcesClient userResourcesClient; |
| | | // private final XpPointClient xpPointClient; |
| | | // private final XpVehicleClient xpVehicleClient; |
| | | // private final XpAppUserCouponClient xpAppUserCouponClient; |
| | | // private final XpFleetClient xpFleetClient; |
| | | // private final XpFleetVehicleClient xpFleetVehicleClient; |
| | | // private final UserVehicleClient userVehicleClient; |
| | | // private final IXpOrderEvaluateService xpOrderEvaluateService; |
| | | // private final IXpTestOrderCancelService xpTestOrderCancelService; |
| | | // private final IXpOrderReassignService xpOrderReassignService; |
| | | // private final RedisService redisService; |
| | | // private final XpPricingClient xpPricingClient; |
| | | // private final XpSystemSettingClient xpSystemSettingClient; |
| | | // private final OrderTrajectoryService orderTrajectoryService; |
| | | // private final XpPushMessageClient xpPushMessageClient; |
| | | // private final OrderMissionClient orderMissionClient; |
| | | // private final XpTestOrderDetailMapper xpTestOrderDetailMapper; |
| | | // private final XpCruiseOrderMapper xpCruiseOrderMapper; |
| | | // private final XpTaskRuleClient xpTaskRuleClient; |
| | | // private final XpCruisePlanClient xpCruisePlanClient; |
| | | // private final XpPricingUtil xpPricingUtil; |
| | | // private final GDMapGeocodingUtil gdMapGeocodingUtil; |
| | | // |
| | | // |
| | | // @Autowired |
| | | // private MongoTemplate mongoTemplate; |
| | | // @Autowired |
| | | // private HolidayUtil holidayUtil; |
| | | // |
| | | // @Value("${robotaxi.appId:xp_robotaxi_api}") |
| | | // private String appid; |
| | | // |
| | | // |
| | | // @Override |
| | | // public OrderStatisticsDTO getOrderStatistics(StatisticsQueryDTO query) { |
| | | // OrderStatisticsDTO dto = new OrderStatisticsDTO(); |
| | | // |
| | | // // 1. 查询订单总数(状态为9=待评价或10=已完成) |
| | | // dto.setTotalCount(baseMapper.countCompletedOrders()); |
| | | // |
| | | // // 2. 查询时间范围内新增订单数 |
| | | // if (Objects.nonNull(query.getStartDate()) && Objects.nonNull(query.getEndDate())) { |
| | | // dto.setNewCount(baseMapper.countNewOrders(query.getStartDate(), query.getEndDate())); |
| | | // } else { |
| | | // dto.setNewCount(0L); |
| | | // } |
| | | // |
| | | // // 3. 查询总交易金额和总收入(pay_money累加) |
| | | // BigDecimal totalMoney = baseMapper.sumTotalMoney(); |
| | | // dto.setTotalMoney(Objects.nonNull(totalMoney) ? totalMoney : BigDecimal.ZERO); |
| | | // dto.setTotalIncome(Objects.nonNull(totalMoney) ? totalMoney : BigDecimal.ZERO); |
| | | // |
| | | // // 4. 查询近N天每日新增订单数(默认30天) |
| | | // Integer trendDays = Objects.nonNull(query.getTrendDays()) ? query.getTrendDays() : 30; |
| | | // LocalDate endDate = LocalDate.now(); |
| | | // LocalDate startDate = endDate.minusDays(trendDays - 1); |
| | | // List<DailyCountDTO> dailyCountList = baseMapper.getDailyOrderCount(startDate, endDate); |
| | | // dto.setDailyCountList(Objects.nonNull(dailyCountList) ? dailyCountList : new ArrayList<>()); |
| | | // |
| | | // return dto; |
| | | // } |
| | | // |
| | | // @Override |
| | | // public PageInfo<XpTestOrderPageVO> pageList(XpTestOrderPageQuery query) { |
| | | // // 0. 车牌号筛选:先查车辆服务获取车辆ID列表 |
| | | // List<Long> vehicleIdsFilter = null; |
| | | // if (StringUtils.isNotBlank(query.getPlateNumber())) { |
| | | // R<List<XpVehicle>> vehicleResult = xpVehicleClient.listByPlateNumber(query.getPlateNumber()); |
| | | // if (vehicleResult == null || CollectionUtils.isEmpty(vehicleResult.getData())) { |
| | | // return buildEmptyOrderPage(query); |
| | | // } |
| | | // vehicleIdsFilter = vehicleResult.getData().stream() |
| | | // .map(XpVehicle::getId) |
| | | // .filter(Objects::nonNull) |
| | | // .distinct() |
| | | // .collect(Collectors.toList()); |
| | | // if (CollectionUtils.isEmpty(vehicleIdsFilter)) { |
| | | // return buildEmptyOrderPage(query); |
| | | // } |
| | | // } |
| | | // // 1. 构建查询条件 |
| | | // LambdaQueryWrapper<XpTestOrder> wrapper = buildQueryWrapper(query); |
| | | // if (CollUtil.isNotEmpty(vehicleIdsFilter)) { |
| | | // wrapper.in(XpTestOrder::getVehicleId, vehicleIdsFilter); |
| | | // } |
| | | // wrapper.orderByDesc(XpTestOrder::getCreateTime); |
| | | // |
| | | // // 2. 分页查询 |
| | | // Page<XpTestOrder> page = new Page<>(query.getPageNum(), query.getPageSize()); |
| | | // Page<XpTestOrder> pageResult = this.page(page, wrapper); |
| | | // |
| | | // if (CollectionUtils.isEmpty(pageResult.getRecords())) { |
| | | // return buildEmptyOrderPage(query); |
| | | // } |
| | | // |
| | | // // 3. 收集关联ID |
| | | // Set<Long> vehicleIds = new HashSet<>(); |
| | | // Set<Long> fleetIds = new HashSet<>(); |
| | | // for (XpTestOrder order : pageResult.getRecords()) { |
| | | // if (Objects.nonNull(order.getVehicleId())) { |
| | | // vehicleIds.add(order.getVehicleId()); |
| | | // } |
| | | // if (Objects.nonNull(order.getFleetId())) { |
| | | // fleetIds.add(order.getFleetId()); |
| | | // } |
| | | // } |
| | | // |
| | | // // 4. 批量查询关联数据 |
| | | // Map<Long, XpVehicle> vehicleMap = batchGetVehicles(vehicleIds); |
| | | // Map<Long, XpFleet> fleetMap = batchGetFleets(fleetIds); |
| | | // |
| | | // // 5. 组装 VO |
| | | // List<XpTestOrderPageVO> voList = pageResult.getRecords().stream() |
| | | // .map(order -> convertToPageVO(order, vehicleMap, fleetMap)) |
| | | // .collect(Collectors.toList()); |
| | | // |
| | | // // 6. 返回分页结果 |
| | | // PageInfo<XpTestOrderPageVO> resultPage = new PageInfo<>(query.getPageNum(), query.getPageSize()); |
| | | // resultPage.setTotal(pageResult.getTotal()); |
| | | // resultPage.setRecords(voList); |
| | | // return resultPage; |
| | | // } |
| | | // |
| | | // private PageInfo<XpTestOrderPageVO> buildEmptyOrderPage(XpTestOrderPageQuery query) { |
| | | // PageInfo<XpTestOrderPageVO> resultPage = new PageInfo<>(query.getPageNum(), query.getPageSize()); |
| | | // resultPage.setTotal(0L); |
| | | // resultPage.setRecords(new ArrayList<>()); |
| | | // return resultPage; |
| | | // } |
| | | // |
| | | // @Override |
| | | // public XpTestOrderDetailVO getOrderDetail(Long id) { |
| | | // // 1. 查询订单基础信息 |
| | | // XpTestOrder order = this.getById(id); |
| | | // if (order == null) { |
| | | // throw new ServiceException("订单不存在"); |
| | | // } |
| | | // |
| | | // // 2. 转换为详情 VO |
| | | // XpTestOrderDetailVO vo = BeanUtil.toBean(order, XpTestOrderDetailVO.class); |
| | | // |
| | | // // 4. 获取车辆信息 |
| | | // if (Objects.nonNull(order.getVehicleId())) { |
| | | // Map<Long, XpVehicle> vehicleMap = batchGetVehicles(Collections.singleton(order.getVehicleId())); |
| | | // XpVehicle vehicle = vehicleMap.get(order.getVehicleId()); |
| | | // if (Objects.nonNull(vehicle)) { |
| | | // vo.setPlateNumber(vehicle.getPlateNumber()); |
| | | // vo.setVehicleModel(vehicle.getVehicleModel()); |
| | | // } |
| | | // } |
| | | // |
| | | // // 5. 获取车队信息 |
| | | // if (Objects.nonNull(order.getFleetId())) { |
| | | // Map<Long, XpFleet> fleetMap = batchGetFleets(Collections.singleton(order.getFleetId())); |
| | | // XpFleet fleet = fleetMap.get(order.getFleetId()); |
| | | // if (Objects.nonNull(fleet)) { |
| | | // vo.setFleetName(fleet.getFleetName()); |
| | | // } |
| | | // } |
| | | // |
| | | // // 6. 获取评价信息 |
| | | // LambdaQueryWrapper<XpOrderEvaluate> evaluateWrapper = new LambdaQueryWrapper<>(); |
| | | // evaluateWrapper.eq(XpOrderEvaluate::getOrderId, id); |
| | | // XpOrderEvaluate evaluate = xpOrderEvaluateService.getOne(evaluateWrapper.orderByDesc(XpOrderEvaluate::getCreateTime).last(" limit 0,1")); |
| | | // if (Objects.nonNull(evaluate)) { |
| | | // vo.setOrderRating(evaluate.getOrderRating()); |
| | | // } |
| | | // // 7. 查询mongodb 该订单上传的经纬度轨迹信息(按订单id) |
| | | // List<OrderTrajectory> trajectories = queryOrderTrajectories(id); |
| | | // vo.setOrderPositionList(convertTrajectoriesToPositions(trajectories)); |
| | | // |
| | | // // 8. 起步价、里程费、时长费、远途费:按订单费用明细聚合 |
| | | // Map<Integer, BigDecimal> feeMap = sumOrderDetailMoneyByDetailType(id); |
| | | // vo.setStartMoney(feeMap.getOrDefault(1, BigDecimal.ZERO)); |
| | | // vo.setMileageMoney(feeMap.getOrDefault(2, BigDecimal.ZERO)); |
| | | // vo.setDurationMoney(feeMap.getOrDefault(3, BigDecimal.ZERO)); |
| | | // vo.setLongDistancemoney(feeMap.getOrDefault(4, BigDecimal.ZERO)); |
| | | // return vo; |
| | | // } |
| | | // |
| | | // @Override |
| | | // public void deleteOrder(Long id) { |
| | | // // 1. 校验订单是否存在 |
| | | // XpTestOrder order = this.getById(id); |
| | | // if (Objects.isNull(order)) { |
| | | // throw new ServiceException("订单不存在", I18nKeyConstant.ORDER_NOT_EXISTS); |
| | | // } |
| | | // |
| | | // this.removeById(id); |
| | | // } |
| | | // |
| | | // @Override |
| | | // public List<XpOrderPageVO> exportList(XpOrderExcelQuery query) { |
| | | // // 1. 构建查询条件 |
| | | // LambdaQueryWrapper<XpTestOrder> wrapper = buildExcelQueryWrapper(query); |
| | | // |
| | | // // 1.1 车牌号筛选:先查车辆服务获取车辆ID列表 |
| | | // if (StringUtils.isNotBlank(query.getPlateNumber())) { |
| | | // R<List<XpVehicle>> vehicleResult = xpVehicleClient.listByPlateNumber(query.getPlateNumber()); |
| | | // if (vehicleResult == null || CollectionUtils.isEmpty(vehicleResult.getData())) { |
| | | // return new ArrayList<>(); |
| | | // } |
| | | // List<Long> vehicleIdsFilter = vehicleResult.getData().stream() |
| | | // .map(XpVehicle::getId) |
| | | // .filter(Objects::nonNull) |
| | | // .distinct() |
| | | // .collect(Collectors.toList()); |
| | | // if (CollectionUtils.isEmpty(vehicleIdsFilter)) { |
| | | // return new ArrayList<>(); |
| | | // } |
| | | // wrapper.in(XpTestOrder::getVehicleId, vehicleIdsFilter); |
| | | // } |
| | | // if (StringUtils.isNotBlank(query.getNickName())) { |
| | | // //根据手机号查询用户信息 |
| | | // UcUserInfo userByMobile = userResourcesClient.getUserByMobile(query.getNickName()); |
| | | // if (userByMobile == null || userByMobile.getId() == null) { |
| | | // return new ArrayList<>(); |
| | | // } |
| | | // query.setUid(userByMobile.getUid()); |
| | | // } |
| | | // wrapper.eq(Objects.nonNull(query.getUid()), XpTestOrder::getAppUserId, query.getUid()); |
| | | // wrapper.orderByDesc(XpTestOrder::getCreateTime); |
| | | // // 2. 查询订单列表 |
| | | // List<XpTestOrder> orderList = this.list(wrapper); |
| | | // |
| | | // if (CollectionUtils.isEmpty(orderList)) { |
| | | // return new ArrayList<>(); |
| | | // } |
| | | // |
| | | // // 3. 收集关联ID |
| | | // Set<Long> userIds = new HashSet<>(); |
| | | // Set<Long> vehicleIds = new HashSet<>(); |
| | | // Set<Long> fleetIds = new HashSet<>(); |
| | | // for (XpTestOrder order : orderList) { |
| | | // if (Objects.nonNull(order.getAppUserId())) { |
| | | // userIds.add(order.getAppUserId()); |
| | | // } |
| | | // if (Objects.nonNull(order.getVehicleId())) { |
| | | // vehicleIds.add(order.getVehicleId()); |
| | | // } |
| | | // if (Objects.nonNull(order.getFleetId())) { |
| | | // fleetIds.add(order.getFleetId()); |
| | | // } |
| | | // } |
| | | // |
| | | // // 4. 批量查询关联数据 |
| | | // Map<String, UcUserInfo> userInfoMap = batchGetUsers(userIds); |
| | | // Map<Long, XpVehicle> vehicleMap = batchGetVehicles(vehicleIds); |
| | | // Map<Long, XpFleet> fleetMap = batchGetFleets(fleetIds); |
| | | // |
| | | // // 5. 组装 VO |
| | | // return orderList.stream() |
| | | // .map(order -> convertToPageVO(order, userInfoMap, vehicleMap, fleetMap)) |
| | | // .collect(Collectors.toList()); |
| | | // } |
| | | // |
| | | // /** |
| | | // * 构建查询条件 |
| | | // */ |
| | | // private LambdaQueryWrapper<XpTestOrder> buildQueryWrapper(XpTestOrderPageQuery query) { |
| | | // LambdaQueryWrapper<XpTestOrder> wrapper = new LambdaQueryWrapper<>(); |
| | | // |
| | | // wrapper.like(StringUtils.isNotBlank(query.getOrderNumber()), XpTestOrder::getOrderNumber, query.getOrderNumber()) |
| | | // .eq(Objects.nonNull(query.getStatus()), XpTestOrder::getStatus, query.getStatus()) |
| | | // if (Objects.nonNull(query.getStartTime())) { |
| | | // wrapper.ge(XpTestOrder::getCreateTime, LocalDateTime.of(query.getStartTime(), LocalTime.MIN)); |
| | | // } |
| | | // if (Objects.nonNull(query.getEndTime())) { |
| | | // wrapper.le(XpTestOrder::getCreateTime, LocalDateTime.of(query.getEndTime(), LocalTime.MAX)); |
| | | // } |
| | | // wrapper.orderByDesc(XpTestOrder::getCreateTime); |
| | | // return wrapper; |
| | | // } |
| | | // |
| | | // private LambdaQueryWrapper<XpTestOrder> buildExcelQueryWrapper(XpOrderExcelQuery query) { |
| | | // LambdaQueryWrapper<XpTestOrder> wrapper = new LambdaQueryWrapper<>(); |
| | | // |
| | | // wrapper.like(StringUtils.isNotBlank(query.getOrderNumber()), XpTestOrder::getOrderNumber, query.getOrderNumber()) |
| | | // .eq(Objects.nonNull(query.getFleetId()), XpTestOrder::getFleetId, query.getFleetId()) |
| | | // .eq(Objects.nonNull(query.getOrderSource()), XpTestOrder::getOrderSource, query.getOrderSource()) |
| | | // .eq(Objects.nonNull(query.getStatus()), XpTestOrder::getStatus, query.getStatus()) |
| | | // .eq(Objects.nonNull(query.getUid()), XpTestOrder::getAppUserId, query.getUid()); |
| | | // |
| | | // RegionCodeFilterUtil.resolveCityCodeFilter(query.getCityCode()) |
| | | // .ifPresent(filter -> { |
| | | // if (RegionCodeFilterUtil.MatchType.LIKE_RIGHT.equals(filter.getMatchType())) { |
| | | // wrapper.likeRight(XpTestOrder::getCityCode, filter.getValue()); |
| | | // } else { |
| | | // wrapper.eq(XpTestOrder::getCityCode, filter.getValue()); |
| | | // } |
| | | // }); |
| | | // |
| | | // if (Objects.nonNull(query.getStartTime())) { |
| | | // wrapper.ge(XpTestOrder::getCreateTime, LocalDateTime.of(query.getStartTime(), LocalTime.MIN)); |
| | | // } |
| | | // if (Objects.nonNull(query.getEndTime())) { |
| | | // wrapper.le(XpTestOrder::getCreateTime, LocalDateTime.of(query.getEndTime(), LocalTime.MAX)); |
| | | // } |
| | | // if (CollUtil.isNotEmpty(query.getIds())) { |
| | | // wrapper.in(XpTestOrder::getId, query.getIds()); |
| | | // } |
| | | // wrapper.orderByDesc(XpTestOrder::getCreateTime); |
| | | // return wrapper; |
| | | // } |
| | | // |
| | | // /** |
| | | // * 批量获取用户信息 |
| | | // */ |
| | | // private Map<String, UcUserInfo> batchGetUsers(Set<Long> userIds) { |
| | | // if (CollectionUtils.isEmpty(userIds)) { |
| | | // return new HashMap<>(); |
| | | // } |
| | | // return userResourcesClient.getUserListByUids(new ArrayList<>(userIds), false); |
| | | // } |
| | | // |
| | | // /** |
| | | // * 批量获取车辆信息 |
| | | // */ |
| | | // private Map<Long, XpVehicle> batchGetVehicles(Set<Long> vehicleIds) { |
| | | // if (CollectionUtils.isEmpty(vehicleIds)) { |
| | | // return new HashMap<>(); |
| | | // } |
| | | // try { |
| | | // R<List<XpVehicle>> result = xpVehicleClient.listByIds(new ArrayList<>(vehicleIds)); |
| | | // if (Objects.nonNull(result) && Objects.nonNull(result.getData())) { |
| | | // return result.getData().stream() |
| | | // .collect(Collectors.toMap(XpVehicle::getId, Function.identity(), (a, b) -> a)); |
| | | // } |
| | | // } catch (Exception e) { |
| | | // log.error("批量获取车辆信息失败: {}", e.getMessage()); |
| | | // } |
| | | // return new HashMap<>(); |
| | | // } |
| | | // |
| | | // /** |
| | | // * 批量获取车队信息 |
| | | // */ |
| | | // private Map<Long, XpFleet> batchGetFleets(Set<Long> fleetIds) { |
| | | // if (CollectionUtils.isEmpty(fleetIds)) { |
| | | // return new HashMap<>(); |
| | | // } |
| | | // try { |
| | | // R<List<XpFleet>> result = xpFleetClient.listByIds(new ArrayList<>(fleetIds)); |
| | | // if (Objects.nonNull(result) && Objects.nonNull(result.getData())) { |
| | | // return result.getData().stream() |
| | | // .collect(Collectors.toMap(XpFleet::getId, Function.identity(), (a, b) -> a)); |
| | | // } |
| | | // } catch (Exception e) { |
| | | // log.error("批量获取车队信息失败: {}", e.getMessage()); |
| | | // } |
| | | // return new HashMap<>(); |
| | | // } |
| | | // |
| | | // |
| | | // @Override |
| | | // @Transactional |
| | | // @ShardingSphereTransactionType(TransactionType.BASE) |
| | | // public void cancelOrCloseOrder(Long orderId, Integer type) { |
| | | // // 1. 校验订单是否存在 |
| | | // XpTestOrder order = this.getById(orderId); |
| | | // if (Objects.isNull(order)) { |
| | | // throw new ServiceException("订单不存在"); |
| | | // } |
| | | // |
| | | // // 2. 校验操作类型 |
| | | // if (type != 1 && type != 2) { |
| | | // throw new ServiceException("操作类型错误,type只能为1或2"); |
| | | // } |
| | | // |
| | | // // 3. 校验订单状态是否允许操作 |
| | | // Integer currentStatus = order.getStatus(); |
| | | // //取消订单:在未接到乘客前都可以,关闭订单,在送达目的地可以操作关闭 |
| | | // if (type == 1) { |
| | | // // 取消订单:只有待接单(1)、待出发(2)、接驾中(3)状态可以取消 |
| | | // if (currentStatus != 1 && currentStatus != 2 && currentStatus != 3 && currentStatus != 4) { |
| | | // throw new ServiceException("当前订单状态不允许取消,只有待接单、待出发、接驾中状态的订单可以取消", I18nKeyConstant.ORDER_CANCEL_FAILED); |
| | | // } |
| | | // } else { |
| | | // // 关闭订单:0=已取消,1=待接单,2=待出发,3=接驾中,4=待客上车,5=乘客已上车,6=服务中 状态可以关闭 |
| | | // if (currentStatus == 7 || currentStatus == 8 || currentStatus == 9 || currentStatus == 10) { |
| | | // throw new ServiceException("当前订单状态不允许关闭", I18nKeyConstant.ORDER_CLOSE_FAILED); |
| | | // } |
| | | // } |
| | | // |
| | | // // 4. 执行操作 |
| | | // if (type == 1) { |
| | | // // 取消订单 |
| | | // cancelOrder(order); |
| | | // } else { |
| | | // // 关闭订单 |
| | | // closeOrder(order); |
| | | // } |
| | | // } |
| | | // |
| | | // /** |
| | | // * 转换为分页列表 VO |
| | | // */ |
| | | // private XpTestOrderPageVO convertToPageVO(XpTestOrder order, |
| | | // Map<Long, XpVehicle> vehicleMap, |
| | | // Map<Long, XpFleet> fleetMap) { |
| | | // XpTestOrderPageVO vo = new XpTestOrderPageVO(); |
| | | // vo.setId(order.getId()); |
| | | // vo.setOrderNumber(order.getOrderNumber()); |
| | | // vo.setCreateTime(order.getCreateTime()); |
| | | // vo.setOrderSource(order.getOrderSource()); |
| | | // vo.setStartAddress(order.getStartAddress()); |
| | | // vo.setEndAddress(order.getEndAddress()); |
| | | // vo.setStatus(order.getStatus()); |
| | | // |
| | | // // 车辆信息 |
| | | // if (Objects.nonNull(order.getVehicleId()) && vehicleMap.containsKey(order.getVehicleId())) { |
| | | // XpVehicle vehicle = vehicleMap.get(order.getVehicleId()); |
| | | // vo.setPlateNumber(vehicle.getPlateNumber()); |
| | | // } |
| | | // |
| | | // // 车队信息 |
| | | // if (Objects.nonNull(order.getFleetId()) && fleetMap.containsKey(order.getFleetId())) { |
| | | // XpFleet fleet = fleetMap.get(order.getFleetId()); |
| | | // vo.setFleetName(fleet.getFleetName()); |
| | | // } |
| | | // |
| | | // return vo; |
| | | // } |
| | | // |
| | | // /** |
| | | // * 取消订单 |
| | | // */ |
| | | // private void cancelOrder(XpTestOrder order) { |
| | | // redisService.removeByPattern(order.getQueueName(), order.getOrderNumber()); |
| | | // //判断还原车辆状态 |
| | | // if (null == order.getVehicleId()) { |
| | | // Object cacheObject1 = redisService.getCacheObject("CREATE_ORDER:" + order.getId().toString()); |
| | | // if (null != cacheObject1) { |
| | | // JSONObject jsonObject = JSON.parseObject(cacheObject1.toString()); |
| | | // String vin = jsonObject.getString("vin"); |
| | | // XpVehicle vehicle = xpVehicleClient.findByVehicleVin(vin).getData(); |
| | | // if (null != vehicle && 0 != vehicle.getState()) { |
| | | // XpVehicle vehicle1 = new XpVehicle(); |
| | | // vehicle1.setId(vehicle.getId()); |
| | | // vehicle1.setState(0); |
| | | // xpVehicleClient.updateVehicleById(vehicle1); |
| | | // } |
| | | // } |
| | | // } |
| | | // |
| | | // Long userId = order.getAppUserId(); |
| | | // if (order.getStatus() == 1) { |
| | | // order.setStatus(0); |
| | | // order.setAppUserId(null); |
| | | // baseMapper.updateById(order); |
| | | // redisService.setCacheObject("ORDER_STATUS:" + order.getId(), 0, 24L, TimeUnit.HOURS); |
| | | // return; |
| | | // } |
| | | // // 1. 更新订单状态为已取消(0) |
| | | // lambdaUpdate().set(XpTestOrder::getStatus, 0) |
| | | // .eq(XpTestOrder::getId, order.getId()).update(); |
| | | // |
| | | // // 2. 保存取消记录 |
| | | // XpTestOrderCancel orderCancel = new XpTestOrderCancel(); |
| | | // orderCancel.setOrderId(order.getId()); |
| | | // orderCancel.setCancelSource(3); // 3=运营人员(后台管理接口固定为运营人员) |
| | | // orderCancel.setUserId(SecurityUtils.getUserId()); // 当前登录用户ID |
| | | // orderCancel.setCancelReason("运营人员取消订单"); |
| | | // xpTestOrderCancelService.save(orderCancel); |
| | | // // 消息推送 |
| | | // Map<String, Object> params = new HashMap<>(); |
| | | // Map<String, Object> content = new HashMap<>(); |
| | | // content.put("orderId", order.getId().toString()); |
| | | // content.put("status", OrderStatusEnum.CANCELED.getCode()); |
| | | // params.put("type", PushMessageTypeEnum.ORDER_STATUS.getDesc()); |
| | | // params.put("content", JSONObject.toJSONString(content)); |
| | | // params.put("timestamp", new Date().getTime() + ""); |
| | | // String message = JSONObject.toJSONString(params); |
| | | // SendMessageDTO sendMessageDTO = new SendMessageDTO(); |
| | | // sendMessageDTO.setMessage(message); |
| | | // sendMessageDTO.setAppUserId(String.valueOf(userId)); |
| | | // R<String> stringR = xpPushMessageClient.sendStatus(sendMessageDTO); |
| | | // //推送失败,重试3次 |
| | | // if(stringR.getCode() != Constants.SUCCESS){ |
| | | // ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>()); |
| | | // executor.execute(() -> { |
| | | // for (int i = 0; i < 3; i++) { |
| | | // R<String> stringR1 = xpPushMessageClient.sendStatus(sendMessageDTO); |
| | | // if(stringR1.getCode() == Constants.SUCCESS){ |
| | | // break; |
| | | // } |
| | | // try { |
| | | // Thread.sleep(1000); |
| | | // } catch (InterruptedException e) { |
| | | // throw new RuntimeException(e); |
| | | // } |
| | | // log.info("运维人员取消订单推送订单状态消息失败:{} {} {}", stringR1.getMsg(), JSON.toJSONString(sendMessageDTO), order.getOrderNumber()); |
| | | // } |
| | | // }); |
| | | // } |
| | | // log.info("运营人员取消订单成功,推送乘客消息完成"); |
| | | // |
| | | // //查询车辆信息 |
| | | // R<XpVehicle> xpVehicleR = xpVehicleClient.queryById(order.getVehicleId()); |
| | | // if (xpVehicleR.getCode() == HttpStatus.SUCCESS && Objects.nonNull(xpVehicleR.getData())) { |
| | | // XpVehicle xpVehicle = xpVehicleR.getData(); |
| | | // // 组装调用车机参数 |
| | | // CancelTaxiPassengerVo cancelTaxiPassengerVo = new CancelTaxiPassengerVo(); |
| | | // cancelTaxiPassengerVo.setVin(xpVehicle.getVehicleVin()); |
| | | // cancelTaxiPassengerVo.setUid(userId.toString()); |
| | | // cancelTaxiPassengerVo.setOrderNo(order.getOrderNumber()); |
| | | // cancelTaxiPassengerVo.setAppId(appid); |
| | | // BaseVehicleUserDto baseVehicleUserDto = userVehicleClient.cancelTaxiPassenger(cancelTaxiPassengerVo); |
| | | // if (baseVehicleUserDto == null) { |
| | | // // TODO 本地无法调通 |
| | | //// throw new RuntimeException("取消订单失败"); |
| | | // } |
| | | // |
| | | // //还原车辆状态 |
| | | // if(1 == xpVehicle.getState()){ |
| | | // XpVehicle vehicle1 = new XpVehicle(); |
| | | // vehicle1.setId(xpVehicle.getId()); |
| | | // vehicle1.setState(0); |
| | | // xpVehicleClient.updateVehicleById(vehicle1); |
| | | // } |
| | | // |
| | | // // 下发命令 |
| | | // PushOrderDto pushOrderDto = new PushOrderDto(); |
| | | // pushOrderDto.setOrderId(order.getId().toString()); |
| | | // pushOrderDto.setVin(xpVehicle.getVehicleVin()); |
| | | // pushOrderDto.setOperation_type(OrderOperationType.CLOUD_CANCEL_ORDER); |
| | | // orderMissionClient.cancelOrder(pushOrderDto); |
| | | // log.info("运营人员取消订单成功,开始执行巡游订单 {}", order.getId()); |
| | | // //车辆继续巡游 |
| | | // addCruiseMission(xpVehicle.getId()); |
| | | // |
| | | // } else { |
| | | // log.info("查询车辆信息失败,订单ID: {}, 下发取消订单命令失败", order.getId()); |
| | | // } |
| | | // log.info("订单取消成功,订单ID: {}, 操作人: {}", order.getId(), SecurityUtils.getUsername()); |
| | | // } |
| | | // |
| | | // /** |
| | | // * 关闭订单 |
| | | // */ |
| | | // private void closeOrder(XpTestOrder order) { |
| | | // XpVehicle xpVehicle = xpVehicleClient.queryById(order.getVehicleId()).getData(); |
| | | // order.setStatus(7); |
| | | // order.setGetoffTime(LocalDateTime.now()); |
| | | // // 解析下车地点 |
| | | // VehiclePosition vehiclePosition = mongoTemplate.findOne(new Query(Criteria.where("vin").is(xpVehicle.getVehicleVin())), VehiclePosition.class); |
| | | // if(Objects.nonNull(vehiclePosition)){ |
| | | // GeoJsonPoint point = vehiclePosition.getPoint(); |
| | | // if(Objects.nonNull(point)){ |
| | | // double x = point.getX(); |
| | | // double y = point.getY(); |
| | | // Map<String, String> geocode = gdMapGeocodingUtil.geocode(String.valueOf(x), String.valueOf(y)); |
| | | // order.setGetoffAddress(geocode.get("address")); |
| | | // } |
| | | // } |
| | | // //计算行驶总距离和时长 |
| | | // List<OrderTrajectory> orderTrajectoryList = mongoTemplate.find(new Query().addCriteria(Criteria.where("orderId").is(order.getId())), OrderTrajectory.class); |
| | | // Double reduce = orderTrajectoryList.stream().map(OrderTrajectory::getDistance).reduce(0.0, Double::sum); |
| | | // order.setMileageKilometers(new BigDecimal(reduce).divide(new BigDecimal(1000)).setScale(4, RoundingMode.HALF_EVEN).doubleValue()); |
| | | // long duration = LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8")) - order.getTripBegin().toEpochSecond(ZoneOffset.of("+8")); |
| | | // order.setDuration(new BigDecimal(duration).divide(new BigDecimal(60), 2, RoundingMode.HALF_EVEN).doubleValue()); |
| | | // Long appUserId = order.getAppUserId(); |
| | | // order.setAppUserId(null); |
| | | // this.updateById(order); |
| | | // |
| | | // // 消息推送 |
| | | // Map<String, Object> params1 = new HashMap<>(); |
| | | // Map<String, Object> content1 = new HashMap<>(); |
| | | // content1.put("orderId", order.getId().toString()); |
| | | // content1.put("status", OrderStatusEnum.SEE_OFF_GUESTS.getCode()); |
| | | // params1.put("type", PushMessageTypeEnum.ORDER_STATUS.getDesc()); |
| | | // params1.put("content", JSON.toJSONString(content1)); |
| | | // params1.put("timestamp", new Date().getTime() + ""); |
| | | // String message1 = JSON.toJSONString(params1); |
| | | // SendMessageDTO sendMessageDTO1 = new SendMessageDTO(); |
| | | // sendMessageDTO1.setMessage(message1); |
| | | // sendMessageDTO1.setAppUserId(appUserId.toString()); |
| | | // R<String> stringR1 = xpPushMessageClient.sendStatus(sendMessageDTO1); |
| | | // //推送失败,重试3次 |
| | | // if(stringR1.getCode() != Constants.SUCCESS){ |
| | | // ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>()); |
| | | // executor.execute(() -> { |
| | | // for (int i = 0; i < 3; i++) { |
| | | // R<String> stringR2 = xpPushMessageClient.sendStatus(sendMessageDTO1); |
| | | // if(stringR2.getCode() == Constants.SUCCESS){ |
| | | // break; |
| | | // } |
| | | // try { |
| | | // Thread.sleep(1000); |
| | | // } catch (InterruptedException e) { |
| | | // throw new RuntimeException(e); |
| | | // } |
| | | // log.info("运维人员关闭订单推送订单状态消息失败:{} {} {}", stringR2.getMsg(), JSON.toJSONString(sendMessageDTO1), order.getOrderNumber()); |
| | | // } |
| | | // }); |
| | | // } |
| | | // |
| | | // // 推送倒计时消息 |
| | | // Map<String, Object> params = new HashMap<>(); |
| | | // Map<String, Object> content = new HashMap<>(); |
| | | // content.put("orderId", order.getId().toString()); |
| | | // content.put("isOpen", 1); |
| | | // params.put("type", PushMessageTypeEnum.OPEN_TRUNK.getDesc()); |
| | | // params.put("content", JSON.toJSONString(content)); |
| | | // params.put("timestamp", new Date().getTime() + ""); |
| | | // String message = JSON.toJSONString(params); |
| | | // SendMessageDTO sendMessageDTO = new SendMessageDTO(); |
| | | // sendMessageDTO.setMessage(message); |
| | | // sendMessageDTO.setAppUserId(appUserId.toString()); |
| | | // R<String> stringR = xpPushMessageClient.sendStatus(sendMessageDTO); |
| | | // //推送失败,重试3次 |
| | | // if(stringR.getCode() != Constants.SUCCESS){ |
| | | // ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>()); |
| | | // executor.execute(() -> { |
| | | // for (int i = 0; i < 3; i++) { |
| | | // R<String> stringR2 = xpPushMessageClient.sendStatus(sendMessageDTO); |
| | | // if(stringR2.getCode() == Constants.SUCCESS){ |
| | | // break; |
| | | // } |
| | | // try { |
| | | // Thread.sleep(1000); |
| | | // } catch (InterruptedException e) { |
| | | // throw new RuntimeException(e); |
| | | // } |
| | | // log.info("推送倒计时消息失败:{} {} {}", stringR2.getMsg(), JSON.toJSONString(sendMessageDTO), order.getOrderNumber()); |
| | | // } |
| | | // }); |
| | | // } |
| | | // |
| | | // //给XPU推送订单取消的报文 |
| | | // PushOrderDto pushOrderDto = new PushOrderDto(); |
| | | // pushOrderDto.setOrderId(order.getId().toString()); |
| | | // pushOrderDto.setVin(xpVehicle.getVehicleVin()); |
| | | // pushOrderDto.setOperation_type(OrderOperationType.CLOUD_CANCEL_ORDER); |
| | | // orderMissionClient.cancelOrder(pushOrderDto); |
| | | // |
| | | // //结束行程,修改状态和计算费用 |
| | | // endTrip(order.getId(), appUserId.toString()); |
| | | // |
| | | // // 消息推送 |
| | | // Map<String, Object> params2 = new HashMap<>(); |
| | | // Map<String, Object> content2 = new HashMap<>(); |
| | | // content2.put("orderId", order.getId().toString()); |
| | | // content2.put("status", OrderStatusEnum.APPROVAL_REJECTION.getCode()); |
| | | // params2.put("type", PushMessageTypeEnum.ORDER_STATUS.getDesc()); |
| | | // params2.put("content", JSON.toJSONString(content2)); |
| | | // params2.put("timestamp", new Date().getTime() + ""); |
| | | // String message2 = JSON.toJSONString(params2); |
| | | // SendMessageDTO sendMessageDTO2 = new SendMessageDTO(); |
| | | // sendMessageDTO2.setMessage(message2); |
| | | // sendMessageDTO2.setAppUserId(appUserId.toString()); |
| | | // R<String> stringR2 = xpPushMessageClient.sendStatus(sendMessageDTO2); |
| | | // //推送失败,重试3次 |
| | | // if(stringR2.getCode() != Constants.SUCCESS){ |
| | | // ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>()); |
| | | // executor.execute(() -> { |
| | | // for (int i = 0; i < 3; i++) { |
| | | // R<String> stringR3 = xpPushMessageClient.sendStatus(sendMessageDTO2); |
| | | // if(stringR3.getCode() == Constants.SUCCESS){ |
| | | // break; |
| | | // } |
| | | // try { |
| | | // Thread.sleep(1000); |
| | | // } catch (InterruptedException e) { |
| | | // throw new RuntimeException(e); |
| | | // } |
| | | // log.info("运维人员关闭订单推送订单状态消息失败:{} {} {}", stringR3.getMsg(), JSON.toJSONString(sendMessageDTO1), order.getOrderNumber()); |
| | | // } |
| | | // }); |
| | | // } |
| | | // |
| | | // //创建定时任务执行延迟驶离终点和下发巡游单 |
| | | // XpTestPoint point = xpPointClient.queryById(order.getEndTestPointId()).getData(); |
| | | // Map<String, ? extends Object> jobMaps = |
| | | // new ImmutableMap.Builder<String, String>() |
| | | // .put("id", order.getId().toString()) |
| | | // .put("appid", appid) |
| | | // .build(); |
| | | // QuartzManager.addJob( |
| | | // AddCruiseMissionJob.class, |
| | | // (AddCruiseMissionJob.name + order.getId()).toUpperCase(), |
| | | // TimeJobType.ADD_CRUISE_MISSION, |
| | | // DateUtils.localDateTimeToDate(LocalDateTime.now().plusMinutes(point.getParkingTimeLimit())), |
| | | // jobMaps |
| | | // ); |
| | | // } |
| | | // |
| | | // /** |
| | | // * 改派订单 |
| | | // */ |
| | | // @Override |
| | | // @Transactional |
| | | // @ShardingSphereTransactionType(TransactionType.BASE) |
| | | // public void reassignOrder(Long orderId, Long newVehicleId, String reassignReason) { |
| | | // // 1. 校验订单是否存在 |
| | | // XpTestOrder order = this.getById(orderId); |
| | | // if (Objects.isNull(order)) { |
| | | // throw new ServiceException("订单不存在"); |
| | | // } |
| | | // |
| | | // // 2. 校验订单状态(只有待出发、接驾中、待乘客上车状态可以改派) |
| | | // Integer currentStatus = order.getStatus(); |
| | | // if (currentStatus != 2 && currentStatus != 3 && currentStatus != 4) { |
| | | // throw new ServiceException("当前订单状态不允许改派,只有待出发、接驾中、待乘客上车状态的订单可以改派", I18nKeyConstant.ORDER_REASSIGN_FAILED); |
| | | // } |
| | | // |
| | | // // 3. 校验新旧车辆是否相同 |
| | | // if (Objects.equals(order.getVehicleId(), newVehicleId)) { |
| | | // throw new ServiceException("新车辆与原车辆相同,无需改派", I18nKeyConstant.ORDER_REASSIGN_VEHICLE_FAILED); |
| | | // } |
| | | // |
| | | // // 4. 查询新车辆信息并校验 |
| | | // R<List<XpVehicle>> vehicleResult = xpVehicleClient.listByIds(Collections.singletonList(newVehicleId)); |
| | | // if (Objects.isNull(vehicleResult) || Objects.isNull(vehicleResult.getData()) || vehicleResult.getData().isEmpty()) { |
| | | // throw new ServiceException("新车辆不存在", I18nKeyConstant.ORDER_REASSIGN_NEW_VEHICLE_NOT_EXISTS); |
| | | // } |
| | | // XpVehicle newVehicle = vehicleResult.getData().get(0); |
| | | // |
| | | // // 5. 校验新车辆的运营状态 |
| | | // // 车辆状态:1=待完善 2=待运营 3=保险/年检过期 |
| | | // // 运营状态:1=运营中 2=维修中 3=已收车 4=车辆异常 |
| | | // // 当前模式:1=接单 2=测试 |
| | | // // 模式状态:1=开始接单/开始测试 2=停止接单/停止测试 |
| | | // if (Objects.isNull(newVehicle.getStatus()) || newVehicle.getStatus() == 3) { |
| | | // throw new ServiceException("新车辆保险或年检已过期,无法接单", I18nKeyConstant.ORDER_REASSIGN_NEW_VEHICLE_STATUS_INVALID); |
| | | // } |
| | | // if (Objects.isNull(newVehicle.getOperatingStatus()) || newVehicle.getOperatingStatus() != 1) { |
| | | // throw new ServiceException("新车辆运营状态异常,无法接单", I18nKeyConstant.ORDER_REASSIGN_NEW_VEHICLE_OPERATING_STATUS_INVALID); |
| | | // } |
| | | // if (Objects.isNull(newVehicle.getAcceptOrTest()) || newVehicle.getAcceptOrTest() != 1) { |
| | | // throw new ServiceException("新车辆当前不在接单模式", I18nKeyConstant.ORDER_REASSIGN_NEW_VEHICLE_NOT_IN_ACCEPT_MODE); |
| | | // } |
| | | // if (Objects.isNull(newVehicle.getAcceptOrTestStatus()) || newVehicle.getAcceptOrTestStatus() != 1) { |
| | | // throw new ServiceException("新车辆未开始接单", I18nKeyConstant.ORDER_REASSIGN_NEW_VEHICLE_NOT_START_ACCEPT); |
| | | // } |
| | | // if (Objects.isNull(newVehicle.getState()) || newVehicle.getState() != 0) { |
| | | // throw new ServiceException("新车辆已接单,请重新选择", I18nKeyConstant.ORDER_REASSIGN_NEW_VEHICLE_NOT_FREE); |
| | | // } |
| | | // |
| | | // // 6. 保存原车辆和车队信息 |
| | | // Long oldVehicleId = order.getVehicleId(); |
| | | // Long oldFleetId = order.getFleetId(); |
| | | // |
| | | // // 6.1 处理原车辆:取消订单指令、解绑乘客、更新状态、创建返程巡游订单 |
| | | // if (Objects.nonNull(oldVehicleId)) { |
| | | // try { |
| | | // R<XpVehicle> oldVehicleResult = xpVehicleClient.queryById(oldVehicleId); |
| | | // if (oldVehicleResult != null && oldVehicleResult.getCode() == HttpStatus.SUCCESS && oldVehicleResult.getData() != null) { |
| | | // XpVehicle oldVehicle = oldVehicleResult.getData(); |
| | | // |
| | | // // 6.1.1 取消原订单指令 |
| | | // PushOrderDto cancelDto = new PushOrderDto(); |
| | | // cancelDto.setOrderId(order.getId().toString()); |
| | | // cancelDto.setVin(oldVehicle.getVehicleVin()); |
| | | // cancelDto.setOperation_type(OrderOperationType.CLOUD_CANCEL_ORDER); |
| | | // orderMissionClient.cancelOrder(cancelDto); |
| | | // log.info("已取消原车辆订单指令,订单ID: {}, VIN: {}", orderId, oldVehicle.getVehicleVin()); |
| | | // |
| | | // // 6.1.2 解绑乘客与原车辆关系 |
| | | // if (Objects.nonNull(order.getAppUserId())) { |
| | | // CancelTaxiPassengerVo cancelVo = new CancelTaxiPassengerVo(); |
| | | // cancelVo.setVin(oldVehicle.getVehicleVin()); |
| | | // cancelVo.setUid(order.getAppUserId().toString()); |
| | | // cancelVo.setOrderNo(order.getOrderNumber()); |
| | | // cancelVo.setAppId(appid); |
| | | // userVehicleClient.cancelTaxiPassenger(cancelVo); |
| | | // log.info("已解绑乘客与原车辆关系,用户ID: {}, VIN: {}", order.getAppUserId(), oldVehicle.getVehicleVin()); |
| | | // } |
| | | // |
| | | // // 6.1.3 修改原车辆状态为空闲 |
| | | // XpVehicle vehicle1 = new XpVehicle(); |
| | | // vehicle1.setId(oldVehicle.getId()); |
| | | // vehicle1.setState(0); |
| | | // xpVehicleClient.updateVehicleById(vehicle1); |
| | | // log.info("已将原车辆状态设为空闲,车辆ID: {}", oldVehicleId); |
| | | // |
| | | // // 6.1.4 为原车辆创建返程巡游订单 |
| | | // createReturnCruiseOrder(oldVehicle.getId(), order); |
| | | // } else { |
| | | // log.warn("查询原车辆信息失败,车辆ID: {}", oldVehicleId); |
| | | // } |
| | | // } catch (Exception e) { |
| | | // log.error("处理原车辆失败,车辆ID: {},错误: {}", oldVehicleId, e.getMessage()); |
| | | // } |
| | | // } |
| | | // |
| | | // // 7. 查询新车辆关联的车队ID |
| | | // Long newFleetId = null; |
| | | // try { |
| | | // R<Long> fleetIdResult = xpFleetVehicleClient.getFleetIdByVehicleId(newVehicleId); |
| | | // if (Objects.nonNull(fleetIdResult) && Objects.nonNull(fleetIdResult.getData())) { |
| | | // newFleetId = fleetIdResult.getData(); |
| | | // log.info("查询到新车辆ID: {} 关联的车队ID: {}", newVehicleId, newFleetId); |
| | | // } else { |
| | | // log.warn("新车辆ID: {} 未关联任何车队,将使用原车队ID: {}", newVehicleId, oldFleetId); |
| | | // newFleetId = oldFleetId; |
| | | // } |
| | | // } catch (Exception e) { |
| | | // log.error("查询新车辆关联的车队ID失败,车辆ID: {},错误: {}", newVehicleId, e.getMessage()); |
| | | // newFleetId = oldFleetId; |
| | | // } |
| | | // |
| | | // // 8. 如果旧订单的车队ID为空,尝试查询旧车辆的车队ID |
| | | // if (Objects.isNull(oldFleetId) && Objects.nonNull(oldVehicleId)) { |
| | | // try { |
| | | // R<Long> oldFleetIdResult = xpFleetVehicleClient.getFleetIdByVehicleId(oldVehicleId); |
| | | // if (Objects.nonNull(oldFleetIdResult) && Objects.nonNull(oldFleetIdResult.getData())) { |
| | | // oldFleetId = oldFleetIdResult.getData(); |
| | | // log.info("补充查询到旧车辆ID: {} 关联的车队ID: {}", oldVehicleId, oldFleetId); |
| | | // } |
| | | // } catch (Exception e) { |
| | | // log.warn("查询旧车辆关联的车队ID失败,车辆ID: {},错误: {}", oldVehicleId, e.getMessage()); |
| | | // } |
| | | // } |
| | | // |
| | | // // 9. 更新订单的车辆和车队信息 |
| | | // order.setVehicleId(newVehicleId); |
| | | // if (Objects.nonNull(newFleetId)) { |
| | | // order.setFleetId(newFleetId); |
| | | // } |
| | | // this.updateById(order); |
| | | // |
| | | // // 10. 保存改派记录 |
| | | // XpOrderReassign orderReassign = new XpOrderReassign(); |
| | | // orderReassign.setOrderId(orderId); |
| | | // orderReassign.setUserId(SecurityUtils.getUserId()); |
| | | // orderReassign.setOperationTime(LocalDateTime.now()); |
| | | // orderReassign.setOldVehicleId(oldVehicleId); |
| | | // orderReassign.setNewVehicleId(newVehicleId); |
| | | // orderReassign.setOldFleetId(oldFleetId); |
| | | // orderReassign.setNewFleetId(newFleetId); |
| | | // orderReassign.setReassignReason( |
| | | // StringUtils.isNotBlank(reassignReason) ? reassignReason : "运营人员改派订单" |
| | | // ); |
| | | // orderReassign.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName()); |
| | | // xpOrderReassignService.save(orderReassign); |
| | | // |
| | | // log.info("订单改派成功,订单ID: {}, 原车辆ID: {}, 新车辆ID: {}, 原车队ID: {}, 新车队ID: {}, 操作人: {}", |
| | | // orderId, oldVehicleId, newVehicleId, oldFleetId, newFleetId, SecurityUtils.getUsername()); |
| | | // |
| | | // // 11. 处理新车辆:绑定乘客、下发订单、更新状态 |
| | | // try { |
| | | // // 11.1 绑定乘客与新车辆关系 |
| | | // if (Objects.nonNull(order.getAppUserId())) { |
| | | // AddTaxiPassengerVo addVo = new AddTaxiPassengerVo(); |
| | | // addVo.setVin(newVehicle.getVehicleVin()); |
| | | // addVo.setUid(order.getAppUserId().toString()); |
| | | // addVo.setOrderNo(order.getOrderNumber()); |
| | | // addVo.setAppId(appid); // TODO 获取appId |
| | | // userVehicleClient.addTaxiPassenger(addVo); |
| | | // log.info("已绑定乘客与新车辆关系,用户ID: {}, VIN: {}", order.getAppUserId(), newVehicle.getVehicleVin()); |
| | | // } |
| | | // |
| | | // // 11.2 下发订单到新车辆 |
| | | // PushOrderDto pushOrderDto = new PushOrderDto(); |
| | | // pushOrderDto.setVin(newVehicle.getVehicleVin()); |
| | | // pushOrderDto.setOrderId(order.getId().toString()); |
| | | // pushOrderDto.setStartLatitude(order.getStartLat()); |
| | | // pushOrderDto.setStartLongitude(order.getStartLon()); |
| | | // pushOrderDto.setEndLatitude(order.getEndLat()); |
| | | // pushOrderDto.setEndLongitude(order.getEndLon()); |
| | | // pushOrderDto.setOrderType(OrderType.USER_ORDER); |
| | | // pushOrderDto.setStage(1); |
| | | // // 调用推送服务 orderId + carVin |
| | | // orderMissionClient.pushOrder(pushOrderDto); |
| | | // |
| | | // |
| | | // log.info("已下发订单到新车辆,订单ID: {}, VIN: {}", orderId, newVehicle.getVehicleVin()); |
| | | // |
| | | // // 11.3 更新新车辆状态为已接单 |
| | | // XpVehicle vehicle1 = new XpVehicle(); |
| | | // vehicle1.setId(newVehicle.getId()); |
| | | // vehicle1.setState(1); |
| | | // xpVehicleClient.updateVehicleById(vehicle1); |
| | | // log.info("已将新车辆状态设为已接单,车辆ID: {}", newVehicleId); |
| | | // |
| | | // } catch (Exception e) { |
| | | // log.error("处理新车辆失败,车辆ID: {},错误: {}", newVehicleId, e.getMessage()); |
| | | // } |
| | | // |
| | | // } |
| | | // |
| | | // /** |
| | | // * 为原车辆创建返程巡游订单 |
| | | // * <p> |
| | | // * 改派时,原车辆需要返回巡游路线: |
| | | // * - 若最新巡游订单状态为已终止(status=2),返回原出发点 |
| | | // * - 若最新巡游订单状态为已完成(status=3),返回原终点 |
| | | // * - 其他状态,默认返回原出发点 |
| | | // * </p> |
| | | // * |
| | | // * @param order 当前订单信息 |
| | | // */ |
| | | // private void createReturnCruiseOrder(Long vehicleId, XpTestOrder order) { |
| | | // XpVehicle oldVehicle = xpVehicleClient.queryById(vehicleId).getData(); |
| | | // try { |
| | | // // 查询该车辆最新的一条巡游订单 |
| | | // XpCruiseOrder lastCruise = xpCruiseOrderMapper.selectOne( |
| | | // new LambdaQueryWrapper<XpCruiseOrder>() |
| | | // .eq(XpCruiseOrder::getVehicleId, oldVehicle.getId()) |
| | | // .orderByDesc(BaseModel::getCreateTime) |
| | | // .last("limit 1") |
| | | // ); |
| | | // |
| | | // if (lastCruise == null) { |
| | | // log.warn("原车辆没有巡游订单记录,跳过创建返程订单,车辆ID: {}", oldVehicle.getId()); |
| | | // return; |
| | | // } |
| | | // |
| | | // XpCruiseOrder returnOrder = new XpCruiseOrder(); |
| | | // returnOrder.setVehicleId(oldVehicle.getId()); |
| | | // returnOrder.setVehicleVin(oldVehicle.getVehicleVin()); |
| | | // returnOrder.setFleetId(oldVehicle.getFleetId()); |
| | | // returnOrder.setOrderType(2); // 返程单 |
| | | // returnOrder.setStatus(1); // 进行中 |
| | | // returnOrder.setLastOrderId(lastCruise.getId()); |
| | | // returnOrder.setCreateTime(LocalDateTime.now()); |
| | | // returnOrder.setMissionId(lastCruise.getMissionId()); |
| | | // |
| | | // // 返程起点 = 当前订单的终点(车辆当前位置附近) |
| | | // returnOrder.setStartPointId(order.getEndPointId()); |
| | | // returnOrder.setStartPointName(order.getEndPointName()); |
| | | // returnOrder.setStartLon(order.getEndLon()); |
| | | // returnOrder.setStartLat(order.getEndLat()); |
| | | // |
| | | // // 根据最新巡游订单状态决定返程终点 |
| | | // if (lastCruise.getStatus() != null && lastCruise.getStatus() == 2) { |
| | | // // 已终止(status=2) -> 返回原出发点 |
| | | // returnOrder.setEndPointId(lastCruise.getStartPointId()); |
| | | // returnOrder.setEndPointName(lastCruise.getStartPointName()); |
| | | // returnOrder.setEndLon(lastCruise.getStartLon()); |
| | | // returnOrder.setEndLat(lastCruise.getStartLat()); |
| | | // returnOrder.setOrderReverse(lastCruise.getOrderReverse()); |
| | | // log.info("巡游订单状态为已终止,返回原出发点"); |
| | | // } else if (lastCruise.getStatus() != null && lastCruise.getStatus() == 3) { |
| | | // // 已完成(status=3) -> 返回原终点 |
| | | // returnOrder.setEndPointId(lastCruise.getEndPointId()); |
| | | // returnOrder.setEndPointName(lastCruise.getEndPointName()); |
| | | // returnOrder.setEndLon(lastCruise.getEndLon()); |
| | | // returnOrder.setEndLat(lastCruise.getEndLat()); |
| | | // returnOrder.setOrderReverse(lastCruise.getOrderReverse()); |
| | | // log.info("巡游订单状态为已完成,返回原终点"); |
| | | // } else { |
| | | // // 其他状态(进行中等),默认返回原出发点 |
| | | // returnOrder.setEndPointId(lastCruise.getStartPointId()); |
| | | // returnOrder.setEndPointName(lastCruise.getStartPointName()); |
| | | // returnOrder.setEndLon(lastCruise.getStartLon()); |
| | | // returnOrder.setEndLat(lastCruise.getStartLat()); |
| | | // returnOrder.setOrderReverse(lastCruise.getOrderReverse()); |
| | | // log.info("巡游订单状态为{},默认返回原出发点", lastCruise.getStatus()); |
| | | // } |
| | | // |
| | | // xpCruiseOrderMapper.insert(returnOrder); |
| | | // |
| | | // // 下发巡游订单到原车辆 |
| | | // PushOrderDto pushOrderDto = new PushOrderDto(); |
| | | // pushOrderDto.setVin(oldVehicle.getVehicleVin()); |
| | | // pushOrderDto.setOrderId("XU" + returnOrder.getId()); |
| | | // pushOrderDto.setStartLatitude(returnOrder.getStartLat()); |
| | | // pushOrderDto.setStartLongitude(returnOrder.getStartLon()); |
| | | // pushOrderDto.setEndLatitude(returnOrder.getEndLat()); |
| | | // pushOrderDto.setEndLongitude(returnOrder.getEndLon()); |
| | | // pushOrderDto.setOrderType(OrderType.CRUISE_ORDER); |
| | | // pushOrderDto.setStage(2); |
| | | // // 调用推送服务 orderId + carVin |
| | | // orderMissionClient.pushOrder(pushOrderDto); |
| | | // |
| | | // log.info("为原车辆创建返程巡游订单成功,订单ID: {}, 车辆ID: {}", returnOrder.getId(), oldVehicle.getId()); |
| | | // |
| | | // } catch (Exception e) { |
| | | // log.error("创建返程巡游订单失败,车辆ID: {},错误: {}", oldVehicle.getId(), e.getMessage()); |
| | | // } |
| | | // } |
| | | // |
| | | // @Override |
| | | // public XpPointInfoVo getUserQuickCapsule(String uid) { |
| | | // try { |
| | | // // 使用Redis的sorted set(排行榜)获取第一个元素 |
| | | // // 获取分数最高的元素(默认按分数从高到低排序) |
| | | // Set<Object> result = redisService.redisTemplate.opsForZSet().reverseRange("history_order_" + uid, 0, 0); |
| | | // if (result != null && !result.isEmpty()) { |
| | | // // 排行榜中存储的是JSON字符串 |
| | | // String jsonString = result.iterator().next().toString(); |
| | | // // 使用Hutool的JSON工具解析为XpPointInfoVo对象 |
| | | // return JSONUtil.toBean(jsonString, XpPointInfoVo.class); |
| | | // } |
| | | // } catch (Exception e) { |
| | | // log.error("获取用户快捷胶囊失败: {}", e.getMessage(), e); |
| | | // } |
| | | // return null; |
| | | // } |
| | | // |
| | | // @Override |
| | | // public List<XpHistoryStartPointsVo> getHistoryStartPoints(String uid, double lon, double lat,Long electronicAreaId) { |
| | | // // |
| | | // List<XpTestOrder> xpOrders = this.baseMapper.getHistoryStartPoints(Long.valueOf(uid),electronicAreaId); |
| | | //// selectList(new LambdaQueryWrapper<XpTestOrder>().eq(XpTestOrder::getAppUserId, Long.parseLong(uid)).orderByDesc(BaseModel::getCreateTime).last("LIMIT 10")); |
| | | // if (xpOrders.isEmpty()) { |
| | | // return Collections.emptyList(); |
| | | // } |
| | | // // 获取点位信息 |
| | | // List<Long> startPointsIds = xpOrders.stream().map(XpTestOrder::getStartPointId).collect(Collectors.toList()); |
| | | // |
| | | // R<List<XpHistoryStartPointsVo>> r = xpPointClient.getHistoryStartPoints(new HistoryStartPointsDto(startPointsIds, lon, lat)); |
| | | // |
| | | // |
| | | // List<XpHistoryStartPointsVo> data = r.getData(); |
| | | // |
| | | // for (XpHistoryStartPointsVo datum : data) { |
| | | // |
| | | // if (datum.getOperationStatus() == 2) { |
| | | // datum.setOperationStatus(1); |
| | | // } |
| | | // |
| | | // |
| | | // // 保留2位数小数 |
| | | // Double distance = datum.getDistance(); |
| | | // datum.setDistance(BigDecimal.valueOf(distance).setScale(2, RoundingMode.HALF_UP).doubleValue()); |
| | | // xpOrders.stream().filter(e -> e.getStartPointId().equals(datum.getId())).findFirst().ifPresent( |
| | | // order -> { |
| | | // datum.setNum(order.getNum()); |
| | | // } |
| | | // ); |
| | | // } |
| | | // data = data.stream().sorted(Comparator.comparingInt(XpHistoryStartPointsVo::getNum).reversed()).collect(Collectors.toList()); |
| | | // |
| | | // return data; |
| | | // |
| | | // } |
| | | // |
| | | // @Override |
| | | // public List<XpHistoryEndPointsVo> getHistoryEndPoints(String uid, double lon, double lat,Long electronicAreaId) { |
| | | // // |
| | | // List<XpTestOrder> xpOrders = this.baseMapper.getHistoryEndPoints(Long.valueOf(uid), electronicAreaId); |
| | | //// selectList(new LambdaQueryWrapper<XpTestOrder>().eq(XpTestOrder::getAppUserId, Long.parseLong(uid)).orderByDesc(BaseModel::getCreateTime).last("LIMIT 10")); |
| | | // if (xpOrders.isEmpty()) { |
| | | // return Collections.emptyList(); |
| | | // } |
| | | // // 获取点位信息 |
| | | // List<Long> endPointsIds = xpOrders.stream().map(XpTestOrder::getEndPointId).collect(Collectors.toList()); |
| | | // |
| | | // R<List<XpHistoryEndPointsVo>> r = xpPointClient.getHistoryEndPoints(new HistoryEndPointsDto(endPointsIds, lon, lat)); |
| | | // |
| | | // List<XpHistoryEndPointsVo> data = r.getData(); |
| | | // |
| | | // for (XpHistoryEndPointsVo datum : data) { |
| | | // // 保留2位数小数 |
| | | // Double distance = datum.getDistance(); |
| | | // datum.setDistance(BigDecimal.valueOf(distance).setScale(2, RoundingMode.HALF_UP).doubleValue()); |
| | | // xpOrders.stream().filter(e -> e.getEndPointId().equals(datum.getId())).findFirst().ifPresent( |
| | | // order -> { |
| | | // datum.setNum(order.getNum()); |
| | | // } |
| | | // ); |
| | | // } |
| | | // data = data.stream().sorted(Comparator.comparingInt(XpHistoryEndPointsVo::getNum).reversed()).collect(Collectors.toList()); |
| | | // |
| | | // return data; |
| | | // |
| | | // } |
| | | // |
| | | // /** |
| | | // * 获取历史订单列表 |
| | | // * |
| | | // * @param query |
| | | // * @param uid |
| | | // * @return |
| | | // */ |
| | | // @Override |
| | | // public XpOrderHistoryVO getHistoryOrderList(XpHistoryOrderListQuery query, String uid) { |
| | | // Page<XpOrderHistoryListVO> page = new Page<>(query.getPageNum(), query.getPageSize()); |
| | | // List<XpOrderHistoryListVO> list = this.baseMapper.getHistoryOrderList(page, query, Long.parseLong(uid)); |
| | | // XpOrderHistoryVO xpOrderHistoryVO = new XpOrderHistoryVO(); |
| | | // if (list.isEmpty()) { |
| | | // return xpOrderHistoryVO; |
| | | // } |
| | | // |
| | | // |
| | | // Set<Long> points = list.stream().map(XpOrderHistoryListVO::getStartPointId).collect(Collectors.toSet()); |
| | | // points.addAll(list.stream().map(XpOrderHistoryListVO::getEndPointId).collect(Collectors.toSet())); |
| | | // |
| | | // |
| | | // // 查询 点位信息 |
| | | // R<List<XpPoint>> pointInfoVos = xpPointClient.getPointsInfo(points); |
| | | // List<XpPoint> pointList = pointInfoVos.getData(); |
| | | // xpOrderHistoryVO.setTotal((int) page.getTotal()); |
| | | // |
| | | // // 根据time分组 |
| | | // Map<String, List<XpOrderHistoryListVO>> map = list.stream().collect(Collectors.groupingBy(XpOrderHistoryListVO::getTimeStr)); |
| | | // List<XpOrderHistoryDateVO> dateVOS = map.entrySet().stream().map(entry -> { |
| | | // XpOrderHistoryDateVO xpOrderHistoryDateVO = new XpOrderHistoryDateVO(); |
| | | // xpOrderHistoryDateVO.setDateLabel(entry.getKey()); |
| | | // List<XpOrderHistoryListVO> value = entry.getValue(); |
| | | // value = value.stream().sorted(Comparator.comparing(XpOrderHistoryListVO::getTime).reversed()).collect(Collectors.toList()); |
| | | // |
| | | // for (XpOrderHistoryListVO xpOrderHistoryListVO : value) { |
| | | // XpPoint xpPoint = pointList.stream().filter(e -> e.getId().equals(xpOrderHistoryListVO.getStartPointId())).findFirst().orElse(null); |
| | | // if (xpPoint != null) { |
| | | // xpOrderHistoryListVO.setStartPointName(xpPoint.getPointName()); |
| | | // xpOrderHistoryListVO.setStartLat(xpPoint.getPointLat()); |
| | | // xpOrderHistoryListVO.setStartLon(xpPoint.getPointLon()); |
| | | // xpOrderHistoryListVO.setXpElectronicFenceAreaId(xpPoint.getElectronicAreaId()); |
| | | // xpOrderHistoryListVO.setStartParkingTimeLimit(xpPoint.getParkingTimeLimit()); |
| | | // } |
| | | // |
| | | // xpPoint = pointList.stream().filter(e -> e.getId().equals(xpOrderHistoryListVO.getEndPointId())).findFirst().orElse(null); |
| | | // if (xpPoint != null) { |
| | | // xpOrderHistoryListVO.setEndPointName(xpPoint.getPointName()); |
| | | // xpOrderHistoryListVO.setEndLat(xpPoint.getPointLat()); |
| | | // xpOrderHistoryListVO.setEndLon(xpPoint.getPointLon()); |
| | | // xpOrderHistoryListVO.setXpElectronicFenceAreaId(xpPoint.getElectronicAreaId()); |
| | | // xpOrderHistoryListVO.setEndParkingTimeLimit(xpPoint.getParkingTimeLimit()); |
| | | // } |
| | | // } |
| | | // |
| | | // |
| | | // xpOrderHistoryDateVO.setOrders(value); |
| | | // return xpOrderHistoryDateVO; |
| | | // }).collect(Collectors.toList()); |
| | | // |
| | | // dateVOS = dateVOS.stream().sorted(Comparator.comparing(XpOrderHistoryDateVO::getDateLabel).reversed()).collect(Collectors.toList()); |
| | | // xpOrderHistoryVO.setList(dateVOS); |
| | | // |
| | | // return xpOrderHistoryVO; |
| | | // } |
| | | // |
| | | // |
| | | // /** |
| | | // * 取消订单 |
| | | // * |
| | | // * @param orderId |
| | | // * @param uid |
| | | // */ |
| | | // @Override |
| | | // @Transactional |
| | | // @ShardingSphereTransactionType(TransactionType.BASE) |
| | | // public void cancelOrder(Long orderId, String uid) { |
| | | // XpTestOrder order = this.getById(orderId); |
| | | // if (order.getStatus() == 0) { |
| | | // return; |
| | | // } |
| | | // if (order == null) { |
| | | // throw new ServiceException("订单不存在", I18nKeyConstant.ORDER_NOT_EXISTS); |
| | | // } |
| | | // if (!order.getAppUserId().toString().equals(uid)) { |
| | | // throw new ServiceException("订单不存在", I18nKeyConstant.ORDER_NOT_EXISTS); |
| | | // } |
| | | // if (order.getStatus() > 5 || order.getStatus() < 1) { |
| | | // throw new ServiceException("订单状态错误", I18nKeyConstant.ORDER_STATUS_ERROR); |
| | | // } |
| | | // |
| | | // try { |
| | | // redisService.removeByPattern(order.getQueueName(), order.getOrderNumber()); |
| | | // } catch (Exception e) { |
| | | // e.printStackTrace(); |
| | | // } |
| | | // //判断还原车辆状态 |
| | | // if (null == order.getVehicleId()) { |
| | | // Object cacheObject1 = redisService.getCacheObject("CREATE_ORDER:" + order.getId().toString()); |
| | | // if (null != cacheObject1) { |
| | | // JSONObject jsonObject = JSON.parseObject(cacheObject1.toString()); |
| | | // String vin = jsonObject.getString("vin"); |
| | | // XpVehicle vehicle = xpVehicleClient.findByVehicleVin(vin).getData(); |
| | | // if (null != vehicle && 0 != vehicle.getState()) { |
| | | // XpVehicle vehicle1 = new XpVehicle(); |
| | | // vehicle1.setId(vehicle.getId()); |
| | | // vehicle1.setState(0); |
| | | // xpVehicleClient.updateVehicleById(vehicle1); |
| | | // } |
| | | // } |
| | | // } |
| | | // |
| | | // if (order.getStatus() == 1) { |
| | | // order.setStatus(0); |
| | | // order.setAppUserId(null); |
| | | // baseMapper.updateById(order); |
| | | // redisService.setCacheObject("ORDER_STATUS:" + order.getId(), 0, 24L, TimeUnit.HOURS); |
| | | // return; |
| | | // } |
| | | // order.setStatus(0); |
| | | // order.setAppUserId(null); |
| | | // baseMapper.updateById(order); |
| | | // redisService.setCacheObject("ORDER_STATUS:" + order.getId(), 0, 24L, TimeUnit.HOURS); |
| | | // XpOrderCancel xpOrderCancel = new XpOrderCancel(); |
| | | // xpOrderCancel.setOrderId(orderId); |
| | | // xpOrderCancel.setUserId(Long.valueOf(uid)); |
| | | // xpOrderCancel.setCancelSource(1); |
| | | // xpOrderCancel.setCancelReason("用户取消订单"); |
| | | // xpOrderCancelService.save(xpOrderCancel); |
| | | // |
| | | // |
| | | // // 设置当天的取消次数缓存 |
| | | // Object cacheObject = redisService.getCacheObject("CANCEL_ORDER_" + uid); |
| | | // if (cacheObject == null) { |
| | | // redisService.setCacheCancelOrder("CANCEL_ORDER_" + uid, 1); |
| | | // } else { |
| | | // Integer i = Integer.valueOf(cacheObject.toString()); |
| | | // redisService.setCacheCancelOrder("CANCEL_ORDER_" + uid, i + 1); |
| | | // } |
| | | // |
| | | // // 移除mongo数据 |
| | | // xpPricingClient.deleteXpGeoQueryEntity(order.getId().toString()); |
| | | // |
| | | // // 下发命令 |
| | | // if (null != order.getVehicleId()) { |
| | | // R<XpVehicle> xpVehicleR = xpVehicleClient.queryById(order.getVehicleId()); |
| | | // // 组装调用车机参数 |
| | | // CancelTaxiPassengerVo cancelTaxiPassengerVo = new CancelTaxiPassengerVo(); |
| | | // XpVehicle xpVehicle = xpVehicleR.getData(); |
| | | // if (xpVehicle == null) { |
| | | // throw new ServiceException("车辆不存在", I18nKeyConstant.VEHICLE_NOT_EXISTS); |
| | | // } |
| | | // cancelTaxiPassengerVo.setVin(xpVehicle.getVehicleVin()); |
| | | // cancelTaxiPassengerVo.setUid(uid); |
| | | // cancelTaxiPassengerVo.setOrderNo(order.getOrderNumber()); |
| | | // cancelTaxiPassengerVo.setAppId(appid); |
| | | // |
| | | // BaseVehicleUserDto baseVehicleUserDto = userVehicleClient.cancelTaxiPassenger(cancelTaxiPassengerVo); |
| | | // if (baseVehicleUserDto == null) { |
| | | // // TODO 本地无法调通 |
| | | //// throw new RuntimeException("取消订单失败"); |
| | | // } |
| | | // |
| | | // //还原车辆状态 |
| | | // if (1 == xpVehicle.getState()) { |
| | | // XpVehicle vehicle1 = new XpVehicle(); |
| | | // vehicle1.setId(xpVehicle.getId()); |
| | | // vehicle1.setState(0); |
| | | // xpVehicleClient.updateVehicleById(vehicle1); |
| | | // } |
| | | // |
| | | // //下发XPU报文 |
| | | // PushOrderDto pushOrderDto = new PushOrderDto(); |
| | | // pushOrderDto.setOrderId(order.getId().toString()); |
| | | // pushOrderDto.setVin(xpVehicle.getVehicleVin()); |
| | | // pushOrderDto.setOperation_type(OrderOperationType.CLOUD_CANCEL_ORDER); |
| | | // orderMissionClient.cancelOrder(pushOrderDto); |
| | | // log.info("用户取消订单成功,开始执行巡游订单 {}", order.getId()); |
| | | // //车辆继续巡游 |
| | | // addCruiseMission(xpVehicle.getId()); |
| | | // } |
| | | // |
| | | // } |
| | | // |
| | | // @Override |
| | | // @Transactional |
| | | // @ShardingSphereTransactionType(TransactionType.BASE) |
| | | // public XpTestOrder cancelOrder(String orderId) { |
| | | // XpTestOrder order = this.getById(orderId); |
| | | // if (order == null) { |
| | | // throw new ServiceException("订单不存在", I18nKeyConstant.ORDER_NOT_EXISTS); |
| | | // } |
| | | // Long appUserId = order.getAppUserId(); |
| | | // order.setStatus(0); |
| | | // order.setAppUserId(null); |
| | | // baseMapper.updateById(order); |
| | | // redisService.setCacheObject("ORDER_STATUS:" + order.getId(), 0, 24L, TimeUnit.HOURS); |
| | | // XpOrderCancel xpOrderCancel = new XpOrderCancel(); |
| | | // xpOrderCancel.setOrderId(Long.valueOf(orderId)); |
| | | // xpOrderCancel.setUserId(1l); |
| | | // xpOrderCancel.setCancelSource(4); |
| | | // xpOrderCancel.setCancelReason("系统取消订单"); |
| | | // xpOrderCancel.setCreateTime(LocalDateTime.now()); |
| | | // xpOrderCancelService.save(xpOrderCancel); |
| | | // |
| | | // redisService.removeByPattern(order.getQueueName(), order.getOrderNumber()); |
| | | // |
| | | // // 消息推送 |
| | | // Map<String, Object> params = new HashMap<>(); |
| | | // Map<String, Object> content = new HashMap<>(); |
| | | // content.put("orderId", order.getId().toString()); |
| | | // content.put("status", OrderStatusEnum.CANCELED.getCode()); |
| | | // params.put("type", PushMessageTypeEnum.ORDER_STATUS.getDesc()); |
| | | // params.put("content", JSONObject.toJSONString(content)); |
| | | // params.put("timestamp", new Date().getTime() + ""); |
| | | // String message = JSONObject.toJSONString(params); |
| | | // SendMessageDTO sendMessageDTO = new SendMessageDTO(); |
| | | // sendMessageDTO.setMessage(message); |
| | | // sendMessageDTO.setAppUserId(String.valueOf(appUserId)); |
| | | // R<String> stringR = xpPushMessageClient.sendStatus(sendMessageDTO); |
| | | // //推送失败,重试3次 |
| | | // if(stringR.getCode() != Constants.SUCCESS){ |
| | | // ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>()); |
| | | // executor.execute(() -> { |
| | | // for (int i = 0; i < 3; i++) { |
| | | // R<String> stringR1 = xpPushMessageClient.sendStatus(sendMessageDTO); |
| | | // if(stringR1.getCode() == Constants.SUCCESS){ |
| | | // break; |
| | | // } |
| | | // try { |
| | | // Thread.sleep(1000); |
| | | // } catch (InterruptedException e) { |
| | | // throw new RuntimeException(e); |
| | | // } |
| | | // log.info("定时任务取消订单推送订单状态消息失败:{} {} {}", stringR1.getMsg(), JSON.toJSONString(sendMessageDTO), order.getOrderNumber()); |
| | | // } |
| | | // }); |
| | | // } |
| | | // |
| | | // |
| | | // log.info("定时任务取消订单推送消息完毕"); |
| | | // |
| | | // // 移除mongo数据 |
| | | // xpPricingClient.deleteXpGeoQueryEntity(order.getId().toString()); |
| | | // // 设置当天的取消次数缓存 |
| | | // Object cacheObject = redisService.getCacheObject("CANCEL_ORDER_" + appUserId); |
| | | // if (cacheObject == null) { |
| | | // redisService.setCacheCancelOrder("CANCEL_ORDER_" + appUserId, 1); |
| | | // } else { |
| | | // Integer i = Integer.valueOf(cacheObject.toString()); |
| | | // redisService.setCacheCancelOrder("CANCEL_ORDER_" + appUserId, i + 1); |
| | | // } |
| | | // return order; |
| | | // } |
| | | // |
| | | // /** |
| | | // * 评价订单 |
| | | // * |
| | | // * @param dto |
| | | // * @param uid |
| | | // */ |
| | | // @Override |
| | | // @Transactional |
| | | // @ShardingSphereTransactionType(TransactionType.BASE) |
| | | // public void comment(XpOrderCommentDto dto, String uid) { |
| | | // XpTestOrder xpOrder = this.getById(dto.getOrderId()); |
| | | // if (xpOrder == null) { |
| | | // throw new ServiceException("订单不存在", I18nKeyConstant.ORDER_NOT_EXISTS); |
| | | // } |
| | | // if (!xpOrder.getAppUserId().toString().equals(uid)) { |
| | | // throw new ServiceException("订单不存在", I18nKeyConstant.ORDER_NOT_EXISTS); |
| | | // } |
| | | // if (xpOrder.getStatus() != 9) { |
| | | // throw new ServiceException("订单状态错误", I18nKeyConstant.ORDER_STATUS_ERROR); |
| | | // } |
| | | // xpOrder.setAppUserId(null); |
| | | // xpOrder.setStatus(10); |
| | | // baseMapper.updateById(xpOrder); |
| | | // redisService.setCacheObject("ORDER_STATUS:" + xpOrder.getId(), 10, 24L, TimeUnit.HOURS); |
| | | // |
| | | // XpOrderEvaluate evaluate = new XpOrderEvaluate(); |
| | | // evaluate.setOrderId(xpOrder.getId()); |
| | | // evaluate.setVehicleId(xpOrder.getVehicleId()); |
| | | // evaluate.setAppUserId(Long.valueOf(uid)); |
| | | // evaluate.setOrderRating(dto.getOrderRating()); |
| | | // evaluate.setEvaluateTime(LocalDateTime.now()); |
| | | // evaluate.setFeedbackContent(dto.getFeedbackContent()); |
| | | // evaluate.setFeedbackPictures(dto.getFeedbackPictures()); |
| | | // evaluate.setFeedbackTypeId(dto.getFeedbackTypeId()); |
| | | // evaluate.setCreateTime(LocalDateTime.now()); |
| | | // xpOrderEvaluateService.save(evaluate); |
| | | // } |
| | | // |
| | | // @Override |
| | | // public R<String> updateOrderStatus(Long orderId, Integer status) { |
| | | // XpTestOrder xpOrder = this.getById(orderId); |
| | | // if (Objects.isNull(xpOrder)) { |
| | | // return R.fail("订单不存在"); |
| | | // } |
| | | // if (xpOrder.getStatus() == 0) { |
| | | // return R.fail("订单已取消"); |
| | | // } |
| | | // if(xpOrder.getStatus() >= 8){ |
| | | // return R.fail("订单已结束"); |
| | | // } |
| | | // Long appUserId = xpOrder.getAppUserId(); |
| | | // // 查询车辆 |
| | | // XpVehicle xpVehicle = xpVehicleClient.queryById(xpOrder.getVehicleId()).getData(); |
| | | // switch (status) { |
| | | // case 4: |
| | | // // 查询起点点位 |
| | | // Long startPointId = xpOrder.getStartPointId(); |
| | | // XpPoint xpPoint = xpPointClient.queryById(startPointId).getData(); |
| | | // // 添加取消订单定时任务job 时间为点位限停时长 |
| | | // Map<String, ? extends Object> cancelJobMaps = |
| | | // new ImmutableMap.Builder<String, Long>(). |
| | | // put("id", xpOrder.getId()) |
| | | // .build(); |
| | | // QuartzManager.addJob( |
| | | // OrderCancelJob.class, |
| | | // (OrderCancelJob.name + xpOrder.getId()).toUpperCase(), |
| | | // TimeJobType.ORDER_CANCEL, |
| | | // DateUtils.localDateTimeToDate(LocalDateTime.now().plusMinutes(xpPoint.getParkingTimeLimit())), |
| | | // cancelJobMaps |
| | | // ); |
| | | // // 车辆到达上车点时间 |
| | | // xpOrder.setArrivalTime(LocalDateTime.now()); |
| | | // break; |
| | | // case 5: |
| | | // LocalDateTime now = LocalDateTime.now(); |
| | | // xpOrder.setBoardingTime(now); |
| | | // xpOrder.setRideTime(now); |
| | | // //推送行起点到终点的驶轨迹给乘客端 |
| | | // sendRoute(appUserId.toString(), orderId, "ORDER_NAVIGATION_END_DATA", xpVehicle.getVehicleVin()); |
| | | // // 删除定时任务job |
| | | // QuartzManager.removeJob((OrderCancelJob.name + xpOrder.getId()).toUpperCase(), TimeJobType.ORDER_CANCEL); |
| | | // break; |
| | | // case 6: |
| | | // // 行程开始时间 |
| | | // xpOrder.setTripBegin(LocalDateTime.now()); |
| | | // break; |
| | | // case 7: |
| | | // xpOrder.setGetoffTime(LocalDateTime.now()); |
| | | // // 解析下车地点 |
| | | // VehiclePosition vehiclePosition = mongoTemplate.findOne(new Query(Criteria.where("vin").is(xpVehicle.getVehicleVin())), VehiclePosition.class); |
| | | // if(Objects.nonNull(vehiclePosition)){ |
| | | // GeoJsonPoint point = vehiclePosition.getPoint(); |
| | | // if(Objects.nonNull(point)){ |
| | | // double x = point.getX(); |
| | | // double y = point.getY(); |
| | | // Map<String, String> geocode = gdMapGeocodingUtil.geocode(String.valueOf(x), String.valueOf(y)); |
| | | // xpOrder.setGetoffAddress(geocode.get("address")); |
| | | // } |
| | | // } |
| | | // //计算行驶总距离和时长 |
| | | // List<OrderTrajectory> orderTrajectoryList = mongoTemplate.find(new Query().addCriteria(Criteria.where("orderId").is(xpOrder.getId())), OrderTrajectory.class); |
| | | // Double reduce = orderTrajectoryList.stream().map(OrderTrajectory::getDistance).reduce(0.0, Double::sum); |
| | | // xpOrder.setMileageKilometers(new BigDecimal(reduce).divide(new BigDecimal(1000)).setScale(4, RoundingMode.HALF_EVEN).doubleValue()); |
| | | // long duration = LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8")) - xpOrder.getTripBegin().toEpochSecond(ZoneOffset.of("+8")); |
| | | // xpOrder.setDuration(new BigDecimal(duration).divide(new BigDecimal(60), 2, RoundingMode.HALF_EVEN).doubleValue()); |
| | | // |
| | | // // 推送倒计时消息 |
| | | // Map<String, Object> params = new HashMap<>(); |
| | | // Map<String, Object> content = new HashMap<>(); |
| | | // content.put("orderId", xpOrder.getId().toString()); |
| | | // content.put("isOpen", 1); |
| | | // params.put("type", PushMessageTypeEnum.OPEN_TRUNK.getDesc()); |
| | | // params.put("content", JSONObject.toJSONString(content)); |
| | | // params.put("timestamp", new Date().getTime() + ""); |
| | | // String message = JSONObject.toJSONString(params); |
| | | // SendMessageDTO sendMessageDTO = new SendMessageDTO(); |
| | | // sendMessageDTO.setMessage(message); |
| | | // sendMessageDTO.setAppUserId(String.valueOf(xpOrder.getAppUserId())); |
| | | // R<String> stringR = xpPushMessageClient.sendStatus(sendMessageDTO); |
| | | // //推送失败,重试3次 |
| | | // if(stringR.getCode() != Constants.SUCCESS){ |
| | | // ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>()); |
| | | // executor.execute(() -> { |
| | | // for (int i = 0; i < 3; i++) { |
| | | // R<String> stringR1 = xpPushMessageClient.sendStatus(sendMessageDTO); |
| | | // if(stringR1.getCode() == Constants.SUCCESS){ |
| | | // break; |
| | | // } |
| | | // try { |
| | | // Thread.sleep(1000); |
| | | // } catch (InterruptedException e) { |
| | | // throw new RuntimeException(e); |
| | | // } |
| | | // log.info("推送倒计时消息失败:{} {} {}", stringR1.getMsg(), JSON.toJSONString(sendMessageDTO), xpOrder.getOrderNumber()); |
| | | // } |
| | | // }); |
| | | // } |
| | | // |
| | | // //创建定时结束订单和等待结束后下发巡游单的定时任务 |
| | | // Integer arriveTime = xpSystemSettingClient.getOrderFinishTime().getData(); |
| | | // // 添加自动结束行程定时任务job |
| | | // Map<String, ? extends Object> endTripJobMaps = |
| | | // new ImmutableMap.Builder<String, String>() |
| | | // .put("id", xpOrder.getId().toString()) |
| | | // .put("appid", appid) |
| | | // .build(); |
| | | // QuartzManager.addJob( |
| | | // EndTripJob.class, |
| | | // (EndTripJob.name + xpOrder.getId()).toUpperCase(), |
| | | // TimeJobType.END_TRIP, |
| | | // DateUtils.localDateTimeToDate(LocalDateTime.now().plusMinutes(arriveTime)), |
| | | // endTripJobMaps |
| | | // ); |
| | | // // 添加车辆到达终点后限停时间到后驶离的定时任务 |
| | | // //时间到后将车辆状态回滚到空闲、添加巡游订单,解绑用户和车辆关系,车辆驶离点位 |
| | | // XpPoint point = xpPointClient.queryById(xpOrder.getEndPointId()).getData(); |
| | | // Map<String, ? extends Object> jobMaps = |
| | | // new ImmutableMap.Builder<String, String>() |
| | | // .put("id", xpOrder.getId().toString()) |
| | | // .put("appid", appid) |
| | | // .build(); |
| | | // QuartzManager.addJob( |
| | | // AddCruiseMissionJob.class, |
| | | // (AddCruiseMissionJob.name + xpOrder.getId()).toUpperCase(), |
| | | // TimeJobType.ADD_CRUISE_MISSION, |
| | | // DateUtils.localDateTimeToDate(LocalDateTime.now().plusMinutes(point.getParkingTimeLimit())), |
| | | // jobMaps |
| | | // ); |
| | | // break; |
| | | // } |
| | | // xpOrder.setStatus(status); |
| | | // xpOrder.setAppUserId(null); |
| | | // this.updateById(xpOrder); |
| | | // redisService.setCacheObject("ORDER_STATUS:" + xpOrder.getId(), status, 24L, TimeUnit.HOURS); |
| | | // return R.ok(); |
| | | // } |
| | | // |
| | | // @Override |
| | | // public Boolean endTrip(Long orderId, String uid) { |
| | | // List<XpOrderDetail> xpOrderDetails = new ArrayList<>(); |
| | | // // 起步价格明细 |
| | | // List<FareBreakdownDetailVo> start = new ArrayList<>(); |
| | | // // 里程费价格明细 |
| | | // List<FareBreakdownDetailVo> mileage = new ArrayList<>(); |
| | | // // 时长费价格明细 |
| | | // List<FareBreakdownDetailVo> duration = new ArrayList<>(); |
| | | // // 远途费价格明细 |
| | | // List<FareBreakdownDetailVo> longDistance = new ArrayList<>(); |
| | | // XpTestOrder order = this.getById(orderId); |
| | | // if (order == null) { |
| | | // throw new RuntimeException("订单不存在"); |
| | | // } |
| | | // |
| | | // if (order.getStatus() != 7) { |
| | | // throw new RuntimeException("订单状态错误"); |
| | | // } |
| | | // order.setStatus(8); |
| | | // order.setAppUserId(null); |
| | | // order.setTripEnd(LocalDateTime.now()); |
| | | // baseMapper.updateById(order); |
| | | // redisService.setCacheObject("ORDER_STATUS:" + order.getId(), 8, 24L, TimeUnit.HOURS); |
| | | // |
| | | // // 根据订单所属开通城市id 查询定价 |
| | | // R<XpPricing> pricingByCityId = xpPricingClient.getPricingByCid(order.getCityId()); |
| | | // XpPricing pricing = pricingByCityId.getData(); |
| | | // if (pricing == null) { |
| | | // throw new ServiceException("当前城市未配置定价规则", I18nKeyConstant.ORDER_PRICING_NOT_EXISTS); |
| | | // } |
| | | // // 费用 |
| | | // // 查询订单轨迹 |
| | | // List<OrderTrajectory> trajectories = mongoTemplate.find( |
| | | // new Query(Criteria.where("orderId").is(orderId)) |
| | | // .with(Sort.by(Sort.Direction.ASC, "locatetime")), |
| | | // OrderTrajectory.class |
| | | // ); |
| | | // List<TaxiPricingDemoService.GpsPoint> gpsPoints = new ArrayList<>(); |
| | | // for (OrderTrajectory trajectory : trajectories) { |
| | | // TaxiPricingDemoService.GpsPoint point = new TaxiPricingDemoService.GpsPoint(trajectory.getDistance(), trajectory.getLocatetime()); |
| | | // gpsPoints.add(point); |
| | | // } |
| | | // |
| | | // TaxiPricingDemoService.PricingConfig config = new TaxiPricingDemoService.PricingConfig(); |
| | | // JSONArray startingFareJsonArray = JSONArray.parseArray(pricing.getStartingFareJson()); |
| | | // |
| | | // LocalDateTime boardingTime = order.getBoardingTime(); |
| | | // Date date = DateUtils.localDateTimeToDate(boardingTime); |
| | | // |
| | | // |
| | | // double paramNum4 = 0.0; |
| | | // double paramNum5 = 0.0; |
| | | // |
| | | // |
| | | // //一口价 |
| | | // if (pricing.getPricingType() == 2) { |
| | | // Double mileageKilometers = order.getMileageKilometers(); |
| | | // Double duration1 = order.getDuration(); |
| | | // |
| | | // JSONObject basicPricingJson = JSONObject.parseObject(pricing.getBasicPricingJson()); |
| | | // |
| | | // XpPricingCardVo xpPricingCardVo = xpPricingUtil.calculationFixedPrice(uid, basicPricingJson, null, mileageKilometers, duration1, 0, 0.0, pricing.getIsDynamicPrice(), order.getCityId(), pricing.getDynamicPricingJson()); |
| | | // XpOrderDetail xpOrderDetail = new XpOrderDetail(); |
| | | // xpOrderDetail.setDetailType(1); |
| | | // xpOrderDetail.setOrderId(orderId); |
| | | // xpOrderDetail.setType(1); |
| | | // xpOrderDetail.setMileage(new BigDecimal(mileageKilometers).setScale(2, RoundingMode.HALF_UP)); |
| | | // String currentTimeSlot = DateUtils.getCurrentTimeSlot(); |
| | | // xpOrderDetail.setTime(currentTimeSlot); |
| | | // xpOrderDetail.setDuration(duration1); |
| | | // xpOrderDetail.setMoney(new BigDecimal(xpPricingCardVo.getStartPrice()).setScale(2, RoundingMode.HALF_UP)); |
| | | // xpOrderDetails.add(xpOrderDetail); |
| | | // xpOrderDetail = new XpOrderDetail(); |
| | | // xpOrderDetail.setDetailType(2); |
| | | // xpOrderDetail.setOrderId(orderId); |
| | | // xpOrderDetail.setType(1); |
| | | // xpOrderDetail.setMoney(new BigDecimal(xpPricingCardVo.getDistancePrice()).setScale(2,RoundingMode.HALF_UP)); |
| | | // xpOrderDetails.add(xpOrderDetail); |
| | | // xpOrderDetail = new XpOrderDetail(); |
| | | // xpOrderDetail.setDetailType(3); |
| | | // xpOrderDetail.setOrderId(orderId); |
| | | // xpOrderDetail.setType(1); |
| | | // xpOrderDetail.setMoney(new BigDecimal(xpPricingCardVo.getDurationPrice()).setScale(2, RoundingMode.HALF_UP)); |
| | | // xpOrderDetails.add(xpOrderDetail); |
| | | // |
| | | // BigDecimal totalPrice =BigDecimal.ZERO; |
| | | // for (XpOrderDetail xpOrderDetail1 : xpOrderDetails) { |
| | | // totalPrice = totalPrice.add(xpOrderDetail1.getMoney()); |
| | | // xpOrderDetailMapper.insert(xpOrderDetail1); |
| | | // } |
| | | // order.setOrderMoney(totalPrice); |
| | | // order.setAppUserId(null); |
| | | // baseMapper.updateById(order); |
| | | // } else { |
| | | // //动态计费 |
| | | // if (pricing.getPricingType() == 1) { |
| | | // |
| | | // for (int i = 0; i < startingFareJsonArray.size(); i++) { |
| | | // JSONObject jsonObject = startingFareJsonArray.getJSONObject(i); |
| | | // String num1 = jsonObject.getString("num1"); |
| | | // String num2 = jsonObject.getString("num2"); |
| | | // String num3 = jsonObject.getString("num3"); |
| | | // String num4 = jsonObject.getString("num4"); |
| | | // String num5 = jsonObject.getString("num5"); |
| | | // String num6 = jsonObject.getString("num6"); |
| | | // String num7 = jsonObject.getString("num7"); |
| | | // config.normals.add(new TaxiPricingDemoService.PricingRule("普通时段", num1, num2, Double.parseDouble(num3), Double.parseDouble(num4), Double.parseDouble(num5), Double.parseDouble(num6), Double.parseDouble(num7))); |
| | | // // 判断当前是那个时段 |
| | | // |
| | | // Calendar calendarStart = Calendar.getInstance(); |
| | | // calendarStart.setTime(date); |
| | | // calendarStart.set(Calendar.HOUR_OF_DAY, Integer.valueOf(jsonObject.getString("num1").split(":")[0])); |
| | | // calendarStart.set(Calendar.MINUTE, Integer.valueOf(jsonObject.getString("num1").split(":")[1])); |
| | | // |
| | | // Calendar calendarEnd = Calendar.getInstance(); |
| | | // calendarEnd.setTime(date); |
| | | // calendarEnd.set(Calendar.HOUR_OF_DAY, Integer.valueOf(jsonObject.getString("num2").split(":")[0])); |
| | | // calendarEnd.set(Calendar.MINUTE, Integer.valueOf(jsonObject.getString("num2").split(":")[1])); |
| | | // // 找到符合条件的直接跳出循环 |
| | | // if (date.getTime() > calendarStart.getTimeInMillis() && date.getTime() < calendarEnd.getTimeInMillis()) { |
| | | // paramNum4 = jsonObject.getDouble("num4"); |
| | | // paramNum5 = jsonObject.getDouble("num5"); |
| | | // break; |
| | | // } |
| | | // } |
| | | // |
| | | // |
| | | // JSONObject basicPricingJson = JSONObject.parseObject(pricing.getBasicPricingJson()); |
| | | // config.peaks.add(new TaxiPricingDemoService.PricingRule("高峰期", basicPricingJson.getString("num21").split(" - ")[0], basicPricingJson.getString("num21").split(" - ")[1], Double.parseDouble(basicPricingJson.getString("num23")), paramNum4, paramNum5, Double.parseDouble(basicPricingJson.getString("num24")), Double.parseDouble(basicPricingJson.getString("num25")))); |
| | | // config.peaks.add(new TaxiPricingDemoService.PricingRule("高峰期", basicPricingJson.getString("num22").split(" - ")[0], basicPricingJson.getString("num22").split(" - ")[1], Double.parseDouble(basicPricingJson.getString("num23")), paramNum4, paramNum5, Double.parseDouble(basicPricingJson.getString("num24")), Double.parseDouble(basicPricingJson.getString("num25")))); |
| | | // config.night = new TaxiPricingDemoService.PricingRule("夜间行驶", basicPricingJson.getString("num14").split(" - ")[0], basicPricingJson.getString("num14").split(" - ")[1], Double.parseDouble(basicPricingJson.getString("num15")), paramNum4, paramNum5, Double.parseDouble(basicPricingJson.getString("num16")), Double.parseDouble(basicPricingJson.getString("num17"))); |
| | | // config.holiday = new TaxiPricingDemoService.PricingRule("节假日", "00:00", "23:59", Double.parseDouble(basicPricingJson.getString("num29")), paramNum4, paramNum5, Double.parseDouble(basicPricingJson.getString("num30")), Double.parseDouble(basicPricingJson.getString("num31"))); |
| | | // // --- 远途加价区间配置 (关键修改) --- |
| | | // // 1. 超过 num1(12) 不足 num2(20), 加收 num3(1.2) |
| | | // config.longSteps.add(new TaxiPricingDemoService.LongRangeStep(paramNum4, Double.parseDouble(basicPricingJson.getString("num7")), Double.parseDouble(basicPricingJson.getString("num8")))); |
| | | // // 2. 超过 num4(20) 不足 num5(35), 加收 num6(2.0) |
| | | // config.longSteps.add(new TaxiPricingDemoService.LongRangeStep(Double.parseDouble(basicPricingJson.getString("num9")), Double.parseDouble(basicPricingJson.getString("num10")), Double.parseDouble(basicPricingJson.getString("num11")))); |
| | | // // 3. 超过 num7(35) 以后, 加收 num8(3.5) -> numEnd 传个极大值 |
| | | // config.longSteps.add(new TaxiPricingDemoService.LongRangeStep(Double.parseDouble(basicPricingJson.getString("num12")), 999999, Double.parseDouble(basicPricingJson.getString("num13")))); |
| | | // } |
| | | // |
| | | // |
| | | // TaxiPricingDemoService.TaxiPricingService service = new TaxiPricingDemoService.TaxiPricingService(); |
| | | // Integer holidayToday = holidayUtil.isHolidayToday(); |
| | | // Map<String, BigDecimal> bill = service.calculateOrderPrice(DateUtils.toDate(order.getBoardingTime()), order.getMileageKilometers(), gpsPoints, config, holidayToday); |
| | | // log.info("======= 订单计费账单 ======="); |
| | | // bill.forEach((detail, price) -> log.info(detail + ": " + price + " 元")); |
| | | // |
| | | // BigDecimal totalAmount = bill.values().stream().reduce(BigDecimal.ZERO, BigDecimal::add); |
| | | // log.info("--------------------------"); |
| | | // log.info("应付总额: " + totalAmount + " 元"); |
| | | // BigDecimal startMoney = BigDecimal.ZERO; |
| | | // // 默认费率1 |
| | | // double priceRate = 1; |
| | | // if (pricing.getIsDynamicPrice() == 1) { |
| | | // // 先判断是否已经调价过了 |
| | | // Object userDynamicPriceObj = redisService.getCacheObject("USER_DYNAMIC_PRICE_" + order.getCityId() + "_" + uid); |
| | | // if (userDynamicPriceObj != null) { |
| | | // // 是否调价过了 |
| | | // priceRate = Double.parseDouble(userDynamicPriceObj.toString()); |
| | | // } else { |
| | | // // 没有调过 |
| | | // //是否触发动态调价 redis获取 |
| | | // Object dynamicPriceObj = redisService.getCacheObject("DYNAMIC_PRICE_" + order.getCityId()); |
| | | // if (dynamicPriceObj != null) { |
| | | // JSONObject jsonObject = JSONObject.parseObject(pricing.getDynamicPricingJson()); |
| | | // // 触发动态调价 |
| | | // // value=时间 |
| | | // String timeStr = dynamicPriceObj.toString(); |
| | | // // 判断当前距离这个时间范围的新增订单数(排除取消) / 上浮数量 算出应该增加的价格率 |
| | | // Integer num = this.getOrderNum(new GetOrderNumDto(timeStr, order.getCityId())); |
| | | // // X单上升一次调价 |
| | | // Integer orderNum = getOrderNum(jsonObject, 4); |
| | | // // 需要调价的次数 |
| | | // int count = num / orderNum; |
| | | // if (count > 0) { |
| | | // // 计算每次上升的费率 |
| | | // Integer upRate = getOrderNum(jsonObject, 5); |
| | | // BigDecimal divide = new BigDecimal(upRate).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP); |
| | | // for (int i = count; i > 0; i--) { |
| | | // // 当前费率+(费率*上升百分比) |
| | | // priceRate = new BigDecimal(priceRate).multiply(divide).add(new BigDecimal(priceRate)).setScale(2, RoundingMode.HALF_UP).doubleValue(); |
| | | // } |
| | | // // 冷却时间 |
| | | // Integer time = getOrderNum(jsonObject, 6); |
| | | // // 触发调价了 |
| | | // redisService.setCacheObject("USER_DYNAMIC_PRICE_" + order.getCityId() + "_" + uid, priceRate, time.longValue(), TimeUnit.MINUTES); |
| | | // } |
| | | // |
| | | // } |
| | | // } |
| | | // |
| | | // } |
| | | // // 封装费用明细数据 |
| | | // for (Map.Entry<String, BigDecimal> stringBigDecimalEntry : bill.entrySet()) { |
| | | // // 封装起步价 |
| | | // FareBreakdownDetailVo startDetail = new FareBreakdownDetailVo(); |
| | | // String key = stringBigDecimalEntry.getKey(); |
| | | // if (key.contains("起步价")) { |
| | | // startDetail.setTime(key.split("\\|")[1]); |
| | | // startDetail.setMoney(stringBigDecimalEntry.getValue()); |
| | | // startMoney = startMoney.add(stringBigDecimalEntry.getValue()); |
| | | // if (key.contains("普通时段")) { |
| | | // startDetail.setType(1); |
| | | // } else if (key.contains("夜间")) { |
| | | // startDetail.setType(2); |
| | | // } else if (key.contains("高峰")) { |
| | | // startDetail.setType(3); |
| | | // } else if (key.contains("节假")) { |
| | | // startDetail.setType(4); |
| | | // } |
| | | // String durationAndMileage = key.split("\\|")[2]; |
| | | // startDetail.setDuration(Double.valueOf(durationAndMileage.split("&")[0])); |
| | | // startDetail.setMileage(new BigDecimal(durationAndMileage.split("&")[1]).multiply(BigDecimal.valueOf(1000))); |
| | | // start.add(startDetail); |
| | | // } |
| | | // // 封装里程费 |
| | | // if (!key.contains("起步") && !key.contains("时长") && !key.contains("远途") && !key.contains("distance")) { |
| | | // FareBreakdownDetailVo mileageDetail = new FareBreakdownDetailVo(); |
| | | // if (key.contains("普通时段")) { |
| | | // mileageDetail.setType(1); |
| | | // String key1 = "distance普通时段|" + key.split("\\|")[1]; |
| | | // String key2 = "普通时段|" + key.split("\\|")[1]; |
| | | // BigDecimal distance = bill.get(key1); |
| | | // BigDecimal money = bill.get(key2); |
| | | // mileageDetail.setMileage(distance); |
| | | // order.setStartMoney(money.multiply(BigDecimal.valueOf(priceRate))); |
| | | // mileageDetail.setMoney(money.multiply(BigDecimal.valueOf(priceRate))); |
| | | // } else if (key.contains("夜间行驶")) { |
| | | // mileageDetail.setType(2); |
| | | // String key1 = "distance夜间行驶|" + key.split("\\|")[1]; |
| | | // String key2 = "夜间行驶|" + key.split("\\|")[1]; |
| | | // BigDecimal distance = bill.get(key1); |
| | | // BigDecimal money = bill.get(key2); |
| | | // mileageDetail.setMileage(distance); |
| | | // order.setStartMoney(money.multiply(BigDecimal.valueOf(priceRate))); |
| | | // |
| | | // mileageDetail.setMoney(money.multiply(BigDecimal.valueOf(priceRate))); |
| | | // } else if (key.contains("高峰期")) { |
| | | // mileageDetail.setType(3); |
| | | // String key1 = "distance高峰期|" + key.split("\\|")[1]; |
| | | // String key2 = "高峰期|" + key.split("\\|")[1]; |
| | | // BigDecimal distance = bill.get(key1); |
| | | // BigDecimal money = bill.get(key2); |
| | | // mileageDetail.setMileage(distance); |
| | | // order.setStartMoney(money.multiply(BigDecimal.valueOf(priceRate))); |
| | | // |
| | | // mileageDetail.setMoney(money.multiply(BigDecimal.valueOf(priceRate))); |
| | | // } else if (key.contains("节假")) { |
| | | // mileageDetail.setType(4); |
| | | // String key1 = "distance节假日|" + key.split("\\|")[1]; |
| | | // String key2 = "节假日|" + key.split("\\|")[1]; |
| | | // BigDecimal distance = bill.get(key1); |
| | | // BigDecimal money = bill.get(key2); |
| | | // mileageDetail.setMileage(distance); |
| | | // order.setStartMoney(money.multiply(BigDecimal.valueOf(priceRate))); |
| | | // mileageDetail.setMoney(money.multiply(BigDecimal.valueOf(priceRate))); |
| | | // } |
| | | // mileage.add(mileageDetail); |
| | | // } |
| | | // // 封装时长费 |
| | | // FareBreakdownDetailVo timeDetail = new FareBreakdownDetailVo(); |
| | | // if (key.contains("时长费")) { |
| | | // if(key.contains("普通时段")){ |
| | | // timeDetail.setType(1); |
| | | // } |
| | | // if(key.contains("夜间行驶")){ |
| | | // timeDetail.setType(2); |
| | | // } |
| | | // if(key.contains("高峰")){ |
| | | // timeDetail.setType(3); |
| | | // } |
| | | // if(key.contains("节假")){ |
| | | // timeDetail.setType(4); |
| | | // } |
| | | // |
| | | // timeDetail.setMoney(stringBigDecimalEntry.getValue()); |
| | | // timeDetail.setDuration(Double.valueOf(key.split("&")[1])); |
| | | // duration.add(timeDetail); |
| | | // } |
| | | // // 封装远途费 |
| | | // FareBreakdownDetailVo longDetail = new FareBreakdownDetailVo(); |
| | | // if (key.contains("远途费")) { |
| | | // longDetail.setType(startDetail.getType()); |
| | | // longDetail.setMoney(stringBigDecimalEntry.getValue()); |
| | | //// longDetail.setMileage(new BigDecimal(key.split("&")[1])); |
| | | // longDistance.add(longDetail); |
| | | // } |
| | | // } |
| | | // for (FareBreakdownDetailVo fareBreakdownDetailVo : start) { |
| | | // XpOrderDetail xpOrderDetail = new XpOrderDetail(); |
| | | // BeanUtils.copyProperties(fareBreakdownDetailVo, xpOrderDetail); |
| | | // xpOrderDetail.setOrderId(orderId); |
| | | // xpOrderDetail.setDetailType(1); |
| | | // xpOrderDetail.setCreateTime(LocalDateTime.now()); |
| | | // xpOrderDetails.add(xpOrderDetail); |
| | | // } |
| | | // BigDecimal mileageMoney = BigDecimal.ZERO; |
| | | // for (FareBreakdownDetailVo fareBreakdownDetailVo : mileage) { |
| | | // XpOrderDetail xpOrderDetail = new XpOrderDetail(); |
| | | // BeanUtils.copyProperties(fareBreakdownDetailVo, xpOrderDetail); |
| | | // xpOrderDetail.setOrderId(orderId); |
| | | // xpOrderDetail.setDetailType(2); |
| | | // xpOrderDetail.setCreateTime(LocalDateTime.now()); |
| | | // mileageMoney = mileageMoney.add(fareBreakdownDetailVo.getMoney()); |
| | | // xpOrderDetails.add(xpOrderDetail); |
| | | // } |
| | | // order.setMileageMoney(mileageMoney); |
| | | // |
| | | // |
| | | // for (FareBreakdownDetailVo fareBreakdownDetailVo : longDistance) { |
| | | // XpOrderDetail xpOrderDetail = new XpOrderDetail(); |
| | | // BeanUtils.copyProperties(fareBreakdownDetailVo, xpOrderDetail); |
| | | // xpOrderDetail.setOrderId(orderId); |
| | | // xpOrderDetail.setDetailType(4); |
| | | // xpOrderDetail.setCreateTime(LocalDateTime.now()); |
| | | // mileageMoney = mileageMoney.add(fareBreakdownDetailVo.getMoney()); |
| | | // xpOrderDetails.add(xpOrderDetail); |
| | | // } |
| | | // |
| | | // |
| | | // for (FareBreakdownDetailVo fareBreakdownDetailVo : duration) { |
| | | // XpOrderDetail xpOrderDetail = new XpOrderDetail(); |
| | | // BeanUtils.copyProperties(fareBreakdownDetailVo, xpOrderDetail); |
| | | // xpOrderDetail.setOrderId(orderId); |
| | | // xpOrderDetail.setDetailType(3); |
| | | // xpOrderDetail.setCreateTime(LocalDateTime.now()); |
| | | // mileageMoney = mileageMoney.add(fareBreakdownDetailVo.getMoney()); |
| | | // xpOrderDetails.add(xpOrderDetail); |
| | | // } |
| | | // |
| | | // |
| | | // for (XpOrderDetail xpOrderDetail : xpOrderDetails) { |
| | | // xpOrderDetailMapper.insert(xpOrderDetail); |
| | | // } |
| | | // |
| | | // for (FareBreakdownDetailVo fareBreakdownDetailVo : duration) { |
| | | // if (order.getDurationMoney() == null) { |
| | | // order.setDurationMoney(BigDecimal.ZERO); |
| | | // } |
| | | // BigDecimal add = order.getDurationMoney().add(fareBreakdownDetailVo.getMoney()); |
| | | // order.setDurationMoney(add); |
| | | // } |
| | | // |
| | | // |
| | | // BigDecimal orderMoney = startMoney.add(mileageMoney).add(order.getDurationMoney() != null ? order.getDurationMoney() : BigDecimal.ZERO) |
| | | // .add(order.getLongDistancemoney() != null ? order.getLongDistancemoney() : BigDecimal.ZERO) |
| | | // .add(order.getWaitMoney() != null ? order.getWaitMoney() : BigDecimal.ZERO); |
| | | // order.setOrderMoney(orderMoney); |
| | | // order.setAppUserId(null); |
| | | // baseMapper.updateById(order); |
| | | // |
| | | // } |
| | | // |
| | | // |
| | | // if (order.getCouponId() != null) { |
| | | //// UseUserCouponDto useUserCouponDto = new UseUserCouponDto(); |
| | | //// useUserCouponDto.setUserId(Long.valueOf(uid)); |
| | | //// useUserCouponDto.setTotalAmount(order.getOrderMoney().doubleValue()); |
| | | //// useUserCouponDto.setOpenCityId(order.getCityId()); |
| | | //// useUserCouponDto.setOrderId(orderId); |
| | | //// useUserCouponDto.setUserCouponId(order.getCouponId()); |
| | | //// xpAppUserCouponClient.useUserCoupon(useUserCouponDto); |
| | | // } |
| | | // // 计算完价格后 挑选优惠券 |
| | | // GetUserCouponDto getUserCouponDto = new GetUserCouponDto(); |
| | | // getUserCouponDto.setUserId(Long.valueOf(uid)); |
| | | // getUserCouponDto.setTotalAmount(order.getOrderMoney().doubleValue()); |
| | | // getUserCouponDto.setUserCouponId(order.getCouponId()); |
| | | // getUserCouponDto.setOpenCityId(order.getCityId()); |
| | | // R<UserCouponVo> userCouponVoR = xpAppUserCouponClient.getUserCoupon(getUserCouponDto); |
| | | // UserCouponVo userCouponVo = userCouponVoR.getData(); |
| | | // |
| | | // // 提示是否换券 |
| | | // boolean tip =false; |
| | | // if (userCouponVo != null) { |
| | | // // 重新选券 |
| | | // if(userCouponVo.getStatus()==2){ |
| | | // getUserCouponDto.setUserId(Long.valueOf(uid)); |
| | | // getUserCouponDto.setTotalAmount(order.getOrderMoney().doubleValue()); |
| | | // getUserCouponDto.setUserCouponId(order.getCouponId()); |
| | | // getUserCouponDto.setOpenCityId(order.getCityId()); |
| | | // userCouponVoR = xpAppUserCouponClient.getUserCoupon(getUserCouponDto); |
| | | // userCouponVo = userCouponVoR.getData(); |
| | | // tip=true; |
| | | // } |
| | | // order.setCouponId(userCouponVo.getId()); |
| | | // order.setCouponMoney(BigDecimal.valueOf(userCouponVo.getMoney())); |
| | | // } |
| | | // order.setAppUserId(null); |
| | | // baseMapper.updateById(order); |
| | | // return tip; |
| | | // } |
| | | // |
| | | // |
| | | // /** |
| | | // * 添加巡游任务下发命令 |
| | | // * |
| | | // * @param vehicle |
| | | // * @param order |
| | | // */ |
| | | // |
| | | // public void addCruiseMission(Long vehicleId, XpTestOrder order) { |
| | | // XpVehicle vehicle = xpVehicleClient.queryById(vehicleId).getData(); |
| | | // log.info("添加巡游订单 {}", vehicle.getPlateNumber()); |
| | | // if (vehicle.getState() != 0 || vehicle.getOperatingStatus() != 1) { |
| | | // log.info("添加巡游单失败,车辆状态限制 {}", vehicle.getState()); |
| | | // return; |
| | | // } |
| | | // // 判断是否有计划 |
| | | // R<XpCruisePlanVehicle> xpCruisePlanR = xpCruisePlanClient.getCruisePlan(vehicle.getId()); |
| | | // if (xpCruisePlanR == null || xpCruisePlanR.getData() == null) { |
| | | // log.info("添加巡游单失败,没有符合条件的巡游计划", vehicle.getPlateNumber()); |
| | | // return; |
| | | // } |
| | | // // 获取配置 根据配置判断是否该收车 如果是则找到收车点位进行收车操作 |
| | | // R<XpTaskRule> xpTaskRuleR = xpTaskRuleClient.queryDetail(); |
| | | // XpTaskRule xpTaskRule = xpTaskRuleR.getData(); |
| | | // |
| | | // // 生成新的巡游单子 回到最新巡游的初始起点位置 |
| | | // XpCruiseOrder xpCruiseOrders = xpCruiseOrderMapper.selectOne(new LambdaQueryWrapper<XpCruiseOrder>().eq(XpCruiseOrder::getVehicleId, vehicle.getId()).eq(XpCruiseOrder::getStatus, 2).orderByDesc(BaseModel::getCreateTime).last("limit 1")); |
| | | // int temp = 0; |
| | | // if (xpCruiseOrders == null) { |
| | | // temp = 1; |
| | | // //特殊情况 可能没有产生终止的订单 (到站点就被正常接单了)所以找正常订单 |
| | | // xpCruiseOrders = xpCruiseOrderMapper.selectOne(new LambdaQueryWrapper<XpCruiseOrder>().eq(XpCruiseOrder::getVehicleId, vehicle.getId()).eq(XpCruiseOrder::getStatus, 3).orderByDesc(BaseModel::getCreateTime).last("limit 1")); |
| | | // } |
| | | // XpCruiseOrder xpCruiseOrder = new XpCruiseOrder(); |
| | | // xpCruiseOrder.setVehicleId(vehicle.getId()); |
| | | // xpCruiseOrder.setFleetId(vehicle.getFleetId()); |
| | | // xpCruiseOrder.setVehicleVin(vehicle.getVehicleVin()); |
| | | // xpCruiseOrder.setOrderType(2); |
| | | // // 返程起点是当前正常订单的终点 |
| | | // xpCruiseOrder.setStartPointId(order.getEndPointId()); |
| | | // xpCruiseOrder.setStartPointName(order.getEndPointName()); |
| | | // xpCruiseOrder.setStartLon(order.getEndLon()); |
| | | // xpCruiseOrder.setStartLat(order.getEndLat()); |
| | | // |
| | | // // 完成的直接走终点 终止的走起点 |
| | | // if(null != xpCruiseOrders){ |
| | | // if (temp == 0) { |
| | | // //当上一笔单有起点点位,才需要将上一笔巡游单的起点作为本次的终点导航 |
| | | // //上一笔单没有起点点位,统一用后面的巡游计划的第一个点位作为本次的终点导航 |
| | | // if(null != xpCruiseOrders.getStartPointId()){ |
| | | // xpCruiseOrder.setEndPointId(xpCruiseOrders.getStartPointId()); |
| | | // xpCruiseOrder.setEndPointName(xpCruiseOrders.getStartPointName()); |
| | | // xpCruiseOrder.setEndLon(xpCruiseOrders.getStartLon()); |
| | | // xpCruiseOrder.setEndLat(xpCruiseOrders.getStartLat()); |
| | | // } |
| | | // } else { |
| | | // xpCruiseOrder.setEndPointId(xpCruiseOrders.getEndPointId()); |
| | | // xpCruiseOrder.setEndPointName(xpCruiseOrders.getEndPointName()); |
| | | // xpCruiseOrder.setEndLon(xpCruiseOrders.getEndLon()); |
| | | // xpCruiseOrder.setEndLat(xpCruiseOrders.getEndLat()); |
| | | // } |
| | | // xpCruiseOrder.setOrderReverse(xpCruiseOrders.getOrderReverse()); |
| | | // xpCruiseOrder.setLastOrderId(xpCruiseOrders.getId()); |
| | | // xpCruiseOrder.setMissionId(xpCruiseOrders.getMissionId()); |
| | | // } |
| | | // //所有没有赋值终点点位的情况,全部导航到巡游计划的第一个点位开始执行巡游任务 |
| | | // if(null == xpCruiseOrder.getEndPointId()){ |
| | | // // 先找计划 |
| | | // List<XpCruisePlanPoint> planPointList = xpCruisePlanClient.getCruisePlanPointList(vehicle.getId()).getData(); |
| | | // XpCruisePlanPoint xpCruisePlanPoint = planPointList.get(0); |
| | | // Long endPointId = xpCruisePlanPoint.getPointId(); |
| | | // XpPoint endPoint = xpPointClient.queryById(endPointId).getData(); |
| | | // xpCruiseOrder.setEndPointId(endPointId); |
| | | // xpCruiseOrder.setEndPointName(endPoint.getPointName()); |
| | | // xpCruiseOrder.setEndLon(endPoint.getPointLon()); |
| | | // xpCruiseOrder.setEndLat(endPoint.getPointLat()); |
| | | // xpCruiseOrder.setMissionId(xpCruisePlanPoint.getCruisePlanId()); |
| | | // xpCruiseOrder.setOrderReverse(1); |
| | | // } |
| | | // xpCruiseOrder.setStatus(0); |
| | | // xpCruiseOrder.setCreateTime(LocalDateTime.now()); |
| | | // |
| | | // // 判断当前时分秒是否大于收车时间 |
| | | // if(null != xpTaskRule){ |
| | | // LocalTime vehicleCollectionTime = xpTaskRule.getVehicleCollectionTime(); |
| | | // if (vehicleCollectionTime.isBefore(LocalTime.now())) { |
| | | // XpVehicle vehicle1 = new XpVehicle(); |
| | | // vehicle1.setId(vehicle.getId()); |
| | | // vehicle1.setOperatingStatus(3); |
| | | // xpVehicleClient.updateVehicleById(vehicle1); |
| | | // //找到车辆的收车点位 更新终点点位 |
| | | // R<XpCruiseOrder> returnCruisePoint = xpCruisePlanClient.findReturnCruisePoint(xpCruiseOrder); |
| | | // xpCruiseOrder = returnCruisePoint.getData(); |
| | | // xpCruiseOrder.setOrderType(2); |
| | | // xpCruiseOrder.setOrderReverse(1); |
| | | // } |
| | | // } |
| | | // xpCruiseOrderMapper.insert(xpCruiseOrder); |
| | | // log.info("添加巡游单成功 {}", xpCruiseOrder.getId()); |
| | | // //下发XUP巡游订单报文 |
| | | // PushOrderDto pushOrderDto = new PushOrderDto(); |
| | | // pushOrderDto.setVin(xpCruiseOrder.getVehicleVin()); |
| | | // pushOrderDto.setOrderId("XU" + xpCruiseOrder.getId()); |
| | | // pushOrderDto.setStartLatitude(xpCruiseOrder.getStartLat()); |
| | | // pushOrderDto.setStartLongitude(xpCruiseOrder.getStartLon()); |
| | | // pushOrderDto.setEndLatitude(xpCruiseOrder.getEndLat()); |
| | | // pushOrderDto.setEndLongitude(xpCruiseOrder.getEndLon()); |
| | | // pushOrderDto.setOrderType(OrderType.CRUISE_ORDER); |
| | | // pushOrderDto.setStage(2); |
| | | // orderMissionClient.pushOrder(pushOrderDto); |
| | | // log.info("下发XUP巡游订单报文成功"); |
| | | // } |
| | | // |
| | | // |
| | | // /** |
| | | // * 取消订单后的继续巡游任务 |
| | | // * @param vehicle |
| | | // */ |
| | | // public void addCruiseMission(Long vehicleId) { |
| | | // XpVehicle vehicle = xpVehicleClient.queryById(vehicleId).getData(); |
| | | // if (vehicle.getState() != 0 || vehicle.getOperatingStatus() != 1) { |
| | | // return; |
| | | // } |
| | | // // 判断是否有计划 |
| | | // R<XpCruisePlanVehicle> xpCruisePlanR = xpCruisePlanClient.getCruisePlan(vehicle.getId()); |
| | | // if (xpCruisePlanR == null || xpCruisePlanR.getData() == null) { |
| | | // log.info("未找到匹配的巡游计划,无法执行巡游订单 {}", vehicle.getPlateNumber()); |
| | | // return; |
| | | // } |
| | | // |
| | | // VehiclePosition vehiclePosition = mongoTemplate.findOne(new Query(Criteria.where("vin").is(vehicle.getVehicleVin())), VehiclePosition.class); |
| | | // // 获取配置 根据配置判断是否该收车 如果是则找到收车点位进行收车操作 |
| | | // R<XpTaskRule> xpTaskRuleR = xpTaskRuleClient.queryDetail(); |
| | | // XpTaskRule xpTaskRule = xpTaskRuleR.getData(); |
| | | // |
| | | // // 生成新的巡游单子 回到最新巡游的初始起点位置 |
| | | // XpCruiseOrder xpCruiseOrders = xpCruiseOrderMapper.selectOne(new LambdaQueryWrapper<XpCruiseOrder>().eq(XpCruiseOrder::getVehicleId, vehicle.getId()).eq(XpCruiseOrder::getStatus, 2).orderByDesc(BaseModel::getCreateTime).last("limit 1")); |
| | | // int temp = 0; |
| | | // if (xpCruiseOrders == null) { |
| | | // temp = 1; |
| | | // //特殊情况 可能没有产生终止的订单 (到站点就被正常接单了)所以找正常订单 |
| | | // xpCruiseOrders = xpCruiseOrderMapper.selectOne(new LambdaQueryWrapper<XpCruiseOrder>().eq(XpCruiseOrder::getVehicleId, vehicle.getId()).eq(XpCruiseOrder::getStatus, 3).orderByDesc(BaseModel::getCreateTime).last("limit 1")); |
| | | // } |
| | | // XpCruiseOrder xpCruiseOrder = new XpCruiseOrder(); |
| | | // xpCruiseOrder.setVehicleId(vehicle.getId()); |
| | | // xpCruiseOrder.setFleetId(vehicle.getFleetId()); |
| | | // xpCruiseOrder.setVehicleVin(vehicle.getVehicleVin()); |
| | | // xpCruiseOrder.setOrderType(2); |
| | | // // 返程起点是当前正常订单的终点 |
| | | // xpCruiseOrder.setStartPointId(null); |
| | | // xpCruiseOrder.setStartPointName(null); |
| | | // xpCruiseOrder.setStartLon(vehiclePosition.getPoint().getX()); |
| | | // xpCruiseOrder.setStartLat(vehiclePosition.getPoint().getY()); |
| | | // |
| | | // // 完成的直接走终点 终止的走起点 |
| | | // if(null != xpCruiseOrders){ |
| | | // if (temp == 0) { |
| | | // //当上一笔单有起点点位,才需要将上一笔巡游单的起点作为本次的终点导航 |
| | | // //上一笔单没有起点点位,统一用后面的巡游计划的第一个点位作为本次的终点导航 |
| | | // if(null != xpCruiseOrders.getStartPointId()){ |
| | | // xpCruiseOrder.setEndPointId(xpCruiseOrders.getStartPointId()); |
| | | // xpCruiseOrder.setEndPointName(xpCruiseOrders.getStartPointName()); |
| | | // xpCruiseOrder.setEndLon(xpCruiseOrders.getStartLon()); |
| | | // xpCruiseOrder.setEndLat(xpCruiseOrders.getStartLat()); |
| | | // } |
| | | // } else { |
| | | // xpCruiseOrder.setEndPointId(xpCruiseOrders.getEndPointId()); |
| | | // xpCruiseOrder.setEndPointName(xpCruiseOrders.getEndPointName()); |
| | | // xpCruiseOrder.setEndLon(xpCruiseOrders.getEndLon()); |
| | | // xpCruiseOrder.setEndLat(xpCruiseOrders.getEndLat()); |
| | | // } |
| | | // xpCruiseOrder.setOrderReverse(xpCruiseOrders.getOrderReverse()); |
| | | // xpCruiseOrder.setLastOrderId(xpCruiseOrders.getId()); |
| | | // xpCruiseOrder.setMissionId(xpCruiseOrders.getMissionId()); |
| | | // } |
| | | // //所有没有赋值终点点位的情况,全部导航到巡游计划的第一个点位开始执行巡游任务 |
| | | // if(null == xpCruiseOrder.getEndPointId()){ |
| | | // // 先找计划 |
| | | // List<XpCruisePlanPoint> planPointList = xpCruisePlanClient.getCruisePlanPointList(vehicle.getId()).getData(); |
| | | // XpCruisePlanPoint xpCruisePlanPoint = planPointList.get(0); |
| | | // Long endPointId = xpCruisePlanPoint.getPointId(); |
| | | // XpPoint endPoint = xpPointClient.queryById(endPointId).getData(); |
| | | // xpCruiseOrder.setEndPointId(endPointId); |
| | | // xpCruiseOrder.setEndPointName(endPoint.getPointName()); |
| | | // xpCruiseOrder.setEndLon(endPoint.getPointLon()); |
| | | // xpCruiseOrder.setEndLat(endPoint.getPointLat()); |
| | | // xpCruiseOrder.setMissionId(xpCruisePlanPoint.getCruisePlanId()); |
| | | // xpCruiseOrder.setOrderReverse(1); |
| | | // } |
| | | // |
| | | // |
| | | // xpCruiseOrder.setStatus(0); |
| | | // xpCruiseOrder.setCreateTime(LocalDateTime.now()); |
| | | // |
| | | // // 判断当前时分秒是否大于收车时间 |
| | | // if(null != xpTaskRule){ |
| | | // LocalTime vehicleCollectionTime = xpTaskRule.getVehicleCollectionTime(); |
| | | // if (vehicleCollectionTime.isBefore(LocalTime.now())) { |
| | | // XpVehicle vehicle1 = new XpVehicle(); |
| | | // vehicle1.setId(vehicle.getId()); |
| | | // vehicle1.setOperatingStatus(3); |
| | | // xpVehicleClient.updateVehicleById(vehicle1); |
| | | // //找到车辆的收车点位 更新终点点位 |
| | | // R<XpCruiseOrder> returnCruisePoint = xpCruisePlanClient.findReturnCruisePoint(xpCruiseOrder); |
| | | // xpCruiseOrder = returnCruisePoint.getData(); |
| | | // xpCruiseOrder.setOrderType(2); |
| | | // xpCruiseOrder.setOrderReverse(1); |
| | | // } |
| | | // } |
| | | // |
| | | // xpCruiseOrderMapper.insert(xpCruiseOrder); |
| | | // log.info("巡游订单创建成功,开始执行巡游订单 {}", JSON.toJSONString(xpCruiseOrder)); |
| | | // |
| | | // //下发XPU消息报文 |
| | | // PushOrderDto pushOrderDto = new PushOrderDto(); |
| | | // pushOrderDto.setVin(xpCruiseOrder.getVehicleVin()); |
| | | // pushOrderDto.setOrderId("XU" + xpCruiseOrder.getId()); |
| | | // pushOrderDto.setStartLatitude(xpCruiseOrder.getStartLat()); |
| | | // pushOrderDto.setStartLongitude(xpCruiseOrder.getStartLon()); |
| | | // pushOrderDto.setEndLatitude(xpCruiseOrder.getEndLat()); |
| | | // pushOrderDto.setEndLongitude(xpCruiseOrder.getEndLon()); |
| | | // pushOrderDto.setOrderType(OrderType.CRUISE_ORDER); |
| | | // pushOrderDto.setStage(2); |
| | | // // 调用推送服务 orderId + carVin |
| | | // log.info("开始推送XPU巡游订单 {}", xpCruiseOrder.getVehicleVin()); |
| | | // orderMissionClient.pushOrder(pushOrderDto); |
| | | // } |
| | | // |
| | | // |
| | | // private MileageDto mileageType(MileageDto param, JSONArray startingFareJsonArray, Date mileageDate, LocalDateTime begin, String num14, String num16, String num17, String num21, String num22, String num24, String num25, String num30, String num31) { |
| | | // // 计算出是在哪个普通时间段内 |
| | | // for (Object o : startingFareJsonArray) { |
| | | // JSONObject startingFare = (JSONObject) o; |
| | | // Calendar calendarStart = Calendar.getInstance(); |
| | | // calendarStart.setTime(mileageDate); |
| | | // calendarStart.set(Calendar.HOUR_OF_DAY, Integer.valueOf(startingFare.getString("num1").split(":")[0])); |
| | | // calendarStart.set(Calendar.MINUTE, Integer.valueOf(startingFare.getString("num1").split(":")[1])); |
| | | // |
| | | // Calendar calendarEnd = Calendar.getInstance(); |
| | | // calendarEnd.setTime(mileageDate); |
| | | // calendarEnd.set(Calendar.HOUR_OF_DAY, Integer.valueOf(startingFare.getString("num2").split(":")[0])); |
| | | // calendarEnd.set(Calendar.MINUTE, Integer.valueOf(startingFare.getString("num2").split(":")[1])); |
| | | // // 找到符合条件的直接跳出循环 |
| | | // if (mileageDate.getTime() > calendarStart.getTimeInMillis() && mileageDate.getTime() < calendarEnd.getTimeInMillis()) { |
| | | // param.setMileage(startingFare.getString("num6")); |
| | | // param.setTime(startingFare.getString("num7")); |
| | | // param.setMileageTypeTemp(1); |
| | | // break; |
| | | // } |
| | | // } |
| | | // // 根据时间确定是否使用基础信息配置 |
| | | // LocalDateTime createTime = begin; |
| | | // Date date = DateUtils.toDate(createTime); |
| | | // LocalDate localDate = DateUtils.toLocalDate(date); |
| | | // // 判断是否为夜间行驶 获取里程费用 |
| | | // Calendar calendarStart = Calendar.getInstance(); |
| | | // calendarStart.setTime(date); |
| | | // calendarStart.set(Calendar.HOUR_OF_DAY, Integer.valueOf(num14.split("-")[0].split(":")[0])); |
| | | // calendarStart.set(Calendar.MINUTE, Integer.valueOf(num14.split("-")[0].split(":")[1])); |
| | | // Calendar calendarEnd = Calendar.getInstance(); |
| | | // calendarEnd.setTime(date); |
| | | // calendarEnd.set(Calendar.HOUR_OF_DAY, Integer.valueOf(num14.split("-")[1].split(":")[0])); |
| | | // calendarEnd.set(Calendar.MINUTE, Integer.valueOf(num14.split("-")[1].split(":")[1])); |
| | | // if (date.getTime() > calendarStart.getTimeInMillis() && date.getTime() < calendarEnd.getTimeInMillis() |
| | | // ) { |
| | | // |
| | | // param.setMileage(num16); |
| | | // param.setTime(num17); |
| | | // param.setMileageTypeTemp(2); |
| | | // } |
| | | // // 判断是否为高峰期 获取里程费用 |
| | | // Calendar calendar1Start = Calendar.getInstance(); |
| | | // calendar1Start.setTime(date); |
| | | // calendar1Start.set(Calendar.HOUR_OF_DAY, Integer.valueOf(num21.split("-")[0].split(":")[0])); |
| | | // calendar1Start.set(Calendar.MINUTE, Integer.valueOf(num21.split("-")[0].split(":")[1])); |
| | | // |
| | | // Calendar calendar1End = Calendar.getInstance(); |
| | | // calendar1End.setTime(date); |
| | | // calendar1End.set(Calendar.HOUR_OF_DAY, Integer.valueOf(num21.split("-")[1].split(":")[0])); |
| | | // calendar1End.set(Calendar.MINUTE, Integer.valueOf(num21.split("-")[1].split(":")[1])); |
| | | // |
| | | // Calendar calendar2Start = Calendar.getInstance(); |
| | | // calendar2Start.setTime(date); |
| | | // calendar2Start.set(Calendar.HOUR_OF_DAY, Integer.valueOf(num22.split("-")[0].split("-")[0].split(":")[0])); |
| | | // calendar2Start.set(Calendar.MINUTE, Integer.valueOf(num22.split("-")[0].split("-")[0].split(":")[1])); |
| | | // |
| | | // Calendar calendar2End = Calendar.getInstance(); |
| | | // calendar2End.setTime(date); |
| | | // calendar2End.set(Calendar.HOUR_OF_DAY, Integer.valueOf(num22.split("-")[1].split(":")[0])); |
| | | // calendar2End.set(Calendar.MINUTE, Integer.valueOf(num22.split("-")[1].split(":")[1])); |
| | | // if ((date.getTime() > calendar1Start.getTimeInMillis() && date.getTime() < calendar1End.getTimeInMillis()) |
| | | // || (date.getTime() > calendar2Start.getTimeInMillis() && date.getTime() < calendar2End.getTimeInMillis())) { |
| | | // |
| | | // param.setMileage(num24); |
| | | // param.setTime(num25); |
| | | // param.setMileageTypeTemp(3); |
| | | // } |
| | | // // 判断当前是否属于节假日 获取里程费用 |
| | | // boolean holiday = holidayUtil.isHoliday(localDate); |
| | | // if (holiday) { |
| | | // // 判断是否为节假日 起步价修改 |
| | | // param.setMileage(num30); |
| | | // param.setTime(num31); |
| | | // param.setMileageTypeTemp(4); |
| | | // } |
| | | // return param; |
| | | // } |
| | | // |
| | | // private void calculateStartingFare(List<OrderTrajectory> trajectories, LocalDateTime tripBegin, boolean startFlag, Double startDistance, JSONArray startingFareJsonArray, String num3, String num4, String num5, Date endDate, XpTestOrder order, String num14, String num15, String num16, String num17, Integer startType, String num21, String num22, String num23, String num24, String num25, String num29, String num30, String num31, SimpleDateFormat timeFormat, Date startDate, List<FareBreakdownDetailVo> start) { |
| | | // String startTime; |
| | | // String num6; |
| | | // String num7; |
| | | // String endTime; |
| | | // // 根据订单创建时间确定是否使用基础信息配置 |
| | | // LocalDateTime createTime = order.getCreateTime(); |
| | | // Date date = DateUtils.toDate(createTime); |
| | | // LocalDate localDate = DateUtils.toLocalDate(date); |
| | | // for (Object o : startingFareJsonArray) { |
| | | // JSONObject startingFare = (JSONObject) o; |
| | | // Calendar calendarStart = Calendar.getInstance(); |
| | | // calendarStart.setTime(date); |
| | | // calendarStart.set(Calendar.HOUR_OF_DAY, Integer.valueOf(startingFare.getString("num1").split(":")[0])); |
| | | // calendarStart.set(Calendar.MINUTE, Integer.valueOf(startingFare.getString("num1").split(":")[1])); |
| | | // |
| | | // Calendar calendarEnd = Calendar.getInstance(); |
| | | // calendarEnd.setTime(date); |
| | | // calendarEnd.set(Calendar.HOUR_OF_DAY, Integer.valueOf(startingFare.getString("num2").split(":")[0])); |
| | | // calendarEnd.set(Calendar.MINUTE, Integer.valueOf(startingFare.getString("num2").split(":")[1])); |
| | | // // 找到符合条件的直接跳出循环 |
| | | // if (date.getTime() > calendarStart.getTimeInMillis() && date.getTime() < calendarEnd.getTimeInMillis()) { |
| | | // num3 = startingFare.getString("num3"); |
| | | // num4 = startingFare.getString("num4"); |
| | | // num5 = startingFare.getString("num5"); |
| | | // num6 = startingFare.getString("num6"); |
| | | // num7 = startingFare.getString("num7"); |
| | | // startTime = startingFare.getString("num1"); |
| | | // endTime = startingFare.getString("num2"); |
| | | // break; |
| | | // } |
| | | // } |
| | | // // 判断是否为夜间行驶 起步价修改 |
| | | // Calendar calendarStart = Calendar.getInstance(); |
| | | // calendarStart.setTime(date); |
| | | // calendarStart.set(Calendar.HOUR_OF_DAY, Integer.valueOf(num14.split("-")[0].split(":")[0])); |
| | | // calendarStart.set(Calendar.MINUTE, Integer.valueOf(num14.split("-")[0].split(":")[1])); |
| | | // Calendar calendarEnd = Calendar.getInstance(); |
| | | // calendarEnd.setTime(date); |
| | | // calendarEnd.set(Calendar.HOUR_OF_DAY, Integer.valueOf(num14.split("-")[1].split(":")[0])); |
| | | // calendarEnd.set(Calendar.MINUTE, Integer.valueOf(num14.split("-")[1].split(":")[1])); |
| | | // if (date.getTime() > calendarStart.getTimeInMillis() && date.getTime() < calendarEnd.getTimeInMillis() |
| | | // ) { |
| | | // num3 = num15; |
| | | // num6 = num16; |
| | | // num7 = num17; |
| | | // startType = 2; |
| | | // |
| | | // } |
| | | // // 判断是否为高峰期 |
| | | // Calendar calendar1Start = Calendar.getInstance(); |
| | | // calendar1Start.setTime(date); |
| | | // calendar1Start.set(Calendar.HOUR_OF_DAY, Integer.valueOf(num21.split("-")[0].split(":")[0])); |
| | | // calendar1Start.set(Calendar.MINUTE, Integer.valueOf(num21.split("-")[0].split(":")[1])); |
| | | // |
| | | // Calendar calendar1End = Calendar.getInstance(); |
| | | // calendar1End.setTime(date); |
| | | // calendar1End.set(Calendar.HOUR_OF_DAY, Integer.valueOf(num21.split("-")[1].split(":")[0])); |
| | | // calendar1End.set(Calendar.MINUTE, Integer.valueOf(num21.split("-")[1].split(":")[1])); |
| | | // |
| | | // Calendar calendar2Start = Calendar.getInstance(); |
| | | // calendar2Start.setTime(date); |
| | | // calendar2Start.set(Calendar.HOUR_OF_DAY, Integer.valueOf(num22.split("-")[0].split("-")[0].split(":")[0])); |
| | | // calendar2Start.set(Calendar.MINUTE, Integer.valueOf(num22.split("-")[0].split("-")[0].split(":")[1])); |
| | | // |
| | | // Calendar calendar2End = Calendar.getInstance(); |
| | | // calendar2End.setTime(date); |
| | | // calendar2End.set(Calendar.HOUR_OF_DAY, Integer.valueOf(num22.split("-")[1].split(":")[0])); |
| | | // calendar2End.set(Calendar.MINUTE, Integer.valueOf(num22.split("-")[1].split(":")[1])); |
| | | // // 判断是否为高峰期 起步价,里程费,时长费修改 |
| | | // if ((date.getTime() > calendar1Start.getTimeInMillis() && date.getTime() < calendar1End.getTimeInMillis()) |
| | | // || (date.getTime() > calendar2Start.getTimeInMillis() && date.getTime() < calendar2End.getTimeInMillis())) { |
| | | // num3 = num23; |
| | | // num6 = num24; |
| | | // num7 = num25; |
| | | // startType = 3; |
| | | // } |
| | | // // 判断当前是否属于节假日 |
| | | // boolean holiday = holidayUtil.isHoliday(localDate); |
| | | // if (holiday) { |
| | | // // 判断是否为节假日 起步价修改 |
| | | // num3 = num29; |
| | | // num6 = num30; |
| | | // num7 = num31; |
| | | // startType = 4; |
| | | // } |
| | | // // 起步价价格明细封装 |
| | | // FareBreakdownDetailVo fareBreakdownDetailVo = new FareBreakdownDetailVo(); |
| | | // fareBreakdownDetailVo.setType(startType); |
| | | // fareBreakdownDetailVo.setTime(timeFormat.format(startDate) + "-" + timeFormat.format(endDate)); |
| | | // fareBreakdownDetailVo.setMileage(new BigDecimal(startDistance / 1000).setScale(2, RoundingMode.HALF_UP)); |
| | | // |
| | | // // 计算startDate和endDate相差多少分钟 |
| | | // // 将 Date 转换为 LocalDateTime |
| | | // LocalDateTime startDateTime = startDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime(); |
| | | // LocalDateTime endDateTime = endDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime(); |
| | | // |
| | | // // 计算时间差(单位:分钟) |
| | | // long minutesDifference = Duration.between(startDateTime, endDateTime).toMinutes(); |
| | | // fareBreakdownDetailVo.setDuration((double) minutesDifference); |
| | | // fareBreakdownDetailVo.setMoney(new BigDecimal(num3)); |
| | | // start.add(fareBreakdownDetailVo); |
| | | // } |
| | | // |
| | | // /** |
| | | // * 获取配置 4每X单 5上升X% 6冷却 |
| | | // * |
| | | // * @param rule |
| | | // * @param num |
| | | // * @return |
| | | // */ |
| | | // private Integer getOrderNum(JSONObject rule, int num) { |
| | | // Integer param = rule.getInteger("num" + num); |
| | | // return param; |
| | | // } |
| | | // |
| | | // @Override |
| | | // public R<FareBreakdownVo> fareBreakdown(Long orderId, String uid) { |
| | | // XpTestOrder order = this.getById(orderId); |
| | | // order.setAppUserId(null); |
| | | // FareBreakdownVo res = new FareBreakdownVo(); |
| | | // res.setChangeMoneyFlag(order.getChangeMoneyFlag()); |
| | | // |
| | | // List<FareBreakdownDetailVo> start = new ArrayList<>(); |
| | | // List<FareBreakdownDetailVo> mileage = new ArrayList<>(); |
| | | // List<FareBreakdownDetailVo> duration = new ArrayList<>(); |
| | | // List<FareBreakdownDetailVo> longDistance = new ArrayList<>(); |
| | | // |
| | | // List<XpOrderDetail> xpOrderDetails = xpOrderDetailMapper.selectList(new LambdaQueryWrapper<XpOrderDetail>().eq(XpOrderDetail::getOrderId, orderId)); |
| | | // for (XpOrderDetail xpOrderDetail : xpOrderDetails) { |
| | | // FareBreakdownDetailVo detail = new FareBreakdownDetailVo(); |
| | | // detail.setType(xpOrderDetail.getType()); |
| | | // detail.setTime(xpOrderDetail.getTime()); |
| | | // detail.setMileage(xpOrderDetail.getMileage()); |
| | | // detail.setDuration((xpOrderDetail.getDuration() == null ? 0 : xpOrderDetail.getDuration())*60); |
| | | // detail.setMoney(xpOrderDetail.getMoney()); |
| | | // if (xpOrderDetail.getDetailType() == 1) { |
| | | // start.add(detail); |
| | | // } else if(xpOrderDetail.getDetailType()==2){ |
| | | // mileage.add(detail); |
| | | // }else if(xpOrderDetail.getDetailType()==3){ |
| | | // duration.add(detail); |
| | | // }else if(xpOrderDetail.getDetailType()==4){ |
| | | // longDistance.add(detail); |
| | | // } |
| | | // } |
| | | // |
| | | // res.setStart(start); |
| | | // res.setMileage(mileage); |
| | | // res.setDuration(duration); |
| | | // res.setLongDistance(longDistance); |
| | | // res.setRedPacketMoney(order.getRedPacketMoney()); |
| | | // res.setCouponMoney(order.getCouponMoney()); |
| | | // res.setOrderMoney(order.getOrderMoney()); |
| | | // res.setKilometer(order.getMileageKilometers() == null ? BigDecimal.ZERO : BigDecimal.valueOf(order.getMileageKilometers()).multiply(BigDecimal.valueOf(1000))); |
| | | // LocalDateTime createTime = order.getCreateTime(); |
| | | // LocalDateTime tripEnd = order.getTripEnd(); |
| | | // if (tripEnd == null) { |
| | | // tripEnd = LocalDateTime.now(); |
| | | // order.setTripEnd(tripEnd); |
| | | // this.updateById(order); |
| | | // } |
| | | // res.setTime(new BigDecimal(order.getDuration() == null ? 0 : order.getDuration()).multiply(new BigDecimal(60)).setScale(0, RoundingMode.HALF_UP)); |
| | | // return R.ok(res); |
| | | // } |
| | | // |
| | | // @Override |
| | | // public R payment(XpOrderPayDto dto, String uid) { |
| | | // // mvp版本不做支付 使用优惠券抵扣为0元订单处理 处理订单状态即可 |
| | | // XpTestOrder order = this.getById(dto.getOrderId()); |
| | | // order.setStatus(9); |
| | | // order.setAppUserId(null); |
| | | // |
| | | // |
| | | // if(order.getCouponId()!=null){ |
| | | // UseUserCouponDto useUserCouponDto = new UseUserCouponDto(); |
| | | // useUserCouponDto.setUserCouponId(order.getCouponId()); |
| | | // R<BigDecimal> decimalR = xpAppUserCouponClient.useUserCoupon(useUserCouponDto); |
| | | // if(decimalR.getCode()==200){ |
| | | // order.setCouponMoney(decimalR.getData()); |
| | | // if(order.getCouponMoney().compareTo(order.getOrderMoney())>0){ |
| | | // order.setPayMoney(BigDecimal.ZERO); |
| | | // order.setCouponMoney(order.getOrderMoney()); |
| | | // }else { |
| | | // order.setPayMoney(order.getOrderMoney().subtract(decimalR.getData())); |
| | | // } |
| | | // } |
| | | // |
| | | // } |
| | | // baseMapper.updateById(order); |
| | | // redisService.setCacheObject("ORDER_STATUS:" + order.getId(), 9, 24L, TimeUnit.HOURS); |
| | | // return R.ok(); |
| | | // } |
| | | // |
| | | // /** |
| | | // * 添加订单 |
| | | // * |
| | | // * @param xpOrder |
| | | // * @return |
| | | // */ |
| | | // @Override |
| | | // public boolean addOrder(XpTestOrder xpOrder) { |
| | | // int insert = this.baseMapper.insert(xpOrder); |
| | | // if (insert <= 0) { |
| | | // return false; |
| | | // } |
| | | // return true; |
| | | // } |
| | | // |
| | | // |
| | | // @Override |
| | | // public XpVehicle queryVehicleByOrderId(Long orderId, String uid) { |
| | | // XpTestOrder xpOrder = this.getById(orderId); |
| | | // XpVehicle xpVehicle = xpVehicleClient.queryById(xpOrder.getVehicleId()).getData(); |
| | | // return xpVehicle; |
| | | // } |
| | | // |
| | | // /** |
| | | // * 获取订单数量 |
| | | // * |
| | | // * @param dto |
| | | // * @return |
| | | // */ |
| | | // @Override |
| | | // public Integer getOrderNum(GetOrderNumDto dto) { |
| | | // Long num = this.baseMapper.selectCount(new LambdaQueryWrapper<XpTestOrder>().eq(XpTestOrder::getCityId, dto.getOpenCityId()).between(BaseModel::getCreateTime, dto.getTimeStr(), new Date())); |
| | | // return num.intValue(); |
| | | // } |
| | | // |
| | | // @Override |
| | | // public Integer countActiveOrdersByCityId(Long cityId) { |
| | | // Long num = this.baseMapper.selectCount(new LambdaQueryWrapper<XpTestOrder>() |
| | | // .eq(XpTestOrder::getCityId, cityId) |
| | | // .eq(XpTestOrder::getStatus, 1)); |
| | | // return num.intValue(); |
| | | // } |
| | | // |
| | | // @Override |
| | | // public void saveVehicleLocation(OrderTrajectory orderTrajectory) { |
| | | // // 查询订单信息 |
| | | // Integer status = redisService.getCacheObject("ORDER_STATUS:" + orderTrajectory.getOrderId()); |
| | | // if(status < 6){ |
| | | // return; |
| | | // } |
| | | // |
| | | // // 计算距离 |
| | | // // 获取上一次定位 |
| | | // String oldLocation = redisService.getCacheObject(CacheConstants.ORDER_OLD_LOCATION + orderTrajectory.getOrderId()); |
| | | // if (StringUtils.isEmpty(oldLocation)) { |
| | | // orderTrajectory.setDistance(0D); |
| | | // // 存储mongo数据 |
| | | // mongoTemplate.save(orderTrajectory); |
| | | // // 存储首次定位 |
| | | // redisService.setCacheObject(CacheConstants.ORDER_OLD_LOCATION + orderTrajectory.getOrderId(), orderTrajectory.getLocation(), 1L, TimeUnit.HOURS); |
| | | // } else { |
| | | // Map<String, Double> distance = GeodesyUtil.getDistance(orderTrajectory.getLocation(), oldLocation); |
| | | // if (null != distance) { |
| | | // Double distance1 = distance.get("WGS84"); |
| | | // // 存储本次距离 |
| | | // orderTrajectory.setDistance(distance1); |
| | | // // 存储mongo数据 |
| | | // mongoTemplate.save(orderTrajectory); |
| | | // // 更新定位 |
| | | // redisService.setCacheObject(CacheConstants.ORDER_OLD_LOCATION + orderTrajectory.getOrderId(), orderTrajectory.getLocation(), 1L, TimeUnit.HOURS); |
| | | // } else { |
| | | // log.error("调用高德计算距离出错"); |
| | | // } |
| | | // } |
| | | // } |
| | | // |
| | | // @Override |
| | | // public OrderDetailVo orderDetail(Long orderId, String uid) { |
| | | // OrderDetailVo orderDetailVo = new OrderDetailVo(); |
| | | // XpTestOrder order = this.getById(orderId); |
| | | // BeanUtils.copyProperties(order, orderDetailVo); |
| | | // // 查询车辆信息 |
| | | // XpVehicle vehicle = xpVehicleClient.queryById(order.getVehicleId()).getData(); |
| | | // if (vehicle != null) { |
| | | // orderDetailVo.setVehicleCode(vehicle.getVehicleCode()); |
| | | // orderDetailVo.setPlateNumber(vehicle.getPlateNumber()); |
| | | // orderDetailVo.setVehicleColor(vehicle.getVehicleColor()); |
| | | // orderDetailVo.setVehiclePictures(vehicle.getVehiclePictures()); |
| | | // } |
| | | // // 查询评价信息 |
| | | // XpOrderEvaluate evaluate = xpOrderEvaluateService.lambdaQuery().eq(XpOrderEvaluate::getOrderId, orderId) |
| | | // .last("limit 1").one(); |
| | | // if (evaluate != null) { |
| | | // orderDetailVo.setFeedbackPictures(evaluate.getFeedbackPictures()); |
| | | // orderDetailVo.setFeedbackContent(evaluate.getFeedbackContent()); |
| | | // orderDetailVo.setOrderRating(evaluate.getOrderRating()); |
| | | // if (evaluate.getFeedbackTypeId() != null) { |
| | | // XpFeedbackType feedbackType = xpSystemSettingClient.getFeedbackTypeById(evaluate.getFeedbackTypeId()).getData(); |
| | | // orderDetailVo.setFeedbackTypeName(feedbackType.getFeedbackType()); |
| | | // } |
| | | // |
| | | // } |
| | | // List<OrderTrajectory> trajectories = queryOrderTrajectories(orderId); |
| | | // orderDetailVo.setTrajectories(trajectories); |
| | | // |
| | | // // 起步价、里程费、时长费、远途费:按订单费用明细聚合,覆盖订单表字段 |
| | | // Map<Integer, BigDecimal> feeMap = sumOrderDetailMoneyByDetailType(orderId); |
| | | // orderDetailVo.setStartMoney(feeMap.getOrDefault(1, BigDecimal.ZERO)); |
| | | // orderDetailVo.setMileageMoney(feeMap.getOrDefault(2, BigDecimal.ZERO)); |
| | | // orderDetailVo.setDurationMoney(feeMap.getOrDefault(3, BigDecimal.ZERO)); |
| | | // orderDetailVo.setLongDistancemoney(feeMap.getOrDefault(4, BigDecimal.ZERO)); |
| | | // if (order.getBoardingTime() != null && order.getTripEnd() != null) { |
| | | // // 计算两个时间相差多少分钟 |
| | | // double exactMinutes = Duration.between(order.getBoardingTime(), order.getTripEnd()).toMillis() / (1000.0 * 60); |
| | | // exactMinutes = new BigDecimal(exactMinutes).setScale(2, RoundingMode.HALF_UP).doubleValue(); |
| | | // orderDetailVo.setOrderTime(exactMinutes); |
| | | // } else { |
| | | // orderDetailVo.setOrderTime(0.0); |
| | | // } |
| | | // orderDetailVo.setTotalMileage(order.getMileageKilometers() != null ? new BigDecimal(order.getMileageKilometers() * 1000).setScale(2, RoundingMode.HALF_UP).doubleValue() : 0D); |
| | | // orderDetailVo.setOrderTime(new BigDecimal(null == order.getDuration() ? 0 : order.getDuration()).multiply(new BigDecimal(60)).setScale(0, RoundingMode.HALF_EVEN).doubleValue()); |
| | | // return orderDetailVo; |
| | | // } |
| | | // |
| | | // /** |
| | | // * 查询订单轨迹(mongodb) |
| | | // * |
| | | // * @param orderId 订单id |
| | | // * @return 轨迹列表(按 locatetime 升序) |
| | | // */ |
| | | // private List<OrderTrajectory> queryOrderTrajectories(Long orderId) { |
| | | // if (orderId == null) { |
| | | // return new ArrayList<>(); |
| | | // } |
| | | // List<OrderTrajectory> trajectories = mongoTemplate.find( |
| | | // new Query(Criteria.where("orderId").is(orderId)) |
| | | // .with(Sort.by(Sort.Direction.ASC, "locatetime")), |
| | | // OrderTrajectory.class |
| | | // ); |
| | | // return trajectories; |
| | | // } |
| | | // |
| | | // /** |
| | | // * 订单费用明细聚合:按 detail_type 汇总 money |
| | | // * |
| | | // * <p>detail_type:1=起步价 2=里程费 3=时长费 4=远途费</p> |
| | | // */ |
| | | // private Map<Integer, BigDecimal> sumOrderDetailMoneyByDetailType(Long orderId) { |
| | | // if (orderId == null) { |
| | | // return Collections.emptyMap(); |
| | | // } |
| | | // List<XpOrderDetail> detailList = xpOrderDetailMapper.selectList( |
| | | // new LambdaQueryWrapper<XpOrderDetail>() |
| | | // .eq(XpOrderDetail::getOrderId, orderId) |
| | | // .ne(XpOrderDetail::getIsDeleted, true) |
| | | // ); |
| | | // if (CollectionUtils.isEmpty(detailList)) { |
| | | // return Collections.emptyMap(); |
| | | // } |
| | | // Map<Integer, BigDecimal> sumMap = new HashMap<>(); |
| | | // for (XpOrderDetail detail : detailList) { |
| | | // if (detail == null || detail.getDetailType() == null) { |
| | | // continue; |
| | | // } |
| | | // BigDecimal money = detail.getMoney() == null ? BigDecimal.ZERO : detail.getMoney(); |
| | | // sumMap.put(detail.getDetailType(), sumMap.getOrDefault(detail.getDetailType(), BigDecimal.ZERO).add(money)); |
| | | // } |
| | | // return sumMap; |
| | | // } |
| | | // |
| | | // /** |
| | | // * 将轨迹点转换为订单经纬度列表 |
| | | // */ |
| | | // private List<XpTestOrderDetailVO.OrderPosition> convertTrajectoriesToPositions(List<OrderTrajectory> trajectories) { |
| | | // if (CollectionUtils.isEmpty(trajectories)) { |
| | | // return new ArrayList<>(); |
| | | // } |
| | | // List<XpTestOrderDetailVO.OrderPosition> positions = new ArrayList<>(); |
| | | // for (OrderTrajectory trajectory : trajectories) { |
| | | // if (trajectory == null || StringUtils.isBlank(trajectory.getLocation())) { |
| | | // continue; |
| | | // } |
| | | // String[] parts = trajectory.getLocation().split(","); |
| | | // if (parts.length != 2) { |
| | | // continue; |
| | | // } |
| | | // try { |
| | | // double longitude = Double.parseDouble(parts[0].trim()); |
| | | // double latitude = Double.parseDouble(parts[1].trim()); |
| | | // XpTestOrderDetailVO.OrderPosition position = new XpTestOrderDetailVO.OrderPosition(); |
| | | // position.setLongitude(longitude); |
| | | // position.setLatitude(latitude); |
| | | // positions.add(position); |
| | | // } catch (Exception e) { |
| | | // // ignore invalid point |
| | | // } |
| | | // } |
| | | // return positions; |
| | | // } |
| | | // |
| | | // @Override |
| | | // public R<String> feeDescription(Long orderId, String uid) { |
| | | // XpTestOrder order = this.getById(orderId); |
| | | // R<XpPricing> pricingByCityId = xpPricingClient.getPricingByCid(order.getCityId()); |
| | | // XpPricing pricing = pricingByCityId.getData(); |
| | | // if (pricing == null) { |
| | | // throw new ServiceException("当前城市未配置定价规则", I18nKeyConstant.ORDER_PRICING_NOT_EXISTS); |
| | | // } else { |
| | | // return R.ok(pricing.getPriceRule()); |
| | | // } |
| | | // } |
| | | // |
| | | // |
| | | // /** |
| | | // * 成功操作下发命令后调用 用于弹出redis队列的获取成功的数据 |
| | | // * |
| | | // * @param dto |
| | | // */ |
| | | // @Override |
| | | // @Transactional |
| | | // @ShardingSphereTransactionType(TransactionType.BASE) |
| | | // public void popOrder(PopOrderDto dto) { |
| | | // log.info("收到XPU消息响应后的业务处理 {}", dto.getOrderId()); |
| | | // String orderType = dto.getOrderType(); |
| | | // Long orderId = dto.getOrderId(); |
| | | // //巡游单处理逻辑 |
| | | // if (OrderType.CRUISE_ORDER.equals(orderType)) { |
| | | // XpCruiseOrder xpCruiseOrder = xpCruiseOrderMapper.selectById(orderId); |
| | | // if (xpCruiseOrder != null) { |
| | | // xpCruiseOrder.setStatus(1); |
| | | // xpCruiseOrder.setVehicleId(null); |
| | | // xpCruiseOrderMapper.updateById(xpCruiseOrder); |
| | | // log.info("修改巡游单状态,开始执行巡游单 {}", dto.getOrderId()); |
| | | // } |
| | | // } |
| | | // //乘客单处理逻辑 |
| | | // if (OrderType.USER_ORDER.equals(orderType)) { |
| | | // XpTestOrder order = this.getById(orderId); |
| | | // Long appUserId = order.getAppUserId(); |
| | | // //订单为待接单状态 |
| | | // if (order.getStatus() < 4) { |
| | | // AddTaxiPassengerVo addTaxiPassengerVo = new AddTaxiPassengerVo(); |
| | | // order.setAcceptanceTime(LocalDateTime.now()); |
| | | // R<XpVehicle> byVehicleVin = xpVehicleClient.findByVehicleVin(dto.getXpVehicleVin()); |
| | | // XpVehicle vehicle = null; |
| | | // if (byVehicleVin.getCode() == 200) { |
| | | // vehicle = byVehicleVin.getData(); |
| | | // order.setVehicleId(vehicle.getId()); |
| | | // order.setFleetId(vehicle.getFleetId()); |
| | | // addTaxiPassengerVo.setVin(vehicle.getVehicleVin()); |
| | | // } |
| | | // order.setStatus(2); |
| | | // |
| | | // // Redis弹出这个队列元素 |
| | | // // value 订单Id_经纬度_状态_用户id_订单编号_距离_时间 |
| | | // try { |
| | | // redisService.popFirstElement(order.getQueueName()); |
| | | // } catch (Exception e) { |
| | | // log.error("Redis弹出队列元素出错"); |
| | | // } |
| | | // // 存mongo数据 |
| | | // xpPricingClient.updateXpGeoQueryEntity(order.getId().toString()); |
| | | // // 修改车辆信息 |
| | | // XpVehicle vehicle1 = new XpVehicle(); |
| | | // vehicle1.setId(vehicle.getId()); |
| | | // vehicle1.setState(1); |
| | | // xpVehicleClient.updateVehicleById(vehicle1); |
| | | // |
| | | // //绑定用户和车辆关系 |
| | | // addTaxiPassengerVo.setUid(appUserId.toString()); |
| | | // order.setAppUserId(null); |
| | | // this.updateById(order); |
| | | // |
| | | // //构建推送消息 |
| | | // Map<String, Object> params = new HashMap<>(); |
| | | // Map<String, Object> content = new HashMap<>(); |
| | | // content.put("orderId", orderId.toString()); |
| | | // content.put("status", 2); |
| | | // params.put("type", PushMessageTypeEnum.ORDER_STATUS.getDesc()); |
| | | // params.put("content", JSONObject.toJSONString(content)); |
| | | // params.put("timestamp", System.currentTimeMillis() + ""); |
| | | // String message = JSONObject.toJSONString(params); |
| | | // SendMessageDTO dto1 = new SendMessageDTO(); |
| | | // dto1.setAppUserId(appUserId + ""); |
| | | // dto1.setMessage(message); |
| | | // R<String> stringR = xpPushMessageClient.sendStatus(dto1); |
| | | // |
| | | // //推送失败,重试3次 |
| | | // if(stringR.getCode() != Constants.SUCCESS){ |
| | | // ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>()); |
| | | // executor.execute(() -> { |
| | | // for (int i = 0; i < 3; i++) { |
| | | // R<String> stringR1 = xpPushMessageClient.sendStatus(dto1); |
| | | // if(stringR1.getCode() == Constants.SUCCESS){ |
| | | // break; |
| | | // } |
| | | // try { |
| | | // Thread.sleep(1000); |
| | | // } catch (InterruptedException e) { |
| | | // throw new RuntimeException(e); |
| | | // } |
| | | // log.info("推送订单状态消息失败:{} {} {}", stringR1.getMsg(), JSON.toJSONString(dto), order.getOrderNumber()); |
| | | // } |
| | | // }); |
| | | // } |
| | | // |
| | | // |
| | | // redisService.setCacheObject("ORDER_STATUS:" + order.getId(), 2, 24L, TimeUnit.HOURS); |
| | | // addTaxiPassengerVo.setOrderNo(order.getOrderNumber()); |
| | | // addTaxiPassengerVo.setAppId(appid); |
| | | // userVehicleClient.addTaxiPassenger(addTaxiPassengerVo); |
| | | // //推送乘客车辆到达预约点的导航数据 |
| | | // sendRoute(addTaxiPassengerVo.getUid(), orderId, "ORDER_NAVIGATION_START_DATA", dto.getXpVehicleVin()); |
| | | // } |
| | | // } |
| | | // } |
| | | // |
| | | // |
| | | // /** |
| | | // * 发送乘客导航路径数据 |
| | | // * |
| | | // * @param appUserId |
| | | // * @param keyStr |
| | | // */ |
| | | // public void sendRoute(String appUserId, Long orderId, String keyStr, String vin) { |
| | | // VehiclePosition vehiclePosition = mongoTemplate.findOne(new Query(Criteria.where("vin").is(vin)), VehiclePosition.class); |
| | | // Object cacheObject = redisService.getCacheObject(keyStr + ":" + appUserId); |
| | | // if (null != cacheObject) { |
| | | // RouteVo routeVo = JSON.parseObject(cacheObject.toString(), RouteVo.class); |
| | | // JSONObject jsonObject = new JSONObject(); |
| | | // jsonObject.put("type", "ORDER_ROUTE"); |
| | | // jsonObject.put("timestamp", System.currentTimeMillis()); |
| | | // JSONObject content = new JSONObject(); |
| | | // content.put("orderId", orderId.toString()); |
| | | // content.put("routeType", "ORDER_NAVIGATION_START_DATA".equals(keyStr) ? 1 : 2); |
| | | // content.put("direction", null != vehiclePosition ? vehiclePosition.getCourse() : 90); |
| | | // JSONObject route = new JSONObject(); |
| | | // route.put("distance", routeVo.getDistance()); |
| | | // route.put("duration", routeVo.getDuration()); |
| | | // route.put("routeID", routeVo.getRouteID()); |
| | | // |
| | | // List<JSONObject> collect = routeVo.getPolyline().stream().map(item -> { |
| | | // JSONObject point = new JSONObject(); |
| | | // point.put("latitude", item.getLatitude()); |
| | | // point.put("longitude", item.getLongitude()); |
| | | // return point; |
| | | // }).collect(Collectors.toList()); |
| | | // |
| | | // route.put("polyline", JSON.toJSONString(collect)); |
| | | // content.put("route", route.toJSONString()); |
| | | // jsonObject.put("content", content.toJSONString()); |
| | | // SendMessageDTO messageDTO = new SendMessageDTO(); |
| | | // messageDTO.setAppUserId(appUserId); |
| | | // messageDTO.setMessage(jsonObject.toJSONString()); |
| | | // R<String> stringR = xpPushMessageClient.sendRoute(messageDTO); |
| | | // XpTestOrder xpOrder = this.getById(orderId); |
| | | // //推送失败,重试3次 |
| | | // if(stringR.getCode() != Constants.SUCCESS){ |
| | | // ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>()); |
| | | // executor.execute(() -> { |
| | | // for (int i = 0; i < 3; i++) { |
| | | // R<String> stringR1 = xpPushMessageClient.sendStatus(messageDTO); |
| | | // if(stringR1.getCode() == Constants.SUCCESS){ |
| | | // break; |
| | | // } |
| | | // try { |
| | | // Thread.sleep(1000); |
| | | // } catch (InterruptedException e) { |
| | | // throw new RuntimeException(e); |
| | | // } |
| | | // log.info("推送乘客端导航数据消息失败:{} {} {}", stringR1.getMsg(), JSON.toJSONString(messageDTO), xpOrder.getOrderNumber()); |
| | | // } |
| | | // }); |
| | | // } |
| | | // } |
| | | // } |
| | | // |
| | | // |
| | | // /** |
| | | // * 获取当前用户正在执行的订单 |
| | | // * |
| | | // * @param uid |
| | | // * @return |
| | | // */ |
| | | // @Override |
| | | // public XpOrderDetailVO getActiveOrder(String uid) { |
| | | // XpOrderDetailVO xpOrderDetailVO = new XpOrderDetailVO(); |
| | | // XpTestOrder xpOrder = this.baseMapper.selectOne(new LambdaQueryWrapper<XpTestOrder>().eq(XpTestOrder::getAppUserId, Long.parseLong(uid)).in(XpTestOrder::getStatus, Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8)).orderByDesc(BaseModel::getCreateTime).last("LIMIT 1")); |
| | | // if (xpOrder == null) { |
| | | // return null; |
| | | // } |
| | | // BeanUtils.copyProperties(xpOrder, xpOrderDetailVO); |
| | | // |
| | | // R<XpPoint> xpPointR = xpPointClient.queryById(xpOrder.getStartPointId()); |
| | | // if (xpPointR.getCode() == R.SUCCESS) { |
| | | // XpPoint startPoint = xpPointR.getData(); |
| | | // xpOrderDetailVO.setStartParkingTimeLimit(startPoint.getParkingTimeLimit()); |
| | | // } |
| | | // |
| | | // R<XpPoint> xpPointR1 = xpPointClient.queryById(xpOrder.getEndPointId()); |
| | | // if (xpPointR1.getCode() == R.SUCCESS) { |
| | | // XpPoint endPoint = xpPointR1.getData(); |
| | | // xpOrderDetailVO.setEndParkingTimeLimit(endPoint.getParkingTimeLimit()); |
| | | // } |
| | | //// // 算时间 |
| | | //// if (xpOrder.getStatus() == 1) { |
| | | //// R<Integer> r = xpPricingClient.getWaitTime(new LonLatDto(xpOrder.getStartLon(), xpOrder.getStartLat())); |
| | | //// if (r.getCode() == R.SUCCESS) { |
| | | //// xpOrderDetailVO.setEstimatedTime(r.getData()); |
| | | //// } else { |
| | | //// throw new RuntimeException(r.getMsg()); |
| | | //// } |
| | | //// |
| | | //// } |
| | | // |
| | | // if (xpOrder.getVehicleId() != null) { |
| | | // R<XpVehicle> xpVehicleR = xpVehicleClient.queryById(xpOrder.getVehicleId()); |
| | | // XpVehicle vehicle = xpVehicleR.getData(); |
| | | // xpOrderDetailVO.setPlateNumber(vehicle.getPlateNumber()); |
| | | // xpOrderDetailVO.setVehiclePictures(vehicle.getVehiclePictures()); |
| | | // } |
| | | // Integer status = xpOrder.getStatus(); |
| | | // if(status == 4 || status == 7 || status == 8){ |
| | | // Boolean data = xpVehicleClient.getVehicleTrunkOpenStatus(xpOrder.getAppUserId(), xpOrder.getVehicleId()).getData(); |
| | | // xpOrder.setOpenTrunk(data ? 1 : 2); |
| | | // xpOrderDetailVO.setOpenTrunk(data ? 1 : 2); |
| | | // xpOrder.setAppUserId(null); |
| | | // this.updateById(xpOrder); |
| | | // } |
| | | // return xpOrderDetailVO; |
| | | // } |
| | | // |
| | | // @Override |
| | | // public void changeAmount(Long id, BigDecimal amount) { |
| | | // if (Objects.isNull(id)) { |
| | | // throw new ServiceException("订单ID不能为空", I18nKeyConstant.ORDER_CHANGE_AMOUNT_ID_REQUIRED); |
| | | // } |
| | | // if (Objects.isNull(amount)) { |
| | | // throw new ServiceException("订单金额不能为空", I18nKeyConstant.ORDER_CHANGE_AMOUNT_AMOUNT_REQUIRED); |
| | | // } |
| | | // if (amount.compareTo(BigDecimal.ZERO) < 0) { |
| | | // throw new ServiceException("订单金额不能小于0", I18nKeyConstant.ORDER_CHANGE_AMOUNT_AMOUNT_INVALID); |
| | | // } |
| | | // |
| | | // XpTestOrder order = this.getById(id); |
| | | // Long appUserId = order.getAppUserId(); |
| | | // |
| | | // if (Objects.isNull(order)) { |
| | | // throw new ServiceException("订单不存在", I18nKeyConstant.ORDER_NOT_EXISTS); |
| | | // } |
| | | // |
| | | // final Integer pendingPaymentStatus = 8; |
| | | // if (!Objects.equals(order.getStatus(), pendingPaymentStatus)) { |
| | | // throw new ServiceException("当前订单状态不允许改价,只有待付款状态的订单可以改价", I18nKeyConstant.ORDER_CHANGE_AMOUNT_STATUS_INVALID); |
| | | // } |
| | | // |
| | | // if (Objects.nonNull(order.getOrderMoney()) && order.getOrderMoney().compareTo(amount) == 0) { |
| | | // return; |
| | | // } |
| | | // |
| | | // boolean updated = this.lambdaUpdate() |
| | | // .set(XpTestOrder::getOrderMoney, amount) |
| | | // .set(XpTestOrder::getChangeMoneyFlag, Boolean.TRUE) |
| | | // .eq(XpTestOrder::getId, id) |
| | | // .eq(XpTestOrder::getStatus, pendingPaymentStatus) |
| | | // .update(); |
| | | // if (!updated) { |
| | | // throw new ServiceException("订单改价失败,请稍后重试", I18nKeyConstant.ORDER_CHANGE_AMOUNT_FAILED); |
| | | // } |
| | | // |
| | | // |
| | | // // 消息推送 |
| | | // Map<String, Object> params = new HashMap<>(); |
| | | // Map<String, Object> content = new HashMap<>(); |
| | | // content.put("orderId", order.getId().toString()); |
| | | // content.put("status", OrderStatusEnum.APPROVAL_REJECTION.getCode()); |
| | | // params.put("type", PushMessageTypeEnum.ORDER_UPDATE_PRICE.getDesc()); |
| | | // params.put("content", JSONObject.toJSONString(content)); |
| | | // params.put("timestamp", new Date().getTime() + ""); |
| | | // String message = JSONObject.toJSONString(params); |
| | | // SendMessageDTO sendMessageDTO = new SendMessageDTO(); |
| | | // sendMessageDTO.setMessage(message); |
| | | // sendMessageDTO.setAppUserId(String.valueOf(appUserId)); |
| | | // R<String> stringR = xpPushMessageClient.sendStatus(sendMessageDTO); |
| | | // //推送失败,重试3次 |
| | | // if(stringR.getCode() != Constants.SUCCESS){ |
| | | // ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>()); |
| | | // executor.execute(() -> { |
| | | // for (int i = 0; i < 3; i++) { |
| | | // R<String> stringR1 = xpPushMessageClient.sendStatus(sendMessageDTO); |
| | | // if(stringR1.getCode() == Constants.SUCCESS){ |
| | | // break; |
| | | // } |
| | | // try { |
| | | // Thread.sleep(1000); |
| | | // } catch (InterruptedException e) { |
| | | // throw new RuntimeException(e); |
| | | // } |
| | | // log.info("运维人员修改订单价格推送订单状态消息失败:{} {} {}", stringR1.getMsg(), JSON.toJSONString(sendMessageDTO), order.getOrderNumber()); |
| | | // } |
| | | // }); |
| | | // } |
| | | // log.info("订单修改价格推送消息完毕"); |
| | | // } |
| | | //} |
| | | package com.xiaopeng.order.service.impl; |
| | | |
| | | import cn.hutool.core.bean.BeanUtil; |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.json.JSONUtil; |
| | | import com.alibaba.fastjson2.JSON; |
| | | import com.alibaba.fastjson2.JSONArray; |
| | | import com.alibaba.fastjson2.JSONObject; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.google.common.collect.ImmutableMap; |
| | | import com.xiaopeng.api.dto.account.GetUserCouponDto; |
| | | import com.xiaopeng.api.dto.account.UcUserInfo; |
| | | import com.xiaopeng.api.dto.account.UseUserCouponDto; |
| | | import com.xiaopeng.api.dto.automaticPilot.PushOrderDto; |
| | | import com.xiaopeng.api.dto.map.RouteAndFareDto; |
| | | import com.xiaopeng.api.dto.operation.LonLatDto; |
| | | import com.xiaopeng.api.dto.order.GetOrderNumDto; |
| | | import com.xiaopeng.api.dto.order.HistoryEndPointsDto; |
| | | import com.xiaopeng.api.dto.order.HistoryStartPointsDto; |
| | | import com.xiaopeng.api.dto.order.PopOrderDto; |
| | | import com.xiaopeng.api.dto.pushMessage.SendMessageDTO; |
| | | import com.xiaopeng.api.dto.statistics.DailyCountDTO; |
| | | import com.xiaopeng.api.dto.statistics.OrderStatisticsDTO; |
| | | import com.xiaopeng.api.dto.statistics.StatisticsQueryDTO; |
| | | import com.xiaopeng.api.dto.vehicleConvoy.BaseVehicleUserDto; |
| | | import com.xiaopeng.api.feignClient.account.UserResourcesClient; |
| | | import com.xiaopeng.api.feignClient.account.XpAppUserCouponClient; |
| | | import com.xiaopeng.api.feignClient.automaticPilot.OrderMissionClient; |
| | | import com.xiaopeng.api.feignClient.maintenance.XpTaskRuleClient; |
| | | import com.xiaopeng.api.feignClient.map.XpMapClient; |
| | | import com.xiaopeng.api.feignClient.operation.*; |
| | | import com.xiaopeng.api.feignClient.pushMessage.XpPushMessageClient; |
| | | import com.xiaopeng.api.feignClient.vehicleConvoy.UserVehicleClient; |
| | | import com.xiaopeng.api.feignClient.vehicleConvoy.XpFleetClient; |
| | | import com.xiaopeng.api.feignClient.vehicleConvoy.XpFleetVehicleClient; |
| | | import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient; |
| | | import com.xiaopeng.api.model.maintenance.XpTaskRule; |
| | | import com.xiaopeng.api.model.operation.*; |
| | | import com.xiaopeng.api.model.order.*; |
| | | import com.xiaopeng.api.model.vehicleConvoy.XpFleet; |
| | | import com.xiaopeng.api.model.vehicleConvoy.XpVehicle; |
| | | import com.xiaopeng.api.vo.OrderType; |
| | | import com.xiaopeng.api.vo.SystemEventType; |
| | | import com.xiaopeng.api.vo.account.UserCouponVo; |
| | | import com.xiaopeng.api.vo.automaticPilot.VehiclePosition; |
| | | import com.xiaopeng.api.vo.operation.FareVo; |
| | | import com.xiaopeng.api.vo.operation.RouteAndFareVo; |
| | | import com.xiaopeng.api.vo.operation.RouteVo; |
| | | import com.xiaopeng.api.vo.order.*; |
| | | import com.xiaopeng.api.vo.vehicleConvoy.AddTaxiPassengerVo; |
| | | import com.xiaopeng.api.vo.vehicleConvoy.CancelTaxiPassengerVo; |
| | | import com.xiaopeng.common.core.constant.CacheConstants; |
| | | import com.xiaopeng.common.core.constant.Constants; |
| | | import com.xiaopeng.common.core.constant.HttpStatus; |
| | | import com.xiaopeng.common.core.domain.R; |
| | | import com.xiaopeng.common.core.enums.OrderStatusEnum; |
| | | import com.xiaopeng.common.core.enums.PushMessageTypeEnum; |
| | | import com.xiaopeng.common.core.exception.ServiceException; |
| | | import com.xiaopeng.common.core.utils.DateUtils; |
| | | import com.xiaopeng.common.core.utils.GeodesyUtil; |
| | | import com.xiaopeng.common.core.utils.StringUtils; |
| | | import com.xiaopeng.common.core.web.domain.BaseModel; |
| | | import com.xiaopeng.common.core.web.page.PageInfo; |
| | | import com.xiaopeng.common.redis.service.RedisService; |
| | | import com.xiaopeng.common.security.utils.SecurityUtils; |
| | | import com.xiaopeng.order.constant.I18nKeyConstant; |
| | | import com.xiaopeng.order.dto.MileageDto; |
| | | import com.xiaopeng.order.job.base.QuartzManager; |
| | | import com.xiaopeng.order.job.base.TimeJobType; |
| | | import com.xiaopeng.order.job.jobs.AddCruiseMissionJob; |
| | | import com.xiaopeng.order.job.jobs.EndTripJob; |
| | | import com.xiaopeng.order.job.jobs.OrderCancelJob; |
| | | import com.xiaopeng.order.mangodb.model.OrderTrajectory; |
| | | import com.xiaopeng.order.mangodb.service.OrderTrajectoryService; |
| | | import com.xiaopeng.order.mapper.*; |
| | | import com.xiaopeng.order.model.dto.XpOrderCommentDto; |
| | | import com.xiaopeng.order.model.dto.XpOrderPayDto; |
| | | import com.xiaopeng.order.model.query.XpHistoryOrderListQuery; |
| | | import com.xiaopeng.order.model.query.XpOrderExcelQuery; |
| | | import com.xiaopeng.order.model.query.XpOrderPageQuery; |
| | | import com.xiaopeng.order.model.query.XpTestOrderPageQuery; |
| | | import com.xiaopeng.order.model.vo.*; |
| | | import com.xiaopeng.order.service.*; |
| | | import com.xiaopeng.order.utils.GDMapGeocodingUtil; |
| | | import com.xiaopeng.order.utils.RegionCodeFilterUtil; |
| | | import com.xiaopeng.order.utils.TaxiPricingDemoService; |
| | | import com.xiaopeng.order.utils.XpPricingUtil; |
| | | import com.xiaopeng.order.utils.holiday.HolidayUtil; |
| | | import com.xiaopeng.order.vo.OrderDetailVo; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.shardingsphere.transaction.annotation.ShardingSphereTransactionType; |
| | | import org.apache.shardingsphere.transaction.core.TransactionType; |
| | | import org.springframework.beans.BeanUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.context.annotation.Lazy; |
| | | import org.springframework.data.domain.Sort; |
| | | import org.springframework.data.mongodb.core.MongoTemplate; |
| | | import org.springframework.data.mongodb.core.geo.GeoJsonPoint; |
| | | import org.springframework.data.mongodb.core.query.Criteria; |
| | | import org.springframework.data.mongodb.core.query.Query; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.util.CollectionUtils; |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.math.BigDecimal; |
| | | import java.math.RoundingMode; |
| | | import java.text.SimpleDateFormat; |
| | | import java.time.*; |
| | | import java.util.*; |
| | | import java.util.concurrent.CompletableFuture; |
| | | import java.util.concurrent.LinkedBlockingQueue; |
| | | import java.util.concurrent.ThreadPoolExecutor; |
| | | import java.util.concurrent.TimeUnit; |
| | | import java.util.function.Function; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * <p> |
| | | * 订单 服务实现类 |
| | | * </p> |
| | | * |
| | | * @author mitao |
| | | * @since 2026-02-03 |
| | | */ |
| | | @Slf4j |
| | | @Service |
| | | @RequiredArgsConstructor(onConstructor_ = @Lazy) |
| | | public class XpTestOrderServiceImpl extends ServiceImpl<XpTestOrderMapper, XpTestOrder> implements IXpTestOrderService { |
| | | |
| | | private final UserResourcesClient userResourcesClient; |
| | | private final XpTestPointClient xpTestPointClient; |
| | | private final XpVehicleClient xpVehicleClient; |
| | | private final XpAppUserCouponClient xpAppUserCouponClient; |
| | | private final XpFleetClient xpFleetClient; |
| | | private final XpFleetVehicleClient xpFleetVehicleClient; |
| | | private final UserVehicleClient userVehicleClient; |
| | | private final IXpOrderEvaluateService xpOrderEvaluateService; |
| | | private final IXpTestOrderCancelService xpTestOrderCancelService; |
| | | private final IXpOrderReassignService xpOrderReassignService; |
| | | private final RedisService redisService; |
| | | private final XpPricingClient xpPricingClient; |
| | | private final XpSystemSettingClient xpSystemSettingClient; |
| | | private final XpPushMessageClient xpPushMessageClient; |
| | | private final OrderMissionClient orderMissionClient; |
| | | private final XpTestOrderDetailMapper xpTestOrderDetailMapper; |
| | | private final XpCruiseOrderMapper xpCruiseOrderMapper; |
| | | private final XpTaskRuleClient xpTaskRuleClient; |
| | | private final XpCruisePlanClient xpCruisePlanClient; |
| | | private final XpPricingUtil xpPricingUtil; |
| | | private final GDMapGeocodingUtil gdMapGeocodingUtil; |
| | | private final XpOpenCityClient openCityClient; |
| | | private final XpMapClient xpMapClient; |
| | | private final XpRoutePlanClient xpRoutePlanClient; |
| | | private final XpTestPlanClient xpTestPlanClient; |
| | | private final HolidayUtil holidayUtil; |
| | | private final MongoTemplate mongoTemplate; |
| | | private final XpElectronicFenceClient xpElectronicFenceClient; |
| | | private final XpElectronicClient xpElectronicClient; |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | /** |
| | | * 添加测试单 |
| | | * @param query |
| | | */ |
| | | @Override |
| | | public void addTestOrder(AddTestOrderVo query) { |
| | | XpTestPlanPoint xpTestPlanPoint = xpTestPlanClient.getXpTestPlanPointById(query.getTestPlanPointId()).getData(); |
| | | Long startTestPointId = xpTestPlanPoint.getStartTestPointId(); |
| | | Long endTestPointId = xpTestPlanPoint.getEndTestPointId(); |
| | | XpTestPoint xpPoint = xpTestPlanClient.getXpTestPointById(startTestPointId).getData(); |
| | | XpTestPoint endXpPoint = xpTestPlanClient.getXpTestPointById(endTestPointId).getData(); |
| | | if(xpPoint ==null || xpPoint.getOperationStatus()!=2){ |
| | | throw new ServiceException("起站点已停止运营", 200,I18nKeyConstant.NO_CURRENT_POINT); |
| | | } |
| | | if(endXpPoint ==null || endXpPoint.getOperationStatus()!=2){ |
| | | throw new ServiceException("终站点已停止运营", 200,I18nKeyConstant.NO_CURRENT_POINT); |
| | | } |
| | | // 是否在运营区域时间内 |
| | | XpElectronicFenceArea xpElectronicFenceArea = xpElectronicClient.queryElectronicFenceAreaById(xpPoint.getElectronicAreaId()).getData(); |
| | | XpElectronicFence xpElectronicFence = xpElectronicFenceClient.selectById(xpElectronicFenceArea.getElectronicId().toString()).getData(); |
| | | String operationStrategy = xpElectronicFence.getOperationStrategy(); |
| | | Boolean inOperationTime = isInOperationTime(operationStrategy); |
| | | if (!inOperationTime && xpElectronicFence.getFailureType()!=1) { |
| | | throw new ServiceException("当前区域未开通服务", I18nKeyConstant.NO_CURRENT_REGION); |
| | | } |
| | | |
| | | // 判断点位是否在运营区域内 |
| | | boolean inTime = xpTestPointClient.nowInTimePoint(startTestPointId).getData(); |
| | | if (!inTime) { |
| | | throw new ServiceException("当前点位未开通服务", I18nKeyConstant.NO_CURRENT_REGION); |
| | | } |
| | | inTime = xpTestPointClient.nowInTimePoint(endTestPointId).getData(); |
| | | if (!inTime) { |
| | | throw new ServiceException("当前点位未开通服务", I18nKeyConstant.NO_CURRENT_REGION); |
| | | } |
| | | |
| | | Map<String, String> geocode = gdMapGeocodingUtil.geocode(xpPoint.getPointLon().toString(), xpPoint.getPointLat().toString()); |
| | | String districtCode = geocode.get("districtCode"); |
| | | String cityCode = geocode.get("cityCode"); |
| | | String provinceCode = geocode.get("provinceCode"); |
| | | XpOpenCity openCity = openCityClient.getXpOpenCity(provinceCode, cityCode, districtCode).getData(); |
| | | if (openCity == null) { |
| | | throw new ServiceException("当前区域未开通服务", I18nKeyConstant.NO_CURRENT_REGION); |
| | | } |
| | | XpPricing xpPricing = xpPricingClient.getPricingByCid(openCity.getId()).getData(); |
| | | if (xpPricing == null) { |
| | | throw new ServiceException("当前区域未开通服务", I18nKeyConstant.NO_CURRENT_REGION); |
| | | } |
| | | |
| | | // 算距离 |
| | | RouteAndFareDto routeAndFareDto = new RouteAndFareDto(); |
| | | LonLatDto lonLatDto = new LonLatDto(); |
| | | lonLatDto.setLongitude(xpPoint.getPointLon()); |
| | | lonLatDto.setLatitude(xpPoint.getPointLat()); |
| | | routeAndFareDto.setOrigin(lonLatDto); |
| | | LonLatDto lonLatDto1 = new LonLatDto(); |
| | | lonLatDto1.setLongitude(endXpPoint.getPointLon()); |
| | | lonLatDto1.setLatitude(endXpPoint.getPointLat()); |
| | | routeAndFareDto.setDestination(lonLatDto1); |
| | | routeAndFareDto.setOpenCityId(openCity.getId()); |
| | | XpRoutePlan xpRoutePlan = xpRoutePlanClient.getXpRoutePlanOpenCityId(openCity.getId()).getData(); |
| | | if(xpRoutePlan!=null&& !"null".equals(xpRoutePlan.getRoutePlanRule())){ |
| | | routeAndFareDto.setRoutePlanRule(Integer.valueOf(xpRoutePlan.getRoutePlanRule())); |
| | | } |
| | | // 调用地图 获取时间 |
| | | R<RouteVo> distanceAndDuration = xpMapClient.getDistanceAndDuration(routeAndFareDto); |
| | | if (distanceAndDuration.getCode() != 200) { |
| | | throw new ServiceException("获取导肮信息失败", I18nKeyConstant.PATH_NOT_FOUND); |
| | | } |
| | | RouteVo routeVo = distanceAndDuration.getData(); |
| | | |
| | | |
| | | // 生成订单数据 |
| | | XpTestOrder xpOrder = new XpTestOrder(); |
| | | xpOrder.setOrderType(query.getOrderType()); |
| | | xpOrder.setMileageKilometers(0.0); |
| | | xpOrder.setOrderNumber("XP" + System.currentTimeMillis()); |
| | | xpOrder.setCityId(openCity.getId()); |
| | | xpOrder.setStartLon(xpPoint.getPointLon()); |
| | | xpOrder.setStartLat(xpPoint.getPointLat()); |
| | | xpOrder.setBoardingLon(xpPoint.getPointLon()); |
| | | xpOrder.setBoardingLat(xpPoint.getPointLat()); |
| | | xpOrder.setBoardingAddress(xpPoint.getPointAddress()); |
| | | |
| | | xpOrder.setEndLon(endXpPoint.getPointLon()); |
| | | xpOrder.setEndLat(endXpPoint.getPointLat()); |
| | | |
| | | xpOrder.setStartAddress(xpPoint.getPointAddress()); |
| | | xpOrder.setEndAddress(endXpPoint.getPointAddress()); |
| | | |
| | | xpOrder.setXpElectronicFenceAreaId(xpPoint.getElectronicAreaId()); |
| | | xpOrder.setStartTestPointId(startTestPointId); |
| | | xpOrder.setEndTestPointId(endTestPointId); |
| | | xpOrder.setStartTestPointName(xpPoint.getPointName()); |
| | | xpOrder.setEndTestPointName(endXpPoint.getPointName()); |
| | | xpOrder.setStatus(1); |
| | | xpOrder.setOrderSource(1); |
| | | xpOrder.setOpenTrunk(2); |
| | | |
| | | // 当前时段 |
| | | String currentTimeSlot = DateUtils.getCurrentTimeSlot(); |
| | | xpOrder.setTimeSlot(currentTimeSlot); |
| | | xpOrder.setCreateTime(LocalDateTime.now()); |
| | | |
| | | xpOrder.setCityCode(openCity.getCityCode()); |
| | | List<XpTestPlanVehicle> data = xpTestPlanClient.getXpTestPlanVehicleByTestPlanId(query.getTestPlanId()).getData(); |
| | | for (XpTestPlanVehicle datum : data) { |
| | | XpVehicle xpVehicle = xpVehicleClient.queryById(datum.getVehicleId()).getData(); |
| | | xpOrder.setVehicleId(datum.getVehicleId()); |
| | | xpOrder.setFleetId(xpVehicle.getFleetId()); |
| | | this.save(xpOrder); |
| | | //缓存导航数据,用于下单后推送导航给车端和乘客端 |
| | | redisService.setCacheObject("TEST_ORDER_NAVIGATION_END_DATA:" + datum.getVehicleId(), JSON.toJSONString(routeVo), 24L, TimeUnit.HOURS); |
| | | //下发XPU消息 |
| | | PushOrderDto pushOrderDto = new PushOrderDto(); |
| | | pushOrderDto.setVin(xpVehicle.getVehicleVin()); |
| | | pushOrderDto.setOrderId("TEST" + xpOrder.getId()); |
| | | pushOrderDto.setStartLatitude(xpOrder.getStartLat()); |
| | | pushOrderDto.setStartLongitude(xpOrder.getStartLon()); |
| | | pushOrderDto.setEndLatitude(xpOrder.getEndLat()); |
| | | pushOrderDto.setEndLongitude(xpOrder.getEndLon()); |
| | | pushOrderDto.setOrderType(OrderType.USER_ORDER); |
| | | pushOrderDto.setStage(1); |
| | | // 调用推送服务 orderId + carVin |
| | | orderMissionClient.pushOrder(pushOrderDto); |
| | | JSONObject jsonObject = new JSONObject(); |
| | | jsonObject.put("event", SystemEventType.CREATE_ORDER); |
| | | jsonObject.put("orderType", OrderType.TEST_ORDER); |
| | | jsonObject.put("orderId", xpOrder.getId()); |
| | | jsonObject.put("vin", xpVehicle.getVehicleVin()); |
| | | redisService.setCacheObject("CREATE_ORDER:" + pushOrderDto.getOrderId(), jsonObject.toJSONString(),30L, TimeUnit.MINUTES); |
| | | log.info("开始推送 {} 订单到XPU。", xpOrder.getOrderNumber()); |
| | | |
| | | } |
| | | } |
| | | |
| | | private Boolean isInOperationTime(String operationStrategy) { |
| | | JSONArray jsonArray = JSONArray.parseArray(operationStrategy); |
| | | Integer holidayToday = holidayUtil.isHolidayToday(); |
| | | for (Object o : jsonArray) { |
| | | JSONObject jsonObject = JSONObject.parseObject(o.toString()); |
| | | String type = jsonObject.getString("type"); |
| | | if (type.equals(holidayToday.toString())) { |
| | | JSONArray time = jsonObject.getJSONArray("time"); |
| | | // 判断当前时间 是否在time时间段中 |
| | | for (Object object : time) { |
| | | String[] timeArray = object.toString().split("-"); |
| | | String startTime = timeArray[0]; |
| | | String endTime = timeArray[1]; |
| | | boolean currentTimeInRange = DateUtils.isCurrentTimeInRange(startTime, endTime); |
| | | if (currentTimeInRange) { |
| | | return true; |
| | | } |
| | | } |
| | | } else if (type.equals("3")) { |
| | | // 判断是什么类型 0每天 1-7 想起 |
| | | String typeStr = jsonObject.getString("typeStr"); |
| | | // 查看今天周几 |
| | | Integer week = DateUtils.getWeek(); |
| | | // 包含每天 或者 包含当天 |
| | | if (typeStr.contains("0") || typeStr.contains(week.toString())) { |
| | | JSONArray time = jsonObject.getJSONArray("time"); |
| | | // 判断当前时间 是否在time时间段中 |
| | | for (Object object : time) { |
| | | String[] timeArray = object.toString().split("-"); |
| | | String startTime = timeArray[0]; |
| | | String endTime = timeArray[1]; |
| | | boolean currentTimeInRange = DateUtils.isCurrentTimeInRange(startTime, endTime); |
| | | if (currentTimeInRange) { |
| | | return true; |
| | | } |
| | | } |
| | | } |
| | | |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | @Override |
| | | public PageInfo<XpTestOrderPageVO> pageList(XpTestOrderPageQuery query) { |
| | | // 0. 车牌号筛选:先查车辆服务获取车辆ID列表 |
| | | List<Long> vehicleIdsFilter = null; |
| | | if (StringUtils.isNotBlank(query.getPlateNumber())) { |
| | | R<List<XpVehicle>> vehicleResult = xpVehicleClient.listByPlateNumber(query.getPlateNumber()); |
| | | if (vehicleResult == null || CollectionUtils.isEmpty(vehicleResult.getData())) { |
| | | return buildEmptyOrderPage(query); |
| | | } |
| | | vehicleIdsFilter = vehicleResult.getData().stream() |
| | | .map(XpVehicle::getId) |
| | | .filter(Objects::nonNull) |
| | | .distinct() |
| | | .collect(Collectors.toList()); |
| | | if (CollectionUtils.isEmpty(vehicleIdsFilter)) { |
| | | return buildEmptyOrderPage(query); |
| | | } |
| | | } |
| | | // 1. 构建查询条件 |
| | | LambdaQueryWrapper<XpTestOrder> wrapper = buildQueryWrapper(query); |
| | | if (CollUtil.isNotEmpty(vehicleIdsFilter)) { |
| | | wrapper.in(XpTestOrder::getVehicleId, vehicleIdsFilter); |
| | | } |
| | | wrapper.orderByDesc(XpTestOrder::getCreateTime); |
| | | |
| | | // 2. 分页查询 |
| | | Page<XpTestOrder> page = new Page<>(query.getPageNum(), query.getPageSize()); |
| | | Page<XpTestOrder> pageResult = this.page(page, wrapper); |
| | | |
| | | if (CollectionUtils.isEmpty(pageResult.getRecords())) { |
| | | return buildEmptyOrderPage(query); |
| | | } |
| | | |
| | | // 3. 收集关联ID |
| | | Set<Long> vehicleIds = new HashSet<>(); |
| | | Set<Long> fleetIds = new HashSet<>(); |
| | | for (XpTestOrder order : pageResult.getRecords()) { |
| | | if (Objects.nonNull(order.getVehicleId())) { |
| | | vehicleIds.add(order.getVehicleId()); |
| | | } |
| | | if (Objects.nonNull(order.getFleetId())) { |
| | | fleetIds.add(order.getFleetId()); |
| | | } |
| | | } |
| | | |
| | | // 4. 批量查询关联数据 |
| | | Map<Long, XpVehicle> vehicleMap = batchGetVehicles(vehicleIds); |
| | | Map<Long, XpFleet> fleetMap = batchGetFleets(fleetIds); |
| | | |
| | | // 5. 组装 VO |
| | | List<XpTestOrderPageVO> voList = pageResult.getRecords().stream() |
| | | .map(order -> convertToPageVO(order, vehicleMap, fleetMap)) |
| | | .collect(Collectors.toList()); |
| | | |
| | | // 6. 返回分页结果 |
| | | PageInfo<XpTestOrderPageVO> resultPage = new PageInfo<>(query.getPageNum(), query.getPageSize()); |
| | | resultPage.setTotal(pageResult.getTotal()); |
| | | resultPage.setRecords(voList); |
| | | return resultPage; |
| | | } |
| | | |
| | | private PageInfo<XpTestOrderPageVO> buildEmptyOrderPage(XpTestOrderPageQuery query) { |
| | | PageInfo<XpTestOrderPageVO> resultPage = new PageInfo<>(query.getPageNum(), query.getPageSize()); |
| | | resultPage.setTotal(0L); |
| | | resultPage.setRecords(new ArrayList<>()); |
| | | return resultPage; |
| | | } |
| | | |
| | | @Override |
| | | public XpTestOrderDetailVO getOrderDetail(Long id) { |
| | | // 1. 查询订单基础信息 |
| | | XpTestOrder order = this.getById(id); |
| | | if (order == null) { |
| | | throw new ServiceException("订单不存在"); |
| | | } |
| | | |
| | | // 2. 转换为详情 VO |
| | | XpTestOrderDetailVO vo = BeanUtil.toBean(order, XpTestOrderDetailVO.class); |
| | | |
| | | // 4. 获取车辆信息 |
| | | if (Objects.nonNull(order.getVehicleId())) { |
| | | Map<Long, XpVehicle> vehicleMap = batchGetVehicles(Collections.singleton(order.getVehicleId())); |
| | | XpVehicle vehicle = vehicleMap.get(order.getVehicleId()); |
| | | if (Objects.nonNull(vehicle)) { |
| | | vo.setPlateNumber(vehicle.getPlateNumber()); |
| | | vo.setVehicleModel(vehicle.getVehicleModel()); |
| | | } |
| | | } |
| | | |
| | | // 5. 获取车队信息 |
| | | if (Objects.nonNull(order.getFleetId())) { |
| | | Map<Long, XpFleet> fleetMap = batchGetFleets(Collections.singleton(order.getFleetId())); |
| | | XpFleet fleet = fleetMap.get(order.getFleetId()); |
| | | if (Objects.nonNull(fleet)) { |
| | | vo.setFleetName(fleet.getFleetName()); |
| | | } |
| | | } |
| | | |
| | | // 6. 获取评价信息 |
| | | LambdaQueryWrapper<XpOrderEvaluate> evaluateWrapper = new LambdaQueryWrapper<>(); |
| | | evaluateWrapper.eq(XpOrderEvaluate::getOrderId, id); |
| | | XpOrderEvaluate evaluate = xpOrderEvaluateService.getOne(evaluateWrapper.orderByDesc(XpOrderEvaluate::getCreateTime).last(" limit 0,1")); |
| | | if (Objects.nonNull(evaluate)) { |
| | | vo.setOrderRating(evaluate.getOrderRating()); |
| | | } |
| | | // 7. 查询mongodb 该订单上传的经纬度轨迹信息(按订单id) |
| | | List<OrderTrajectory> trajectories = queryOrderTrajectories(id); |
| | | vo.setOrderPositionList(convertTrajectoriesToPositions(trajectories)); |
| | | |
| | | // 8. 起步价、里程费、时长费、远途费:按订单费用明细聚合 |
| | | Map<Integer, BigDecimal> feeMap = sumOrderDetailMoneyByDetailType(id); |
| | | vo.setStartMoney(feeMap.getOrDefault(1, BigDecimal.ZERO)); |
| | | vo.setMileageMoney(feeMap.getOrDefault(2, BigDecimal.ZERO)); |
| | | vo.setDurationMoney(feeMap.getOrDefault(3, BigDecimal.ZERO)); |
| | | vo.setLongDistancemoney(feeMap.getOrDefault(4, BigDecimal.ZERO)); |
| | | return vo; |
| | | } |
| | | |
| | | @Override |
| | | public void deleteOrder(Long id) { |
| | | // 1. 校验订单是否存在 |
| | | XpTestOrder order = this.getById(id); |
| | | if (Objects.isNull(order)) { |
| | | throw new ServiceException("订单不存在", I18nKeyConstant.ORDER_NOT_EXISTS); |
| | | } |
| | | |
| | | this.removeById(id); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 构建查询条件 |
| | | */ |
| | | private LambdaQueryWrapper<XpTestOrder> buildQueryWrapper(XpTestOrderPageQuery query) { |
| | | LambdaQueryWrapper<XpTestOrder> wrapper = new LambdaQueryWrapper<>(); |
| | | |
| | | wrapper.like(StringUtils.isNotBlank(query.getOrderNumber()), XpTestOrder::getOrderNumber, query.getOrderNumber()) |
| | | .eq(Objects.nonNull(query.getStatus()), XpTestOrder::getStatus, query.getStatus()); |
| | | if (Objects.nonNull(query.getStartTime())) { |
| | | wrapper.ge(XpTestOrder::getCreateTime, LocalDateTime.of(query.getStartTime(), LocalTime.MIN)); |
| | | } |
| | | if (Objects.nonNull(query.getEndTime())) { |
| | | wrapper.le(XpTestOrder::getCreateTime, LocalDateTime.of(query.getEndTime(), LocalTime.MAX)); |
| | | } |
| | | wrapper.orderByDesc(XpTestOrder::getCreateTime); |
| | | return wrapper; |
| | | } |
| | | |
| | | /** |
| | | * 批量获取车辆信息 |
| | | */ |
| | | private Map<Long, XpVehicle> batchGetVehicles(Set<Long> vehicleIds) { |
| | | if (CollectionUtils.isEmpty(vehicleIds)) { |
| | | return new HashMap<>(); |
| | | } |
| | | try { |
| | | R<List<XpVehicle>> result = xpVehicleClient.listByIds(new ArrayList<>(vehicleIds)); |
| | | if (Objects.nonNull(result) && Objects.nonNull(result.getData())) { |
| | | return result.getData().stream() |
| | | .collect(Collectors.toMap(XpVehicle::getId, Function.identity(), (a, b) -> a)); |
| | | } |
| | | } catch (Exception e) { |
| | | log.error("批量获取车辆信息失败: {}", e.getMessage()); |
| | | } |
| | | return new HashMap<>(); |
| | | } |
| | | |
| | | /** |
| | | * 批量获取车队信息 |
| | | */ |
| | | private Map<Long, XpFleet> batchGetFleets(Set<Long> fleetIds) { |
| | | if (CollectionUtils.isEmpty(fleetIds)) { |
| | | return new HashMap<>(); |
| | | } |
| | | try { |
| | | R<List<XpFleet>> result = xpFleetClient.listByIds(new ArrayList<>(fleetIds)); |
| | | if (Objects.nonNull(result) && Objects.nonNull(result.getData())) { |
| | | return result.getData().stream() |
| | | .collect(Collectors.toMap(XpFleet::getId, Function.identity(), (a, b) -> a)); |
| | | } |
| | | } catch (Exception e) { |
| | | log.error("批量获取车队信息失败: {}", e.getMessage()); |
| | | } |
| | | return new HashMap<>(); |
| | | } |
| | | |
| | | |
| | | @Override |
| | | @Transactional |
| | | @ShardingSphereTransactionType(TransactionType.BASE) |
| | | public void cancelOrCloseOrder(Long orderId, Integer type) { |
| | | // 1. 校验订单是否存在 |
| | | XpTestOrder order = this.getById(orderId); |
| | | if (Objects.isNull(order)) { |
| | | throw new ServiceException("订单不存在"); |
| | | } |
| | | |
| | | // 2. 校验操作类型 |
| | | if (type != 1 && type != 2) { |
| | | throw new ServiceException("操作类型错误,type只能为1或2"); |
| | | } |
| | | |
| | | // 3. 校验订单状态是否允许操作 |
| | | Integer currentStatus = order.getStatus(); |
| | | //取消订单:在未接到乘客前都可以,关闭订单,在送达目的地可以操作关闭 |
| | | if (type == 1) { |
| | | // 取消订单:只有待接单(1)、待出发(2)、接驾中(3)状态可以取消 |
| | | if (currentStatus != 1 && currentStatus != 2 && currentStatus != 3 && currentStatus != 4) { |
| | | throw new ServiceException("当前订单状态不允许取消,只有待接单、待出发、接驾中状态的订单可以取消", I18nKeyConstant.ORDER_CANCEL_FAILED); |
| | | } |
| | | } else { |
| | | // 关闭订单:0=已取消,1=待接单,2=待出发,3=接驾中,4=待客上车,5=乘客已上车,6=服务中 状态可以关闭 |
| | | if (currentStatus == 7 || currentStatus == 8 || currentStatus == 9 || currentStatus == 10) { |
| | | throw new ServiceException("当前订单状态不允许关闭", I18nKeyConstant.ORDER_CLOSE_FAILED); |
| | | } |
| | | } |
| | | |
| | | // 4. 执行操作 |
| | | if (type == 1) { |
| | | // 取消订单 |
| | | cancelOrder(order); |
| | | } else { |
| | | // 关闭订单 |
| | | closeOrder(order); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 转换为分页列表 VO |
| | | */ |
| | | private XpTestOrderPageVO convertToPageVO(XpTestOrder order, |
| | | Map<Long, XpVehicle> vehicleMap, |
| | | Map<Long, XpFleet> fleetMap) { |
| | | XpTestOrderPageVO vo = new XpTestOrderPageVO(); |
| | | vo.setId(order.getId()); |
| | | vo.setOrderNumber(order.getOrderNumber()); |
| | | vo.setCreateTime(order.getCreateTime()); |
| | | vo.setOrderSource(order.getOrderSource()); |
| | | vo.setStartAddress(order.getStartAddress()); |
| | | vo.setEndAddress(order.getEndAddress()); |
| | | vo.setStatus(order.getStatus()); |
| | | |
| | | // 车辆信息 |
| | | if (Objects.nonNull(order.getVehicleId()) && vehicleMap.containsKey(order.getVehicleId())) { |
| | | XpVehicle vehicle = vehicleMap.get(order.getVehicleId()); |
| | | vo.setPlateNumber(vehicle.getPlateNumber()); |
| | | } |
| | | |
| | | // 车队信息 |
| | | if (Objects.nonNull(order.getFleetId()) && fleetMap.containsKey(order.getFleetId())) { |
| | | XpFleet fleet = fleetMap.get(order.getFleetId()); |
| | | vo.setFleetName(fleet.getFleetName()); |
| | | } |
| | | |
| | | return vo; |
| | | } |
| | | |
| | | /** |
| | | * 取消订单 |
| | | */ |
| | | private void cancelOrder(XpTestOrder order) { |
| | | redisService.removeByPattern(order.getQueueName(), order.getOrderNumber()); |
| | | //判断还原车辆状态 |
| | | if (null == order.getVehicleId()) { |
| | | Object cacheObject1 = redisService.getCacheObject("CREATE_ORDER:" + order.getId().toString()); |
| | | if (null != cacheObject1) { |
| | | JSONObject jsonObject = JSON.parseObject(cacheObject1.toString()); |
| | | String vin = jsonObject.getString("vin"); |
| | | XpVehicle vehicle = xpVehicleClient.findByVehicleVin(vin).getData(); |
| | | if (null != vehicle && 0 != vehicle.getState()) { |
| | | XpVehicle vehicle1 = new XpVehicle(); |
| | | vehicle1.setId(vehicle.getId()); |
| | | vehicle1.setState(0); |
| | | xpVehicleClient.updateVehicleById(vehicle1); |
| | | } |
| | | } |
| | | } |
| | | // 1. 更新订单状态为已取消(0) |
| | | lambdaUpdate().set(XpTestOrder::getStatus, 0) |
| | | .eq(XpTestOrder::getId, order.getId()).update(); |
| | | |
| | | // 2. 保存取消记录 |
| | | XpTestOrderCancel orderCancel = new XpTestOrderCancel(); |
| | | orderCancel.setOrderId(order.getId()); |
| | | orderCancel.setCancelSource(3); // 3=运营人员(后台管理接口固定为运营人员) |
| | | orderCancel.setUserId(SecurityUtils.getUserId()); // 当前登录用户ID |
| | | orderCancel.setCancelReason("运营人员取消订单"); |
| | | xpTestOrderCancelService.save(orderCancel); |
| | | |
| | | //查询车辆信息 |
| | | R<XpVehicle> xpVehicleR = xpVehicleClient.queryById(order.getVehicleId()); |
| | | if (xpVehicleR.getCode() == HttpStatus.SUCCESS && Objects.nonNull(xpVehicleR.getData())) { |
| | | XpVehicle xpVehicle = xpVehicleR.getData(); |
| | | //还原车辆状态 |
| | | if(1 == xpVehicle.getState()){ |
| | | XpVehicle vehicle1 = new XpVehicle(); |
| | | vehicle1.setId(xpVehicle.getId()); |
| | | vehicle1.setState(0); |
| | | xpVehicleClient.updateVehicleById(vehicle1); |
| | | } |
| | | |
| | | // 下发命令 |
| | | PushOrderDto pushOrderDto = new PushOrderDto(); |
| | | pushOrderDto.setOrderId(order.getId().toString()); |
| | | pushOrderDto.setVin(xpVehicle.getVehicleVin()); |
| | | pushOrderDto.setOperation_type(OrderOperationType.CLOUD_CANCEL_ORDER); |
| | | orderMissionClient.cancelOrder(pushOrderDto); |
| | | log.info("运营人员取消订单成功,开始执行巡游订单 {}", order.getId()); |
| | | //车辆继续巡游 |
| | | addCruiseMission(xpVehicle.getId()); |
| | | |
| | | } else { |
| | | log.info("查询车辆信息失败,订单ID: {}, 下发取消订单命令失败", order.getId()); |
| | | } |
| | | log.info("订单取消成功,订单ID: {}, 操作人: {}", order.getId(), SecurityUtils.getUsername()); |
| | | } |
| | | |
| | | /** |
| | | * 关闭订单 |
| | | */ |
| | | private void closeOrder(XpTestOrder order) { |
| | | XpVehicle xpVehicle = xpVehicleClient.queryById(order.getVehicleId()).getData(); |
| | | order.setStatus(7); |
| | | order.setGetoffTime(LocalDateTime.now()); |
| | | // 解析下车地点 |
| | | VehiclePosition vehiclePosition = mongoTemplate.findOne(new Query(Criteria.where("vin").is(xpVehicle.getVehicleVin())), VehiclePosition.class); |
| | | if(Objects.nonNull(vehiclePosition)){ |
| | | GeoJsonPoint point = vehiclePosition.getPoint(); |
| | | if(Objects.nonNull(point)){ |
| | | double x = point.getX(); |
| | | double y = point.getY(); |
| | | Map<String, String> geocode = gdMapGeocodingUtil.geocode(String.valueOf(x), String.valueOf(y)); |
| | | order.setGetoffAddress(geocode.get("address")); |
| | | } |
| | | } |
| | | //计算行驶总距离和时长 |
| | | List<OrderTrajectory> orderTrajectoryList = mongoTemplate.find(new Query().addCriteria(Criteria.where("orderId").is(order.getId())), OrderTrajectory.class); |
| | | Double reduce = orderTrajectoryList.stream().map(OrderTrajectory::getDistance).reduce(0.0, Double::sum); |
| | | order.setMileageKilometers(new BigDecimal(reduce).divide(new BigDecimal(1000)).setScale(4, RoundingMode.HALF_EVEN).doubleValue()); |
| | | long duration = LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8")) - order.getTripBegin().toEpochSecond(ZoneOffset.of("+8")); |
| | | order.setDuration(new BigDecimal(duration).divide(new BigDecimal(60), 2, RoundingMode.HALF_EVEN).doubleValue()); |
| | | order.setVehicleId(null); |
| | | this.updateById(order); |
| | | |
| | | |
| | | //给XPU推送订单取消的报文 |
| | | PushOrderDto pushOrderDto = new PushOrderDto(); |
| | | pushOrderDto.setOrderId(order.getId().toString()); |
| | | pushOrderDto.setVin(xpVehicle.getVehicleVin()); |
| | | pushOrderDto.setOperation_type(OrderOperationType.CLOUD_CANCEL_ORDER); |
| | | orderMissionClient.cancelOrder(pushOrderDto); |
| | | |
| | | //结束行程,修改状态和计算费用 |
| | | endTrip(order.getId()); |
| | | |
| | | //创建定时任务执行延迟驶离终点和下发巡游单 |
| | | XpTestPoint point = xpTestPointClient.queryById(order.getEndTestPointId()).getData(); |
| | | Map<String, ? extends Object> jobMaps = |
| | | new ImmutableMap.Builder<String, String>() |
| | | .put("id", order.getId().toString()) |
| | | .put("appid", appid) |
| | | .build(); |
| | | QuartzManager.addJob( |
| | | AddCruiseMissionJob.class, |
| | | (AddCruiseMissionJob.name + order.getId()).toUpperCase(), |
| | | TimeJobType.ADD_CRUISE_MISSION, |
| | | DateUtils.localDateTimeToDate(LocalDateTime.now().plusMinutes(point.getParkingTimeLimit())), |
| | | jobMaps |
| | | ); |
| | | } |
| | | |
| | | /** |
| | | * 改派订单 |
| | | */ |
| | | @Override |
| | | @Transactional |
| | | @ShardingSphereTransactionType(TransactionType.BASE) |
| | | public void reassignOrder(Long orderId, Long newVehicleId, String reassignReason) { |
| | | // 1. 校验订单是否存在 |
| | | XpTestOrder order = this.getById(orderId); |
| | | if (Objects.isNull(order)) { |
| | | throw new ServiceException("订单不存在"); |
| | | } |
| | | |
| | | // 2. 校验订单状态(只有待出发、接驾中、待乘客上车状态可以改派) |
| | | Integer currentStatus = order.getStatus(); |
| | | if (currentStatus != 2 && currentStatus != 3 && currentStatus != 4) { |
| | | throw new ServiceException("当前订单状态不允许改派,只有待出发、接驾中、待乘客上车状态的订单可以改派", I18nKeyConstant.ORDER_REASSIGN_FAILED); |
| | | } |
| | | |
| | | // 3. 校验新旧车辆是否相同 |
| | | if (Objects.equals(order.getVehicleId(), newVehicleId)) { |
| | | throw new ServiceException("新车辆与原车辆相同,无需改派", I18nKeyConstant.ORDER_REASSIGN_VEHICLE_FAILED); |
| | | } |
| | | |
| | | // 4. 查询新车辆信息并校验 |
| | | R<List<XpVehicle>> vehicleResult = xpVehicleClient.listByIds(Collections.singletonList(newVehicleId)); |
| | | if (Objects.isNull(vehicleResult) || Objects.isNull(vehicleResult.getData()) || vehicleResult.getData().isEmpty()) { |
| | | throw new ServiceException("新车辆不存在", I18nKeyConstant.ORDER_REASSIGN_NEW_VEHICLE_NOT_EXISTS); |
| | | } |
| | | XpVehicle newVehicle = vehicleResult.getData().get(0); |
| | | |
| | | // 5. 校验新车辆的运营状态 |
| | | // 车辆状态:1=待完善 2=待运营 3=保险/年检过期 |
| | | // 运营状态:1=运营中 2=维修中 3=已收车 4=车辆异常 |
| | | // 当前模式:1=接单 2=测试 |
| | | // 模式状态:1=开始接单/开始测试 2=停止接单/停止测试 |
| | | if (Objects.isNull(newVehicle.getStatus()) || newVehicle.getStatus() == 3) { |
| | | throw new ServiceException("新车辆保险或年检已过期,无法接单", I18nKeyConstant.ORDER_REASSIGN_NEW_VEHICLE_STATUS_INVALID); |
| | | } |
| | | if (Objects.isNull(newVehicle.getOperatingStatus()) || newVehicle.getOperatingStatus() != 1) { |
| | | throw new ServiceException("新车辆运营状态异常,无法接单", I18nKeyConstant.ORDER_REASSIGN_NEW_VEHICLE_OPERATING_STATUS_INVALID); |
| | | } |
| | | if (Objects.isNull(newVehicle.getAcceptOrTest()) || newVehicle.getAcceptOrTest() != 1) { |
| | | throw new ServiceException("新车辆当前不在接单模式", I18nKeyConstant.ORDER_REASSIGN_NEW_VEHICLE_NOT_IN_ACCEPT_MODE); |
| | | } |
| | | if (Objects.isNull(newVehicle.getAcceptOrTestStatus()) || newVehicle.getAcceptOrTestStatus() != 1) { |
| | | throw new ServiceException("新车辆未开始接单", I18nKeyConstant.ORDER_REASSIGN_NEW_VEHICLE_NOT_START_ACCEPT); |
| | | } |
| | | if (Objects.isNull(newVehicle.getState()) || newVehicle.getState() != 0) { |
| | | throw new ServiceException("新车辆已接单,请重新选择", I18nKeyConstant.ORDER_REASSIGN_NEW_VEHICLE_NOT_FREE); |
| | | } |
| | | |
| | | // 6. 保存原车辆和车队信息 |
| | | Long oldVehicleId = order.getVehicleId(); |
| | | Long oldFleetId = order.getFleetId(); |
| | | |
| | | // 6.1 处理原车辆:取消订单指令、解绑乘客、更新状态、创建返程巡游订单 |
| | | if (Objects.nonNull(oldVehicleId)) { |
| | | try { |
| | | R<XpVehicle> oldVehicleResult = xpVehicleClient.queryById(oldVehicleId); |
| | | if (oldVehicleResult != null && oldVehicleResult.getCode() == HttpStatus.SUCCESS && oldVehicleResult.getData() != null) { |
| | | XpVehicle oldVehicle = oldVehicleResult.getData(); |
| | | |
| | | // 6.1.1 取消原订单指令 |
| | | PushOrderDto cancelDto = new PushOrderDto(); |
| | | cancelDto.setOrderId(order.getId().toString()); |
| | | cancelDto.setVin(oldVehicle.getVehicleVin()); |
| | | cancelDto.setOperation_type(OrderOperationType.CLOUD_CANCEL_ORDER); |
| | | orderMissionClient.cancelOrder(cancelDto); |
| | | log.info("已取消原车辆订单指令,订单ID: {}, VIN: {}", orderId, oldVehicle.getVehicleVin()); |
| | | |
| | | // 6.1.3 修改原车辆状态为空闲 |
| | | XpVehicle vehicle1 = new XpVehicle(); |
| | | vehicle1.setId(oldVehicle.getId()); |
| | | vehicle1.setState(0); |
| | | xpVehicleClient.updateVehicleById(vehicle1); |
| | | log.info("已将原车辆状态设为空闲,车辆ID: {}", oldVehicleId); |
| | | |
| | | } else { |
| | | log.warn("查询原车辆信息失败,车辆ID: {}", oldVehicleId); |
| | | } |
| | | } catch (Exception e) { |
| | | log.error("处理原车辆失败,车辆ID: {},错误: {}", oldVehicleId, e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | // 7. 查询新车辆关联的车队ID |
| | | Long newFleetId = null; |
| | | try { |
| | | R<Long> fleetIdResult = xpFleetVehicleClient.getFleetIdByVehicleId(newVehicleId); |
| | | if (Objects.nonNull(fleetIdResult) && Objects.nonNull(fleetIdResult.getData())) { |
| | | newFleetId = fleetIdResult.getData(); |
| | | log.info("查询到新车辆ID: {} 关联的车队ID: {}", newVehicleId, newFleetId); |
| | | } else { |
| | | log.warn("新车辆ID: {} 未关联任何车队,将使用原车队ID: {}", newVehicleId, oldFleetId); |
| | | newFleetId = oldFleetId; |
| | | } |
| | | } catch (Exception e) { |
| | | log.error("查询新车辆关联的车队ID失败,车辆ID: {},错误: {}", newVehicleId, e.getMessage()); |
| | | newFleetId = oldFleetId; |
| | | } |
| | | |
| | | // 8. 如果旧订单的车队ID为空,尝试查询旧车辆的车队ID |
| | | if (Objects.isNull(oldFleetId) && Objects.nonNull(oldVehicleId)) { |
| | | try { |
| | | R<Long> oldFleetIdResult = xpFleetVehicleClient.getFleetIdByVehicleId(oldVehicleId); |
| | | if (Objects.nonNull(oldFleetIdResult) && Objects.nonNull(oldFleetIdResult.getData())) { |
| | | oldFleetId = oldFleetIdResult.getData(); |
| | | log.info("补充查询到旧车辆ID: {} 关联的车队ID: {}", oldVehicleId, oldFleetId); |
| | | } |
| | | } catch (Exception e) { |
| | | log.warn("查询旧车辆关联的车队ID失败,车辆ID: {},错误: {}", oldVehicleId, e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | // 9. 更新订单的车辆和车队信息 |
| | | order.setVehicleId(newVehicleId); |
| | | if (Objects.nonNull(newFleetId)) { |
| | | order.setFleetId(newFleetId); |
| | | } |
| | | this.updateById(order); |
| | | |
| | | // 10. 保存改派记录 |
| | | XpOrderReassign orderReassign = new XpOrderReassign(); |
| | | orderReassign.setOrderId(orderId); |
| | | orderReassign.setUserId(SecurityUtils.getUserId()); |
| | | orderReassign.setOperationTime(LocalDateTime.now()); |
| | | orderReassign.setOldVehicleId(oldVehicleId); |
| | | orderReassign.setNewVehicleId(newVehicleId); |
| | | orderReassign.setOldFleetId(oldFleetId); |
| | | orderReassign.setNewFleetId(newFleetId); |
| | | orderReassign.setReassignReason( |
| | | StringUtils.isNotBlank(reassignReason) ? reassignReason : "运营人员改派订单" |
| | | ); |
| | | orderReassign.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName()); |
| | | xpOrderReassignService.save(orderReassign); |
| | | |
| | | log.info("订单改派成功,订单ID: {}, 原车辆ID: {}, 新车辆ID: {}, 原车队ID: {}, 新车队ID: {}, 操作人: {}", |
| | | orderId, oldVehicleId, newVehicleId, oldFleetId, newFleetId, SecurityUtils.getUsername()); |
| | | |
| | | // 11. 处理新车辆:绑定乘客、下发订单、更新状态 |
| | | try { |
| | | // 11.2 下发订单到新车辆 |
| | | PushOrderDto pushOrderDto = new PushOrderDto(); |
| | | pushOrderDto.setVin(newVehicle.getVehicleVin()); |
| | | pushOrderDto.setOrderId(order.getId().toString()); |
| | | pushOrderDto.setStartLatitude(order.getStartLat()); |
| | | pushOrderDto.setStartLongitude(order.getStartLon()); |
| | | pushOrderDto.setEndLatitude(order.getEndLat()); |
| | | pushOrderDto.setEndLongitude(order.getEndLon()); |
| | | pushOrderDto.setOrderType(OrderType.USER_ORDER); |
| | | pushOrderDto.setStage(1); |
| | | // 调用推送服务 orderId + carVin |
| | | orderMissionClient.pushOrder(pushOrderDto); |
| | | |
| | | log.info("已下发订单到新车辆,订单ID: {}, VIN: {}", orderId, newVehicle.getVehicleVin()); |
| | | |
| | | // 11.3 更新新车辆状态为已接单 |
| | | XpVehicle vehicle1 = new XpVehicle(); |
| | | vehicle1.setId(newVehicle.getId()); |
| | | vehicle1.setState(1); |
| | | xpVehicleClient.updateVehicleById(vehicle1); |
| | | log.info("已将新车辆状态设为已接单,车辆ID: {}", newVehicleId); |
| | | |
| | | } catch (Exception e) { |
| | | log.error("处理新车辆失败,车辆ID: {},错误: {}", newVehicleId, e.getMessage()); |
| | | } |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | @Override |
| | | public R<String> updateOrderStatus(Long orderId, Integer status) { |
| | | XpTestOrder xpOrder = this.getById(orderId); |
| | | if (Objects.isNull(xpOrder)) { |
| | | return R.fail("订单不存在"); |
| | | } |
| | | if (xpOrder.getStatus() == 0) { |
| | | return R.fail("订单已取消"); |
| | | } |
| | | if(xpOrder.getStatus() >= 8){ |
| | | return R.fail("订单已结束"); |
| | | } |
| | | // 查询车辆 |
| | | XpVehicle xpVehicle = xpVehicleClient.queryById(xpOrder.getVehicleId()).getData(); |
| | | if(xpOrder.getOrderType() == 1){ |
| | | switch (status) { |
| | | case 4: |
| | | // 查询起点点位 |
| | | Long startPointId = xpOrder.getStartTestPointId(); |
| | | XpTestPoint xpPoint = xpTestPointClient.queryById(startPointId).getData(); |
| | | // 添加取消订单定时任务job 时间为点位限停时长 |
| | | Map<String, ? extends Object> cancelJobMaps = |
| | | new ImmutableMap.Builder<String, Long>(). |
| | | put("id", xpOrder.getId()) |
| | | .build(); |
| | | QuartzManager.addJob( |
| | | OrderCancelJob.class, |
| | | (OrderCancelJob.name + xpOrder.getId()).toUpperCase(), |
| | | TimeJobType.ORDER_CANCEL, |
| | | DateUtils.localDateTimeToDate(LocalDateTime.now().plusMinutes(xpPoint.getParkingTimeLimit())), |
| | | cancelJobMaps |
| | | ); |
| | | // 车辆到达上车点时间 |
| | | xpOrder.setArrivalTime(LocalDateTime.now()); |
| | | break; |
| | | case 5: |
| | | LocalDateTime now = LocalDateTime.now(); |
| | | xpOrder.setBoardingTime(now); |
| | | xpOrder.setRideTime(now); |
| | | // 删除定时任务job |
| | | QuartzManager.removeJob((OrderCancelJob.name + xpOrder.getId()).toUpperCase(), TimeJobType.ORDER_CANCEL); |
| | | break; |
| | | case 6: |
| | | // 行程开始时间 |
| | | xpOrder.setTripBegin(LocalDateTime.now()); |
| | | break; |
| | | case 7: |
| | | xpOrder.setGetoffTime(LocalDateTime.now()); |
| | | // 解析下车地点 |
| | | VehiclePosition vehiclePosition = mongoTemplate.findOne(new Query(Criteria.where("vin").is(xpVehicle.getVehicleVin())), VehiclePosition.class); |
| | | if(Objects.nonNull(vehiclePosition)){ |
| | | GeoJsonPoint point = vehiclePosition.getPoint(); |
| | | if(Objects.nonNull(point)){ |
| | | double x = point.getX(); |
| | | double y = point.getY(); |
| | | Map<String, String> geocode = gdMapGeocodingUtil.geocode(String.valueOf(x), String.valueOf(y)); |
| | | xpOrder.setGetoffAddress(geocode.get("address")); |
| | | } |
| | | } |
| | | //计算行驶总距离和时长 |
| | | List<OrderTrajectory> orderTrajectoryList = mongoTemplate.find(new Query().addCriteria(Criteria.where("orderId").is(xpOrder.getId())), OrderTrajectory.class); |
| | | Double reduce = orderTrajectoryList.stream().map(OrderTrajectory::getDistance).reduce(0.0, Double::sum); |
| | | xpOrder.setMileageKilometers(new BigDecimal(reduce).divide(new BigDecimal(1000)).setScale(4, RoundingMode.HALF_EVEN).doubleValue()); |
| | | long duration = LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8")) - xpOrder.getTripBegin().toEpochSecond(ZoneOffset.of("+8")); |
| | | xpOrder.setDuration(new BigDecimal(duration).divide(new BigDecimal(60), 2, RoundingMode.HALF_EVEN).doubleValue()); |
| | | |
| | | //创建定时结束订单和等待结束后下发巡游单的定时任务 |
| | | Integer arriveTime = xpSystemSettingClient.getOrderFinishTime().getData(); |
| | | // 添加自动结束行程定时任务job |
| | | Map<String, ? extends Object> endTripJobMaps = |
| | | new ImmutableMap.Builder<String, String>() |
| | | .put("id", xpOrder.getId().toString()) |
| | | .put("appid", appid) |
| | | .build(); |
| | | QuartzManager.addJob( |
| | | EndTripJob.class, |
| | | (EndTripJob.name + xpOrder.getId()).toUpperCase(), |
| | | TimeJobType.END_TRIP, |
| | | DateUtils.localDateTimeToDate(LocalDateTime.now().plusMinutes(arriveTime)), |
| | | endTripJobMaps |
| | | ); |
| | | // 添加车辆到达终点后限停时间到后驶离的定时任务 |
| | | //时间到后将车辆状态回滚到空闲、添加巡游订单,解绑用户和车辆关系,车辆驶离点位 |
| | | XpTestPoint point = xpTestPointClient.queryById(xpOrder.getEndTestPointId()).getData(); |
| | | Map<String, ? extends Object> jobMaps = |
| | | new ImmutableMap.Builder<String, String>() |
| | | .put("id", xpOrder.getId().toString()) |
| | | .put("appid", appid) |
| | | .build(); |
| | | QuartzManager.addJob( |
| | | AddCruiseMissionJob.class, |
| | | (AddCruiseMissionJob.name + xpOrder.getId()).toUpperCase(), |
| | | TimeJobType.ADD_CRUISE_MISSION, |
| | | DateUtils.localDateTimeToDate(LocalDateTime.now().plusMinutes(point.getParkingTimeLimit())), |
| | | jobMaps |
| | | ); |
| | | break; |
| | | } |
| | | |
| | | xpOrder.setStatus(status); |
| | | xpOrder.setVehicleId(null); |
| | | this.updateById(xpOrder); |
| | | redisService.setCacheObject("ORDER_STATUS:" + xpOrder.getId(), status, 24L, TimeUnit.HOURS); |
| | | }else{ |
| | | if(status == 10){ |
| | | xpOrder.setStatus(status); |
| | | xpOrder.setVehicleId(null); |
| | | this.updateById(xpOrder); |
| | | redisService.setCacheObject("ORDER_STATUS:" + xpOrder.getId(), status, 24L, TimeUnit.HOURS); |
| | | } |
| | | } |
| | | return R.ok(); |
| | | } |
| | | |
| | | @Override |
| | | public Boolean endTrip(Long orderId) { |
| | | List<XpTestOrderDetail> xpOrderDetails = new ArrayList<>(); |
| | | // 起步价格明细 |
| | | List<FareBreakdownDetailVo> start = new ArrayList<>(); |
| | | // 里程费价格明细 |
| | | List<FareBreakdownDetailVo> mileage = new ArrayList<>(); |
| | | // 时长费价格明细 |
| | | List<FareBreakdownDetailVo> duration = new ArrayList<>(); |
| | | // 远途费价格明细 |
| | | List<FareBreakdownDetailVo> longDistance = new ArrayList<>(); |
| | | XpTestOrder order = this.getById(orderId); |
| | | if (order == null) { |
| | | throw new RuntimeException("订单不存在"); |
| | | } |
| | | |
| | | if (order.getStatus() != 7) { |
| | | throw new RuntimeException("订单状态错误"); |
| | | } |
| | | order.setStatus(8); |
| | | order.setVehicleId(null); |
| | | order.setTripEnd(LocalDateTime.now()); |
| | | baseMapper.updateById(order); |
| | | redisService.setCacheObject("ORDER_STATUS:" + order.getId(), 8, 24L, TimeUnit.HOURS); |
| | | |
| | | // 根据订单所属开通城市id 查询定价 |
| | | R<XpPricing> pricingByCityId = xpPricingClient.getPricingByCid(order.getCityId()); |
| | | XpPricing pricing = pricingByCityId.getData(); |
| | | if (pricing == null) { |
| | | throw new ServiceException("当前城市未配置定价规则", I18nKeyConstant.ORDER_PRICING_NOT_EXISTS); |
| | | } |
| | | // 费用 |
| | | // 查询订单轨迹 |
| | | List<OrderTrajectory> trajectories = mongoTemplate.find( |
| | | new Query(Criteria.where("orderId").is(orderId)) |
| | | .with(Sort.by(Sort.Direction.ASC, "locatetime")), |
| | | OrderTrajectory.class |
| | | ); |
| | | List<TaxiPricingDemoService.GpsPoint> gpsPoints = new ArrayList<>(); |
| | | for (OrderTrajectory trajectory : trajectories) { |
| | | TaxiPricingDemoService.GpsPoint point = new TaxiPricingDemoService.GpsPoint(trajectory.getDistance(), trajectory.getLocatetime()); |
| | | gpsPoints.add(point); |
| | | } |
| | | |
| | | TaxiPricingDemoService.PricingConfig config = new TaxiPricingDemoService.PricingConfig(); |
| | | JSONArray startingFareJsonArray = JSONArray.parseArray(pricing.getStartingFareJson()); |
| | | |
| | | LocalDateTime boardingTime = order.getBoardingTime(); |
| | | Date date = DateUtils.localDateTimeToDate(boardingTime); |
| | | |
| | | |
| | | double paramNum4 = 0.0; |
| | | double paramNum5 = 0.0; |
| | | |
| | | |
| | | //一口价 |
| | | if (pricing.getPricingType() == 2) { |
| | | Double mileageKilometers = order.getMileageKilometers(); |
| | | Double duration1 = order.getDuration(); |
| | | |
| | | JSONObject basicPricingJson = JSONObject.parseObject(pricing.getBasicPricingJson()); |
| | | |
| | | XpPricingCardVo xpPricingCardVo = xpPricingUtil.calculationFixedPrice(uid, basicPricingJson, null, mileageKilometers, duration1, 0, 0.0, pricing.getIsDynamicPrice(), order.getCityId(), pricing.getDynamicPricingJson()); |
| | | XpTestOrderDetail xpOrderDetail = new XpTestOrderDetail(); |
| | | xpOrderDetail.setDetailType(1); |
| | | xpOrderDetail.setOrderId(orderId); |
| | | xpOrderDetail.setType(1); |
| | | xpOrderDetail.setMileage(new BigDecimal(mileageKilometers).setScale(2, RoundingMode.HALF_UP)); |
| | | String currentTimeSlot = DateUtils.getCurrentTimeSlot(); |
| | | xpOrderDetail.setTime(currentTimeSlot); |
| | | xpOrderDetail.setDuration(duration1); |
| | | xpOrderDetail.setMoney(new BigDecimal(xpPricingCardVo.getStartPrice()).setScale(2, RoundingMode.HALF_UP)); |
| | | xpOrderDetails.add(xpOrderDetail); |
| | | xpOrderDetail = new XpTestOrderDetail(); |
| | | xpOrderDetail.setDetailType(2); |
| | | xpOrderDetail.setOrderId(orderId); |
| | | xpOrderDetail.setType(1); |
| | | xpOrderDetail.setMoney(new BigDecimal(xpPricingCardVo.getDistancePrice()).setScale(2,RoundingMode.HALF_UP)); |
| | | xpOrderDetails.add(xpOrderDetail); |
| | | xpOrderDetail = new XpTestOrderDetail(); |
| | | xpOrderDetail.setDetailType(3); |
| | | xpOrderDetail.setOrderId(orderId); |
| | | xpOrderDetail.setType(1); |
| | | xpOrderDetail.setMoney(new BigDecimal(xpPricingCardVo.getDurationPrice()).setScale(2, RoundingMode.HALF_UP)); |
| | | xpOrderDetails.add(xpOrderDetail); |
| | | |
| | | BigDecimal totalPrice =BigDecimal.ZERO; |
| | | for (XpTestOrderDetail xpOrderDetail1 : xpOrderDetails) { |
| | | totalPrice = totalPrice.add(xpOrderDetail1.getMoney()); |
| | | xpTestOrderDetailMapper.insert(xpOrderDetail1); |
| | | } |
| | | order.setOrderMoney(totalPrice); |
| | | order.setVehicleId(null); |
| | | baseMapper.updateById(order); |
| | | } else { |
| | | //动态计费 |
| | | if (pricing.getPricingType() == 1) { |
| | | |
| | | for (int i = 0; i < startingFareJsonArray.size(); i++) { |
| | | JSONObject jsonObject = startingFareJsonArray.getJSONObject(i); |
| | | String num1 = jsonObject.getString("num1"); |
| | | String num2 = jsonObject.getString("num2"); |
| | | String num3 = jsonObject.getString("num3"); |
| | | String num4 = jsonObject.getString("num4"); |
| | | String num5 = jsonObject.getString("num5"); |
| | | String num6 = jsonObject.getString("num6"); |
| | | String num7 = jsonObject.getString("num7"); |
| | | config.normals.add(new TaxiPricingDemoService.PricingRule("普通时段", num1, num2, Double.parseDouble(num3), Double.parseDouble(num4), Double.parseDouble(num5), Double.parseDouble(num6), Double.parseDouble(num7))); |
| | | // 判断当前是那个时段 |
| | | |
| | | Calendar calendarStart = Calendar.getInstance(); |
| | | calendarStart.setTime(date); |
| | | calendarStart.set(Calendar.HOUR_OF_DAY, Integer.valueOf(jsonObject.getString("num1").split(":")[0])); |
| | | calendarStart.set(Calendar.MINUTE, Integer.valueOf(jsonObject.getString("num1").split(":")[1])); |
| | | |
| | | Calendar calendarEnd = Calendar.getInstance(); |
| | | calendarEnd.setTime(date); |
| | | calendarEnd.set(Calendar.HOUR_OF_DAY, Integer.valueOf(jsonObject.getString("num2").split(":")[0])); |
| | | calendarEnd.set(Calendar.MINUTE, Integer.valueOf(jsonObject.getString("num2").split(":")[1])); |
| | | // 找到符合条件的直接跳出循环 |
| | | if (date.getTime() > calendarStart.getTimeInMillis() && date.getTime() < calendarEnd.getTimeInMillis()) { |
| | | paramNum4 = jsonObject.getDouble("num4"); |
| | | paramNum5 = jsonObject.getDouble("num5"); |
| | | break; |
| | | } |
| | | } |
| | | |
| | | |
| | | JSONObject basicPricingJson = JSONObject.parseObject(pricing.getBasicPricingJson()); |
| | | config.peaks.add(new TaxiPricingDemoService.PricingRule("高峰期", basicPricingJson.getString("num21").split(" - ")[0], basicPricingJson.getString("num21").split(" - ")[1], Double.parseDouble(basicPricingJson.getString("num23")), paramNum4, paramNum5, Double.parseDouble(basicPricingJson.getString("num24")), Double.parseDouble(basicPricingJson.getString("num25")))); |
| | | config.peaks.add(new TaxiPricingDemoService.PricingRule("高峰期", basicPricingJson.getString("num22").split(" - ")[0], basicPricingJson.getString("num22").split(" - ")[1], Double.parseDouble(basicPricingJson.getString("num23")), paramNum4, paramNum5, Double.parseDouble(basicPricingJson.getString("num24")), Double.parseDouble(basicPricingJson.getString("num25")))); |
| | | config.night = new TaxiPricingDemoService.PricingRule("夜间行驶", basicPricingJson.getString("num14").split(" - ")[0], basicPricingJson.getString("num14").split(" - ")[1], Double.parseDouble(basicPricingJson.getString("num15")), paramNum4, paramNum5, Double.parseDouble(basicPricingJson.getString("num16")), Double.parseDouble(basicPricingJson.getString("num17"))); |
| | | config.holiday = new TaxiPricingDemoService.PricingRule("节假日", "00:00", "23:59", Double.parseDouble(basicPricingJson.getString("num29")), paramNum4, paramNum5, Double.parseDouble(basicPricingJson.getString("num30")), Double.parseDouble(basicPricingJson.getString("num31"))); |
| | | // --- 远途加价区间配置 (关键修改) --- |
| | | // 1. 超过 num1(12) 不足 num2(20), 加收 num3(1.2) |
| | | config.longSteps.add(new TaxiPricingDemoService.LongRangeStep(paramNum4, Double.parseDouble(basicPricingJson.getString("num7")), Double.parseDouble(basicPricingJson.getString("num8")))); |
| | | // 2. 超过 num4(20) 不足 num5(35), 加收 num6(2.0) |
| | | config.longSteps.add(new TaxiPricingDemoService.LongRangeStep(Double.parseDouble(basicPricingJson.getString("num9")), Double.parseDouble(basicPricingJson.getString("num10")), Double.parseDouble(basicPricingJson.getString("num11")))); |
| | | // 3. 超过 num7(35) 以后, 加收 num8(3.5) -> numEnd 传个极大值 |
| | | config.longSteps.add(new TaxiPricingDemoService.LongRangeStep(Double.parseDouble(basicPricingJson.getString("num12")), 999999, Double.parseDouble(basicPricingJson.getString("num13")))); |
| | | } |
| | | |
| | | |
| | | TaxiPricingDemoService.TaxiPricingService service = new TaxiPricingDemoService.TaxiPricingService(); |
| | | Integer holidayToday = holidayUtil.isHolidayToday(); |
| | | Map<String, BigDecimal> bill = service.calculateOrderPrice(DateUtils.toDate(order.getBoardingTime()), order.getMileageKilometers(), gpsPoints, config, holidayToday); |
| | | log.info("======= 订单计费账单 ======="); |
| | | bill.forEach((detail, price) -> log.info(detail + ": " + price + " 元")); |
| | | |
| | | BigDecimal totalAmount = bill.values().stream().reduce(BigDecimal.ZERO, BigDecimal::add); |
| | | log.info("--------------------------"); |
| | | log.info("应付总额: " + totalAmount + " 元"); |
| | | BigDecimal startMoney = BigDecimal.ZERO; |
| | | // 默认费率1 |
| | | double priceRate = 1; |
| | | if (pricing.getIsDynamicPrice() == 1) { |
| | | // 先判断是否已经调价过了 |
| | | Object userDynamicPriceObj = redisService.getCacheObject("USER_DYNAMIC_PRICE_" + order.getCityId() + "_" + uid); |
| | | if (userDynamicPriceObj != null) { |
| | | // 是否调价过了 |
| | | priceRate = Double.parseDouble(userDynamicPriceObj.toString()); |
| | | } else { |
| | | // 没有调过 |
| | | //是否触发动态调价 redis获取 |
| | | Object dynamicPriceObj = redisService.getCacheObject("DYNAMIC_PRICE_" + order.getCityId()); |
| | | if (dynamicPriceObj != null) { |
| | | JSONObject jsonObject = JSONObject.parseObject(pricing.getDynamicPricingJson()); |
| | | // 触发动态调价 |
| | | // value=时间 |
| | | String timeStr = dynamicPriceObj.toString(); |
| | | // 判断当前距离这个时间范围的新增订单数(排除取消) / 上浮数量 算出应该增加的价格率 |
| | | Integer num = this.getOrderNum(new GetOrderNumDto(timeStr, order.getCityId())); |
| | | // X单上升一次调价 |
| | | Integer orderNum = getOrderNum(jsonObject, 4); |
| | | // 需要调价的次数 |
| | | int count = num / orderNum; |
| | | if (count > 0) { |
| | | // 计算每次上升的费率 |
| | | Integer upRate = getOrderNum(jsonObject, 5); |
| | | BigDecimal divide = new BigDecimal(upRate).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP); |
| | | for (int i = count; i > 0; i--) { |
| | | // 当前费率+(费率*上升百分比) |
| | | priceRate = new BigDecimal(priceRate).multiply(divide).add(new BigDecimal(priceRate)).setScale(2, RoundingMode.HALF_UP).doubleValue(); |
| | | } |
| | | // 冷却时间 |
| | | Integer time = getOrderNum(jsonObject, 6); |
| | | // 触发调价了 |
| | | redisService.setCacheObject("USER_DYNAMIC_PRICE_" + order.getCityId() + "_" + uid, priceRate, time.longValue(), TimeUnit.MINUTES); |
| | | } |
| | | |
| | | } |
| | | } |
| | | |
| | | } |
| | | // 封装费用明细数据 |
| | | for (Map.Entry<String, BigDecimal> stringBigDecimalEntry : bill.entrySet()) { |
| | | // 封装起步价 |
| | | FareBreakdownDetailVo startDetail = new FareBreakdownDetailVo(); |
| | | String key = stringBigDecimalEntry.getKey(); |
| | | if (key.contains("起步价")) { |
| | | startDetail.setTime(key.split("\\|")[1]); |
| | | startDetail.setMoney(stringBigDecimalEntry.getValue()); |
| | | startMoney = startMoney.add(stringBigDecimalEntry.getValue()); |
| | | if (key.contains("普通时段")) { |
| | | startDetail.setType(1); |
| | | } else if (key.contains("夜间")) { |
| | | startDetail.setType(2); |
| | | } else if (key.contains("高峰")) { |
| | | startDetail.setType(3); |
| | | } else if (key.contains("节假")) { |
| | | startDetail.setType(4); |
| | | } |
| | | String durationAndMileage = key.split("\\|")[2]; |
| | | startDetail.setDuration(Double.valueOf(durationAndMileage.split("&")[0])); |
| | | startDetail.setMileage(new BigDecimal(durationAndMileage.split("&")[1]).multiply(BigDecimal.valueOf(1000))); |
| | | start.add(startDetail); |
| | | } |
| | | // 封装里程费 |
| | | if (!key.contains("起步") && !key.contains("时长") && !key.contains("远途") && !key.contains("distance")) { |
| | | FareBreakdownDetailVo mileageDetail = new FareBreakdownDetailVo(); |
| | | if (key.contains("普通时段")) { |
| | | mileageDetail.setType(1); |
| | | String key1 = "distance普通时段|" + key.split("\\|")[1]; |
| | | String key2 = "普通时段|" + key.split("\\|")[1]; |
| | | BigDecimal distance = bill.get(key1); |
| | | BigDecimal money = bill.get(key2); |
| | | mileageDetail.setMileage(distance); |
| | | order.setStartMoney(money.multiply(BigDecimal.valueOf(priceRate))); |
| | | mileageDetail.setMoney(money.multiply(BigDecimal.valueOf(priceRate))); |
| | | } else if (key.contains("夜间行驶")) { |
| | | mileageDetail.setType(2); |
| | | String key1 = "distance夜间行驶|" + key.split("\\|")[1]; |
| | | String key2 = "夜间行驶|" + key.split("\\|")[1]; |
| | | BigDecimal distance = bill.get(key1); |
| | | BigDecimal money = bill.get(key2); |
| | | mileageDetail.setMileage(distance); |
| | | order.setStartMoney(money.multiply(BigDecimal.valueOf(priceRate))); |
| | | |
| | | mileageDetail.setMoney(money.multiply(BigDecimal.valueOf(priceRate))); |
| | | } else if (key.contains("高峰期")) { |
| | | mileageDetail.setType(3); |
| | | String key1 = "distance高峰期|" + key.split("\\|")[1]; |
| | | String key2 = "高峰期|" + key.split("\\|")[1]; |
| | | BigDecimal distance = bill.get(key1); |
| | | BigDecimal money = bill.get(key2); |
| | | mileageDetail.setMileage(distance); |
| | | order.setStartMoney(money.multiply(BigDecimal.valueOf(priceRate))); |
| | | |
| | | mileageDetail.setMoney(money.multiply(BigDecimal.valueOf(priceRate))); |
| | | } else if (key.contains("节假")) { |
| | | mileageDetail.setType(4); |
| | | String key1 = "distance节假日|" + key.split("\\|")[1]; |
| | | String key2 = "节假日|" + key.split("\\|")[1]; |
| | | BigDecimal distance = bill.get(key1); |
| | | BigDecimal money = bill.get(key2); |
| | | mileageDetail.setMileage(distance); |
| | | order.setStartMoney(money.multiply(BigDecimal.valueOf(priceRate))); |
| | | mileageDetail.setMoney(money.multiply(BigDecimal.valueOf(priceRate))); |
| | | } |
| | | mileage.add(mileageDetail); |
| | | } |
| | | // 封装时长费 |
| | | FareBreakdownDetailVo timeDetail = new FareBreakdownDetailVo(); |
| | | if (key.contains("时长费")) { |
| | | if(key.contains("普通时段")){ |
| | | timeDetail.setType(1); |
| | | } |
| | | if(key.contains("夜间行驶")){ |
| | | timeDetail.setType(2); |
| | | } |
| | | if(key.contains("高峰")){ |
| | | timeDetail.setType(3); |
| | | } |
| | | if(key.contains("节假")){ |
| | | timeDetail.setType(4); |
| | | } |
| | | |
| | | timeDetail.setMoney(stringBigDecimalEntry.getValue()); |
| | | timeDetail.setDuration(Double.valueOf(key.split("&")[1])); |
| | | duration.add(timeDetail); |
| | | } |
| | | // 封装远途费 |
| | | FareBreakdownDetailVo longDetail = new FareBreakdownDetailVo(); |
| | | if (key.contains("远途费")) { |
| | | longDetail.setType(startDetail.getType()); |
| | | longDetail.setMoney(stringBigDecimalEntry.getValue()); |
| | | // longDetail.setMileage(new BigDecimal(key.split("&")[1])); |
| | | longDistance.add(longDetail); |
| | | } |
| | | } |
| | | for (FareBreakdownDetailVo fareBreakdownDetailVo : start) { |
| | | XpTestOrderDetail xpOrderDetail = new XpTestOrderDetail(); |
| | | BeanUtils.copyProperties(fareBreakdownDetailVo, xpOrderDetail); |
| | | xpOrderDetail.setOrderId(orderId); |
| | | xpOrderDetail.setDetailType(1); |
| | | xpOrderDetail.setCreateTime(LocalDateTime.now()); |
| | | xpOrderDetails.add(xpOrderDetail); |
| | | } |
| | | BigDecimal mileageMoney = BigDecimal.ZERO; |
| | | for (FareBreakdownDetailVo fareBreakdownDetailVo : mileage) { |
| | | XpTestOrderDetail xpOrderDetail = new XpTestOrderDetail(); |
| | | BeanUtils.copyProperties(fareBreakdownDetailVo, xpOrderDetail); |
| | | xpOrderDetail.setOrderId(orderId); |
| | | xpOrderDetail.setDetailType(2); |
| | | xpOrderDetail.setCreateTime(LocalDateTime.now()); |
| | | mileageMoney = mileageMoney.add(fareBreakdownDetailVo.getMoney()); |
| | | xpOrderDetails.add(xpOrderDetail); |
| | | } |
| | | order.setMileageMoney(mileageMoney); |
| | | |
| | | |
| | | for (FareBreakdownDetailVo fareBreakdownDetailVo : longDistance) { |
| | | XpTestOrderDetail xpOrderDetail = new XpTestOrderDetail(); |
| | | BeanUtils.copyProperties(fareBreakdownDetailVo, xpOrderDetail); |
| | | xpOrderDetail.setOrderId(orderId); |
| | | xpOrderDetail.setDetailType(4); |
| | | xpOrderDetail.setCreateTime(LocalDateTime.now()); |
| | | mileageMoney = mileageMoney.add(fareBreakdownDetailVo.getMoney()); |
| | | xpOrderDetails.add(xpOrderDetail); |
| | | } |
| | | |
| | | |
| | | for (FareBreakdownDetailVo fareBreakdownDetailVo : duration) { |
| | | XpTestOrderDetail xpOrderDetail = new XpTestOrderDetail(); |
| | | BeanUtils.copyProperties(fareBreakdownDetailVo, xpOrderDetail); |
| | | xpOrderDetail.setOrderId(orderId); |
| | | xpOrderDetail.setDetailType(3); |
| | | xpOrderDetail.setCreateTime(LocalDateTime.now()); |
| | | mileageMoney = mileageMoney.add(fareBreakdownDetailVo.getMoney()); |
| | | xpOrderDetails.add(xpOrderDetail); |
| | | } |
| | | |
| | | |
| | | for (XpTestOrderDetail xpOrderDetail : xpOrderDetails) { |
| | | xpTestOrderDetailMapper.insert(xpOrderDetail); |
| | | } |
| | | |
| | | for (FareBreakdownDetailVo fareBreakdownDetailVo : duration) { |
| | | if (order.getDurationMoney() == null) { |
| | | order.setDurationMoney(BigDecimal.ZERO); |
| | | } |
| | | BigDecimal add = order.getDurationMoney().add(fareBreakdownDetailVo.getMoney()); |
| | | order.setDurationMoney(add); |
| | | } |
| | | |
| | | |
| | | BigDecimal orderMoney = startMoney.add(mileageMoney).add(order.getDurationMoney() != null ? order.getDurationMoney() : BigDecimal.ZERO) |
| | | .add(order.getLongDistancemoney() != null ? order.getLongDistancemoney() : BigDecimal.ZERO) |
| | | .add(order.getWaitMoney() != null ? order.getWaitMoney() : BigDecimal.ZERO); |
| | | order.setOrderMoney(orderMoney); |
| | | order.setVehicleId(null); |
| | | baseMapper.updateById(order); |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | // 计算完价格后 挑选优惠券 |
| | | GetUserCouponDto getUserCouponDto = new GetUserCouponDto(); |
| | | getUserCouponDto.setUserId(Long.valueOf(uid)); |
| | | getUserCouponDto.setTotalAmount(order.getOrderMoney().doubleValue()); |
| | | getUserCouponDto.setUserCouponId(order.getCouponId()); |
| | | getUserCouponDto.setOpenCityId(order.getCityId()); |
| | | R<UserCouponVo> userCouponVoR = xpAppUserCouponClient.getUserCoupon(getUserCouponDto); |
| | | UserCouponVo userCouponVo = userCouponVoR.getData(); |
| | | |
| | | // 提示是否换券 |
| | | boolean tip =false; |
| | | if (userCouponVo != null) { |
| | | // 重新选券 |
| | | if(userCouponVo.getStatus()==2){ |
| | | getUserCouponDto.setUserId(Long.valueOf(uid)); |
| | | getUserCouponDto.setTotalAmount(order.getOrderMoney().doubleValue()); |
| | | getUserCouponDto.setUserCouponId(order.getCouponId()); |
| | | getUserCouponDto.setOpenCityId(order.getCityId()); |
| | | userCouponVoR = xpAppUserCouponClient.getUserCoupon(getUserCouponDto); |
| | | userCouponVo = userCouponVoR.getData(); |
| | | tip=true; |
| | | } |
| | | order.setCouponId(userCouponVo.getId()); |
| | | order.setCouponMoney(BigDecimal.valueOf(userCouponVo.getMoney())); |
| | | } |
| | | order.setVehicleId(null); |
| | | baseMapper.updateById(order); |
| | | return tip; |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | /** |
| | | * 获取配置 4每X单 5上升X% 6冷却 |
| | | * |
| | | * @param rule |
| | | * @param num |
| | | * @return |
| | | */ |
| | | private Integer getOrderNum(JSONObject rule, int num) { |
| | | Integer param = rule.getInteger("num" + num); |
| | | return param; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 获取订单数量 |
| | | * |
| | | * @param dto |
| | | * @return |
| | | */ |
| | | @Override |
| | | public Integer getOrderNum(GetOrderNumDto dto) { |
| | | Long num = this.baseMapper.selectCount(new LambdaQueryWrapper<XpTestOrder>().eq(XpTestOrder::getCityId, dto.getOpenCityId()).between(BaseModel::getCreateTime, dto.getTimeStr(), new Date())); |
| | | return num.intValue(); |
| | | } |
| | | |
| | | |
| | | @Override |
| | | public void saveVehicleLocation(OrderTrajectory orderTrajectory) { |
| | | // 查询订单信息 |
| | | Integer status = redisService.getCacheObject("ORDER_STATUS:" + orderTrajectory.getOrderId()); |
| | | if(status < 6){ |
| | | return; |
| | | } |
| | | |
| | | // 计算距离 |
| | | // 获取上一次定位 |
| | | String oldLocation = redisService.getCacheObject(CacheConstants.ORDER_OLD_LOCATION + orderTrajectory.getOrderId()); |
| | | if (StringUtils.isEmpty(oldLocation)) { |
| | | orderTrajectory.setDistance(0D); |
| | | // 存储mongo数据 |
| | | mongoTemplate.save(orderTrajectory); |
| | | // 存储首次定位 |
| | | redisService.setCacheObject(CacheConstants.ORDER_OLD_LOCATION + orderTrajectory.getOrderId(), orderTrajectory.getLocation(), 1L, TimeUnit.HOURS); |
| | | } else { |
| | | Map<String, Double> distance = GeodesyUtil.getDistance(orderTrajectory.getLocation(), oldLocation); |
| | | if (null != distance) { |
| | | Double distance1 = distance.get("WGS84"); |
| | | // 存储本次距离 |
| | | orderTrajectory.setDistance(distance1); |
| | | // 存储mongo数据 |
| | | mongoTemplate.save(orderTrajectory); |
| | | // 更新定位 |
| | | redisService.setCacheObject(CacheConstants.ORDER_OLD_LOCATION + orderTrajectory.getOrderId(), orderTrajectory.getLocation(), 1L, TimeUnit.HOURS); |
| | | } else { |
| | | log.error("调用高德计算距离出错"); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 查询订单轨迹(mongodb) |
| | | * |
| | | * @param orderId 订单id |
| | | * @return 轨迹列表(按 locatetime 升序) |
| | | */ |
| | | private List<OrderTrajectory> queryOrderTrajectories(Long orderId) { |
| | | if (orderId == null) { |
| | | return new ArrayList<>(); |
| | | } |
| | | List<OrderTrajectory> trajectories = mongoTemplate.find( |
| | | new Query(Criteria.where("orderId").is(orderId)) |
| | | .with(Sort.by(Sort.Direction.ASC, "locatetime")), |
| | | OrderTrajectory.class |
| | | ); |
| | | return trajectories; |
| | | } |
| | | |
| | | /** |
| | | * 订单费用明细聚合:按 detail_type 汇总 money |
| | | * |
| | | * <p>detail_type:1=起步价 2=里程费 3=时长费 4=远途费</p> |
| | | */ |
| | | private Map<Integer, BigDecimal> sumOrderDetailMoneyByDetailType(Long orderId) { |
| | | if (orderId == null) { |
| | | return Collections.emptyMap(); |
| | | } |
| | | List<XpTestOrderDetail> detailList = xpTestOrderDetailMapper.selectList( |
| | | new LambdaQueryWrapper<XpTestOrderDetail>() |
| | | .eq(XpTestOrderDetail::getOrderId, orderId) |
| | | .ne(XpTestOrderDetail::getIsDeleted, true) |
| | | ); |
| | | if (CollectionUtils.isEmpty(detailList)) { |
| | | return Collections.emptyMap(); |
| | | } |
| | | Map<Integer, BigDecimal> sumMap = new HashMap<>(); |
| | | for (XpTestOrderDetail detail : detailList) { |
| | | if (detail == null || detail.getDetailType() == null) { |
| | | continue; |
| | | } |
| | | BigDecimal money = detail.getMoney() == null ? BigDecimal.ZERO : detail.getMoney(); |
| | | sumMap.put(detail.getDetailType(), sumMap.getOrDefault(detail.getDetailType(), BigDecimal.ZERO).add(money)); |
| | | } |
| | | return sumMap; |
| | | } |
| | | |
| | | /** |
| | | * 将轨迹点转换为订单经纬度列表 |
| | | */ |
| | | private List<XpTestOrderDetailVO.OrderPosition> convertTrajectoriesToPositions(List<OrderTrajectory> trajectories) { |
| | | if (CollectionUtils.isEmpty(trajectories)) { |
| | | return new ArrayList<>(); |
| | | } |
| | | List<XpTestOrderDetailVO.OrderPosition> positions = new ArrayList<>(); |
| | | for (OrderTrajectory trajectory : trajectories) { |
| | | if (trajectory == null || StringUtils.isBlank(trajectory.getLocation())) { |
| | | continue; |
| | | } |
| | | String[] parts = trajectory.getLocation().split(","); |
| | | if (parts.length != 2) { |
| | | continue; |
| | | } |
| | | try { |
| | | double longitude = Double.parseDouble(parts[0].trim()); |
| | | double latitude = Double.parseDouble(parts[1].trim()); |
| | | XpTestOrderDetailVO.OrderPosition position = new XpTestOrderDetailVO.OrderPosition(); |
| | | position.setLongitude(longitude); |
| | | position.setLatitude(latitude); |
| | | positions.add(position); |
| | | } catch (Exception e) { |
| | | // ignore invalid point |
| | | } |
| | | } |
| | | return positions; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 发送乘客导航路径数据 |
| | | * |
| | | * @param appUserId |
| | | * @param keyStr |
| | | */ |
| | | public void sendRoute(String appUserId, Long orderId, String keyStr, String vin) { |
| | | VehiclePosition vehiclePosition = mongoTemplate.findOne(new Query(Criteria.where("vin").is(vin)), VehiclePosition.class); |
| | | Object cacheObject = redisService.getCacheObject(keyStr + ":" + appUserId); |
| | | if (null != cacheObject) { |
| | | RouteVo routeVo = JSON.parseObject(cacheObject.toString(), RouteVo.class); |
| | | JSONObject jsonObject = new JSONObject(); |
| | | jsonObject.put("type", "ORDER_ROUTE"); |
| | | jsonObject.put("timestamp", System.currentTimeMillis()); |
| | | JSONObject content = new JSONObject(); |
| | | content.put("orderId", orderId.toString()); |
| | | content.put("routeType", "ORDER_NAVIGATION_START_DATA".equals(keyStr) ? 1 : 2); |
| | | content.put("direction", null != vehiclePosition ? vehiclePosition.getCourse() : 90); |
| | | JSONObject route = new JSONObject(); |
| | | route.put("distance", routeVo.getDistance()); |
| | | route.put("duration", routeVo.getDuration()); |
| | | route.put("routeID", routeVo.getRouteID()); |
| | | |
| | | List<JSONObject> collect = routeVo.getPolyline().stream().map(item -> { |
| | | JSONObject point = new JSONObject(); |
| | | point.put("latitude", item.getLatitude()); |
| | | point.put("longitude", item.getLongitude()); |
| | | return point; |
| | | }).collect(Collectors.toList()); |
| | | |
| | | route.put("polyline", JSON.toJSONString(collect)); |
| | | content.put("route", route.toJSONString()); |
| | | jsonObject.put("content", content.toJSONString()); |
| | | SendMessageDTO messageDTO = new SendMessageDTO(); |
| | | messageDTO.setAppUserId(appUserId); |
| | | messageDTO.setMessage(jsonObject.toJSONString()); |
| | | R<String> stringR = xpPushMessageClient.sendRoute(messageDTO); |
| | | XpTestOrder xpOrder = this.getById(orderId); |
| | | //推送失败,重试3次 |
| | | if(stringR.getCode() != Constants.SUCCESS){ |
| | | ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>()); |
| | | executor.execute(() -> { |
| | | for (int i = 0; i < 3; i++) { |
| | | R<String> stringR1 = xpPushMessageClient.sendStatus(messageDTO); |
| | | if(stringR1.getCode() == Constants.SUCCESS){ |
| | | break; |
| | | } |
| | | try { |
| | | Thread.sleep(1000); |
| | | } catch (InterruptedException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | log.info("推送乘客端导航数据消息失败:{} {} {}", stringR1.getMsg(), JSON.toJSONString(messageDTO), xpOrder.getOrderNumber()); |
| | | } |
| | | }); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | @Override |
| | | public void changeAmount(Long id, BigDecimal amount) { |
| | | if (Objects.isNull(id)) { |
| | | throw new ServiceException("订单ID不能为空", I18nKeyConstant.ORDER_CHANGE_AMOUNT_ID_REQUIRED); |
| | | } |
| | | if (Objects.isNull(amount)) { |
| | | throw new ServiceException("订单金额不能为空", I18nKeyConstant.ORDER_CHANGE_AMOUNT_AMOUNT_REQUIRED); |
| | | } |
| | | if (amount.compareTo(BigDecimal.ZERO) < 0) { |
| | | throw new ServiceException("订单金额不能小于0", I18nKeyConstant.ORDER_CHANGE_AMOUNT_AMOUNT_INVALID); |
| | | } |
| | | |
| | | XpTestOrder order = this.getById(id); |
| | | |
| | | if (Objects.isNull(order)) { |
| | | throw new ServiceException("订单不存在", I18nKeyConstant.ORDER_NOT_EXISTS); |
| | | } |
| | | |
| | | final Integer pendingPaymentStatus = 8; |
| | | if (!Objects.equals(order.getStatus(), pendingPaymentStatus)) { |
| | | throw new ServiceException("当前订单状态不允许改价,只有待付款状态的订单可以改价", I18nKeyConstant.ORDER_CHANGE_AMOUNT_STATUS_INVALID); |
| | | } |
| | | |
| | | if (Objects.nonNull(order.getOrderMoney()) && order.getOrderMoney().compareTo(amount) == 0) { |
| | | return; |
| | | } |
| | | |
| | | boolean updated = this.lambdaUpdate() |
| | | .set(XpTestOrder::getOrderMoney, amount) |
| | | .set(XpTestOrder::getChangeMoneyFlag, Boolean.TRUE) |
| | | .eq(XpTestOrder::getId, id) |
| | | .eq(XpTestOrder::getStatus, pendingPaymentStatus) |
| | | .update(); |
| | | if (!updated) { |
| | | throw new ServiceException("订单改价失败,请稍后重试", I18nKeyConstant.ORDER_CHANGE_AMOUNT_FAILED); |
| | | } |
| | | } |
| | | } |