package com.xiaopeng.maintenance.controller; import cn.hutool.core.lang.Snowflake; import com.alibaba.fastjson2.JSONObject; import com.xiaopeng.api.dto.automaticPilot.VehicleEventDTO; import com.xiaopeng.api.dto.operation.NewCruiseOrderDto; import com.xiaopeng.api.feignClient.automaticPilot.VehicleBuriedPointClient; import com.xiaopeng.api.feignClient.operation.XpCruisePlanClient; import com.xiaopeng.api.feignClient.order.XpCruiseOrderClient; import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient; import com.xiaopeng.api.model.order.XpCruiseOrder; import com.xiaopeng.api.model.vehicleConvoy.XpVehicle; import com.xiaopeng.api.vo.automaticPilot.VehiclePosition; import com.xiaopeng.api.vo.automaticPilot.protobuf.TaskActionType; import com.xiaopeng.common.core.domain.R; import com.xiaopeng.common.core.web.page.PageInfo; import com.xiaopeng.evi.oss.service.AliOssService; import com.xiaopeng.maintenance.dto.VehicleDispatchAcceptDTO; import com.xiaopeng.maintenance.dto.VehicleDispatchDepartureDTO; import com.xiaopeng.maintenance.model.query.OperationRecordsQuery; import com.xiaopeng.maintenance.model.vo.OperationRecordsVO; import com.xiaopeng.maintenance.service.IXpVehiclePreparationService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; 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.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import java.io.UnsupportedEncodingException; import java.util.HashMap; import java.util.Map; /** *

* 车辆管理 前端控制器 *

* * @author mitao * @since 2026-02-03 */ @Slf4j @RestController @Api(tags = "车辆运维") public class XpVehicleOperationsController { @Resource private IXpVehiclePreparationService xpVehiclePreparationService; @Resource private XpVehicleClient xpVehicleClient; @Resource private XpCruiseOrderClient xpCruiseOrderClient; @Resource private MongoTemplate mongoTemplate; @Resource private AliOssService aliOssService; @Autowired private XpCruisePlanClient xpCruisePlanClient; @Autowired private VehicleBuriedPointClient vehicleBuriedPointClient; @Resource(name = "hutoolSnowflake") private Snowflake snowflake; /** * 车辆详情-车辆调度-发车 收车 */ @Transactional(rollbackFor = Exception.class) @ApiOperation(value = "车辆运维-车辆调度-发车/收车", tags = {"运维APP-车辆管理"}) @PostMapping("/maintenance-app/api/v1/vehicle/vehicleDispatchDeparture") public R vehicleDispatchDeparture(@RequestBody VehicleDispatchDepartureDTO dto) { // 判断是否有正在进行的正常订单 // 查询车辆 XpVehicle xpVehicle = xpVehicleClient.queryById(dto.getVehicleId()).getData(); if(xpVehicle.getState()==1){ return R.fail("车辆正在接单中"); } VehiclePosition vehiclePosition = mongoTemplate.findOne(new Query(Criteria.where("vin").is(xpVehicle.getVehicleVin())), VehiclePosition.class); if(vehiclePosition==null || vehiclePosition.getPoint()==null){ return R.fail("车辆位置信息不存在"); } Integer departureStatus = dto.getDepartureStatus(); XpVehicle vehicle1 = new XpVehicle(); vehicle1.setOperatingStatus(departureStatus); vehicle1.setId(xpVehicle.getId()); xpVehicleClient.updateVehicleById(vehicle1); // 封装埋点消息实体 VehicleEventDTO vehicleEventDTO = new VehicleEventDTO(); vehicleEventDTO.setVin(xpVehicle.getVehicleVin()); vehicleEventDTO.setXpuId(""); vehicleEventDTO.setOrderId(""); vehicleEventDTO.setEventKey("RT_web_vehicle_status_changed"); vehicleEventDTO.setEventTime(System.currentTimeMillis()); Map attributes = new HashMap<>(); attributes.put("vin",xpVehicle.getVehicleVin()); attributes.put("order_id",""); attributes.put("timestamp",vehicleEventDTO.getEventTime()); if(departureStatus == 1){ attributes.put("main_status","ONLINE"); // TODO 预留位置 目前无状态 attributes.put("sub_status",""); attributes.put("prev_sub_status",""); }else { attributes.put("main_status","OFFLINE"); // TODO 预留位置 目前无状态 attributes.put("sub_status",""); attributes.put("prev_sub_status",""); } vehicleEventDTO.setAttributes(attributes); vehicleBuriedPointClient.sendVehicleEvent(vehicleEventDTO); // 发车 if(dto.getDepartureStatus()==1){ // 找车辆的任务 生成巡游单子 下发命令 //发车之前,检查所有之前没终止的数据,将其终止 xpCruiseOrderClient.stopAllCruiseOrder(xpVehicle.getVehicleVin()); R newCruiseOrder = xpCruisePlanClient.getNewCruiseOrder(new NewCruiseOrderDto(xpVehicle.getId(),xpVehicle.getVehicleVin(),xpVehicle.getFleetId(),vehiclePosition.getPoint())); if(newCruiseOrder.getData()!=null){ //标记订单为返程类型巡游单 //方向为正向 XpCruiseOrder cruiseOrder = newCruiseOrder.getData(); cruiseOrder.setOrderType(2); cruiseOrder.setOrderReverse(1); //不停车替换新任务 cruiseOrder.setTaskActionType(TaskActionType.kTerminateForNewTask); R longR = xpCruiseOrderClient.addCruiseOrder(cruiseOrder); if(200 != longR.getCode()){ return R.fail(longR.getMsg()); } } }else if(dto.getDepartureStatus()==3){ // 收车 关闭当前巡游单子 生成新的返程单子 找到收车站点 XpCruiseOrder oldCruiseOrder = xpCruiseOrderClient.cancelCruiseOrderByVin(xpVehicle.getVehicleVin()).getData(); XpCruiseOrder xpCruiseOrder = new XpCruiseOrder(); if(vehiclePosition!=null){ double x = vehiclePosition.getPoint().getX(); double y = vehiclePosition.getPoint().getY(); xpCruiseOrder.setStartLon(x); xpCruiseOrder.setStartLat(y); } xpCruiseOrder.setVehicleId(xpVehicle.getId()); xpCruiseOrder.setFleetId(xpVehicle.getFleetId()); xpCruiseOrder.setOrderType(2); xpCruiseOrder.setStatus(1); xpCruiseOrder.setOrderReverse(1); xpCruiseOrder.setLastOrderId(oldCruiseOrder.getId()); xpCruiseOrder.setOrderReverse(1); xpCruiseOrder.setXpuTaskId(snowflake.nextId() + ""); // 找到收车站点 XpCruiseOrder returnCruisePoint = xpCruisePlanClient.findReturnCruisePoint(xpCruiseOrder).getData(); if(returnCruisePoint!=null){ //不停车替换新任务 returnCruisePoint.setLastOrderId1("XU" + oldCruiseOrder.getId()); returnCruisePoint.setLastXpuTaskId(oldCruiseOrder.getXpuTaskId()); returnCruisePoint.setTaskActionType(TaskActionType.kTerminateForNewTask); xpCruiseOrderClient.addCruiseOrder(returnCruisePoint); } } return R.ok(); } /** * 车辆详情-车辆调度-接单、测试 */ @ApiOperation(value = "车辆运维-车辆调度-接单、测试", tags = {"运维APP-车辆管理"}) @PostMapping("/maintenance-app/api/v1/vehicle/vehicleDispatchAccept") public R vehicleDispatchAccept(@RequestBody VehicleDispatchAcceptDTO dto) { // 查询车辆 XpVehicle xpVehicle = xpVehicleClient.queryById(dto.getVehicleId()).getData(); XpVehicle vehicle1 = new XpVehicle(); vehicle1.setId(xpVehicle.getId()); vehicle1.setAcceptOrTest(dto.getAcceptOrTest()); vehicle1.setAcceptOrTestStatus(dto.getAcceptOrTestStatus()); xpVehicleClient.updateVehicleById(vehicle1); return R.ok(); } /** * 车辆详情-车辆调度-运维记录 */ @ApiOperation(value = "车辆运维-车辆调度-运维记录", tags = {"运维APP-车辆管理"}) @PostMapping("/maintenance-app/api/v1/vehicle/operationRecords") public R> operationRecords(@Validated @RequestBody OperationRecordsQuery query) throws UnsupportedEncodingException { PageInfo operationRecords = xpVehiclePreparationService.operationRecords(query); for (OperationRecordsVO record : operationRecords.getRecords()) { String vehiclePictures = record.getVehiclePictures(); if (StringUtils.isNotBlank(vehiclePictures)) { JSONObject jsonObject = JSONObject.parseObject(vehiclePictures); // 1 String downloadUrl = jsonObject.getString("url");; try { downloadUrl = aliOssService.getDownloadUrl(jsonObject.getString("id"), jsonObject.getString("name"), true); } catch (UnsupportedEncodingException e) { log.error("获取图片下载地址失败", e); } jsonObject.put("url", downloadUrl); record.setVehiclePictures(jsonObject.toJSONString()); } } return R.ok(operationRecords); } }