xuhy
2026-04-20 a5e4c4c7ffd5ad80c3d4b2f1fff69ce9b071bdcf
Merge branch '1.0' of http://120.76.84.145:10101/gitblit/r/java/Robotaxi into 1.0
22个文件已修改
271 ■■■■■ 已修改文件
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/config/MiniprogramConfigurer.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/operation/XpOpenCityClientFallbackFactory.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/map/XpMapClient.java 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/operation/XpOpenCityClient.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/order/XpOrder.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/order/XpOrderReassign.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/vehicleConvoy/XpVehicle.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/config/MiniprogramConfigurer.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/controller/ActiveOrderController.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/utils/XpPricingUtil.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpMapController.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/config/MiniprogramConfigurer.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpOpenCityController.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpTargetedServiceController.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/task/TaskUtil.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/controller/XpOrderController.java 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/controller/XpOrderReassignController.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/model/dto/XpOrderOperateDTO.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/IXpOrderService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-push-message-boot/src/main/java/com/xiaopeng/pushMessage/webSocket/handler/WebSocketTextFrameHandler.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpVehicleServiceImpl.java 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/config/MiniprogramConfigurer.java
@@ -10,7 +10,7 @@
import javax.annotation.Resource;
@Slf4j
@Configuration
//@Configuration
public class MiniprogramConfigurer extends WebMvcConfigurerAdapter {
    @Resource
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/operation/XpOpenCityClientFallbackFactory.java
@@ -35,6 +35,12 @@
                log.error("获取开通城市失败");
                return R.fail("获取开通城市失败");
            }
            @Override
            public R<XpOpenCity> getXpOpenCityById(Long id) {
                log.error("获取开通城市失败");
                return R.fail("获取开通城市失败");
            }
        };
    }
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/map/XpMapClient.java
@@ -57,6 +57,6 @@
    /**
     * 获取指定城市的天气
     */
    @GetMapping("/logan/inner/weatherInfo")
    R<WeatherDTO> wether(@RequestParam String cityCode);
    @PostMapping("/logan/inner/weatherInfo")
    R<WeatherDTO> wether(@RequestParam("cityCode") String cityCode);
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/operation/XpOpenCityClient.java
@@ -31,4 +31,13 @@
    R<XpOpenCity> getXpOpenCity(@RequestParam("provinceCode") String provinceCode,
                                @RequestParam("cityCode") String cityCode,
                                @RequestParam("districtCode") String districtCode);
    /**
     * 根据id查询开通城市
     * @param id
     * @return
     */
    @PostMapping("/logan/inner/v1/openCity/getXpOpenCityById")
    R<XpOpenCity> getXpOpenCityById(@RequestParam("id") Long id);
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/order/XpOrder.java
@@ -127,6 +127,9 @@
    @ApiModelProperty(value = "预付金额")
    private BigDecimal prepayMoney;
    @ApiModelProperty(value = "关闭订单的时候不能为空 是否豁免(0=否,1=是)")
    private Boolean isFree;
    @ApiModelProperty(value = "起步里程")
    private Double startMileage;
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/order/XpOrderReassign.java
@@ -1,14 +1,15 @@
package com.xiaopeng.api.model.order;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xiaopeng.common.core.web.domain.BaseModel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import com.fasterxml.jackson.annotation.JsonFormat;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
/**
@@ -33,7 +34,9 @@
    private Long id;
    @ApiModelProperty(value = "订单id")
    @NotNull(message = "订单id不能为空")
    private Long orderId;
    @TableField(exist = false)
    @ApiModelProperty(value = "订单号")
    private String orderNumber;
@@ -49,6 +52,7 @@
    private Long oldVehicleId;
    @ApiModelProperty(value = "新车辆id")
    @NotNull(message = "新车辆id不能为空")
    private Long newVehicleId;
    @ApiModelProperty(value = "原车队id")
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/vehicleConvoy/XpVehicle.java
@@ -136,4 +136,14 @@
    @TableField(exist = false)
    private String vehicleModelName;
    @ApiModelProperty(value = "在订单改派里展示-预估到达时间")
    @TableField(exist = false)
    private String arrivalTime;
    @TableField(exist = false)
    @ApiModelProperty(value = "在订单改派里展示-预估到达时间秒")
    private Integer arrivalTimeSecond;
    @ApiModelProperty(value = "在订单改派里展示-预估到达距离米")
    @TableField(exist = false)
    private Integer arrivalDistance;
}
xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/config/MiniprogramConfigurer.java
@@ -10,7 +10,7 @@
import javax.annotation.Resource;
@Slf4j
@Configuration
//@Configuration
public class MiniprogramConfigurer extends WebMvcConfigurerAdapter {
    @Resource
xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/controller/ActiveOrderController.java
@@ -35,7 +35,7 @@
@Slf4j
@RestController
@RequestMapping("")
@Api(tags = "费用管理")
@Api(tags = "行程中管理")
public class ActiveOrderController {
    @Resource
xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/utils/XpPricingUtil.java
@@ -7,7 +7,9 @@
import com.xiaopeng.api.dto.WeatherDTO;
import com.xiaopeng.api.dto.order.GetOrderNumDto;
import com.xiaopeng.api.feignClient.map.XpMapClient;
import com.xiaopeng.api.feignClient.operation.XpOpenCityClient;
import com.xiaopeng.api.feignClient.order.XpOrderClient;
import com.xiaopeng.api.model.operation.XpOpenCity;
import com.xiaopeng.api.vo.order.XpPricingCardVo;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.redis.service.RedisService;
@@ -69,6 +71,11 @@
//
    @Resource XpMapClient xpMapClient;
    @Resource
    private XpOpenCityClient openCityClient;
    /**
     * 计算一口价
     */
@@ -106,20 +113,25 @@
                                // 当前费率+(费率*上升百分比)
                                priceRate =  new BigDecimal(priceRate).multiply(divide).add(new BigDecimal(priceRate)).setScale(2, RoundingMode.HALF_UP).doubleValue();
                            }
                            List<WeatherDTO.Lives> lives = xpMapClient.wether(openCityId.toString()).getData().getLives();
                            if(lives!=null && !lives.isEmpty()){
                                String w = lives.get(0).getWeather();
                                Set<String> weather = jsonObject.getJSONObject("weather").keySet();
                                for (String k : weather) {
                                    if(w.contains(k)){
                                        double floatRate = jsonObject.getDouble(k);
                                        priceRate = new BigDecimal(priceRate).add(new BigDecimal(floatRate)).doubleValue();
                                        break;
                            JSONObject jsonObject1 = jsonObject.getJSONObject("weather");
                            if(null != jsonObject1){
                                XpOpenCity openCity = openCityClient.getXpOpenCityById(openCityId).getData();
                                WeatherDTO data = xpMapClient.wether(openCity.getCityCode()).getData();
                                List<WeatherDTO.Lives> lives = data.getLives();
                                if(lives!=null && !lives.isEmpty()){
                                    String w = lives.get(0).getWeather();
                                    Set<String> weather = jsonObject1.keySet();
                                    for (String k : weather) {
                                        if(w.contains(k)){
                                            double floatRate = jsonObject.getDouble(k);
                                            priceRate = new BigDecimal(priceRate).add(new BigDecimal(floatRate)).doubleValue();
                                            break;
                                        }
                                    }
                                }
                            }
                            // 冷却时间
                            Integer time = getOrderNum(jsonObject, 6);
                            // 触发调价了
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpMapController.java
@@ -205,21 +205,23 @@
    String key;
    @ApiOperation(value = "获取天气信息", tags = {"内部-调价"})
    @GetMapping("/logan/inner/weatherInfo")
    public R<WeatherDTO> weather(@RequestParam String city) throws IOException {
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpGet httpGet = new HttpGet(String.format(WEATHER_URL, key, city));
            try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    String resp = EntityUtils.toString(entity, StandardCharsets.UTF_8);
                    System.out.println(resp);
                    return R.ok(om.readValue(resp, WeatherDTO.class));
                }
                return R.fail("获取天气信息失败");
    @PostMapping("/logan/inner/weatherInfo")
    public R<WeatherDTO> wether(@RequestParam("cityCode") String cityCode) {
        try{
            CloseableHttpClient httpClient = HttpClients.createDefault();
            HttpGet httpGet = new HttpGet(String.format(WEATHER_URL, key, cityCode));
            CloseableHttpResponse response = httpClient.execute(httpGet);
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                String resp = EntityUtils.toString(entity, StandardCharsets.UTF_8);
                log.info("天气预报查询结果:{}", resp);
                return R.ok(om.readValue(resp, WeatherDTO.class));
            }
            return R.fail("获取天气信息失败");
        }catch (Exception e){
            e.printStackTrace();
        }
        return R.fail("获取天气信息失败");
    }
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/config/MiniprogramConfigurer.java
@@ -10,7 +10,7 @@
import javax.annotation.Resource;
@Slf4j
@Configuration
//@Configuration
public class MiniprogramConfigurer extends WebMvcConfigurerAdapter {
    @Resource
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpOpenCityController.java
@@ -153,4 +153,16 @@
        XpOpenCity xpOpenCity = xpOpenCityService.getXpOpenCity(provinceCode, cityCode, districtCode);
        return R.ok(xpOpenCity);
    }
    /**
     * 根据id查询开通城市
     * @param id
     * @return
     */
    @PostMapping("/logan/inner/v1/openCity/getXpOpenCityById")
    public R<XpOpenCity> getXpOpenCityById(@RequestParam("id") Long id){
        XpOpenCity xpOpenCity = xpOpenCityService.getById(id);
        return R.ok(xpOpenCity);
    }
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpTargetedServiceController.java
@@ -116,7 +116,7 @@
    /**
     * 批量删除
     */
    @GetMapping("/api/v1/whitelist/deleteByIds")
    @GetMapping("/api/v1/targetedService/deleteByIds")
    @ApiOperation(value = "定向服务-批量删除", tags = {"管理后台-定向服务批量删除"})
    public R deleteByIds(String ids) {
        SysUser sysUser = tokenService.getLoginUser().getSysUser();
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/task/TaskUtil.java
@@ -24,10 +24,8 @@
    @Resource
    private  XpPointService xpPointService;
    @Resource
    private  IXpElectronicFenceAreaService xpElectronicFenceAreaService;
    @Resource
    private  IXpElectronicFenceService xpElectronicFenceService;
    // 每隔1分钟执行一次 如果运营区域不处于启用状态 将关联的点位状态修改为已停用
    @Scheduled(fixedRate = 60 * 1000)
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/controller/XpOrderController.java
@@ -291,7 +291,7 @@
    @ApiOperation(value = "取消/关闭订单", tags = {"管理后台-交易管理-订单管理"})
    @PostMapping("/api/v1/order/cancelAndCloseById")
    public R<?> cancelAndCloseById(@Validated @RequestBody XpOrderOperateDTO dto) {
        xpOrderService.cancelOrCloseOrder(dto.getOrderId(), dto.getType());
        xpOrderService.cancelOrCloseOrder(dto.getOrderId(), dto.getType(),dto.getIsFree());
        return R.ok();
    }
@@ -301,7 +301,7 @@
     * @param dto 改派请求参数
     * @return 操作结果
     */
    @ApiOperation(value = "改派订单", tags = {"管理后台-交易管理-订单管理"}, notes = "车辆列表在vehicleConvoy服务")
    @ApiOperation(value = "改派订单", tags = {"管理后台-交易管理-订单管理"}, notes = "车辆列表在 vehicleConvoy.availableList 服务")
    @PostMapping("/api/v1/order/reassignById")
    public R<?> reassignById(@Validated @RequestBody XpOrderReassignDTO dto) {
        xpOrderService.reassignOrder(
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/controller/XpOrderReassignController.java
@@ -4,7 +4,6 @@
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.xiaopeng.api.model.order.XpOrderReassign;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.enums.OrderStatusEnum;
import com.xiaopeng.order.service.IXpOrderReassignService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@@ -17,7 +16,6 @@
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
 * <p>
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/model/dto/XpOrderOperateDTO.java
@@ -24,4 +24,9 @@
    @NotNull(message = "操作类型不能为空")
    private Integer type;
    @ApiModelProperty(value = "关闭订单的时候不能为空 是否豁免费用(0=否,1=是)")
    private Boolean isFree;
}
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/IXpOrderService.java
@@ -88,7 +88,7 @@
     * @param orderId 订单ID
     * @param type 操作类型:1=取消订单,2=关闭订单
     */
    void cancelOrCloseOrder(Long orderId, Integer type);
    void cancelOrCloseOrder(Long orderId, Integer type,Boolean isFree);
    /**
     * 改派订单
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java
@@ -547,14 +547,14 @@
    @Override
    @Transactional
    @ShardingSphereTransactionType(TransactionType.BASE)
    public void cancelOrCloseOrder(Long orderId, Integer type) {
    public void cancelOrCloseOrder(Long orderId, Integer type,Boolean isFree) {
        // 1. 校验订单是否存在
        XpOrder order = this.getById(orderId);
        if (Objects.isNull(order)) {
            throw new ServiceException("订单不存在");
        }
        // 2. 校验操作类型
        // 2. 校验操作类型 操作类型:1=取消订单,2=关闭订单
        if (type != 1 && type != 2) {
            throw new ServiceException("操作类型错误,type只能为1或2");
        }
@@ -568,6 +568,9 @@
                throw new ServiceException("当前订单状态不允许取消,只有待接单、待出发、接驾中状态的订单可以取消", I18nKeyConstant.ORDER_CANCEL_FAILED);
            }
        } else {
            if(isFree == null){
                throw new ServiceException("是否豁免费用不能为空", I18nKeyConstant.ORDER_CLOSE_FAILED);
            }
            // 关闭订单:0=已取消,1=待接单,2=待出发,3=接驾中,4=待客上车,5=乘客已上车,6=服务中 状态可以关闭
            if (currentStatus == 7 || currentStatus == 8 || currentStatus == 9 || currentStatus == 10) {
                throw new ServiceException("当前订单状态不允许关闭", I18nKeyConstant.ORDER_CLOSE_FAILED);
@@ -581,6 +584,9 @@
        } else {
            // 关闭订单
            closeOrder(order);
            if(isFree){
                this.setFree(order.getId());
            }
        }
    }
@@ -2073,15 +2079,25 @@
        this.endTrip(xpOrder.getId(),appUserId.toString());
        //将支付金额修改成0 并将状态修改成 订单状态9
        setFree(xpOrder.getId());
        return R.ok();
    }
    /**
     * 豁免
     */
    public void setFree(Long id){
        //将支付金额修改成0 并将状态修改成 订单状态9
        XpOrder xpOrder1 = new XpOrder();
        xpOrder1.setId(xpOrder.getId());
        xpOrder1.setId(id);
        xpOrder1.setIsFree( true);//豁免
        xpOrder1.setPayMoney(BigDecimal.ZERO);
        xpOrder1.setStatus(OrderStatusEnum.PENDING_PAYMENT.getCode());
        xpOrder1.setUpdateTime(LocalDateTime.now());
        baseMapper.updateById(xpOrder1);
        redisService.setCacheObject("ORDER_STATUS:" + xpOrder.getId(), xpOrder1.getStatus(), 24L, TimeUnit.HOURS);
        redisService.setCacheObject("ORDER_STATUS:" + id, xpOrder1.getStatus(), 24L, TimeUnit.HOURS);
        return R.ok();
    }
xp-robotaxi-push-message-boot/src/main/java/com/xiaopeng/pushMessage/webSocket/handler/WebSocketTextFrameHandler.java
@@ -155,6 +155,14 @@
            log.info("收到用户 {} 的业务消息: {}", appUserId, messageObj.toJSONString());
            businessMsgHandlers.get(messageObj.getString("type")).handle(appUserId, messageObj.getString("message"));
            //判断处理用户实时位置
            if ("location".equals(messageObj.getString("type"))) {
                log.info("收到用户 {} 的实时位置消息: {}", appUserId, messageObj.toJSONString());
                Double latitude = messageObj.getDouble("latitude");
                Double longitude = messageObj.getDouble("longitude");
                String timestamp = messageObj.getString("timestamp");
            }
            // 回复消息
            JSONObject response = new JSONObject();
xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpVehicleServiceImpl.java
@@ -10,16 +10,16 @@
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
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.UcUserInfo;
import com.xiaopeng.api.dto.pushMessage.SendMessageDTO;
import com.xiaopeng.api.dto.map.OrderRouteAndFareDto;
import com.xiaopeng.api.dto.operation.LonLatDto;
import com.xiaopeng.api.dto.vehicleConvoy.ServiceVehicleListDto;
import com.xiaopeng.api.dto.vehicleConvoy.VehicleTemperatureDto;
import com.xiaopeng.api.feignClient.account.UserResourcesClient;
import com.xiaopeng.api.feignClient.automaticPilot.XpuVinClient;
import com.xiaopeng.api.feignClient.map.AdcFencePushClient;
import com.xiaopeng.api.feignClient.map.XpMapClient;
import com.xiaopeng.api.feignClient.operation.XpElectronicClient;
import com.xiaopeng.api.feignClient.operation.XpSystemSettingClient;
import com.xiaopeng.api.feignClient.order.XpOrderClient;
import com.xiaopeng.api.feignClient.order.XpTestOrderClient;
import com.xiaopeng.api.feignClient.pushMessage.XpPushMessageClient;
@@ -29,31 +29,30 @@
import com.xiaopeng.api.model.operation.XpElectronicFenceArea;
import com.xiaopeng.api.model.order.XpOrder;
import com.xiaopeng.api.model.order.XpTestOrder;
import com.xiaopeng.api.model.vehicleConvoy.*;
import com.xiaopeng.api.model.vehicleConvoy.XpFleetOperations;
import com.xiaopeng.api.model.vehicleConvoy.XpFleetVehicle;
import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
import com.xiaopeng.api.model.vehicleConvoy.XpVehicleAnnualRecord;
import com.xiaopeng.api.vo.automaticPilot.VehiclePosition;
import com.xiaopeng.api.vo.operation.ElectronicFenceDetailVo;
import com.xiaopeng.api.vo.operation.RouteVo;
import com.xiaopeng.api.vo.vehicleConvoy.*;
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.web.page.PageInfo;
import com.xiaopeng.common.redis.service.RedisService;
import com.xiaopeng.evi.oss.service.AliOssService;
import com.xiaopeng.vehicleConvoy.constant.I18nKeyConstant;
import com.xiaopeng.vehicleConvoy.mapper.XpFleetMapper;
import com.xiaopeng.vehicleConvoy.mapper.XpFleetOperationsMapper;
import com.xiaopeng.vehicleConvoy.mapper.XpVehicleMapper;
import com.xiaopeng.vehicleConvoy.model.dto.*;
import com.xiaopeng.vehicleConvoy.model.importExcel.XpVehicleImportExcel;
import com.xiaopeng.vehicleConvoy.model.query.*;
import com.xiaopeng.vehicleConvoy.model.vo.XpVehicleVO;
import com.xiaopeng.vehicleConvoy.service.IXpFleetService;
import com.xiaopeng.vehicleConvoy.service.IXpVehicleAnnualRecordService;
import com.xiaopeng.vehicleConvoy.service.IXpFleetVehicleService;
import com.xiaopeng.vehicleConvoy.service.IXpVehicleAnnualRecordService;
import com.xiaopeng.vehicleConvoy.service.IXpVehicleService;
import com.xiaopeng.vehicleConvoy.util.VehicleControlUtil;
import lombok.extern.slf4j.Slf4j;
@@ -63,7 +62,6 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.data.geo.Point;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
import org.springframework.data.mongodb.core.query.Criteria;
@@ -74,12 +72,14 @@
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
 * <p>
@@ -117,6 +117,8 @@
    private RedisService redisService;
    @Autowired
    private MongoTemplate mongoTemplate;
    @Resource
    private XpMapClient xpMapClient;
    @Autowired
    private AliOssService aliOssService;
    @Autowired
@@ -153,10 +155,19 @@
        return super.listByIds(ids);
    }
    /**
     *
     * @param orderId
     * @param orderType 订单类型(1=用户单,2=测试单)
     * @return
     */
    @Override
    public List<XpVehicle> listAvailableVehicles(Long orderId, Integer orderType) {
        // 1. 通过订单ID查询订单信息,获取区域ID
        Long areaId = null;
         Double longitude =null;//经度
         Double latitude =null;//纬度
        if (null == orderType || 1 == orderType) {
            R<XpOrder> orderResult = xpOrderClient.queryOrderById(orderId);
            if (orderResult == null || orderResult.getData() == null) {
@@ -166,9 +177,13 @@
            XpOrder order = orderResult.getData();
            areaId = order.getXpElectronicFenceAreaId();
            longitude = order.getStartLon();
            latitude = order.getStartLat();
        } else {
            XpTestOrder testOrder = xpTestOrderClient.queryOrderById(orderId).getData();
            areaId = testOrder.getXpElectronicFenceAreaId();
            longitude = testOrder.getStartLon();
            latitude = testOrder.getStartLat();
        }
        if (areaId == null) {
@@ -198,8 +213,69 @@
        // 排序:按电量降序、入库时间降序
        wrapper.orderByDesc(XpVehicle::getCurrentElectricity)
                .orderByDesc(XpVehicle::getWarehousingTime);
        List<XpVehicle> list = this.list(wrapper);
        //获取车的位置 和订单的位置 并计算 距离 和 时间
        if(!list.isEmpty()){
            for (XpVehicle xpVehicle : list) {
        return this.list(wrapper);
                VehiclePosition vehiclePosition = mongoTemplate.findOne(new Query(Criteria.where("vin").is(xpVehicle.getVehicleVin())), VehiclePosition.class);
                if(vehiclePosition == null){
                    continue;
                }
                OrderRouteAndFareDto dto = new OrderRouteAndFareDto();
                dto.setOrderId(orderId);
                LonLatDto origin = new LonLatDto();
                origin.setLongitude(longitude);
                origin.setLatitude(latitude);
                dto.setOrigin(origin);
                LonLatDto destination = new LonLatDto();
                destination.setLongitude(vehiclePosition.getPoint().getX());
                destination.setLatitude(vehiclePosition.getPoint().getY());
                dto.setDestination(destination);
                dto.setRouteType(1);
//                dto.setVehicleId(xpVehicle.getId());
                R<RouteVo> routeVoR = xpMapClient.getOrderDistanceAndDuration(dto);
                if (200 != routeVoR.getCode()) {
                    throw new RuntimeException("获取订单线路失败");
                }
                if(routeVoR.getData() != null){
                    xpVehicle.setArrivalDistance(routeVoR.getData().getDistance());
                    xpVehicle.setArrivalTimeSecond(routeVoR.getData().getDuration());
                    if(routeVoR.getData().getDuration() != null){
                        BigDecimal time = new BigDecimal(routeVoR.getData().getDuration());
                        if(time.compareTo(new BigDecimal("60"))<0){ //秒
                            xpVehicle.setArrivalTime(time.toPlainString()+"秒");
                        }else if(time.compareTo(new BigDecimal("60"))>0 && time.compareTo(new BigDecimal("3600"))<0){//分
                            BigDecimal min = time.divide(new BigDecimal("60"), 0, RoundingMode.HALF_UP);
                            xpVehicle.setArrivalTime(min.toPlainString()+"分钟");
                        }else if(time.compareTo(new BigDecimal("3600"))>0){//小时
                            // 计算小时和分钟
                            long totalSeconds = time.longValue();
                            long hours = totalSeconds / 3600;
                            long minutes = (totalSeconds % 3600) / 60;
                            StringBuilder timeStr = new StringBuilder();
                            if (hours > 0) {
                                timeStr.append(hours).append("小时");
                            }
                            if (minutes > 0 || hours == 0) {
                                timeStr.append(minutes).append("分钟");
                            }
                            xpVehicle.setArrivalTime(timeStr.toString());
                        }
                    }
                }
            }
            // 按预计到达时间(秒)升序排序
            list.sort(Comparator.comparing(XpVehicle::getArrivalTimeSecond, Comparator.nullsLast(Comparator.naturalOrder())));
        }
        return list;
    }
    @Override