puzhibing
2026-02-12 10a6186cc7b3fa100c9b8abb00291cd7642dc7d6
Merge remote-tracking branch 'origin/master'

# Conflicts:
# xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpVehicleController.java
# xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpVehicleServiceImpl.java
3 文件已复制
1 文件已重命名
5个文件已添加
26个文件已修改
1038 ■■■■■ 已修改文件
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/maintenance/XpChargingRecordClientFallbackFactory.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/maintenance/XpVehiclePreparationClientFallbackFactory.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/order/XpOrderClientFallbackFactory.java 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/maintenance/XpChargingRecordClient.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/maintenance/XpVehiclePreparationClient.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/maintenance/XpChargingRecord.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/maintenance/XpChargingRecordVO.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpChargingRecordController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpTaskController.java 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpVehicleDetectionController.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpVehiclePreparationController.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpVehicleRepairController.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/model/query/XpChargingRecordPageQuery.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/model/query/XpTaskRecordPageQuery.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/model/query/XpVehicleDetectionPageQuery.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/model/query/XpVehiclePreparationPageQuery.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/model/query/XpVehicleRepairPageQuery.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/model/vo/XpTaskRecordVO.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/IXpChargingRecordService.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/IXpVehicleDetectionService.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/IXpVehiclePreparationService.java 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/IXpVehicleRepairService.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/XpTaskService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpChargingRecordServiceImpl.java 107 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpTaskServiceImpl.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpVehicleDetectionServiceImpl.java 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpVehiclePreparationServiceImpl.java 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpVehicleRepairServiceImpl.java 113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpPricingServiceImpl.java 155 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/utils/XpPricingUtil.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/utils/holiday/HolidayUtil.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpVehicleController.java 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/query/XpVehicleAnnualRecordPageQuery.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpVehicleServiceImpl.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/maintenance/XpChargingRecordClientFallbackFactory.java
New file
@@ -0,0 +1,25 @@
package com.xiaopeng.api.factory.maintenance;
import com.xiaopeng.api.feignClient.maintenance.XpChargingRecordClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
/**
 * 车辆整备Feign客户端降级工厂
 *
 * @author mitao
 * @since 2026-02-11
 */
@Slf4j
@Component
public class XpChargingRecordClientFallbackFactory implements FallbackFactory<XpChargingRecordClient> {
    @Override
    public XpChargingRecordClient create(Throwable cause) {
        log.error("车辆整备服务调用失败: {}", cause.getMessage());
        return new XpChargingRecordClient() {
        };
    }
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/maintenance/XpVehiclePreparationClientFallbackFactory.java
@@ -1,10 +1,6 @@
package com.xiaopeng.api.factory.maintenance;
import com.xiaopeng.api.feignClient.maintenance.XpVehiclePreparationClient;
import com.xiaopeng.api.model.query.XpVehiclePreparationPageQuery;
import com.xiaopeng.api.vo.maintenance.XpVehiclePreparationDetailVO;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.web.page.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
@@ -23,11 +19,7 @@
    public XpVehiclePreparationClient create(Throwable cause) {
        log.error("车辆整备服务调用失败: {}", cause.getMessage());
        return new XpVehiclePreparationClient() {
            @Override
            public R<PageInfo<XpVehiclePreparationDetailVO>> queryByVehicleId(XpVehiclePreparationPageQuery query) {
                log.error("查询车辆整备记录失败,车辆ID: {}, 原因: {}", query.getVehicleId(), cause.getMessage());
                return R.fail("查询车辆整备记录失败: " + cause.getMessage());
            }
        };
    }
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/order/XpOrderClientFallbackFactory.java
@@ -69,6 +69,7 @@
                return R.fail();
            }
            @Override
            public R<Integer> getOrderNum(GetOrderNumDto dto) {
                log.error("获取订单数量失败,原因: {}", cause.getMessage());
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/maintenance/XpChargingRecordClient.java
New file
@@ -0,0 +1,18 @@
package com.xiaopeng.api.feignClient.maintenance;
import com.xiaopeng.api.factory.maintenance.XpVehiclePreparationClientFallbackFactory;
import com.xiaopeng.common.core.dto.ServiceNameConstantsEnum;
import org.springframework.cloud.openfeign.FeignClient;
/**
 * 车辆整备Feign客户端
 *
 * @author mitao
 * @since 2026-02-11
 */
@FeignClient(contextId = "XpChargingRecordClient",
        value = ServiceNameConstantsEnum.XP_MAINTENANCE_SERVICE,
        fallbackFactory = XpVehiclePreparationClientFallbackFactory.class)
public interface XpChargingRecordClient {
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/maintenance/XpVehiclePreparationClient.java
@@ -1,14 +1,8 @@
package com.xiaopeng.api.feignClient.maintenance;
import com.xiaopeng.api.factory.maintenance.XpVehiclePreparationClientFallbackFactory;
import com.xiaopeng.api.model.query.XpVehiclePreparationPageQuery;
import com.xiaopeng.api.vo.maintenance.XpVehiclePreparationDetailVO;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.dto.ServiceNameConstantsEnum;
import com.xiaopeng.common.core.web.page.PageInfo;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
/**
 * 车辆整备Feign客户端
@@ -21,12 +15,4 @@
        fallbackFactory = XpVehiclePreparationClientFallbackFactory.class)
public interface XpVehiclePreparationClient {
    /**
     * 通过车辆ID查询整备分页列表(内部接口)
     *
     * @param query 查询参数
     * @return 整备记录分页列表
     */
    @PostMapping("/inner/vehiclePreparation/queryByVehicleId")
    R<PageInfo<XpVehiclePreparationDetailVO>> queryByVehicleId(@RequestBody XpVehiclePreparationPageQuery query);
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/maintenance/XpChargingRecord.java
@@ -1,17 +1,17 @@
package com.xiaopeng.api.model.maintenance;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.time.LocalDateTime;
import java.io.Serializable;
import com.baomidou.mybatisplus.annotation.TableName;
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 java.time.LocalDateTime;
/**
 * <p>
@@ -46,6 +46,7 @@
    private String startChargingPicture;
    @ApiModelProperty(value = "开始充电时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private LocalDateTime startTime;
    @ApiModelProperty(value = "结束剩余电量")
@@ -55,6 +56,7 @@
    private String endChargingPicture;
    @ApiModelProperty(value = "结束充电时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private LocalDateTime endTime;
    @ApiModelProperty(value = "开始充电操作人")
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/maintenance/XpChargingRecordVO.java
New file
@@ -0,0 +1,23 @@
package com.xiaopeng.api.vo.maintenance;
import com.xiaopeng.api.model.maintenance.XpChargingRecord;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
 * @author MiTao
 * @date 2026-02-12 11:50
 *
 */
@Data
@EqualsAndHashCode(callSuper = true)
@ApiModel("充电记录视图对象")
public class XpChargingRecordVO extends XpChargingRecord {
    @ApiModelProperty(value = "开始充电操作人名称")
    private String startOperationsUserName;
    @ApiModelProperty(value = "结束充电操作人名称")
    private String endOperationsUserName;
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpChargingRecordController.java
@@ -3,10 +3,9 @@
import com.xiaopeng.api.feignClient.account.XpOperationUserClient;
import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient;
import com.xiaopeng.api.model.account.XpOperationsUser;
import com.xiaopeng.api.model.maintenance.XpChargingRecord;
import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
import com.xiaopeng.maintenance.model.query.XpChargingRecordPageQuery;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.common.security.service.TokenService;
import com.xiaopeng.maintenance.dto.XpChargingRecordStartDTO;
import com.xiaopeng.maintenance.dto.XpChargingRecordStopDTO;
@@ -14,12 +13,10 @@
import com.xiaopeng.maintenance.service.IXpChargingRecordService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.util.Objects;
import javax.validation.Valid;
/**
 * <p>
@@ -77,5 +74,17 @@
        return R.ok(xpChargingRecordVO);
    }
    /**
     * 通过车辆id查询充电分页列表
     *
     * @param query 查询参数
     * @return 充电记录分页列表
     */
    @ApiOperation(value = "通过车辆id查询充电分页列表", tags = {"管理后台-车辆管理-运营车辆管理"})
    @PostMapping("/api/v1/vehicle/queryChargingByVehicleId")
    public R<PageInfo<XpChargingRecordVO>> queryChargingByVehicleId(
            @Valid @RequestBody XpChargingRecordPageQuery query) {
        return R.ok(xpChargingRecordService.queryChargingByVehicleId(query));
    }
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpTaskController.java
@@ -14,20 +14,21 @@
import com.xiaopeng.maintenance.dto.SaveRoutineDetailDto;
import com.xiaopeng.maintenance.dto.SaveVehicleAccidentDto;
import com.xiaopeng.maintenance.model.query.TaskPageListQuery;
import com.xiaopeng.maintenance.model.vo.TaskAccidentDetailVO;
import com.xiaopeng.maintenance.model.vo.TaskChargingDetailVO;
import com.xiaopeng.maintenance.model.vo.TaskPageListVO;
import com.xiaopeng.maintenance.model.vo.TaskRoutineDetailVO;
import com.xiaopeng.maintenance.model.query.XpTaskRecordPageQuery;
import com.xiaopeng.maintenance.model.vo.*;
import com.xiaopeng.maintenance.service.IXpErrorTypeService;
import com.xiaopeng.maintenance.service.XpTaskService;
import com.xiaopeng.maintenance.vo.VehicleListVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.GetMapping;
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 javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
@@ -41,8 +42,6 @@
 */
@RestController
@Slf4j
@Api(tags = "运维APP-任务中心")
@RequestMapping("/api/v1/task")
public class XpTaskController {
    @Resource
    private XpTaskService xpTaskService;
@@ -54,25 +53,25 @@
    private XpFleetOperationsClient xpFleetOperationsClient;
    @Resource
    private XpVehicleClient xpVehicleClient;
    @ApiOperation(value = "任务中心列表", response = XpErrorType.class)
    @GetMapping("/errorTypeList")
    @ApiOperation(value = "任务中心列表", response = XpErrorType.class, tags = "运维APP-任务中心")
    @GetMapping("/api/v1/task/errorTypeList")
    public R<List<XpErrorType>> errorTypeList() {
        return xpErrorTypeService.errorTypeList();
    }
    @ApiOperation(value = "任务中心列表", response = TaskPageListVO.class)
    @PostMapping("/pageList")
    @ApiOperation(value = "任务中心列表", response = TaskPageListVO.class, tags = "运维APP-任务中心")
    @PostMapping("/api/v1/task/pageList")
    public R<PageInfo<TaskPageListVO>> pageList(@RequestBody TaskPageListQuery query) {
        PageInfo<TaskPageListVO> pageList = xpTaskService.pageList(query);
        return R.ok(pageList);
    }
    @ApiOperation(value = "事故任务确认到达")
    @GetMapping("/confirmArrive")
    @ApiOperation(value = "事故任务确认到达", tags = "运维APP-任务中心")
    @GetMapping("/api/v1/task/confirmArrive")
    @Transactional
    public R confirmArrive( Integer id) {
        return xpTaskService.confirmArrive(id);
    }
    @ApiOperation(value = "查询车辆不分页列表")
    @PostMapping("/listVehicle")
    @ApiOperation(value = "查询车辆不分页列表", tags = "运维APP-任务中心")
    @PostMapping("/api/v1/task/listVehicle")
    public R<List<VehicleListVO>> listVehicle() {
        LoginOperationUser loginOperationUser = tokenService.getLoginOperationUser();
        XpOperationsUser xpOperationsUser = loginOperationUser.getXpOperationsUser();
@@ -102,60 +101,60 @@
        return R.ok(new ArrayList<>());
    }
    @ApiOperation(value = "上传车辆事故")
    @PostMapping("/saveVehicleAccident")
    @ApiOperation(value = "上传车辆事故", tags = "运维APP-任务中心")
    @PostMapping("/api/v1/task/saveVehicleAccident")
    public R saveVehicleAccident(@RequestBody SaveVehicleAccidentDto dto) {
        LoginOperationUser loginOperationUser = tokenService.getLoginOperationUser();
        XpOperationsUser xpOperationsUser = loginOperationUser.getXpOperationsUser();
        xpTaskService.saveVehicleAccident(dto, xpOperationsUser);
        return R.ok();
    }
    @ApiOperation(value = "车辆事故任务详情")
    @GetMapping("/vehicleAccidentDetail")
    @ApiOperation(value = "车辆事故任务详情", tags = "运维APP-任务中心")
    @GetMapping("/api/v1/task/vehicleAccidentDetail")
    public R<TaskAccidentDetailVO> vehicleAccidentDetail(Long id) {
        return xpTaskService.vehicleAccidentDetail(id);
    }
    @ApiOperation(value = "车辆其他常规任务详情")
    @GetMapping("/vehicleRoutineDetail")
    @ApiOperation(value = "车辆其他常规任务详情", tags = "运维APP-任务中心")
    @GetMapping("/api/v1/task/vehicleRoutineDetail")
    public R<TaskRoutineDetailVO> vehicleRoutineDetail(Long id) {
        return xpTaskService.vehicleRoutineDetail(id);
    }
    @ApiOperation(value = "上传车辆其他常规任务详情")
    @PostMapping("/saveRoutineDetail")
    @ApiOperation(value = "上传车辆其他常规任务详情", tags = "运维APP-任务中心")
    @PostMapping("/api/v1/task/saveRoutineDetail")
    public R saveRoutineDetail(@RequestBody SaveRoutineDetailDto dto) {
        LoginOperationUser loginOperationUser = tokenService.getLoginOperationUser();
        Long id = loginOperationUser.getId();
        return xpTaskService.saveRoutineDetail(dto, id);
    }
    @ApiOperation(value = "车辆常规充电任务详情")
    @GetMapping("/chargingDetail")
    @ApiOperation(value = "车辆常规充电任务详情", tags = "运维APP-任务中心")
    @GetMapping("/api/v1/task/chargingDetail")
    public R<TaskChargingDetailVO> chargingDetail(Long id) {
        return xpTaskService.chargingDetail(id);
    }
    @ApiOperation(value = "车辆常规维修任务详情")
    @GetMapping("/repairDetail")
    @ApiOperation(value = "车辆常规维修任务详情", tags = "运维APP-任务中心")
    @GetMapping("/api/v1/task/repairDetail")
    public R<com.xiaopeng.maintenance.vo.TaskRepairDetailVO> repairDetail(Long id) {
        return xpTaskService.repairDetail(id);
    }
    @ApiOperation(value = "车辆常规整备任务详情")
    @GetMapping("/preparationDetail")
    @ApiOperation(value = "车辆常规整备任务详情", tags = "运维APP-任务中心")
    @GetMapping("/api/v1/task/preparationDetail")
    public R<com.xiaopeng.maintenance.vo.TaskPreparationDetailVO> preparationDetail(Long id) {
        return xpTaskService.preparationDetail(id);
    }
    @ApiOperation(value = "车辆常规检测任务详情")
    @GetMapping("/detectionDetail")
    @ApiOperation(value = "车辆常规检测任务详情", tags = "运维APP-任务中心")
    @GetMapping("/api/v1/task/detectionDetail")
    public R<com.xiaopeng.maintenance.vo.TaskDetectionDetailVO> detectionDetail(Long id) {
        return xpTaskService.detectionDetail(id);
    }
    @ApiOperation(value = "车辆常规洗车任务详情")
    @GetMapping("/cleanDetail")
    @ApiOperation(value = "车辆常规洗车任务详情", tags = "运维APP-任务中心")
    @GetMapping("/api/v1/task/cleanDetail")
    public R<com.xiaopeng.maintenance.vo.TaskCleanDetailVO> cleanDetail(Long id) {
        return xpTaskService.cleanDetail(id);
    }
    @ApiOperation(value = "处理车辆事故")
    @PostMapping("/handleVehicleAccident")
    @ApiOperation(value = "处理车辆事故", tags = "运维APP-任务中心")
    @PostMapping("/api/v1/task/handleVehicleAccident")
    @Transactional
    public R handleVehicleAccident(@RequestBody HandleVehicleAccidentDto dto) {
        LoginOperationUser loginOperationUser = tokenService.getLoginOperationUser();
@@ -163,4 +162,13 @@
        return xpTaskService.handleVehicleAccident(dto,xpOperationsUser);
    }
    /**
     * 通过车辆id查询任务事故分页列表
     * @return
     */
    @ApiOperation(value = "通过车辆id查询任务事故分页列表", tags = {"管理后台-车辆管理-运营车辆管理"})
    @PostMapping("/api/v1/vehicle/queryTaskByVehicleId")
    public R<PageInfo<XpTaskRecordVO>> queryTaskByVehicleId(@Valid @RequestBody XpTaskRecordPageQuery query) {
        return R.ok(xpTaskService.queryTaskByVehicleId(query));
    }
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpVehicleDetectionController.java
@@ -3,27 +3,20 @@
import com.xiaopeng.api.feignClient.account.XpOperationUserClient;
import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient;
import com.xiaopeng.api.model.account.XpOperationsUser;
import com.xiaopeng.api.model.maintenance.XpChargingRecord;
import com.xiaopeng.api.model.maintenance.XpVehicleClean;
import com.xiaopeng.api.model.maintenance.XpVehicleDetection;
import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.common.security.service.TokenService;
import com.xiaopeng.maintenance.dto.XpChargingRecordStartDTO;
import com.xiaopeng.maintenance.dto.XpVehicleDetectionDTO;
import com.xiaopeng.maintenance.model.vo.XpVehicleCleanVO;
import com.xiaopeng.maintenance.model.query.XpVehicleDetectionPageQuery;
import com.xiaopeng.maintenance.model.vo.XpVehicleDetectionVO;
import com.xiaopeng.maintenance.service.IXpChargingRecordService;
import com.xiaopeng.maintenance.service.IXpVehicleDetectionService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.time.LocalDateTime;
import java.util.Objects;
/**
 * <p>
@@ -84,5 +77,16 @@
        return R.ok(xpVehicleDetectionVO);
    }
    /**
     * 管理后台-车辆管理-运营车辆管理 通过车辆id查询检测分页列表
     *
     * @return
     */
    @ApiOperation(value = "通过车辆id查询检测分页列表", tags = {"管理后台-车辆管理-运营车辆管理"})
    @PostMapping("/api/v1/vehicle/queryDetectionByVehicleId")
    public R<PageInfo<XpVehicleDetectionVO>> queryDetectionByVehicleId(@Valid @RequestBody XpVehicleDetectionPageQuery query) {
        PageInfo<XpVehicleDetectionVO> pageInfo = xpVehicleDetectionService.queryDetectionByVehicleId(query);
        return R.ok(pageInfo);
    }
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpVehiclePreparationController.java
@@ -3,7 +3,7 @@
import com.xiaopeng.api.feignClient.account.XpOperationUserClient;
import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient;
import com.xiaopeng.api.model.query.XpVehiclePreparationPageQuery;
import com.xiaopeng.maintenance.model.query.XpVehiclePreparationPageQuery;
import com.xiaopeng.api.vo.maintenance.XpVehiclePreparationDetailVO;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.web.page.PageInfo;
@@ -15,6 +15,8 @@
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
/**
 * <p>
@@ -60,15 +62,15 @@
    }
    /**
     * 通过车辆ID查询整备分页列表(内部接口)
     * 通过车辆ID查询整备分页列表
     *
     * @param query 查询参数
     * @return 整备记录分页列表
     */
    @ApiOperation(value = "通过车辆ID查询整备分页列表", tags = {"内部接口"})
    @PostMapping("/inner/vehiclePreparation/queryByVehicleId")
    public R<PageInfo<XpVehiclePreparationDetailVO>> queryByVehicleId(@RequestBody XpVehiclePreparationPageQuery query) {
        return R.ok(xpVehiclePreparationService.queryByVehicleId(query));
    @ApiOperation(value = "通过车辆ID查询整备分页列表", tags = {"管理后台-车辆管理-运营车辆管理"})
    @PostMapping("/api/v1/vehicle/queryPreparationByVehicleId")
    public R<PageInfo<XpVehiclePreparationDetailVO>> queryPreparationByVehicleId(@Valid @RequestBody XpVehiclePreparationPageQuery query) {
        return R.ok(xpVehiclePreparationService.queryPreparationByVehicleId(query));
    }
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpVehicleRepairController.java
@@ -1,27 +1,22 @@
package com.xiaopeng.maintenance.controller;
import com.xiaopeng.api.feignClient.account.XpOperationUserClient;
import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient;
import com.xiaopeng.api.model.account.XpOperationsUser;
import com.xiaopeng.api.model.maintenance.XpVehiclePreparation;
import com.xiaopeng.api.model.maintenance.XpVehicleRepair;
import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.common.security.service.TokenService;
import com.xiaopeng.maintenance.dto.XpVehicleRepairReturnDTO;
import com.xiaopeng.maintenance.dto.XpVehicleRepairStartDTO;
import com.xiaopeng.maintenance.model.vo.XpVehiclePreparationVO;
import com.xiaopeng.maintenance.model.query.XpVehicleRepairPageQuery;
import com.xiaopeng.maintenance.model.vo.XpVehicleRepairVO;
import com.xiaopeng.maintenance.service.IXpVehicleRepairService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.time.LocalDateTime;
import java.util.Objects;
/**
 * <p>
@@ -90,5 +85,17 @@
        XpVehicleRepairVO xpVehicleRepairVO = xpVehicleRepairService.repairDetail(id);
        return R.ok(xpVehicleRepairVO);
    }
    /**
     * 管理后台-车辆管理-运营车辆管理 通过车辆id查询维修分页列表
     *
     * @return
     */
    @ApiOperation(value = "通过车辆id查询维修分页列表", tags = {"管理后台-车辆管理-运营车辆管理"})
    @PostMapping("/api/v1/vehicle/queryRepairByVehicleId")
    public R<PageInfo<XpVehicleRepairVO>> queryRepairByVehicleId(@Valid @RequestBody XpVehicleRepairPageQuery query) {
        PageInfo<XpVehicleRepairVO> pageInfo = xpVehicleRepairService.queryDetectionByVehicleId(query);
        return R.ok(pageInfo);
    }
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/model/query/XpChargingRecordPageQuery.java
copy from xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/query/XpVehiclePreparationPageQuery.java copy to xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/model/query/XpChargingRecordPageQuery.java
File was copied from xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/query/XpVehiclePreparationPageQuery.java
@@ -1,4 +1,4 @@
package com.xiaopeng.api.model.query;
package com.xiaopeng.maintenance.model.query;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xiaopeng.common.core.web.page.BasePage;
@@ -11,15 +11,15 @@
import java.time.LocalDate;
/**
 * 车辆整备分页查询参数
 * 充电记录分页查询参数
 *
 * @author mitao
 * @since 2026-02-11
 */
@Data
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "车辆整备分页查询参数")
public class XpVehiclePreparationPageQuery extends BasePage {
@ApiModel(value = "充电记录分页查询参数")
public class XpChargingRecordPageQuery extends BasePage {
    @NotNull(message = "车辆ID不能为空")
    @ApiModelProperty(value = "车辆ID", required = true)
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/model/query/XpTaskRecordPageQuery.java
New file
@@ -0,0 +1,40 @@
package com.xiaopeng.maintenance.model.query;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xiaopeng.common.core.web.page.BasePage;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotNull;
import java.time.LocalDate;
/**
 * @author MiTao
 * @date 2026-02-12 16:05
 *
 */
@Data
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "任务/事故查询对象")
public class XpTaskRecordPageQuery extends BasePage {
    @NotNull(message = "车辆ID不能为空")
    @ApiModelProperty(value = "车辆ID", required = true)
    private Long vehicleId;
    @ApiModelProperty(value = "任务类别 1常规 2事故")
    private Integer taskCategory;
    @ApiModelProperty(value = "任务类型id 任务类别为2时对应数据字典,多个逗号分割,为1的时候 枚举1车辆检查 2车辆充电 3车辆整备 4整备洗车 5车辆维修 6车辆保养 7车辆保险到期 8车辆年检到期 9车辆运营资质到期")
    private String taskTypeId;
    @ApiModelProperty(value = "开始时间")
    @JsonFormat(pattern = "yyyy-MM-dd")
    private LocalDate startTime;
    @ApiModelProperty(value = "结束时间")
    @JsonFormat(pattern = "yyyy-MM-dd")
    private LocalDate endTime;
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/model/query/XpVehicleDetectionPageQuery.java
copy from xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/query/XpVehiclePreparationPageQuery.java copy to xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/model/query/XpVehicleDetectionPageQuery.java
File was copied from xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/query/XpVehiclePreparationPageQuery.java
@@ -1,4 +1,4 @@
package com.xiaopeng.api.model.query;
package com.xiaopeng.maintenance.model.query;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xiaopeng.common.core.web.page.BasePage;
@@ -11,21 +11,21 @@
import java.time.LocalDate;
/**
 * 车辆整备分页查询参数
 * 车辆检测分页查询参数
 *
 * @author mitao
 * @since 2026-02-11
 */
@Data
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "车辆整备分页查询参数")
public class XpVehiclePreparationPageQuery extends BasePage {
@ApiModel(value = "检测记录分页查询参数")
public class XpVehicleDetectionPageQuery extends BasePage {
    @NotNull(message = "车辆ID不能为空")
    @ApiModelProperty(value = "车辆ID", required = true)
    private Long vehicleId;
    @ApiModelProperty(value = "操作人姓名")
    @ApiModelProperty(value = "检测人姓名")
    private String operationsUserName;
    @ApiModelProperty(value = "开始时间")
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/model/query/XpVehiclePreparationPageQuery.java
File was renamed from xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/query/XpVehiclePreparationPageQuery.java
@@ -1,4 +1,4 @@
package com.xiaopeng.api.model.query;
package com.xiaopeng.maintenance.model.query;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xiaopeng.common.core.web.page.BasePage;
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/model/query/XpVehicleRepairPageQuery.java
copy from xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/query/XpVehiclePreparationPageQuery.java copy to xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/model/query/XpVehicleRepairPageQuery.java
File was copied from xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/query/XpVehiclePreparationPageQuery.java
@@ -1,4 +1,4 @@
package com.xiaopeng.api.model.query;
package com.xiaopeng.maintenance.model.query;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xiaopeng.common.core.web.page.BasePage;
@@ -11,22 +11,25 @@
import java.time.LocalDate;
/**
 * 车辆整备分页查询参数
 * 车辆维修分页查询参数
 *
 * @author mitao
 * @since 2026-02-11
 */
@Data
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "车辆整备分页查询参数")
public class XpVehiclePreparationPageQuery extends BasePage {
@ApiModel(value = "车辆维修记录分页查询参数")
public class XpVehicleRepairPageQuery extends BasePage {
    @NotNull(message = "车辆ID不能为空")
    @ApiModelProperty(value = "车辆ID", required = true)
    private Long vehicleId;
    @ApiModelProperty(value = "操作人姓名")
    private String operationsUserName;
    @ApiModelProperty(value = "操作人")
    private String sendUserName;
    @ApiModelProperty(value = "维修原因")
    private String repairReason;
    @ApiModelProperty(value = "开始时间")
    @JsonFormat(pattern = "yyyy-MM-dd")
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/model/vo/XpTaskRecordVO.java
New file
@@ -0,0 +1,22 @@
package com.xiaopeng.maintenance.model.vo;
import com.xiaopeng.api.model.maintenance.XpTask;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
 * @author MiTao
 * @date 2026-02-12 16:05
 *
 */
@EqualsAndHashCode(callSuper = true)
@Data
@ApiModel("任务实图对象")
public class XpTaskRecordVO extends XpTask {
    @ApiModelProperty(value = "类型名称")
    private String typeName;
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/IXpChargingRecordService.java
@@ -2,6 +2,8 @@
import com.xiaopeng.api.model.maintenance.XpChargingRecord;
import com.baomidou.mybatisplus.extension.service.IService;
import com.xiaopeng.maintenance.model.query.XpChargingRecordPageQuery;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.maintenance.dto.XpChargingRecordStartDTO;
import com.xiaopeng.maintenance.dto.XpChargingRecordStopDTO;
import com.xiaopeng.maintenance.model.vo.XpChargingRecordVO;
@@ -39,4 +41,12 @@
     * @return
     */
    XpChargingRecordVO chargingDetail(Long id);
    /**
     * 通过车辆ID查询充电记录分页列表(内部接口)
     *
     * @param query 查询参数
     * @return 充电记录分页列表
     */
    PageInfo<XpChargingRecordVO> queryChargingByVehicleId(XpChargingRecordPageQuery query);
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/IXpVehicleDetectionService.java
@@ -2,7 +2,11 @@
import com.xiaopeng.api.model.maintenance.XpVehicleDetection;
import com.baomidou.mybatisplus.extension.service.IService;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.maintenance.model.query.XpVehicleDetectionPageQuery;
import com.xiaopeng.maintenance.model.vo.XpVehicleDetectionVO;
import javax.validation.Valid;
/**
 * <p>
@@ -21,4 +25,11 @@
     * @return
     */
    XpVehicleDetectionVO detectionDetail(Long id);
    /**
     * 管理后台-车辆管理-运营车辆管理 通过车辆id查询检测分页列表
     * @param query
     * @return
     */
    PageInfo<XpVehicleDetectionVO> queryDetectionByVehicleId(@Valid XpVehicleDetectionPageQuery query);
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/IXpVehiclePreparationService.java
@@ -2,7 +2,7 @@
import com.xiaopeng.api.model.maintenance.XpVehiclePreparation;
import com.baomidou.mybatisplus.extension.service.IService;
import com.xiaopeng.api.model.query.XpVehiclePreparationPageQuery;
import com.xiaopeng.maintenance.model.query.XpVehiclePreparationPageQuery;
import com.xiaopeng.api.vo.maintenance.XpVehiclePreparationDetailVO;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.maintenance.model.query.OperationRecordsQuery;
@@ -35,5 +35,5 @@
     * @param query 查询参数
     * @return 整备记录分页列表
     */
    PageInfo<XpVehiclePreparationDetailVO> queryByVehicleId(XpVehiclePreparationPageQuery query);
    PageInfo<XpVehiclePreparationDetailVO> queryPreparationByVehicleId(XpVehiclePreparationPageQuery query);
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/IXpVehicleRepairService.java
@@ -2,7 +2,11 @@
import com.xiaopeng.api.model.maintenance.XpVehicleRepair;
import com.baomidou.mybatisplus.extension.service.IService;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.maintenance.model.query.XpVehicleRepairPageQuery;
import com.xiaopeng.maintenance.model.vo.XpVehicleRepairVO;
import javax.validation.Valid;
/**
 * <p>
@@ -21,4 +25,11 @@
     * @return
     */
    XpVehicleRepairVO repairDetail(Long id);
    /**
     * 管理后台-车辆管理-运营车辆管理 通过车辆id查询维修分页列表
     *
     * @return
     */
    PageInfo<XpVehicleRepairVO> queryDetectionByVehicleId(@Valid XpVehicleRepairPageQuery query);
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/XpTaskService.java
@@ -9,12 +9,11 @@
import com.xiaopeng.maintenance.dto.SaveRoutineDetailDto;
import com.xiaopeng.maintenance.dto.SaveVehicleAccidentDto;
import com.xiaopeng.maintenance.model.query.WorkBenchQuery;
import com.xiaopeng.maintenance.model.vo.WorkBenchVO;
import com.xiaopeng.maintenance.model.query.XpTaskRecordPageQuery;
import com.xiaopeng.maintenance.model.vo.*;
import com.xiaopeng.maintenance.model.query.TaskPageListQuery;
import com.xiaopeng.maintenance.model.vo.TaskAccidentDetailVO;
import com.xiaopeng.maintenance.model.vo.TaskChargingDetailVO;
import com.xiaopeng.maintenance.model.vo.TaskPageListVO;
import com.xiaopeng.maintenance.model.vo.TaskRoutineDetailVO;
import javax.validation.Valid;
/**
 * <p>
@@ -51,4 +50,11 @@
    R<com.xiaopeng.maintenance.vo.TaskCleanDetailVO> cleanDetail(Long id);
    R confirmArrive(Integer id);
    /**
     * 通过车辆id查询任务事故分页列表
     * @param query
     * @return
     */
    PageInfo<XpTaskRecordVO> queryTaskByVehicleId(@Valid XpTaskRecordPageQuery query);
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpChargingRecordServiceImpl.java
@@ -1,22 +1,31 @@
package com.xiaopeng.maintenance.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xiaopeng.api.feignClient.account.XpOperationUserClient;
import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient;
import com.xiaopeng.api.model.account.XpOperationsUser;
import com.xiaopeng.api.model.maintenance.XpChargingRecord;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
import com.xiaopeng.maintenance.model.query.XpChargingRecordPageQuery;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.maintenance.dto.XpChargingRecordStartDTO;
import com.xiaopeng.maintenance.dto.XpChargingRecordStopDTO;
import com.xiaopeng.maintenance.mapper.XpChargingRecordMapper;
import com.xiaopeng.maintenance.model.vo.XpChargingRecordVO;
import com.xiaopeng.maintenance.service.IXpChargingRecordService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.time.LocalDateTime;
import java.util.Objects;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
 * <p>
@@ -81,4 +90,100 @@
        }
        return xpChargingRecordVO;
    }
    @Override
    public PageInfo<XpChargingRecordVO> queryChargingByVehicleId(XpChargingRecordPageQuery query) {
        // 1. 如果有操作人姓名过滤条件,先查询符合条件的用户ID列表
        List<Long> userIds = null;
        if (StringUtils.isNotBlank(query.getOperationsUserName())) {
            R<List<XpOperationsUser>> userResult = xpOperationUserClient.listByName(query.getOperationsUserName());
            List<XpOperationsUser> users = userResult.getData();
            // 如果没有匹配的用户,直接返回空结果
            if (CollectionUtils.isEmpty(users)) {
                return new PageInfo<>(query.getPageNum(), query.getPageSize());
            }
            // 提取用户ID列表
            userIds = users.stream()
                    .map(XpOperationsUser::getId)
                    .collect(Collectors.toList());
        }
        // 2. 使用 MyBatis-Plus Lambda 语法构建查询条件
        LambdaQueryWrapper<XpChargingRecord> wrapper = new LambdaQueryWrapper<>();
        // 必填条件: 车辆ID
        wrapper.eq(XpChargingRecord::getVehicleId, query.getVehicleId());
        // 可选条件: 操作人ID列表
        if (!CollectionUtils.isEmpty(userIds)) {
            wrapper.in(XpChargingRecord::getStartOperationsUserId, userIds);
        }
        // 可选条件: 开始时间
        if (query.getStartTime() != null) {
            wrapper.ge(XpChargingRecord::getCreateTime, query.getStartTime().atStartOfDay());
        }
        // 可选条件: 结束时间
        if (query.getEndTime() != null) {
            wrapper.le(XpChargingRecord::getCreateTime, query.getEndTime().atTime(23, 59, 59));
        }
        // 排序: 按创建时间倒序
        wrapper.orderByDesc(XpChargingRecord::getCreateTime);
        // 3. 执行分页查询
        Page<XpChargingRecord> page = new Page<>(query.getPageNum(), query.getPageSize());
        Page<XpChargingRecord> resultPage = this.page(page, wrapper);
        // 4. 转换为 VO 并填充操作人姓名
        List<XpChargingRecordVO> records = new ArrayList<>();
        if (!CollectionUtils.isEmpty(resultPage.getRecords())) {
            // 提取所有操作人ID
            List<Long> allUserIds = resultPage.getRecords().stream()
                    .flatMap(record -> Stream.of(
                            record.getStartOperationsUserId(),
                            record.getEndOperationsUserId()
                    ))
                    .filter(Objects::nonNull)
                    .distinct()
                    .collect(Collectors.toList());
            // 批量查询操作人信息
            Map<Long, String> userNameMap = new HashMap<>();
            if (!CollectionUtils.isEmpty(allUserIds)) {
                R<List<XpOperationsUser>> userResult = xpOperationUserClient.listByIds(allUserIds);
                List<XpOperationsUser> users = userResult.getData();
                if (!CollectionUtils.isEmpty(users)) {
                    userNameMap = users.stream()
                            .collect(Collectors.toMap(XpOperationsUser::getId, XpOperationsUser::getNickName));
                }
            }
            // 转换并填充数据
            for (XpChargingRecord chargingRecord : resultPage.getRecords()) {
                XpChargingRecordVO vo = new XpChargingRecordVO();
                BeanUtils.copyProperties(chargingRecord, vo);
                vo.setOperationTime(chargingRecord.getCreateTime());
                // 填充操作人姓名
                if (chargingRecord.getStartOperationsUserId() != null) {
                    String userName = userNameMap.get(chargingRecord.getStartOperationsUserId());
                    vo.setOperatorStartName(userName);
                }
                if (chargingRecord.getEndOperationsUserId() != null) {
                    String userName = userNameMap.get(chargingRecord.getEndOperationsUserId());
                    vo.setOperatorEndName(userName);
                }
                records.add(vo);
            }
        }
        // 5. 构建分页结果
        PageInfo<XpChargingRecordVO> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize());
        pageInfo.setRecords(records);
        pageInfo.setTotal(resultPage.getTotal());
        return pageInfo;
    }
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpTaskServiceImpl.java
@@ -6,7 +6,6 @@
import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient;
import com.xiaopeng.api.model.account.XpOperationsUser;
import com.xiaopeng.api.model.maintenance.*;
import com.xiaopeng.api.model.maintenance.XpErrorType;
import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.exception.ServiceException;
@@ -16,21 +15,17 @@
import com.xiaopeng.maintenance.dto.SaveRoutineDetailDto;
import com.xiaopeng.maintenance.dto.SaveVehicleAccidentDto;
import com.xiaopeng.maintenance.mapper.*;
import com.xiaopeng.maintenance.model.query.WorkBenchQuery;
import com.xiaopeng.maintenance.model.query.TaskPageListQuery;
import com.xiaopeng.maintenance.model.query.WorkBenchQuery;
import com.xiaopeng.maintenance.model.query.XpTaskRecordPageQuery;
import com.xiaopeng.maintenance.model.vo.*;
import com.xiaopeng.maintenance.service.XpTaskService;
import com.xiaopeng.maintenance.model.vo.WorkBenchVO;
import com.xiaopeng.maintenance.model.vo.TaskAccidentDetailVO;
import com.xiaopeng.maintenance.model.vo.TaskChargingDetailVO;
import com.xiaopeng.maintenance.model.vo.TaskPageListVO;
import com.xiaopeng.maintenance.model.vo.TaskRoutineDetailVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
@@ -584,4 +579,8 @@
        return R.ok();
    }
    @Override
    public PageInfo<XpTaskRecordVO> queryTaskByVehicleId(XpTaskRecordPageQuery query) {
        return null;
    }
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpVehicleDetectionServiceImpl.java
@@ -1,19 +1,27 @@
package com.xiaopeng.maintenance.service.impl;
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.xiaopeng.api.feignClient.account.XpOperationUserClient;
import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient;
import com.xiaopeng.api.model.account.XpOperationsUser;
import com.xiaopeng.api.model.maintenance.XpVehicleDetection;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.maintenance.mapper.XpVehicleDetectionMapper;
import com.xiaopeng.maintenance.model.query.XpVehicleDetectionPageQuery;
import com.xiaopeng.maintenance.model.vo.XpVehicleDetectionVO;
import com.xiaopeng.maintenance.service.IXpVehicleDetectionService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.Objects;
import java.util.*;
import java.util.stream.Collectors;
/**
 * <p>
@@ -52,4 +60,93 @@
        }
        return xpVehicleDetectionVO;
    }
    @Override
    public PageInfo<XpVehicleDetectionVO> queryDetectionByVehicleId(XpVehicleDetectionPageQuery query) {
        // 1. 如果有操作人姓名过滤条件,先查询符合条件的用户ID列表
        List<Long> userIds = null;
        if (StringUtils.isNotBlank(query.getOperationsUserName())) {
            R<List<XpOperationsUser>> userResult = xpOperationUserClient.listByName(query.getOperationsUserName());
            List<XpOperationsUser> users = userResult.getData();
            // 如果没有匹配的用户,直接返回空结果
            if (CollectionUtils.isEmpty(users)) {
                return new PageInfo<>(query.getPageNum(), query.getPageSize());
            }
            // 提取用户ID列表
            userIds = users.stream()
                    .map(XpOperationsUser::getId)
                    .collect(Collectors.toList());
        }
        // 2. 使用 MyBatis-Plus Lambda 语法构建查询条件
        LambdaQueryWrapper<XpVehicleDetection> wrapper = new LambdaQueryWrapper<>();
        // 必填条件: 车辆ID
        wrapper.eq(XpVehicleDetection::getVehicleId, query.getVehicleId());
        // 可选条件: 操作人ID列表
        if (!CollectionUtils.isEmpty(userIds)) {
            wrapper.in(XpVehicleDetection::getOperationsUserId, userIds);
        }
        // 可选条件: 开始时间
        if (query.getStartTime() != null) {
            wrapper.ge(XpVehicleDetection::getCreateTime, query.getStartTime().atStartOfDay());
        }
        // 可选条件: 结束时间
        if (query.getEndTime() != null) {
            wrapper.le(XpVehicleDetection::getCreateTime, query.getEndTime().atTime(23, 59, 59));
        }
        // 排序: 按创建时间倒序
        wrapper.orderByDesc(XpVehicleDetection::getCreateTime);
        // 3. 执行分页查询
        Page<XpVehicleDetection> page = new Page<>(query.getPageNum(), query.getPageSize());
        Page<XpVehicleDetection> resultPage = this.page(page, wrapper);
        // 4. 转换为 VO 并填充操作人姓名
        List<XpVehicleDetectionVO> records = new ArrayList<>();
        if (!CollectionUtils.isEmpty(resultPage.getRecords())) {
            // 提取所有操作人ID
            List<Long> allUserIds = resultPage.getRecords().stream()
                    .map(XpVehicleDetection::getOperationsUserId)
                    .filter(Objects::nonNull)
                    .distinct()
                    .collect(Collectors.toList());
            // 批量查询操作人信息
            Map<Long, String> userNameMap = new HashMap<>();
            if (!CollectionUtils.isEmpty(allUserIds)) {
                R<List<XpOperationsUser>> userResult = xpOperationUserClient.listByIds(allUserIds);
                List<XpOperationsUser> users = userResult.getData();
                if (!CollectionUtils.isEmpty(users)) {
                    userNameMap = users.stream()
                            .collect(Collectors.toMap(XpOperationsUser::getId, XpOperationsUser::getNickName));
                }
            }
            // 转换并填充数据
            for (XpVehicleDetection xpVehicleDetection : resultPage.getRecords()) {
                XpVehicleDetectionVO vo = new XpVehicleDetectionVO();
                BeanUtils.copyProperties(xpVehicleDetection, vo);
                vo.setOperationTime(xpVehicleDetection.getCreateTime());
                // 填充操作人姓名
                if (xpVehicleDetection.getOperationsUserId() != null) {
                    String userName = userNameMap.get(xpVehicleDetection.getOperationsUserId());
                    vo.setOperatorStartName(userName);
                }
                records.add(vo);
            }
        }
        // 5. 构建分页结果
        PageInfo<XpVehicleDetectionVO> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize());
        pageInfo.setRecords(records);
        pageInfo.setTotal(resultPage.getTotal());
        return pageInfo;
    }
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpVehiclePreparationServiceImpl.java
@@ -7,7 +7,7 @@
import com.xiaopeng.api.model.account.XpOperationsUser;
import com.xiaopeng.api.model.maintenance.XpVehiclePreparation;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaopeng.api.model.query.XpVehiclePreparationPageQuery;
import com.xiaopeng.maintenance.model.query.XpVehiclePreparationPageQuery;
import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
import com.xiaopeng.api.vo.maintenance.XpVehiclePreparationDetailVO;
import com.xiaopeng.common.core.domain.R;
@@ -144,7 +144,7 @@
    }
    @Override
    public PageInfo<XpVehiclePreparationDetailVO> queryByVehicleId(XpVehiclePreparationPageQuery query) {
    public PageInfo<XpVehiclePreparationDetailVO> queryPreparationByVehicleId(XpVehiclePreparationPageQuery query) {
        // 1. 如果有操作人姓名过滤条件,先查询符合条件的用户ID列表
        List<Long> userIds = null;
        if (StringUtils.isNotBlank(query.getOperationsUserName())) {
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpVehicleRepairServiceImpl.java
@@ -1,19 +1,28 @@
package com.xiaopeng.maintenance.service.impl;
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.xiaopeng.api.feignClient.account.XpOperationUserClient;
import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient;
import com.xiaopeng.api.model.account.XpOperationsUser;
import com.xiaopeng.api.model.maintenance.XpVehicleRepair;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.maintenance.mapper.XpVehicleRepairMapper;
import com.xiaopeng.maintenance.model.query.XpVehicleRepairPageQuery;
import com.xiaopeng.maintenance.model.vo.XpVehicleRepairVO;
import com.xiaopeng.maintenance.service.IXpVehicleRepairService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.Objects;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
 * <p>
@@ -56,4 +65,104 @@
        }
        return xpVehicleRepairVO;
    }
    @Override
    public PageInfo<XpVehicleRepairVO> queryDetectionByVehicleId(XpVehicleRepairPageQuery query) {
        // 1. 如果有操作人姓名过滤条件,先查询符合条件的用户ID列表
        List<Long> userIds = null;
        if (StringUtils.isNotBlank(query.getSendUserName())) {
            R<List<XpOperationsUser>> userResult = xpOperationUserClient.listByName(query.getSendUserName());
            List<XpOperationsUser> users = userResult.getData();
            // 如果没有匹配的用户,直接返回空结果
            if (CollectionUtils.isEmpty(users)) {
                return new PageInfo<>(query.getPageNum(), query.getPageSize());
            }
            // 提取用户ID列表
            userIds = users.stream()
                    .map(XpOperationsUser::getId)
                    .collect(Collectors.toList());
        }
        // 2. 使用 MyBatis-Plus Lambda 语法构建查询条件
        LambdaQueryWrapper<XpVehicleRepair> wrapper = new LambdaQueryWrapper<>();
        // 必填条件: 车辆ID
        wrapper.eq(XpVehicleRepair::getVehicleId, query.getVehicleId());
        // 可选条件: 操作人ID列表
        if (!CollectionUtils.isEmpty(userIds)) {
            wrapper.in(XpVehicleRepair::getSendUserId, userIds);
        }
        // 可选条件: 开始时间
        if (query.getStartTime() != null) {
            wrapper.ge(XpVehicleRepair::getCreateTime, query.getStartTime().atStartOfDay());
        }
        // 可选条件: 结束时间
        if (query.getEndTime() != null) {
            wrapper.le(XpVehicleRepair::getCreateTime, query.getEndTime().atTime(23, 59, 59));
        }
        // 可选条件: 维修原因
        if (query.getRepairReason() != null) {
            wrapper.like(XpVehicleRepair::getRepairReason, query.getRepairReason());
        }
        // 排序: 按创建时间倒序
        wrapper.orderByDesc(XpVehicleRepair::getCreateTime);
        // 3. 执行分页查询
        Page<XpVehicleRepair> page = new Page<>(query.getPageNum(), query.getPageSize());
        Page<XpVehicleRepair> resultPage = this.page(page, wrapper);
        // 4. 转换为 VO 并填充操作人姓名
        List<XpVehicleRepairVO> records = new ArrayList<>();
        if (!CollectionUtils.isEmpty(resultPage.getRecords())) {
            // 提取所有操作人ID
            List<Long> allUserIds = resultPage.getRecords().stream()
                    .flatMap(record -> Stream.of(
                            record.getSendUserId(),
                            record.getReturnUserId()
                    ))
                    .filter(Objects::nonNull)
                    .distinct()
                    .collect(Collectors.toList());
            // 批量查询操作人信息
            Map<Long, String> userNameMap = new HashMap<>();
            if (!CollectionUtils.isEmpty(allUserIds)) {
                R<List<XpOperationsUser>> userResult = xpOperationUserClient.listByIds(allUserIds);
                List<XpOperationsUser> users = userResult.getData();
                if (!CollectionUtils.isEmpty(users)) {
                    userNameMap = users.stream()
                            .collect(Collectors.toMap(XpOperationsUser::getId, XpOperationsUser::getNickName));
                }
            }
            // 转换并填充数据
            for (XpVehicleRepair chargingRecord : resultPage.getRecords()) {
                XpVehicleRepairVO vo = new XpVehicleRepairVO();
                BeanUtils.copyProperties(chargingRecord, vo);
                vo.setOperationTime(chargingRecord.getCreateTime());
                // 填充操作人姓名
                if (chargingRecord.getSendUserId() != null) {
                    String userName = userNameMap.get(chargingRecord.getSendUserId());
                    vo.setOperatorStartName(userName);
                }
                if (chargingRecord.getReturnUserId() != null) {
                    String userName = userNameMap.get(chargingRecord.getReturnUserId());
                    vo.setOperatorEndName(userName);
                }
                records.add(vo);
            }
        }
        // 5. 构建分页结果
        PageInfo<XpVehicleRepairVO> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize());
        pageInfo.setRecords(records);
        pageInfo.setTotal(resultPage.getTotal());
        return pageInfo;
    }
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpPricingServiceImpl.java
@@ -1,6 +1,7 @@
package com.xiaopeng.operation.service.impl;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -33,6 +34,7 @@
import com.xiaopeng.operation.service.IXpGeoQueryEntityService;
import com.xiaopeng.operation.service.XpPricingService;
import com.xiaopeng.operation.utils.XpPricingUtil;
import com.xiaopeng.operation.utils.holiday.HolidayUtil;
import com.xiaopeng.operation.utils.map.FastDistanceCalculator;
import com.xiaopeng.operation.vo.XpPricingCardVo;
import org.springframework.beans.factory.annotation.Autowired;
@@ -100,14 +102,19 @@
    @Resource
    private XpAppUserClient xpAppUserClient;
    @Resource
    private HolidayUtil holidayUtil;
    @Autowired
    private IXpGeoQueryEntityService geoQueryEntityService;
    @Autowired
    private XpElectronicFenceMapper xpElectronicFenceMapper;
    // 自定义线程池用于并行执行任务
    private final ExecutorService executorService;
    // 初始化自定义线程池
    public XpPricingServiceImpl() {
@@ -170,7 +177,7 @@
                + "-" + routeAndFareDto.getDestination().getLongitude() + "-" + routeAndFareDto.getDestination().getLatitude() + "-" + getCurrentTimeSlot() + "-" + userId;
        if (redisService.hasKey(key)) {
            String jsonStr = Objects.requireNonNull(redisService.getCacheObject( key)).toString();
            String jsonStr = Objects.requireNonNull(redisService.getCacheObject(key)).toString();
            RouteAndFareVo RouteAndFareVo = JSONObject.parseObject(jsonStr, RouteAndFareVo.class);
            return (RouteAndFareVo);
        }
@@ -215,11 +222,11 @@
        // 优惠券
        CompletableFuture<R<UserCouponVo>> couponFuture = CompletableFuture.supplyAsync(
                () -> {
                        // 优惠券
                        return xpAppUserCouponClient.getUserCoupon(
                    // 优惠券
                    return xpAppUserCouponClient.getUserCoupon(
//                                new GetUserCouponDto(Long.valueOf(userId), xpPricingCardVo.getTotalPrice(),routeAndFareDto.getOpenCityId())
                                new GetUserCouponDto(Long.valueOf(userId), 1d,routeAndFareDto.getOpenCityId())
                        );
                            new GetUserCouponDto(Long.valueOf(userId), 1d, routeAndFareDto.getOpenCityId())
                    );
                },
                executorService
        );
@@ -285,7 +292,7 @@
        // 10. 检查等待时间
        Integer waitTime = getWaitTime(routeAndFareDto.getOrigin().getLongitude(), routeAndFareDto.getOrigin().getLatitude());
        if(waitTime>3){
        if (waitTime > 3) {
            throw new ServiceException("当前区域正在等待中,请耐心等待", I18nKeyConstant.WAITING_TIME);
        }
        fareVo.setWaitingTime(waitTime);
@@ -315,7 +322,7 @@
     * @return
     */
    @Override
    public Integer getWaitTime(double lon,double lat) {
    public Integer getWaitTime(double lon, double lat) {
        List<XpGeoQueryEntity> entities = geoQueryEntityService.findByLocationWithin500MetersAndLastWeekAndStatusGreater(
                lon,
                lat,
@@ -324,7 +331,7 @@
        if (entities.isEmpty()) {
           return 1;
            return 1;
        } else {
            // 已完成接单的数据
            List<XpGeoQueryEntity> validEntities = entities.stream().filter(e -> e.getStatus() > 1).collect(Collectors.toList());
@@ -336,7 +343,7 @@
                // 未完成接单的数量
                int count = entities.size() - validEntities.size();
                if (count == 0) {
                   return 1;
                    return 1;
                } else {
                    double waitMinutes = (average * count) / 60;
                    if (waitMinutes > 3) {
@@ -345,19 +352,28 @@
                    return (int) waitMinutes;
                }
            } else {
                return  1;
                return 1;
            }
        }
    }
    @Override
    public Long saveOrder(XpOrderDto dto, String uid) {
        // 是否在运营区域时间内
        XpElectronicFenceArea xpElectronicFenceArea = xpElectronicFenceAreaMapper.selectById(dto.getXpElectronicFenceAreaId());
        XpElectronicFence xpElectronicFence = xpElectronicFenceMapper.selectById(xpElectronicFenceArea.getElectronicId());
        String operationStrategy = xpElectronicFence.getOperationStrategy();
        Boolean inOperationTime = isInOperationTime(operationStrategy);
        if (!inOperationTime) {
            throw new ServiceException("当前区域未开通服务", I18nKeyConstant.NO_CURRENT_REGION);
        }
        Integer cancelCount = xpTradingStrategyMapper.selectOne(null).getCancleCount();
        // 判断是否有进行的订单
        R<Long> r = xpOrderClient.hasUnPaodOrder(uid);
        if(r.getData()>0){
        if (r.getData() > 0) {
            throw new RuntimeException("有正在进行的订单");
        }
@@ -369,30 +385,42 @@
        // 判断当天取消的次数 后台配置 redis 查询
        Object cancelOrder = redisService.getCacheObject("CANCEL_ORDER_" + uid);
        if(cancelOrder!=null){
        // 静默处理
        boolean isSilent = false;
        if (cancelOrder != null) {
            Integer num = Integer.valueOf(cancelOrder.toString());
            if(num>=cancelCount){
                return 0l;
            if (num >= cancelCount) {
                isSilent =true;
            }
        }
        // 获取起步里程
        XpPricing xpPricing = this.baseMapper.selectOne(new LambdaQueryWrapper<XpPricing>().eq(XpPricing::getCityId, dto.getOpenCityId()));
        Integer startMileage = XpPricingUtil.getStartMileage(xpPricing.getStartingFareJson());
        if (startMileage == null) {
            throw new ServiceException("当前区域未开通服务", I18nKeyConstant.NO_CURRENT_REGION);
        }
        // 根据id获取手机号
        Boolean isPriorityDispatch=false;
        Boolean isPriorityDispatch = false;
        R<XpAppUser> xpAppUserR = xpAppUserClient.queryOperationsUserById(Long.valueOf(uid));
        if(xpAppUserR.getCode()==R.SUCCESS){
        if (xpAppUserR.getCode() == R.SUCCESS) {
            Long count = xpWhitelistMapper.selectCount(new LambdaQueryWrapper<XpWhitelist>().eq(XpWhitelist::getAccount, xpAppUserR.getData().getPhoneNumber()).eq(XpWhitelist::getIsPriorityDispatch, 1));
            if(count>0){
                isPriorityDispatch=true;
            if (count > 0) {
                isPriorityDispatch = true;
            }
        }
        // 生成订单数据
        XpOrder xpOrder = new XpOrder();
        xpOrder.setStartMileage(Double.valueOf(startMileage));
        xpOrder.setAppUserId(Long.valueOf(uid));
        xpOrder.setOrderNumber("XP"+System.currentTimeMillis());
        xpOrder.setOrderNumber("XP" + System.currentTimeMillis());
        xpOrder.setPlacementLon(dto.getPlacementLon());
        xpOrder.setPlacementLat(dto.getPlacementLat());
        xpOrder.setPlacementAddress(dto.getPlacementAddress());
@@ -444,27 +472,32 @@
        R<RouteVo> distanceAndDuration = xpMapClient.getDistanceAndDuration(routeAndFareDto);
        Integer distance = 0;
        Integer duration = 0;
        if(distanceAndDuration.getCode()!=200){
            //静默处理
            return 0l;
        if (distanceAndDuration.getCode() != 200) {
            throw new ServiceException("订单生成失败", I18nKeyConstant.ORDER_CREATE_FAIL);
        }
        distance=distanceAndDuration.getData().getDistance();
        duration=distanceAndDuration.getData().getDuration();
        distance = distanceAndDuration.getData().getDistance();
        duration = distanceAndDuration.getData().getDuration();
        // 产生订单
        R<Long> addOrderR = xpOrderClient.addOrder(xpOrder);
        if(addOrderR.getCode()!=R.SUCCESS){
        if (addOrderR.getCode() != R.SUCCESS) {
            throw new ServiceException("订单生成失败", I18nKeyConstant.ORDER_CREATE_FAIL);
        }
        Long orderId = addOrderR.getData();
        // 静默处理 不推单
        if(isSilent){
            return orderId;
        }
        // 最大距离
        Object maxPushDistanceObj = redisService.getCacheObject(CacheConstants.MAX_PUSH_DISTANCE);
        Double maxPushDistance= 0.0;
        if(maxPushDistanceObj!=null){
             maxPushDistance = Double.valueOf(maxPushDistanceObj.toString());
        }else {
             maxPushDistance = xpTradingStrategyMapper.selectOne(null).getThreePushDistance();
        Double maxPushDistance = 0.0;
        if (maxPushDistanceObj != null) {
            maxPushDistance = Double.valueOf(maxPushDistanceObj.toString());
        } else {
            maxPushDistance = xpTradingStrategyMapper.selectOne(null).getThreePushDistance();
        }
        // 找出现在所有的队列 通过计算距离 算出目前应该放在那个队列  如果没有符合的新增一个队列  符合后看是否白名单账号 是则直接放在队列前端
@@ -474,20 +507,20 @@
            String lonLat = s.split("-")[2];
            // 和上车点进行判断是否<maxPushDistance
            double v = FastDistanceCalculator.distanceFast(Double.parseDouble(lonLat.split(",")[1]), Double.parseDouble(lonLat.split(",")[0]), xpPoint.getPointLat(), xpPoint.getPointLon());
            if(v<maxPushDistance){
                if(isPriorityDispatch){
            if (v < maxPushDistance) {
                if (isPriorityDispatch) {
                    // 头部  value 订单_经纬度_状态_用户id_订单编号_距离_时间
                    redisService.addToTail(s,orderId+"_"+xpPoint.getPointLon()+","+xpPoint.getPointLat()+"_0"+"_"+uid+"_"+xpOrder.getOrderNumber()+"_"+distance+"_"+duration+"_"+routeAndFareDto.getRoutePlanRule());
                }else {
                    redisService.addToTail(s, orderId + "_" + xpPoint.getPointLon() + "," + xpPoint.getPointLat() + "_0" + "_" + uid + "_" + xpOrder.getOrderNumber() + "_" + distance + "_" + duration + "_" + routeAndFareDto.getRoutePlanRule());
                } else {
                    // 尾部
                    redisService.addToTail(s,orderId+"_"+xpPoint.getPointLon()+","+xpPoint.getPointLat()+"_0"+"_"+uid+"_"+xpOrder.getOrderNumber()+"_"+distance+"_"+duration+"_"+routeAndFareDto.getRoutePlanRule());
                    redisService.addToTail(s, orderId + "_" + xpPoint.getPointLon() + "," + xpPoint.getPointLat() + "_0" + "_" + uid + "_" + xpOrder.getOrderNumber() + "_" + distance + "_" + duration + "_" + routeAndFareDto.getRoutePlanRule());
                }
                return orderId;
            }
        }
        String key = CacheConstants.QUEUE_POINT_ID+"-"+ xpPoint.getId()+"-"+xpPoint.getPointLon()+","+xpPoint.getPointLat();
        redisService.setCacheList(key,Arrays.asList(orderId+"_"+xpPoint.getPointLon()+","+xpPoint.getPointLat()+"_0"+"_"+uid+"_"+xpOrder.getOrderNumber()+"_"+distance+"_"+duration+"_"+routeAndFareDto.getRoutePlanRule()));
        String key = CacheConstants.QUEUE_POINT_ID + "-" + xpPoint.getId() + "-" + xpPoint.getPointLon() + "," + xpPoint.getPointLat();
        redisService.setCacheList(key, Arrays.asList(orderId + "_" + xpPoint.getPointLon() + "," + xpPoint.getPointLat() + "_0" + "_" + uid + "_" + xpOrder.getOrderNumber() + "_" + distance + "_" + duration + "_" + routeAndFareDto.getRoutePlanRule()));
        return orderId;
//
@@ -497,12 +530,54 @@
//
        // 产生订单  存订单数据  // 下发指令  消息推送用户端
//        return null;
    }
    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;
    }
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/utils/XpPricingUtil.java
@@ -35,6 +35,35 @@
    /**
     * 获取起步里程
     * @param startingFareJsonStr
     * @return
     */
    public static Integer getStartMileage(String startingFareJsonStr) {
        Date date = new Date();
        JSONArray startingFareJson = JSONObject.parseArray(startingFareJsonStr);
        for (Object o : startingFareJson) {
            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()) {
                Integer mileage = startingFare.getInteger("num4");
                return mileage;
            }
        }
        return null;
    }
    /**
     *  计算基础价格
     * @param rule 基础规则
     * @param distance 里程
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/utils/holiday/HolidayUtil.java
@@ -4,6 +4,7 @@
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.xiaopeng.common.core.constant.CacheConstants;
import com.xiaopeng.common.core.utils.HttpUtils;
import com.xiaopeng.common.redis.service.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
@@ -43,4 +44,38 @@
        return false;
    }
    /**
     * 2非工作日  0工作日  1节假日 3调休日
     * @return
     */
    public  Integer isHolidayToday() {
        LocalDate now = LocalDate.now();
        Object cacheObject = redisService.getCacheObject(CacheConstants.IS_DAY + now);
        // 判断缓存里面是否有节假日算法
        if (cacheObject!=null) {
            return Integer.valueOf(cacheObject.toString());
        }
        String result = HttpUtils.sendGet("https://publicapi.xiaoai.me/holiday/day?date=" +now);
//        String result = HttpUtils.sendGet("https://publicapi.xiaoai.me/holiday/day?date=2026-01-04");
        JSONObject jsonObject = JSONObject.parseObject(result);
        Object data = jsonObject.get("data");
        JSONArray parse = JSONArray.parse(data.toString());
        for (int i = 0; i < parse.size(); i++) {
            JSONObject jsonObject1 = parse.getJSONObject(i);
            String daytype = jsonObject1.get("daytype").toString();
            if (daytype.equals("0")) {
                redisService.setCacheObject(CacheConstants.IS_DAY + now, "0", 1l, TimeUnit.DAYS);
                return 0;
            } else if (daytype.equals("1")) {
                redisService.setCacheObject(CacheConstants.IS_DAY + now, "1", 1l, TimeUnit.DAYS);
                return 1;
            } else if (daytype.equals("2")) {
                redisService.setCacheObject(CacheConstants.IS_DAY + now, "0", 1l, TimeUnit.DAYS);
                return 0;
            }
        }
        return 0;
    }
}
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java
@@ -797,10 +797,16 @@
                        DateUtils.localDateTimeToDate(LocalDateTime.now().plusMinutes(5)),
                        cancelJobMaps
                );
                // 车辆到达上车点时间
                xpOrder.setArrivalTime(LocalDateTime.now());
                break;
            case 5:
                // 删除定时任务job
                QuartzManager.removeJob((OrderCancelJob.name + xpOrder.getId()).toUpperCase(), TimeJobType.ORDER_CANCEL);
                break;
            case 6:
                // 行程开始时间
                xpOrder.setTripBegin(LocalDateTime.now());
                break;
            case 7:
                // 查询自动结束行程时间
@@ -819,7 +825,7 @@
                );
                break;
        }
        baseMapper.updateById(xpOrder);
        this.updateById(xpOrder);
        return R.ok();
    }
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpVehicleController.java
@@ -10,12 +10,12 @@
import com.xiaopeng.api.dto.vehicleConvoy.VehicleTemperatureDto;
import com.xiaopeng.api.feignClient.order.XpOrderClient;
import com.xiaopeng.api.model.order.XpOrder;
import com.xiaopeng.api.feignClient.maintenance.XpChargingRecordClient;
import com.xiaopeng.api.feignClient.maintenance.XpVehiclePreparationClient;
import com.xiaopeng.api.model.query.XpVehiclePreparationPageQuery;
import com.xiaopeng.api.feignClient.order.XpOrderClient;
import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
import com.xiaopeng.api.vo.vehicleConvoy.VehicleTemperatureVo;
import com.xiaopeng.api.model.vehicleConvoy.XpVehicleAnnualRecord;
import com.xiaopeng.api.vo.maintenance.XpVehiclePreparationDetailVO;
import com.xiaopeng.api.vo.vehicleConvoy.VehicleTemperatureVo;
import com.xiaopeng.api.vo.vehicleConvoy.VehiclesCommandCallbackVo;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.exception.ServiceException;
@@ -50,7 +50,6 @@
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
 * <p>
@@ -70,7 +69,7 @@
    private final XpOrderClient xpOrderClient;
    private final IXpVehicleAnnualRecordService xpVehicleAnnualRecordService;
    private final XpVehiclePreparationClient xpVehiclePreparationClient;
    private final XpChargingRecordClient xpChargingRecordClient;
    /**
     * 根据ID列表批量查询车辆信息(内部接口)
     *
@@ -113,7 +112,7 @@
     * @param dto 车辆信息
     * @return 操作结果
     */
    @ApiOperation(value = "新增车辆", tags = {"管理后台-车辆车队管理-在库车辆管理"})
    @ApiOperation(value = "新增车辆", tags = {"管理后台-车辆管理-在库车辆管理"})
    @PostMapping("/api/v1/vehicle/add")
    public R<?> addVehicle(@Valid @RequestBody VehicleAddDTO dto) {
        xpVehicleService.addVehicle(dto);
@@ -126,7 +125,7 @@
     * @param dto 车辆信息
     * @return 操作结果
     */
    @ApiOperation(value = "编辑车辆", tags = {"管理后台-车辆车队管理-在库车辆管理"})
    @ApiOperation(value = "编辑车辆", tags = {"管理后台-车辆管理-在库车辆管理"})
    @PostMapping("/api/v1/vehicle/edit")
    public R<?> editVehicle(@Valid @RequestBody VehicleEditDTO dto) {
        xpVehicleService.editVehicle(dto);
@@ -139,7 +138,7 @@
     * @param dto 车辆信息
     * @return 操作结果
     */
    @ApiOperation(value = "完善/更新车辆信息", tags = {"管理后台-车辆车队管理-在库车辆管理"})
    @ApiOperation(value = "完善/更新车辆信息", tags = {"管理后台-车辆管理-在库车辆管理"})
    @PostMapping("/api/v1/vehicle/improveInfo")
    public R<?> improveInfo(@RequestBody VehicleImproveInfoDTO dto) {
        xpVehicleService.improveInfo(dto);
@@ -152,7 +151,7 @@
     * @param idStr 车辆ID字符串列表
     * @return 操作结果
     */
    @ApiOperation(value = "批量运营", tags = {"管理后台-车辆车队管理-在库车辆管理"})
    @ApiOperation(value = "批量运营", tags = {"管理后台-车辆管理-在库车辆管理"})
    @PostMapping("/api/v1/vehicle/batchOperation")
    @ApiImplicitParam(name = "idStr", value = "车辆ID字符串列表,逗号分隔", required = true, dataTypeClass = String.class)
    public R<?> batchOperation(@RequestParam String idStr) {
@@ -166,7 +165,7 @@
     * @param dto 批量设置运营区域参数
     * @return 操作结果
     */
    @ApiOperation(value = "批量设置运营区域", tags = {"管理后台-车辆车队管理-在库车辆管理"})
    @ApiOperation(value = "批量设置运营区域", tags = {"管理后台-车辆管理-在库车辆管理"})
    @PostMapping("/api/v1/vehicle/batchSetElectronic")
    public R<?> batchSetElectronic(@Valid @RequestBody VehicleBatchSetElectronicDTO dto) {
        xpVehicleService.batchSetElectronic(dto.getIds(), dto.getElectronicId());
@@ -179,7 +178,7 @@
     * @param query 查询参数
     * @return 分页结果
     */
    @ApiOperation(value = "在库车辆管理分页列表", tags = {"管理后台-车辆车队管理-在库车辆管理"})
    @ApiOperation(value = "在库车辆管理分页列表", tags = {"管理后台-车辆管理-在库车辆管理"})
    @PostMapping("/api/v1/vehicle/pageList")
    public R<PageInfo<XpVehicle>> vehiclePageList(@RequestBody VehiclePageQuery query) {
        return R.ok(xpVehicleService.vehiclePageList(query));
@@ -191,7 +190,7 @@
     * @param file Excel文件
     * @return 操作结果
     */
    @ApiOperation(value = "导入", tags = {"管理后台-车辆车队管理-在库车辆管理"})
    @ApiOperation(value = "导入", tags = {"管理后台-车辆管理-在库车辆管理"})
    @PostMapping("/api/v1/vehicle/importExcel")
    public R<?> importExcel(@RequestPart("file") MultipartFile file) {
        ImportParams params = new ImportParams();
@@ -225,7 +224,7 @@
     *
     * @param query 查询参数
     */
    @ApiOperation(value = "导出", tags = {"管理后台-车辆车队管理-在库车辆管理"})
    @ApiOperation(value = "导出", tags = {"管理后台-车辆管理-在库车辆管理"})
    @PostMapping("/api/v1/vehicle/exportExcel")
    public void exportExcel(@RequestBody VehicleExportQuery query) {
        // 1. 查询导出数据
@@ -271,7 +270,7 @@
     * @param idStr 车辆ID列表
     * @return 操作结果
     */
    @ApiOperation(value = "批量在库", tags = {"管理后台-车辆车队管理-运营车辆管理"})
    @ApiOperation(value = "批量在库", tags = {"管理后台-车辆管理-运营车辆管理"})
    @ApiImplicitParam(name = "idStr", value = "车辆ID字符串列表,逗号分隔", required = true, dataTypeClass = String.class)
    @PostMapping("/api/v1/vehicle/batchStock")
    public R<?> batchStock(@RequestParam String idStr) {
@@ -285,7 +284,7 @@
     * @param id 车辆ID
     * @return 车辆详情
     */
    @ApiOperation(value = "车辆详情", tags = {"管理后台-车辆车队管理-在库车辆管理"})
    @ApiOperation(value = "车辆详情", tags = {"管理后台-车辆管理-在库车辆管理"})
    @GetMapping("/api/v1/vehicle/queryById")
    public R<XpVehicle> getVehicleDetail(@ApiParam(value = "车辆id", required = true) @RequestParam Long id) {
        return R.ok(xpVehicleService.getVehicleDetail(id));
@@ -309,7 +308,7 @@
     * @param query 查询参数
     * @return 分页结果
     */
    @ApiOperation(value = "运营车辆管理分页列表", tags = {"管理后台-车辆车队管理-运营车辆管理"})
    @ApiOperation(value = "运营车辆管理分页列表", tags = {"管理后台-车辆管理-运营车辆管理"})
    @PostMapping("/api/v1/vehicle/operationPageList")
    public R<PageInfo<XpVehicle>> operationPageList(@RequestBody OperationVehiclePageQuery query) {
        return R.ok(xpVehicleService.operationPageList(query));
@@ -320,7 +319,7 @@
     *
     * @param query 查询参数
     */
    @ApiOperation(value = "运营车辆管理列表导出", tags = {"管理后台-车辆车队管理-在库车辆管理"})
    @ApiOperation(value = "运营车辆管理列表导出", tags = {"管理后台-车辆管理-在库车辆管理"})
    @PostMapping("/api/v1/vehicle/operationExportExcel")
    public void exportExcel(@RequestBody OperationVehicleExportQuery query) {
        // 1. 查询导出数据
@@ -360,23 +359,11 @@
        }
    }
    @ApiOperation(value = "通过车辆id查询年检分页列表", tags = {"管理后台-车辆车队管理-运营车辆管理"})
    @ApiOperation(value = "通过车辆id查询年检分页列表", tags = {"管理后台-车辆管理-运营车辆管理"})
    @PostMapping("/api/v1/vehicle/queryTaskRoutineByVehicleId")
    public R<PageInfo<XpVehicleAnnualRecord>> queryTaskRoutineByVehicleId(@RequestBody XpVehicleAnnualRecordPageQuery query){
    public R<PageInfo<XpVehicleAnnualRecord>> queryTaskRoutineByVehicleId(
            @Valid @RequestBody XpVehicleAnnualRecordPageQuery query){
        return R.ok(xpVehicleAnnualRecordService.queryTaskRoutineByVehicleId(query));
    }
    /**
     * 通过车辆id查询整备分页列表
     *
     * @param query 查询参数
     * @return 整备记录分页列表
     */
    @ApiOperation(value = "通过车辆id查询整备分页列表", tags = {"管理后台-车辆车队管理-运营车辆管理"})
    @PostMapping("/api/v1/vehicle/queryPreparationByVehicleId")
    public R<PageInfo<XpVehiclePreparationDetailVO>> queryPreparationByVehicleId(
            @Valid @RequestBody XpVehiclePreparationPageQuery query) {
        return xpVehiclePreparationClient.queryByVehicleId(query);
    }
    /**
@@ -480,8 +467,8 @@
    @GetMapping("/api/v1/order/queryTemperatureByOrderId")
    public R<VehicleTemperatureDto> queryTemperatureByOrderId(@RequestParam Long orderId, HttpServletRequest request) {
        String uid = request.getHeader("XP-Uid");
        VehicleTemperatureDto vehicleTemperatureVo = xpVehicleService.queryTemperatureByOrderId(orderId,uid);
        return R.ok(vehicleTemperatureVo);
        VehicleTemperatureDto vehicleTemperatureDto = xpVehicleService.queryTemperatureByOrderId(orderId,uid);
        return R.ok(vehicleTemperatureDto);
    }
}
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/query/XpVehicleAnnualRecordPageQuery.java
@@ -8,6 +8,7 @@
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotNull;
import java.time.LocalDate;
/**
@@ -22,6 +23,7 @@
public class XpVehicleAnnualRecordPageQuery extends BasePage {
    @ApiModelProperty(value = "车辆ID")
    @NotNull(message = "车辆ID不能为空")
    private Long vehicleId;
    @ApiModelProperty(value = "操作人")
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpVehicleServiceImpl.java
@@ -601,7 +601,7 @@
            throw new ServiceException("未查询到有效车辆信息", I18nKeyConstant.VEHICLE_NOT_EXISTS);
        }
        try{
            VehicleTemperatureDto vehicleTemperatureDto = vehicleControlUtil.queryVehicleTemperature(uid, xpVehicle.getVehicleVin());
            VehicleTemperatureDto vehicleTemperatureDto = vehicleControlUtil.queryVehicleTemperature(Long.valueOf(uid), xpVehicle.getVehicleVin());
            log.info("查询车辆温度成功:{}",vehicleTemperatureDto);
            return vehicleTemperatureDto;
        }catch (Exception e){