xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/XpOperationsUserController.java
@@ -1,12 +1,18 @@ package com.xiaopeng.account.controller; import com.xiaopeng.account.mapper.XpOperationsRoleMapper; import com.xiaopeng.account.service.IXpOperationsUserService; import com.xiaopeng.api.dto.account.XpOperationsUserQueryDTO; import com.xiaopeng.api.model.account.XpOperationsUser; import com.xiaopeng.api.vo.account.XpOperationsUserWithRoleVO; import com.xiaopeng.common.core.domain.R; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.CollectionUtils; import org.springframework.web.bind.annotation.*; import java.util.ArrayList; import java.util.List; /** @@ -23,9 +29,12 @@ private final IXpOperationsUserService xpOperationsUserService; private final XpOperationsRoleMapper xpOperationsRoleMapper; @Autowired public XpOperationsUserController(IXpOperationsUserService xpOperationsUserService) { public XpOperationsUserController(IXpOperationsUserService xpOperationsUserService, XpOperationsRoleMapper xpOperationsRoleMapper) { this.xpOperationsUserService = xpOperationsUserService; this.xpOperationsRoleMapper = xpOperationsRoleMapper; } /** @@ -55,4 +64,51 @@ public R<List<XpOperationsUser>> listByName(@RequestBody String nickName) { return R.ok(xpOperationsUserService.listByName(nickName)); } /** * 根据用户ID列表批量查询用户及角色信息(内部接口) * @param ids 用户ID列表 * @return 用户及角色信息列表 */ @ApiOperation(value = "批量查询用户及角色信息", tags = {"内部接口"}) @PostMapping("/inner/xpOperationsUser/listByIdsWithRole") public R<List<XpOperationsUserWithRoleVO>> listByIdsWithRole(@RequestBody List<Long> ids) { if (CollectionUtils.isEmpty(ids)) { return R.ok(new ArrayList<>()); } List<XpOperationsUserWithRoleVO> result = xpOperationsRoleMapper.selectUsersWithRoleByIds(ids); return R.ok(result); } /** * 根据条件查询用户及角色信息(内部接口) * @param dto 查询条件 * @return 用户及角色信息列表 */ @ApiOperation(value = "根据条件查询用户及角色信息", tags = {"内部接口"}) @PostMapping("/inner/xpOperationsUser/queryByConditions") public R<List<XpOperationsUserWithRoleVO>> queryByConditions(@RequestBody XpOperationsUserQueryDTO dto) { List<XpOperationsUserWithRoleVO> result = xpOperationsRoleMapper.selectUsersByConditions( dto.getNickName(), dto.getPhoneNumber(), dto.getRoleId() ); return R.ok(result); } /** * 根据条件查询用户及角色信息 * @param dto 查询条件 * @return 用户及角色信息列表 */ @ApiOperation(value = "根据条件查询用户不分页列表", tags = {"管理后台-车队管理"}) @PostMapping("/api/v1/xpOperationsUser/queryByConditions") public R<List<XpOperationsUserWithRoleVO>> getList(@RequestBody XpOperationsUserQueryDTO dto) { List<XpOperationsUserWithRoleVO> result = xpOperationsRoleMapper.selectUsersByConditions( dto.getNickName(), dto.getPhoneNumber(), dto.getRoleId() ); return R.ok(result); } } xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/mapper/XpOperationsRoleMapper.java
@@ -2,6 +2,10 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.xiaopeng.api.model.account.XpOperationsRole; import com.xiaopeng.api.vo.account.XpOperationsUserWithRoleVO; import org.apache.ibatis.annotations.Param; import java.util.List; /** * <p> @@ -13,4 +17,25 @@ */ public interface XpOperationsRoleMapper extends BaseMapper<XpOperationsRole> { /** * 根据用户ID列表查询用户及角色信息 * * @param ids 用户ID列表 * @return 用户及角色信息列表 */ List<XpOperationsUserWithRoleVO> selectUsersWithRoleByIds(@Param("ids") List<Long> ids); /** * 根据条件查询用户及角色信息 * * @param nickName 姓名(模糊查询) * @param phoneNumber 手机号(模糊查询) * @param roleId 角色ID(精确查询) * @return 用户及角色信息列表 */ List<XpOperationsUserWithRoleVO> selectUsersByConditions( @Param("nickName") String nickName, @Param("phoneNumber") String phoneNumber, @Param("roleId") Long roleId ); } xp-robotaxi-account-boot/src/main/resources/mapper/account/XpOperationsRoleMapper.xml
@@ -7,4 +7,40 @@ operations_user_id, role_id </sql> <!-- 根据用户ID列表查询用户及角色信息 --> <select id="selectUsersWithRoleByIds" resultType="com.xiaopeng.api.vo.account.XpOperationsUserWithRoleVO"> SELECT u.*, r.id AS roleId, r.role_name AS roleName FROM xp_operations_user u LEFT JOIN xp_operations_role ur ON u.id = ur.operations_user_id LEFT JOIN sys_role r ON ur.role_id = r.id AND r.is_deleted = 0 WHERE u.id IN <foreach collection="ids" item="id" open="(" separator="," close=")"> #{id} </foreach> </select> <!-- 根据条件查询用户及角色信息 --> <select id="selectUsersByConditions" resultType="com.xiaopeng.api.vo.account.XpOperationsUserWithRoleVO"> SELECT u.*, r.id AS roleId, r.role_name AS roleName FROM xp_operations_user u LEFT JOIN xp_operations_role ur ON u.id = ur.operations_user_id LEFT JOIN sys_role r ON ur.role_id = r.id AND r.is_deleted = 0 WHERE 1=1 <if test="nickName != null and nickName != ''"> AND u.nick_name LIKE CONCAT('%', #{nickName}, '%') </if> <if test="phoneNumber != null and phoneNumber != ''"> AND u.phone_number LIKE CONCAT('%', #{phoneNumber}, '%') </if> <if test="roleId != null"> AND r.id = #{roleId} </if> </select> </mapper> xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/account/XpOperationsUserQueryDTO.java
New file @@ -0,0 +1,24 @@ package com.xiaopeng.api.dto.account; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; /** * 运维人员查询条件DTO * * @author mitao */ @Data @ApiModel("运维人员查询条件DTO") public class XpOperationsUserQueryDTO { @ApiModelProperty(value = "姓名(模糊查询)") private String nickName; @ApiModelProperty(value = "手机号(模糊查询)") private String phoneNumber; @ApiModelProperty(value = "角色ID(精确查询)") private Long roleId; } xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/account/XpOperationUserClientFallbackFactory.java
@@ -1,7 +1,9 @@ package com.xiaopeng.api.factory.account; import com.xiaopeng.api.dto.account.XpOperationsUserQueryDTO; import com.xiaopeng.api.feignClient.account.XpOperationUserClient; import com.xiaopeng.api.model.account.XpOperationsUser; import com.xiaopeng.api.vo.account.XpOperationsUserWithRoleVO; import com.xiaopeng.common.core.domain.R; import lombok.extern.slf4j.Slf4j; import org.springframework.cloud.openfeign.FallbackFactory; @@ -34,8 +36,21 @@ @Override public R<List<XpOperationsUser>> listByName(String nickName) { log.error("根据昵称查询运维用户信息失败,原因:{}", cause.getMessage()); return R.fail("根据昵称查询运维用户信息失败:" + cause.getMessage()); } @Override public R<List<XpOperationsUserWithRoleVO>> listByIdsWithRole(List<Long> ids) { log.error("根据id列表获取运维人员列表失败,原因:{}", cause.getMessage()); return R.fail("根据id列表获取运维人员列表失败"); } @Override public R<List<XpOperationsUserWithRoleVO>> queryByConditions(XpOperationsUserQueryDTO dto) { log.error("根据条件查询运维用户信息失败,原因:{}", cause.getMessage()); return R.fail("根据条件查询运维用户信息失败:" + cause.getMessage()); } }; } } xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/account/XpOperationUserClient.java
@@ -1,7 +1,9 @@ package com.xiaopeng.api.feignClient.account; import com.xiaopeng.api.dto.account.XpOperationsUserQueryDTO; import com.xiaopeng.api.factory.account.XpAppUserClientFallbackFactory; import com.xiaopeng.api.model.account.XpOperationsUser; import com.xiaopeng.api.vo.account.XpOperationsUserWithRoleVO; import com.xiaopeng.common.core.domain.R; import com.xiaopeng.common.core.dto.ServiceNameConstantsEnum; import org.springframework.cloud.openfeign.FeignClient; @@ -43,4 +45,20 @@ */ @PostMapping("/inner/xpOperationsUser/listByName") R<List<XpOperationsUser>> listByName(@RequestParam("nickName") String nickName); /** * 根据用户ID列表批量查询用户及角色信息 * @param ids 用户ID列表 * @return 用户及角色信息列表 */ @PostMapping("/inner/xpOperationsUser/listByIdsWithRole") R<List<XpOperationsUserWithRoleVO>> listByIdsWithRole(@RequestBody List<Long> ids); /** * 根据条件查询用户及角色信息 * @param dto 查询条件 * @return 用户及角色信息列表 */ @PostMapping("/inner/xpOperationsUser/queryByConditions") R<List<XpOperationsUserWithRoleVO>> queryByConditions(@RequestBody XpOperationsUserQueryDTO dto); } xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/maintenance/XpTask.java
@@ -1,18 +1,17 @@ package com.xiaopeng.api.model.maintenance; import java.math.BigDecimal; 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.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.math.BigDecimal; import java.time.LocalDateTime; /** * <p> @@ -40,7 +39,7 @@ @ApiModelProperty(value = "任务类别1常规 2事故") private Integer taskCategory; //1:车辆检查,2:车辆充电,3:车辆整备,4:整备洗车,5:车辆维修,6:车辆保养,7:车辆保险到期,8:车辆年检到期9:车辆运营资质到期 @ApiModelProperty(value = "任务类型id 任务类别为2时对应数据字典,多个逗号分割,为1的时候 枚举1车辆检查 2车辆充电 3车辆整备 4整备洗车 5车辆维修 6车辆保养 7车辆保险到期 8车辆年检到期 9车辆运营资质到期") private String taskTypeId; xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpAgreementAppUser.java
@@ -30,7 +30,7 @@ private static final long serialVersionUID = 1L; @TableId(value = "id", type = IdType.AUTO) @TableId(value = "id", type = IdType.ASSIGN_ID) private Long id; @ApiModelProperty(value = "用户id") xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/account/XpOperationsUserWithRoleVO.java
New file @@ -0,0 +1,24 @@ package com.xiaopeng.api.vo.account; import com.xiaopeng.api.model.account.XpOperationsUser; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.EqualsAndHashCode; /** * 运维人员及角色信息视图对象 * * @author mitao */ @EqualsAndHashCode(callSuper = true) @Data @ApiModel("运维人员及角色信息视图对象") public class XpOperationsUserWithRoleVO extends XpOperationsUser { @ApiModelProperty(value = "角色id") private Long roleId; @ApiModelProperty(value = "角色名称") private String roleName; } xp-robotaxi-common/xp-common-core/src/main/java/com/xiaopeng/common/core/enums/TaskTypeEnum.java
New file @@ -0,0 +1,38 @@ package com.xiaopeng.common.core.enums; import lombok.Getter; import lombok.AllArgsConstructor; @Getter @AllArgsConstructor public enum TaskTypeEnum { VEHICLE_INSPECTION(1, "车辆检查"), VEHICLE_CHARGING(2, "车辆充电"), VEHICLE_PREPARATION(3, "车辆整备"), VEHICLE_WASH(4, "整备洗车"), VEHICLE_REPAIR(5, "车辆维修"), VEHICLE_MAINTENANCE(6, "车辆保养"), VEHICLE_INSURANCE_EXPIRE(7, "车辆保险到期"), ANNUAL_INSPECTION_EXPIRE(8, "车辆年检到期"), LICENSE_EXPIRE(9,"车辆运营资质到期"); private final Integer code; private final String desc; public static TaskTypeEnum getEnumByCode(Integer code) { for (TaskTypeEnum e : TaskTypeEnum.values()) { if (e.code.equals(code)) { return e; } } return null; } public static String getEnumDescByCode(Integer code) { for (TaskTypeEnum e : TaskTypeEnum.values()) { if (e.code.equals(code)) { return e.getDesc(); } } return ""; } } xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpChargingRecordController.java
@@ -86,5 +86,17 @@ @Valid @RequestBody XpChargingRecordPageQuery query) { return R.ok(xpChargingRecordService.queryChargingByVehicleId(query)); } /** * 管理后台-车辆管理-运营车辆管理-删除充电记录 * @param id * @return */ @ApiOperation(value = "删除充电记录", tags = {"管理后台-车辆管理-运营车辆管理"}) @DeleteMapping("/api/v1/chargingRecord/delete/{id}") public R<?> deleteRecordById(@PathVariable Long id){ xpChargingRecordService.deleteRecordById(id); return R.ok(); } } xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpCheckLocationController.java
New file @@ -0,0 +1,32 @@ package com.xiaopeng.maintenance.controller; import com.xiaopeng.api.model.maintenance.XpCheckLocation; import com.xiaopeng.common.core.domain.R; import com.xiaopeng.common.core.enums.DisabledEnum; import com.xiaopeng.maintenance.service.IXpCheckLocationService; import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Lazy; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; /** * @author MiTao * @date 2026-02-12 21:17 * */ @Validated @RestController @RequiredArgsConstructor(onConstructor_ = @Lazy) public class XpCheckLocationController { private final IXpCheckLocationService xpCheckLocationService; @GetMapping("/api/v1/check-location/list") @ApiOperation(value = "获取打卡地址列表", tags = {"管理后台-车队管理"}) public R<List<XpCheckLocation>> getList(){ return R.ok(xpCheckLocationService.lambdaQuery().eq(XpCheckLocation::getStatus, DisabledEnum.YES.getCode()).list()); } } xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpTaskController.java
@@ -20,12 +20,10 @@ import com.xiaopeng.maintenance.service.XpTaskService; import com.xiaopeng.maintenance.vo.VehicleListVO; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import lombok.extern.slf4j.Slf4j; import org.springframework.transaction.annotation.Transactional; 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 org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.validation.Valid; @@ -171,4 +169,16 @@ public R<PageInfo<XpTaskRecordVO>> queryTaskByVehicleId(@Valid @RequestBody XpTaskRecordPageQuery query) { return R.ok(xpTaskService.queryTaskByVehicleId(query)); } /** * 管理后台-车辆管理-运营车辆管理-删除任务/事故 * @param id * @return */ @ApiOperation(value = "删除删除任务/事故", tags = {"管理后台-车辆管理-运营车辆管理"}) @DeleteMapping("/api/v1/task/delete/{id}") public R<?> deleteTaskById(@ApiParam(name = "id", value = "任务ID") @PathVariable Long id){ xpTaskService.deleteTaskById(id); return R.ok(); } } xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/IXpChargingRecordService.java
@@ -49,4 +49,10 @@ * @return 充电记录分页列表 */ PageInfo<XpChargingRecordVO> queryChargingByVehicleId(XpChargingRecordPageQuery query); /** * 根据ID删除充电记录 * @param id */ void deleteRecordById(Long id); } xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/XpTaskService.java
@@ -57,4 +57,10 @@ * @return */ PageInfo<XpTaskRecordVO> queryTaskByVehicleId(@Valid XpTaskRecordPageQuery query); /** * 删除任务/事故 * @param id */ void deleteTaskById(Long id); } xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpChargingRecordServiceImpl.java
@@ -186,4 +186,9 @@ pageInfo.setTotal(resultPage.getTotal()); return pageInfo; } @Override public void deleteRecordById(Long id) { removeById(id); } } xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpTaskServiceImpl.java
@@ -1,6 +1,7 @@ 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; @@ -8,6 +9,7 @@ import com.xiaopeng.api.model.maintenance.*; import com.xiaopeng.api.model.vehicleConvoy.XpVehicle; import com.xiaopeng.common.core.domain.R; import com.xiaopeng.common.core.enums.TaskTypeEnum; import com.xiaopeng.common.core.exception.ServiceException; import com.xiaopeng.common.core.web.page.PageInfo; import com.xiaopeng.maintenance.constant.I18nKeyConstant; @@ -20,15 +22,16 @@ import com.xiaopeng.maintenance.model.query.XpTaskRecordPageQuery; import com.xiaopeng.maintenance.model.vo.*; import com.xiaopeng.maintenance.service.XpTaskService; 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.time.LocalTime; import java.time.format.DateTimeFormatter; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.*; import java.util.stream.Collectors; /** @@ -41,6 +44,22 @@ */ @Service public class XpTaskServiceImpl extends ServiceImpl<XpTaskMapper, XpTask> implements XpTaskService { /** * 常规任务类型映射 */ private static final Map<String, String> TASK_TYPE_MAP = new java.util.HashMap<>(); static { TASK_TYPE_MAP.put("1", "车辆检查"); TASK_TYPE_MAP.put("2", "车辆充电"); TASK_TYPE_MAP.put("3", "车辆整备"); TASK_TYPE_MAP.put("4", "整备洗车"); TASK_TYPE_MAP.put("5", "车辆维修"); TASK_TYPE_MAP.put("6", "车辆保养"); TASK_TYPE_MAP.put("7", "车辆保险到期"); TASK_TYPE_MAP.put("8", "车辆年检到期"); TASK_TYPE_MAP.put("9", "车辆运营资质到期"); } @Autowired private XpTaskHandleDetailMapper xpTaskHandleDetailMapper; @@ -581,6 +600,101 @@ @Override public PageInfo<XpTaskRecordVO> queryTaskByVehicleId(XpTaskRecordPageQuery query) { return null; // 1. 构建查询条件 LambdaQueryWrapper<XpTask> wrapper = new LambdaQueryWrapper<>(); wrapper.eq(XpTask::getVehicleId, query.getVehicleId()); if (query.getTaskCategory() != null) { wrapper.eq(XpTask::getTaskCategory, query.getTaskCategory()); } if (StringUtils.isNotBlank(query.getTaskTypeId())) { wrapper.eq(XpTask::getTaskTypeId, query.getTaskTypeId()); } if (query.getStartTime() != null) { wrapper.ge(XpTask::getCreateTime, query.getStartTime().atStartOfDay()); } if (query.getEndTime() != null) { wrapper.le(XpTask::getCreateTime, query.getEndTime().atTime(23, 59, 59)); } wrapper.orderByDesc(XpTask::getCreateTime); // 2. 执行分页查询 Page<XpTask> page = new Page<>(query.getPageNum(), query.getPageSize()); Page<XpTask> resultPage = this.page(page, wrapper); // 3. 转换为 VO 并填充 typeName List<XpTaskRecordVO> records = new ArrayList<>(); if (!CollectionUtils.isEmpty(resultPage.getRecords())) { // 3.1 收集所有事故任务的 errorType ID Set<Long> errorTypeIds = new HashSet<>(); for (XpTask task : resultPage.getRecords()) { if (task.getTaskCategory() != null && task.getTaskCategory() == 2 && StringUtils.isNotBlank(task.getTaskTypeId())) { String[] ids = task.getTaskTypeId().split(","); for (String id : ids) { try { errorTypeIds.add(Long.parseLong(id.trim())); } catch (NumberFormatException e) { // 忽略格式错误的ID } } } } // 3.2 批量查询 errorType Map<Long, String> errorTypeMap = new HashMap<>(); if (!errorTypeIds.isEmpty()) { List<XpErrorType> errorTypes = errorTypeMapper.selectBatchIds(errorTypeIds); for (XpErrorType errorType : errorTypes) { errorTypeMap.put(errorType.getId(), errorType.getErrorName()); } } // 3.3 填充 typeName for (XpTask task : resultPage.getRecords()) { XpTaskRecordVO vo = new XpTaskRecordVO(); BeanUtils.copyProperties(task, vo); // 填充 typeName if (task.getTaskCategory() != null && task.getTaskCategory() == 1) { // 常规任务: 使用枚举映射 vo.setTypeName(TaskTypeEnum.getEnumDescByCode(Integer.valueOf(task.getTaskTypeId()))); } else if (task.getTaskCategory() != null && task.getTaskCategory() == 2) { // 事故任务: 拼接父子级名称 if (StringUtils.isNotBlank(task.getTaskTypeId())) { String[] ids = task.getTaskTypeId().split(","); if (ids.length >= 2) { try { String parentName = errorTypeMap.get(Long.parseLong(ids[0].trim())); String childName = errorTypeMap.get(Long.parseLong(ids[1].trim())); if (parentName != null && childName != null) { vo.setTypeName(parentName + "->" + childName); } } catch (NumberFormatException e) { // 忽略格式错误的ID } } } } records.add(vo); } } // 4. 构建分页结果 PageInfo<XpTaskRecordVO> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize()); pageInfo.setRecords(records); pageInfo.setTotal(resultPage.getTotal()); return pageInfo; } @Override public void deleteTaskById(Long id) { removeById(id); } } xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java
@@ -2,7 +2,7 @@ import cn.hutool.core.bean.BeanUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson2.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; @@ -12,6 +12,7 @@ import com.xiaopeng.api.dto.order.GetOrderNumDto; import com.xiaopeng.api.dto.order.HistoryEndPointsDto; import com.xiaopeng.api.dto.order.HistoryStartPointsDto; import com.xiaopeng.api.dto.pushMessage.SendMessageDTO; import com.xiaopeng.api.dto.statistics.DailyCountDTO; import com.xiaopeng.api.dto.statistics.OrderStatisticsDTO; import com.xiaopeng.api.dto.statistics.StatisticsQueryDTO; @@ -19,6 +20,7 @@ import com.xiaopeng.api.feignClient.account.XpAppUserClient; import com.xiaopeng.api.feignClient.account.XpAppUserCouponClient; import com.xiaopeng.api.feignClient.operation.XpSystemSettingClient; import com.xiaopeng.api.feignClient.pushMessage.XpPushMessageClient; import com.xiaopeng.api.feignClient.vehicleConvoy.UserVehicleClient; import com.xiaopeng.api.feignClient.vehicleConvoy.XpFleetClient; import com.xiaopeng.api.feignClient.vehicleConvoy.XpFleetVehicleClient; @@ -39,6 +41,8 @@ import com.xiaopeng.api.vo.vehicleConvoy.CancelTaxiPassengerVo; import com.xiaopeng.common.core.constant.CacheConstants; import com.xiaopeng.common.core.domain.R; import com.xiaopeng.common.core.enums.OrderStatusEnum; import com.xiaopeng.common.core.enums.PushMessageTypeEnum; import com.xiaopeng.common.core.exception.ServiceException; import com.xiaopeng.common.core.utils.DateUtils; import com.xiaopeng.common.core.utils.GeodesyUtil; @@ -116,6 +120,7 @@ private final XpPricingClient xpPricingClient; private final XpSystemSettingClient xpSystemSettingClient; private final OrderTrajectoryService orderTrajectoryService; private final XpPushMessageClient xpPushMessageClient; @Autowired private MongoTemplate mongoTemplate; @@ -753,6 +758,23 @@ xpOrderCancel.setCancelSource(4); xpOrderCancel.setCancelReason("系统取消订单"); xpOrderCancelService.save(xpOrderCancel); // 推送消息 // 消息推送 Map<String, Object> params = new HashMap<>(); Map<String, Object> content = new HashMap<>(); content.put("orderId",order.getId()); content.put("status", OrderStatusEnum.CANCELED.getCode()); params.put("type", PushMessageTypeEnum.ORDER_STATUS.getDesc()); params.put("content", com.alibaba.fastjson2.JSONObject.toJSONString(content)); params.put("timestamp", new Date().getTime()+""); String message = JSONObject.toJSONString(params); SendMessageDTO sendMessageDTO = new SendMessageDTO(); sendMessageDTO.setMessage(message); sendMessageDTO.setAppUserId(String.valueOf(order.getAppUserId())); xpPushMessageClient.sendStatus(sendMessageDTO); log.info("订单取消消息推送完毕"); } /** xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/constant/I18nKeyConstant.java
@@ -19,4 +19,10 @@ String VEHICLE_OPERATION_INFO_INCOMPLETE = "vehicle.operation.info.incomplete"; String VEHICLE_BATCH_OPERATION_CONDITION_NOT_MET = "vehicle.batch.operation.condition.not.met"; String VEHICLE_TIME_EXPIRED = "vehicle.time.expired"; // ========== 车队相关 ========== String FLEET_OPERATION_USER_BOUND_V1 = "fleet.operation.user.bound.v1"; String FLEET_OPERATION_USER_BOUND_2 = "fleet.operation.user.bound.v2"; String FLEET_VEHICLE_BOUND_V1 = "fleet.vehicle.bound.v1"; String FLEET_VEHICLE_BOUND_V2 = "fleet.vehicle.bound.v2"; } xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpFleetController.java
@@ -2,15 +2,21 @@ import com.xiaopeng.api.model.vehicleConvoy.XpFleet; import com.xiaopeng.common.core.domain.R; import com.xiaopeng.common.core.web.page.PageInfo; import com.xiaopeng.vehicleConvoy.model.dto.FleetAddDTO; import com.xiaopeng.vehicleConvoy.model.dto.FleetEditDTO; import com.xiaopeng.vehicleConvoy.model.query.FleetPageQuery; import com.xiaopeng.vehicleConvoy.model.query.FleetUserPageQuery; import com.xiaopeng.vehicleConvoy.model.query.FleetVehiclePageQuery; import com.xiaopeng.vehicleConvoy.model.vo.*; import com.xiaopeng.vehicleConvoy.service.IXpFleetService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.*; import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Lazy; import org.springframework.util.CollectionUtils; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.validation.Valid; import java.util.ArrayList; import java.util.List; @@ -22,12 +28,12 @@ * @author mitao * @since 2026-02-03 */ @RestController @Api(tags = "车队管理") @RequiredArgsConstructor(onConstructor_ = @Lazy) @RestController public class XpFleetController { @Resource private IXpFleetService xpFleetService; private final IXpFleetService xpFleetService; /** * 根据ID列表批量查询车队信息(内部接口) @@ -43,4 +49,104 @@ } return R.ok(xpFleetService.listByIds(ids)); } /** * 添加车队 * * @param dto 添加车队DTO * @return 操作结果 */ @ApiOperation(value = "添加车队", tags = {"管理后台-车队管理"}) @PostMapping("/api/v1/fleet/add") public R<Void> add(@Valid @RequestBody FleetAddDTO dto) { return xpFleetService.add(dto); } /** * 编辑车队 * * @param dto 编辑车队DTO * @return 操作结果 */ @ApiOperation(value = "编辑车队", tags = {"管理后台-车队管理"}, notes = "打卡地列表接口在xp-robotaxi-maintenance-boot,人员列表在xp-robotaxi-account-boot") @PostMapping("/api/v1/fleet/edit") public R<Void> edit(@Valid @RequestBody FleetEditDTO dto) { return xpFleetService.edit(dto); } /** * 查询车队详情 * * @param id 车队id * @return 车队详情 */ @ApiOperation(value = "查询车队详情", tags = {"管理后台-车队管理"}) @GetMapping("/api/v1/fleet/queryById") public R<FleetDetailVO> queryById(@RequestParam Long id) { return xpFleetService.queryById(id); } /** * 车队分页列表 * * @param query 查询参数 * @return 分页结果 */ @ApiOperation(value = "车队分页列表", tags = {"管理后台-车队管理"}) @PostMapping("/api/v1/fleet/pageList") public R<PageInfo<FleetPageVO>> pageList(@Valid @RequestBody FleetPageQuery query) { return xpFleetService.pageList(query); } /** * 查询车队车辆分页列表 * * @param query 查询参数 * @return 分页结果 */ @ApiOperation(value = "查询车队车辆分页列表", tags = {"管理后台-车队管理"}) @PostMapping("/api/v1/fleet/queryVehiclePageList") public R<PageInfo<FleetVehicleVO>> queryVehiclePageList(@Valid @RequestBody FleetVehiclePageQuery query) { return xpFleetService.queryVehiclePageList(query); } /** * 查询车队人员分页列表 * * @param query 查询参数 * @return 分页结果 */ @ApiOperation(value = "查询车队人员分页列表", tags = {"管理后台-车队管理"}) @PostMapping("/api/v1/fleet/queryUserPageList") public R<PageInfo<FleetUserVO>> queryUserPageList(@Valid @RequestBody FleetUserPageQuery query) { return xpFleetService.queryUserPageList(query); } @ApiOperation(value = "删除车队", tags = {"管理后台-车队管理"}) @DeleteMapping("/api/v1/fleet/delete/{id}") public R<?> deleteById(@ApiParam(name = "id", value = "车队ID") @PathVariable Long id) { xpFleetService.deleteById(id); return R.ok(); } @ApiOperation(value = "车队添加车辆成员", tags = {"管理后台-车队管理"}) @PostMapping("/api/v1/fleet/vehicle/add") @ApiImplicitParams({ @ApiImplicitParam(name = "fleetId", value = "车队ID", dataTypeClass = Long.class), @ApiImplicitParam(name = "vehicleId", value = "车辆ID", dataTypeClass = Long.class)}) public R<?> addVehicle(Long fleetId, Long vehicleId) { xpFleetService.addVehicle(fleetId, vehicleId); return R.ok(); } @ApiOperation(value = "车队添加人员成员", tags = {"管理后台-车队管理"}) @PostMapping("/api/v1/fleet/operation-user/add") @ApiImplicitParams({ @ApiImplicitParam(name = "fleetId", value = "车队ID", dataTypeClass = Long.class), @ApiImplicitParam(name = "operationUserId", value = "车辆ID", dataTypeClass = Long.class)}) public R<?> addOperationUserId(Long fleetId, Long operationUserId) { xpFleetService.addOperationUserId(fleetId, operationUserId); return R.ok(); } } xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpVehicleController.java
@@ -7,18 +7,12 @@ import cn.hutool.core.bean.BeanUtil; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.xiaopeng.api.dto.operation.VehiclePositionByVinDto; 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.feignClient.order.XpOrderClient; import com.xiaopeng.api.model.vehicleConvoy.XpVehicle; import com.xiaopeng.api.model.vehicleConvoy.XpVehicleAnnualRecord; import com.xiaopeng.api.vo.operation.VehiclePositionVo; 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; @@ -493,5 +487,12 @@ VehicleTemperatureDto vehicleTemperatureDto = xpVehicleService.queryTemperatureByOrderId(orderId,uid); return R.ok(vehicleTemperatureDto); } @ApiOperation(value = "获取车辆不分页列表", tags = {"管理后台-车队管理"}) @PostMapping("/api/v1/vehicle/list") @ApiImplicitParams({ @ApiImplicitParam(name = "plateNumber", value = "车牌号", dataTypeClass = String.class), @ApiImplicitParam(name = "fleetName", value = "车队名称", dataTypeClass = String.class)}) public R<List<XpVehicleVO>> getList(String plateNumber, String fleetName) { return R.ok(xpVehicleService.getList(plateNumber, fleetName)); } } xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/mapper/XpVehicleMapper.java
@@ -7,6 +7,7 @@ import com.xiaopeng.vehicleConvoy.model.query.VehicleExportQuery; import com.xiaopeng.vehicleConvoy.model.query.VehicleMapQuery; import com.xiaopeng.vehicleConvoy.model.query.VehiclePageQuery; import com.xiaopeng.vehicleConvoy.model.vo.XpVehicleVO; import org.apache.ibatis.annotations.Param; import java.time.LocalDate; @@ -79,4 +80,12 @@ * @return 车辆列表 */ List<XpVehicle> vehicleExportList(@Param("query") VehicleExportQuery query); /** * 车辆不分页列表 * @param plateNumber * @param fleetName * @return */ List<XpVehicleVO> getList(String plateNumber, String fleetName); } xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/dto/FleetAddDTO.java
New file @@ -0,0 +1,40 @@ package com.xiaopeng.vehicleConvoy.model.dto; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import java.util.List; /** * 添加车队DTO * * @author mitao */ @Data @ApiModel("添加车队数据传输对象") public class FleetAddDTO { @ApiModelProperty(value = "车队名称", required = true) @NotBlank(message = "车队名称不能为空") private String fleetName; @ApiModelProperty(value = "负责人id", required = true) @NotNull(message = "负责人id不能为空") private Long operationsUserId; @ApiModelProperty(value = "打卡地id", required = true) @NotNull(message = "打卡地id不能为空") private Long locationId; @ApiModelProperty(value = "关联车辆ids", required = true) @NotEmpty(message = "关联车辆不能为空") private List<Long> vehicleIds; @ApiModelProperty(value = "关联人员ids", required = true) @NotEmpty(message = "关联人员不能为空") private List<Long> operationsUserIds; } xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/dto/FleetEditDTO.java
New file @@ -0,0 +1,33 @@ package com.xiaopeng.vehicleConvoy.model.dto; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; /** * 编辑车队DTO * * @author mitao */ @Data @ApiModel("编辑车队数据传输对象") public class FleetEditDTO { @ApiModelProperty(value = "车队id", required = true) @NotNull(message = "车队id不能为空") private Long id; @ApiModelProperty(value = "车队名称", required = true) @NotBlank(message = "车队名称不能为空") private String fleetName; @ApiModelProperty(value = "负责人id", required = true) @NotNull(message = "负责人id不能为空") private Long operationsUserId; @ApiModelProperty(value = "打卡地ID") private Long locationId; } xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/query/FleetPageQuery.java
New file @@ -0,0 +1,24 @@ package com.xiaopeng.vehicleConvoy.model.query; import com.xiaopeng.common.core.web.page.BasePage; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.EqualsAndHashCode; /** * 车队分页查询参数 * * @author mitao */ @Data @EqualsAndHashCode(callSuper = true) @ApiModel(value = "车队分页查询参数") public class FleetPageQuery extends BasePage { @ApiModelProperty(value = "车队名称") private String fleetName; @ApiModelProperty(value = "负责人电话") private String phoneNumber; } xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/query/FleetUserPageQuery.java
New file @@ -0,0 +1,30 @@ package com.xiaopeng.vehicleConvoy.model.query; import com.xiaopeng.common.core.web.page.BasePage; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.EqualsAndHashCode; /** * 车队人员分页查询参数 * * @author mitao */ @Data @EqualsAndHashCode(callSuper = true) @ApiModel(value = "车队人员分页查询参数") public class FleetUserPageQuery extends BasePage { @ApiModelProperty(value = "车队id") private Long fleetId; @ApiModelProperty(value = "人员姓名") private String nickName; @ApiModelProperty(value = "电话") private String phone; @ApiModelProperty(value = "角色ID") private Long roleId; } xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/query/FleetVehiclePageQuery.java
New file @@ -0,0 +1,27 @@ package com.xiaopeng.vehicleConvoy.model.query; 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; /** * 车队车辆分页查询参数 * * @author mitao */ @Data @EqualsAndHashCode(callSuper = true) @ApiModel(value = "车队车辆分页查询参数") public class FleetVehiclePageQuery extends BasePage { @ApiModelProperty(value = "车队id", required = true) @NotNull(message = "车队id不能为空") private Long fleetId; @ApiModelProperty(value = "车牌号") private String plateNumber; } xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/vo/FleetDetailVO.java
New file @@ -0,0 +1,53 @@ package com.xiaopeng.vehicleConvoy.model.vo; import com.fasterxml.jackson.annotation.JsonFormat; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.time.LocalDateTime; /** * 车队详情视图对象 * * @author mitao */ @Data @ApiModel("车队详情视图对象") public class FleetDetailVO { @ApiModelProperty(value = "车队id") private Long id; @ApiModelProperty(value = "车队名称") private String fleetName; @ApiModelProperty(value = "负责人id") private Long operationsUserId; @ApiModelProperty(value = "负责人姓名") private String operationsUserName; @ApiModelProperty(value = "打卡地id") private Long locationId; @ApiModelProperty(value = "打卡地名称") private String locationName; @ApiModelProperty(value = "电子围栏id") private Long electronicId; @ApiModelProperty(value = "人员数量") private Integer userCount; @ApiModelProperty(value = "车辆数量") private Integer vehicleCount; @ApiModelProperty(value = "创建时间") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private LocalDateTime createTime; @ApiModelProperty(value = "更新时间") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private LocalDateTime updateTime; } xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/vo/FleetPageVO.java
New file @@ -0,0 +1,46 @@ package com.xiaopeng.vehicleConvoy.model.vo; import com.fasterxml.jackson.annotation.JsonFormat; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.time.LocalDateTime; /** * 车队分页列表视图对象 * * @author mitao */ @Data @ApiModel("车队分页列表视图对象") public class FleetPageVO { @ApiModelProperty(value = "车队id") private Long id; @ApiModelProperty(value = "车队名称") private String fleetName; @ApiModelProperty(value = "负责人id") private Long operationsUserId; @ApiModelProperty(value = "负责人姓名") private String operationsUserName; @ApiModelProperty(value = "关联运营区域") private String electronicName; @ApiModelProperty(value = "负责人电话") private String phoneNumber; @ApiModelProperty(value = "人员数量") private Integer userCount; @ApiModelProperty(value = "车辆数量") private Integer vehicleCount; @ApiModelProperty(value = "创建时间") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private LocalDateTime createTime; } xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/vo/FleetUserVO.java
New file @@ -0,0 +1,30 @@ package com.xiaopeng.vehicleConvoy.model.vo; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; /** * 车队人员视图对象 * * @author mitao */ @Data @ApiModel("车队人员视图对象") public class FleetUserVO { @ApiModelProperty(value = "人员id") private Long userId; @ApiModelProperty(value = "人员姓名") private String nickName; @ApiModelProperty(value = "电话") private String phoneNumber; @ApiModelProperty(value = "工号") private String jobNumber; @ApiModelProperty(value = "角色名称") private String roleName; } xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/vo/FleetVehicleVO.java
New file @@ -0,0 +1,36 @@ package com.xiaopeng.vehicleConvoy.model.vo; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; /** * 车队车辆视图对象 * * @author mitao */ @Data @ApiModel("车队车辆视图对象") public class FleetVehicleVO { @ApiModelProperty(value = "车辆id") private Long vehicleId; @ApiModelProperty(value = "车辆编码") private String vehicleCode; @ApiModelProperty(value = "车牌号") private String plateNumber; @ApiModelProperty(value = "车辆颜色") private String vehicleColor; @ApiModelProperty(value = "车辆型号") private String vehicleModel; @ApiModelProperty(value = "运营状态") private Integer operatingStatus; @ApiModelProperty(value = "运营状态描述") private String operatingStatusDesc; } xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/vo/XpVehicleVO.java
New file @@ -0,0 +1,21 @@ package com.xiaopeng.vehicleConvoy.model.vo; import com.xiaopeng.api.model.vehicleConvoy.XpVehicle; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.EqualsAndHashCode; /** * @author MiTao * @date 2026-02-12 21:36 * */ @Data @EqualsAndHashCode(callSuper = true) @ApiModel("车辆视图对象") public class XpVehicleVO extends XpVehicle { @ApiModelProperty(value = "车队名称") private String fleetName; } xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/IXpFleetService.java
@@ -1,7 +1,15 @@ package com.xiaopeng.vehicleConvoy.service; import com.xiaopeng.api.model.vehicleConvoy.XpFleet; import com.baomidou.mybatisplus.extension.service.IService; import com.xiaopeng.api.model.vehicleConvoy.XpFleet; import com.xiaopeng.common.core.domain.R; import com.xiaopeng.common.core.web.page.PageInfo; import com.xiaopeng.vehicleConvoy.model.dto.FleetAddDTO; import com.xiaopeng.vehicleConvoy.model.dto.FleetEditDTO; import com.xiaopeng.vehicleConvoy.model.query.FleetPageQuery; import com.xiaopeng.vehicleConvoy.model.query.FleetUserPageQuery; import com.xiaopeng.vehicleConvoy.model.query.FleetVehiclePageQuery; import com.xiaopeng.vehicleConvoy.model.vo.*; import java.util.List; @@ -22,4 +30,74 @@ * @return 车队列表 */ List<XpFleet> listByIds(List<Long> ids); /** * 添加车队 * * @param dto 添加车队DTO * @return 操作结果 */ R<Void> add(FleetAddDTO dto); /** * 编辑车队 * * @param dto 编辑车队DTO * @return 操作结果 */ R<Void> edit(FleetEditDTO dto); /** * 查询车队详情 * * @param id 车队id * @return 车队详情 */ R<FleetDetailVO> queryById(Long id); /** * 车队分页列表 * * @param query 查询参数 * @return 分页结果 */ R<PageInfo<FleetPageVO>> pageList(FleetPageQuery query); /** * 查询车队车辆分页列表 * * @param query 查询参数 * @return 分页结果 */ R<PageInfo<FleetVehicleVO>> queryVehiclePageList(FleetVehiclePageQuery query); /** * 查询车队人员分页列表 * * @param query 查询参数 * @return 分页结果 */ R<PageInfo<FleetUserVO>> queryUserPageList(FleetUserPageQuery query); /** * 根据ID删除车队 * @param id */ void deleteById(Long id); /** * 车队添加车辆成员 * @param fleetId * @param vehicleId */ void addVehicle(Long fleetId, Long vehicleId); /** * 车队添加人员成员 * * @param fleetId * @param operationUserId */ void addOperationUserId(Long fleetId, Long operationUserId); } xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/IXpVehicleService.java
@@ -3,11 +3,11 @@ import com.baomidou.mybatisplus.extension.service.IService; import com.xiaopeng.api.dto.vehicleConvoy.VehicleTemperatureDto; import com.xiaopeng.api.model.vehicleConvoy.XpVehicle; import com.xiaopeng.api.vo.vehicleConvoy.VehicleTemperatureVo; import com.xiaopeng.common.core.web.page.PageInfo; 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 java.util.List; @@ -166,4 +166,13 @@ * @return 车辆温度 */ VehicleTemperatureDto queryTemperatureByOrderId(Long orderId, String uid); /** * 车辆不分页列表 * * @param plateNumber * @param fleetName * @return */ List<XpVehicleVO> getList(String plateNumber, String fleetName); } xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpFleetServiceImpl.java
@@ -1,14 +1,46 @@ package com.xiaopeng.vehicleConvoy.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.dto.account.XpOperationsUserQueryDTO; import com.xiaopeng.api.feignClient.account.XpOperationUserClient; import com.xiaopeng.api.feignClient.operation.XpElectronicClient; import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient; import com.xiaopeng.api.model.account.XpOperationsUser; import com.xiaopeng.api.model.operation.XpElectronicFence; import com.xiaopeng.api.model.vehicleConvoy.XpFleet; 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.vo.account.XpOperationsUserWithRoleVO; import com.xiaopeng.common.core.domain.R; import com.xiaopeng.common.core.exception.ServiceException; import com.xiaopeng.common.core.web.page.PageInfo; import com.xiaopeng.vehicleConvoy.constant.I18nKeyConstant; import com.xiaopeng.vehicleConvoy.mapper.XpFleetMapper; import com.xiaopeng.vehicleConvoy.model.dto.FleetAddDTO; import com.xiaopeng.vehicleConvoy.model.dto.FleetEditDTO; import com.xiaopeng.vehicleConvoy.model.query.FleetPageQuery; import com.xiaopeng.vehicleConvoy.model.query.FleetUserPageQuery; import com.xiaopeng.vehicleConvoy.model.query.FleetVehiclePageQuery; import com.xiaopeng.vehicleConvoy.model.vo.FleetDetailVO; import com.xiaopeng.vehicleConvoy.model.vo.FleetPageVO; import com.xiaopeng.vehicleConvoy.model.vo.FleetUserVO; import com.xiaopeng.vehicleConvoy.model.vo.FleetVehicleVO; import com.xiaopeng.vehicleConvoy.service.IXpFleetOperationsService; import com.xiaopeng.vehicleConvoy.service.IXpFleetService; import com.xiaopeng.vehicleConvoy.service.IXpFleetVehicleService; import lombok.RequiredArgsConstructor; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.BeanUtils; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import java.util.ArrayList; import java.util.List; import java.util.*; import java.util.stream.Collectors; /** * <p> @@ -19,7 +51,18 @@ * @since 2026-02-03 */ @Service @RequiredArgsConstructor(onConstructor_ = @Lazy) public class XpFleetServiceImpl extends ServiceImpl<XpFleetMapper, XpFleet> implements IXpFleetService { private final IXpFleetOperationsService xpFleetOperationsService; private final IXpFleetVehicleService xpFleetVehicleService; private final XpOperationUserClient xpOperationUserClient; private final XpVehicleClient xpVehicleClient; private final XpElectronicClient xpElectronicClient; @Override public List<XpFleet> listByIds(List<Long> ids) { @@ -28,4 +71,432 @@ } return super.listByIds(ids); } @Override @Transactional(rollbackFor = Exception.class) public R<Void> add(FleetAddDTO dto) { // 1. 校验车队名称不能重复 long count = this.count(new LambdaQueryWrapper<XpFleet>() .eq(XpFleet::getFleetName, dto.getFleetName())); if (count > 0) { throw new ServiceException("车队名称已存在"); } // 2. 校验运维人员绑定 validateUserBinding(dto.getOperationsUserIds(), null); // 3. 校验车辆绑定 validateVehicleBinding(dto.getVehicleIds(), null); // 4. 插入车队主表记录 XpFleet fleet = new XpFleet(); fleet.setFleetName(dto.getFleetName()); fleet.setOperationsUserId(dto.getOperationsUserId()); fleet.setLocationId(dto.getLocationId()); this.save(fleet); // 5. 批量插入车队-人员关联表 List<XpFleetOperations> operationsList = dto.getOperationsUserIds().stream() .map(userId -> { XpFleetOperations operations = new XpFleetOperations(); operations.setFleetId(fleet.getId()); operations.setOperationsUserId(userId); return operations; }).collect(Collectors.toList()); if (!CollectionUtils.isEmpty(operationsList)) { xpFleetOperationsService.saveBatch(operationsList); } // 6. 批量插入车队-车辆关联表 List<XpFleetVehicle> vehicleList = dto.getVehicleIds().stream() .map(vehicleId -> { XpFleetVehicle fleetVehicle = new XpFleetVehicle(); fleetVehicle.setFleetId(fleet.getId()); fleetVehicle.setVehicleId(vehicleId); return fleetVehicle; }).collect(Collectors.toList()); if (!CollectionUtils.isEmpty(vehicleList)) { xpFleetVehicleService.saveBatch(vehicleList); } return R.ok(); } @Override @Transactional(rollbackFor = Exception.class) public R<Void> edit(FleetEditDTO dto) { // 1. 查询车队是否存在 XpFleet fleet = this.getById(dto.getId()); if (fleet == null) { throw new ServiceException("车队不存在"); } // 2. 校验车队名称不能与其他车队重复 long count = this.count(new LambdaQueryWrapper<XpFleet>() .eq(XpFleet::getFleetName, dto.getFleetName()) .ne(XpFleet::getId, dto.getId())); if (count > 0) { throw new ServiceException("车队名称已存在"); } // 3. 校验负责人绑定(如果修改了负责人) if (!dto.getOperationsUserId().equals(fleet.getOperationsUserId())) { List<Long> userIds = new ArrayList<>(); userIds.add(dto.getOperationsUserId()); validateUserBinding(userIds, dto.getId()); } // 4. 更新车队主表记录 fleet.setFleetName(dto.getFleetName()); fleet.setOperationsUserId(dto.getOperationsUserId()); fleet.setLocationId(dto.getLocationId()); this.updateById(fleet); return R.ok(); } /** * 校验人员绑定 * * @param userIds 人员ID列表 * @param excludeFleetId 排除的车队ID(编辑时使用) */ private void validateUserBinding(List<Long> userIds, Long excludeFleetId) { if (CollectionUtils.isEmpty(userIds)) { return; } for (Long userId : userIds) { LambdaQueryWrapper<XpFleetOperations> wrapper = new LambdaQueryWrapper<>(); wrapper.eq(XpFleetOperations::getOperationsUserId, userId); if (excludeFleetId != null) { wrapper.ne(XpFleetOperations::getFleetId, excludeFleetId); } XpFleetOperations operations = xpFleetOperationsService.getOne(wrapper); if (operations != null) { // 查询人员姓名和车队名称 R<XpOperationsUser> userResult = xpOperationUserClient.queryById(userId); XpFleet fleet = this.getById(operations.getFleetId()); String userName = userResult.getData() != null ? userResult.getData().getNickName() : "未知"; String fleetName = fleet != null ? fleet.getFleetName() : "未知"; List<Object> argsList = new ArrayList<>(); argsList.add(userName); argsList.add(fleetName); Object[] args = argsList.toArray(); throw new ServiceException("运维人员" + userName + "已绑定车队" + fleetName, I18nKeyConstant.FLEET_OPERATION_USER_BOUND_V1, args); } } } /** * 校验车辆绑定 * * @param vehicleIds 车辆ID列表 * @param excludeFleetId 排除的车队ID(编辑时使用) */ private void validateVehicleBinding(List<Long> vehicleIds, Long excludeFleetId) { if (CollectionUtils.isEmpty(vehicleIds)) { return; } for (Long vehicleId : vehicleIds) { LambdaQueryWrapper<XpFleetVehicle> wrapper = new LambdaQueryWrapper<>(); wrapper.eq(XpFleetVehicle::getVehicleId, vehicleId); if (excludeFleetId != null) { wrapper.ne(XpFleetVehicle::getFleetId, excludeFleetId); } XpFleetVehicle fleetVehicle = xpFleetVehicleService.getOne(wrapper); if (fleetVehicle != null) { // 查询车牌号和车队名称 R<XpVehicle> vehicleResult = xpVehicleClient.queryById(vehicleId); XpFleet fleet = this.getById(fleetVehicle.getFleetId()); String plateNumber = vehicleResult.getData() != null ? vehicleResult.getData().getPlateNumber() : "未知"; String fleetName = fleet != null ? fleet.getFleetName() : "未知"; List<Object> argList = new ArrayList<>(); argList.add(plateNumber); argList.add(fleetName); throw new ServiceException("车辆[" + plateNumber + "]已绑定车队[" + fleetName + "]", I18nKeyConstant.FLEET_VEHICLE_BOUND_V1, argList.toArray()); } } } @Override public R<FleetDetailVO> queryById(Long id) { // 1. 查询车队主表 XpFleet fleet = this.getById(id); if (fleet == null) { throw new ServiceException("车队不存在"); } // 2. 组装VO FleetDetailVO vo = new FleetDetailVO(); BeanUtils.copyProperties(fleet, vo); // 3. 统计人员数量 long userCount = xpFleetOperationsService.count(new LambdaQueryWrapper<XpFleetOperations>() .eq(XpFleetOperations::getFleetId, id)); vo.setUserCount((int) userCount); // 4. 统计车辆数量 long vehicleCount = xpFleetVehicleService.count(new LambdaQueryWrapper<XpFleetVehicle>() .eq(XpFleetVehicle::getFleetId, id)); vo.setVehicleCount((int) vehicleCount); // 5. 查询负责人信息 if (fleet.getOperationsUserId() != null) { R<XpOperationsUser> userResult = xpOperationUserClient.queryById(fleet.getOperationsUserId()); if (userResult.getData() != null) { vo.setOperationsUserName(userResult.getData().getNickName()); } } return R.ok(vo); } @Override public R<PageInfo<FleetPageVO>> pageList(FleetPageQuery query) { // 1. 构建查询条件 LambdaQueryWrapper<XpFleet> wrapper = new LambdaQueryWrapper<>(); if (StringUtils.isNotBlank(query.getFleetName())) { wrapper.like(XpFleet::getFleetName, query.getFleetName()); } wrapper.orderByDesc(XpFleet::getCreateTime); // 2. 执行分页查询 Page<XpFleet> page = new Page<>(query.getPageNum(), query.getPageSize()); Page<XpFleet> resultPage = this.page(page, wrapper); // 3. 收集所有需要查询的ID List<Long> userIds = resultPage.getRecords().stream() .map(XpFleet::getOperationsUserId) .filter(Objects::nonNull) .distinct() .collect(Collectors.toList()); List<Long> electronicIds = resultPage.getRecords().stream() .map(XpFleet::getElectronicId) .filter(Objects::nonNull) .distinct() .collect(Collectors.toList()); // 4. 批量查询负责人信息并转换为Map Map<Long, XpOperationsUser> userMap = new HashMap<>(); if (!CollectionUtils.isEmpty(userIds)) { R<List<XpOperationsUser>> usersResult = xpOperationUserClient.listByIds(userIds); if (usersResult.getData() != null) { userMap = usersResult.getData().stream() .collect(Collectors.toMap(XpOperationsUser::getId, user -> user)); } } // 5. 批量查询围栏信息并转换为Map Map<Long, XpElectronicFence> fenceMap = new HashMap<>(); if (!CollectionUtils.isEmpty(electronicIds)) { R<List<XpElectronicFence>> fencesResult = xpElectronicClient.listByIds(electronicIds); if (fencesResult.getData() != null) { fenceMap = fencesResult.getData().stream() .collect(Collectors.toMap(XpElectronicFence::getId, fence -> fence)); } } // 6. 转换为VO并填充信息 List<FleetPageVO> records = new ArrayList<>(); for (XpFleet fleet : resultPage.getRecords()) { FleetPageVO vo = new FleetPageVO(); BeanUtils.copyProperties(fleet, vo); // 统计人员数量 long userCount = xpFleetOperationsService.count(new LambdaQueryWrapper<XpFleetOperations>() .eq(XpFleetOperations::getFleetId, fleet.getId())); vo.setUserCount((int) userCount); // 统计车辆数量 long vehicleCount = xpFleetVehicleService.count(new LambdaQueryWrapper<XpFleetVehicle>() .eq(XpFleetVehicle::getFleetId, fleet.getId())); vo.setVehicleCount((int) vehicleCount); // 从Map中获取负责人信息 if (fleet.getOperationsUserId() != null) { XpOperationsUser user = userMap.get(fleet.getOperationsUserId()); if (user != null) { vo.setOperationsUserName(user.getNickName()); vo.setPhoneNumber(user.getPhoneNumber()); } } // 从Map中获取围栏名称 if (fleet.getElectronicId() != null) { XpElectronicFence fence = fenceMap.get(fleet.getElectronicId()); if (fence != null) { vo.setElectronicName(fence.getElectronicName()); } } records.add(vo); } // 7. 构建分页结果 PageInfo<FleetPageVO> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize()); pageInfo.setRecords(records); pageInfo.setTotal(resultPage.getTotal()); return R.ok(pageInfo); } @Override public R<PageInfo<FleetVehicleVO>> queryVehiclePageList(FleetVehiclePageQuery query) { // 1. 查询车队-车辆关联表 LambdaQueryWrapper<XpFleetVehicle> wrapper = new LambdaQueryWrapper<>(); wrapper.eq(XpFleetVehicle::getFleetId, query.getFleetId()); Page<XpFleetVehicle> page = new Page<>(query.getPageNum(), query.getPageSize()); Page<XpFleetVehicle> resultPage = xpFleetVehicleService.page(page, wrapper); // 2. 获取车辆ID列表 List<Long> vehicleIds = resultPage.getRecords().stream() .map(XpFleetVehicle::getVehicleId) .collect(Collectors.toList()); // 3. 批量查询车辆信息 List<FleetVehicleVO> records = new ArrayList<>(); if (!CollectionUtils.isEmpty(vehicleIds)) { R<List<XpVehicle>> vehiclesResult = xpVehicleClient.listByIds(vehicleIds); if (vehiclesResult.getData() != null) { for (XpVehicle vehicle : vehiclesResult.getData()) { // 如果有车牌号筛选条件,进行过滤 if (StringUtils.isNotBlank(query.getPlateNumber()) && !vehicle.getPlateNumber().contains(query.getPlateNumber())) { continue; } FleetVehicleVO vo = new FleetVehicleVO(); vo.setVehicleId(vehicle.getId()); vo.setVehicleCode(vehicle.getVehicleCode()); vo.setPlateNumber(vehicle.getPlateNumber()); vo.setVehicleColor(vehicle.getVehicleColor()); vo.setVehicleModel(vehicle.getVehicleModel()); vo.setOperatingStatus(vehicle.getOperatingStatus()); records.add(vo); } } } // 4. 构建分页结果 PageInfo<FleetVehicleVO> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize()); pageInfo.setRecords(records); pageInfo.setTotal(resultPage.getTotal()); return R.ok(pageInfo); } @Override public R<PageInfo<FleetUserVO>> queryUserPageList(FleetUserPageQuery query) { // 1. 先根据条件查询符合条件的运维用户 List<Long> filteredUserIds = new ArrayList<>(); if (StringUtils.isNotBlank(query.getNickName()) || StringUtils.isNotBlank(query.getPhone()) || query.getRoleId() != null) { // 构建查询条件 XpOperationsUserQueryDTO queryDTO = new XpOperationsUserQueryDTO(); queryDTO.setNickName(query.getNickName()); queryDTO.setPhoneNumber(query.getPhone()); queryDTO.setRoleId(query.getRoleId()); // 远程查询符合条件的用户 R<List<XpOperationsUserWithRoleVO>> usersResult = xpOperationUserClient.queryByConditions(queryDTO); if (usersResult.getData() == null || usersResult.getData().isEmpty()) { // 没有符合条件的用户,直接返回空结果 PageInfo<FleetUserVO> emptyPageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize()); emptyPageInfo.setRecords(new ArrayList<>()); emptyPageInfo.setTotal(0L); return R.ok(emptyPageInfo); } // 收集用户ID列表 filteredUserIds = usersResult.getData().stream() .map(XpOperationsUserWithRoleVO::getId) .collect(Collectors.toList()); } // 2. 查询车队-人员关联表(使用用户ID列表作为条件) LambdaQueryWrapper<XpFleetOperations> wrapper = new LambdaQueryWrapper<>(); if (query.getFleetId() != null) { wrapper.eq(XpFleetOperations::getFleetId, query.getFleetId()); } // 如果有用户ID过滤条件,添加到查询中 if (!CollectionUtils.isEmpty(filteredUserIds)) { wrapper.in(XpFleetOperations::getOperationsUserId, filteredUserIds); } Page<XpFleetOperations> page = new Page<>(query.getPageNum(), query.getPageSize()); Page<XpFleetOperations> resultPage = xpFleetOperationsService.page(page, wrapper); // 3. 获取人员ID列表 List<Long> userIds = resultPage.getRecords().stream() .map(XpFleetOperations::getOperationsUserId) .collect(Collectors.toList()); // 4. 批量查询人员及角色信息 List<FleetUserVO> records = new ArrayList<>(); if (!CollectionUtils.isEmpty(userIds)) { R<List<XpOperationsUserWithRoleVO>> usersResult = xpOperationUserClient.listByIdsWithRole(userIds); if (usersResult.getData() != null) { for (XpOperationsUserWithRoleVO user : usersResult.getData()) { FleetUserVO vo = new FleetUserVO(); vo.setUserId(user.getId()); vo.setNickName(user.getNickName()); vo.setPhoneNumber(user.getPhoneNumber()); vo.setJobNumber(user.getUniqueNumber()); vo.setRoleName(user.getRoleName()); records.add(vo); } } } // 5. 构建分页结果 PageInfo<FleetUserVO> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize()); pageInfo.setRecords(records); pageInfo.setTotal(resultPage.getTotal()); return R.ok(pageInfo); } @Override @Transactional(rollbackFor = Exception.class) public void deleteById(Long id) { // 删除用户关联 xpFleetOperationsService.lambdaUpdate().eq(XpFleetOperations::getFleetId, id).remove(); // 删除车辆关联 xpFleetVehicleService.lambdaUpdate().eq(XpFleetVehicle::getFleetId, id).remove(); // 删除车队 removeById(id); } @Override public void addVehicle(Long fleetId, Long vehicleId) { // 查询是否已关联 Long count = xpFleetVehicleService.lambdaQuery().eq(XpFleetVehicle::getFleetId, fleetId) .eq(XpFleetVehicle::getVehicleId, vehicleId).count(); if (count > 0) { throw new ServiceException("当前车队已和该车辆关联", I18nKeyConstant.FLEET_VEHICLE_BOUND_V2); } //保存关联关系 XpFleetVehicle xpFleetVehicle = new XpFleetVehicle(); xpFleetVehicle.setFleetId(fleetId); xpFleetVehicle.setVehicleId(vehicleId); xpFleetVehicleService.save(xpFleetVehicle); } @Override public void addOperationUserId(Long fleetId, Long operationUserId) { // 查询是否已关联 Long count = xpFleetOperationsService.lambdaQuery().eq(XpFleetOperations::getFleetId, fleetId) .eq(XpFleetOperations::getOperationsUserId, operationUserId).count(); if (count > 0) { throw new ServiceException("当前车队已和该人员关联", I18nKeyConstant.FLEET_OPERATION_USER_BOUND_2); } //保存关联 XpFleetOperations operations = new XpFleetOperations(); operations.setFleetId(fleetId); operations.setOperationsUserId(operationUserId); xpFleetOperationsService.save(operations); } } xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpVehicleServiceImpl.java
@@ -13,7 +13,6 @@ import com.xiaopeng.api.model.vehicleConvoy.XpVehicle; import com.xiaopeng.api.model.vehicleConvoy.XpVehicleAnnualRecord; import com.xiaopeng.api.vo.operation.ElectronicFenceDetailVo; import com.xiaopeng.api.vo.vehicleConvoy.VehicleTemperatureVo; import com.xiaopeng.api.vo.vehicleConvoy.VehiclesCommandEnum; import com.xiaopeng.api.vo.vehicleConvoy.VehiclesCommandParamVo; import com.xiaopeng.api.vo.vehicleConvoy.VehiclesCommandVo; @@ -26,6 +25,7 @@ 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.IXpVehicleAnnualRecordService; import com.xiaopeng.vehicleConvoy.service.IXpVehicleService; import com.xiaopeng.vehicleConvoy.util.VehicleControlUtil; @@ -37,7 +37,6 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import javax.annotation.Resource; import java.time.LocalDateTime; import java.time.LocalTime; import java.util.*; @@ -609,4 +608,9 @@ return new VehicleTemperatureDto(); } } @Override public List<XpVehicleVO> getList(String plateNumber, String fleetName) { return baseMapper.getList(plateNumber, fleetName); } } xp-robotaxi-vehicleConvoy-boot/src/main/resources/i18n/messages.properties
@@ -1,5 +1,9 @@ # 中文 fleet.operation.user.bound.v2=当前车队已和该人员关联 policy.application.audit.ids.notEmpty=保单申请ID列表不能为空 fleet.user.bound=运维人员[{0}]已绑定车队[{1}] fleet.vehicle.bound.v2=当前车队已和该车辆关联 fleet.vehicle.bound.v1=车辆[{0}]已绑定车队[{1}] policy.application.audit.status.notNull=保单审核状态不能为空 welcome.message=欢迎来到我们的应用程序! # 车辆管理 xp-robotaxi-vehicleConvoy-boot/src/main/resources/i18n/messages_en_US.properties
@@ -1,5 +1,8 @@ # English (US) fleet.operation.user.bound.v2=The current fleet has been associated with this person policy.application.audit.ids.notEmpty=The list of policy application ids cannot be empty fleet.operation.user.bound.v1=Operation user [{0}] already bound fleet:[{1}] fleet.vehicle.bound.v2=The current team has been associated with this vehicle. policy.application.audit.status.notNull=The review status of the insurance policy cannot be empty welcome.message=Welcome to our application! order.not.exists=No valid order information found xp-robotaxi-vehicleConvoy-boot/src/main/resources/i18n/messages_zh_CN.properties
@@ -1,5 +1,8 @@ # 中文 fleet.operation.user.bound.v2=当前车队已和该人员关联 policy.application.audit.ids.notEmpty=保单申请ID列表不能为空 fleet.user.bound=运维人员[{0}]已绑定车队[{1}] fleet.vehicle.bound.v2=当前车队已和该车辆关联 policy.application.audit.status.notNull=保单审核状态不能为空 welcome.message=欢迎来到我们的应用程序! order.not.exists=未查询到有效订单信息 xp-robotaxi-vehicleConvoy-boot/src/main/resources/mapper/vehicleConvoy/XpVehicleMapper.xml
@@ -108,5 +108,8 @@ </where> ORDER BY create_time DESC </select> <select id="getList" resultType="com.xiaopeng.vehicleConvoy.model.vo.XpVehicleVO"> </select> </mapper>