package com.xiaopeng.order.service.impl;
|
|
import cn.hutool.core.bean.BeanUtil;
|
import cn.hutool.json.JSONUtil;
|
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONObject;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
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.UseUserCouponDto;
|
import com.xiaopeng.api.dto.automaticPilot.PushOrderDto;
|
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.XpAppUserClient;
|
import com.xiaopeng.api.feignClient.account.XpAppUserCouponClient;
|
import com.xiaopeng.api.feignClient.automaticPilot.OrderMissionClient;
|
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.account.XpAppUser;
|
import com.xiaopeng.api.model.operation.XpFeedbackType;
|
import com.xiaopeng.api.model.operation.XpGeoQueryEntity;
|
import com.xiaopeng.api.model.operation.XpPoint;
|
import com.xiaopeng.api.model.operation.XpPricing;
|
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.account.UserCouponVo;
|
import com.xiaopeng.api.vo.automaticPilot.proto.down.cloudOrderOperation.OrderOperationType;
|
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.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.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.XpCruiseOrderMapper;
|
import com.xiaopeng.order.mapper.XpOrderDetailMapper;
|
import com.xiaopeng.order.mapper.XpOrderMapper;
|
import com.xiaopeng.order.model.dto.XpOrderCommentDto;
|
import com.xiaopeng.order.model.dto.XpOrderPayDto;
|
import com.xiaopeng.order.model.query.XpCruiseOrderPageQuery;
|
import com.xiaopeng.order.model.query.XpHistoryOrderListQuery;
|
import com.xiaopeng.order.model.query.XpOrderPageQuery;
|
import com.xiaopeng.order.model.vo.*;
|
import com.xiaopeng.order.service.*;
|
import com.xiaopeng.order.utils.TaxiPricingDemoService;
|
import com.xiaopeng.order.utils.TrajectoryGenerator;
|
import com.xiaopeng.order.utils.holiday.HolidayUtil;
|
import com.xiaopeng.order.vo.OrderDetailVo;
|
import lombok.RequiredArgsConstructor;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.factory.annotation.Autowired;
|
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.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.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 XpCruiseOrderServiceImpl extends ServiceImpl<XpCruiseOrderMapper, XpCruiseOrder> implements IXpCruiseOrderService {
|
|
private final XpVehicleClient xpVehicleClient;
|
private final XpFleetVehicleClient xpFleetVehicleClient;
|
private final XpFleetClient xpFleetClient;
|
|
/**
|
* 关闭当前巡游单子
|
* @param vin
|
*/
|
@Override
|
public String updateCruiseOrder(String vin) {
|
LambdaQueryWrapper<XpCruiseOrder> wrapper = new LambdaQueryWrapper<XpCruiseOrder>().eq(XpCruiseOrder::getVehicleVin, vin).eq(XpCruiseOrder::getStatus, 1);
|
XpCruiseOrder xpCruiseOrder = this.getOne(wrapper);
|
if (xpCruiseOrder != null) {
|
xpCruiseOrder.setStatus(2);
|
this.update(xpCruiseOrder, wrapper);
|
return xpCruiseOrder.getId();
|
}
|
return null;
|
}
|
|
@Override
|
public String closeCruiseOrder(String vin) {
|
LambdaQueryWrapper<XpCruiseOrder> wrapper = new LambdaQueryWrapper<XpCruiseOrder>().eq(XpCruiseOrder::getVehicleVin, vin).eq(XpCruiseOrder::getStatus, 1);
|
XpCruiseOrder xpCruiseOrder = this.getOne(wrapper);
|
if (xpCruiseOrder != null) {
|
xpCruiseOrder.setStatus(3);
|
this.update(xpCruiseOrder, wrapper);
|
return xpCruiseOrder.getId();
|
}
|
return null;
|
}
|
|
@Override
|
public PageInfo<XpCruiseOrderPageVO> pageList(XpCruiseOrderPageQuery query) {
|
PageInfo<XpCruiseOrderPageVO> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize());
|
LambdaQueryWrapper<XpCruiseOrder> wrapper = new LambdaQueryWrapper<XpCruiseOrder>()
|
.eq(XpCruiseOrder::getMissionId, String.valueOf(query.getMissionId()))
|
.like(StringUtils.isNotBlank(query.getOrderNumber()), XpCruiseOrder::getOrderNumber, query.getOrderNumber())
|
.eq(query.getStatus() != null, XpCruiseOrder::getStatus, query.getStatus());
|
|
if (query.getStartTime() != null) {
|
wrapper.ge(BaseModel::getCreateTime, query.getStartTime().atStartOfDay());
|
}
|
if (query.getEndTime() != null) {
|
wrapper.le(BaseModel::getCreateTime, query.getEndTime().plusDays(1).atStartOfDay());
|
}
|
|
if (query.getFleetId() != null) {
|
R<List<Long>> fleetVehicleResult = xpFleetVehicleClient.listVehicleIdsByFleetId(query.getFleetId());
|
if (fleetVehicleResult == null || CollectionUtils.isEmpty(fleetVehicleResult.getData())) {
|
pageInfo.setRecords(Collections.emptyList());
|
return pageInfo;
|
}
|
wrapper.in(XpCruiseOrder::getVehicleId, fleetVehicleResult.getData());
|
}
|
|
if (StringUtils.isNotBlank(query.getPlateNumber())) {
|
R<List<XpVehicle>> vehicleResult = xpVehicleClient.listByPlateNumber(query.getPlateNumber());
|
if (vehicleResult == null || CollectionUtils.isEmpty(vehicleResult.getData())) {
|
pageInfo.setRecords(Collections.emptyList());
|
return pageInfo;
|
}
|
List<Long> vehicleIds = vehicleResult.getData().stream().map(XpVehicle::getId).collect(Collectors.toList());
|
wrapper.in(XpCruiseOrder::getVehicleId, vehicleIds);
|
}
|
|
wrapper.orderByDesc(BaseModel::getCreateTime);
|
Page<XpCruiseOrder> page = new Page<>(query.getPageNum(), query.getPageSize());
|
Page<XpCruiseOrder> pageResult = this.page(page, wrapper);
|
if (CollectionUtils.isEmpty(pageResult.getRecords())) {
|
pageInfo.setTotal(0L);
|
pageInfo.setRecords(Collections.emptyList());
|
return pageInfo;
|
}
|
Set<Long> vehicleIds = pageResult.getRecords().stream()
|
.map(XpCruiseOrder::getVehicleId)
|
.filter(Objects::nonNull)
|
.collect(Collectors.toSet());
|
Map<Long, XpVehicle> vehicleMap;
|
if (!vehicleIds.isEmpty()) {
|
R<List<XpVehicle>> vehicleResult = xpVehicleClient.listByIds(new ArrayList<>(vehicleIds));
|
if (vehicleResult != null && !CollectionUtils.isEmpty(vehicleResult.getData())) {
|
vehicleMap = vehicleResult.getData().stream().collect(Collectors.toMap(XpVehicle::getId, v -> v));
|
} else {
|
vehicleMap = Collections.emptyMap();
|
}
|
} else {
|
vehicleMap = Collections.emptyMap();
|
}
|
Map<Long, Long> vehicleFleetIdMap = new HashMap<>();
|
if (!vehicleIds.isEmpty()) {
|
for (Long vehicleId : vehicleIds) {
|
R<Long> fleetIdResult = xpFleetVehicleClient.getFleetIdByVehicleId(vehicleId);
|
if (fleetIdResult != null && fleetIdResult.getData() != null) {
|
vehicleFleetIdMap.put(vehicleId, fleetIdResult.getData());
|
}
|
}
|
}
|
Map<Long, String> fleetNameMap;
|
if (!vehicleFleetIdMap.isEmpty()) {
|
List<Long> fleetIds = vehicleFleetIdMap.values().stream().distinct().collect(Collectors.toList());
|
R<List<XpFleet>> fleetResult = xpFleetClient.listByIds(fleetIds);
|
if (fleetResult != null && !CollectionUtils.isEmpty(fleetResult.getData())) {
|
fleetNameMap = fleetResult.getData().stream()
|
.collect(Collectors.toMap(XpFleet::getId, XpFleet::getFleetName, (a, b) -> a));
|
} else {
|
fleetNameMap = Collections.emptyMap();
|
}
|
} else {
|
fleetNameMap = Collections.emptyMap();
|
}
|
List<XpCruiseOrderPageVO> voList = pageResult.getRecords().stream().map(order -> {
|
XpCruiseOrderPageVO vo = new XpCruiseOrderPageVO();
|
BeanUtils.copyProperties(order, vo);
|
XpVehicle vehicle = vehicleMap.get(order.getVehicleId());
|
if (vehicle != null) {
|
vo.setPlateNumber(vehicle.getPlateNumber());
|
}
|
Long fleetId = vehicleFleetIdMap.get(order.getVehicleId());
|
if (fleetId != null) {
|
vo.setFleetName(fleetNameMap.get(fleetId));
|
}
|
return vo;
|
}).collect(Collectors.toList());
|
pageInfo.setTotal(pageResult.getTotal());
|
pageInfo.setRecords(voList);
|
return pageInfo;
|
}
|
}
|