“mitao”
2026-02-13 c1dd7b55b725c5ce0cc7c639cd2d43ff10d26a18
feat(management):管理后台-开通城市管理
4个文件已添加
13个文件已修改
453 ■■■■■ 已修改文件
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/constant/I18nKeyConstant.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpOpenCityController.java 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/dto/OpenCityAddDTO.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/dto/OpenCityEditDTO.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/query/OpenCityPageQuery.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/XpOpenCityService.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpOpenCityServiceImpl.java 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/resources/i18n/messages.properties 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/resources/i18n/messages_en_US.properties 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/resources/i18n/messages_zh_CN.properties 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/config/DataUpdateHandlerConfig.java 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpFleetController.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpFleetVehicleController.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpVehicleController.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/mapper/XpVehicleMapper.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpFleetServiceImpl.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-vehicleConvoy-boot/src/main/resources/mapper/vehicleConvoy/XpVehicleMapper.xml 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/constant/I18nKeyConstant.java
@@ -32,4 +32,7 @@
    // 订单创建失败
    String ORDER_CREATE_FAIL = "order.create.fail";
    //开通城市已存在
    String OPEN_CITY_EXISTS = "open.city.exists";
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpOpenCityController.java
@@ -3,17 +3,20 @@
import com.xiaopeng.api.model.operation.XpOpenCity;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.web.controller.BaseController;
import com.xiaopeng.common.core.web.domain.AjaxResult;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.operation.dto.OpenCityAddDTO;
import com.xiaopeng.operation.dto.OpenCityEditDTO;
import com.xiaopeng.operation.query.OpenCityPageQuery;
import com.xiaopeng.operation.service.XpOpenCityService;
import com.xiaopeng.operation.vo.OpenCityListVO;
import com.xiaopeng.operation.vo.XpOpenCityVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -71,6 +74,63 @@
        return R.ok(nameLists);
    }
    /**
     * 管理后台-开通城市管理-开通城市分页列表
     * @param query
     * @return
     */
    @ApiOperation(value = "开通城市分页列表", tags = {"管理后台-开通城市管理"})
    @PostMapping("/api/v1/openCity/pageList")
    public R<PageInfo<XpOpenCity>> getPageList(@RequestBody OpenCityPageQuery query) {
        return R.ok(xpOpenCityService.getPageList(query));
    }
    /**
     * 管理后台-开通城市管理-新增开通城市
     * @param dto
     * @return
     */
    @ApiOperation(value = "新增开通城市", tags = {"管理后台-开通城市管理"})
    @PostMapping("/api/v1/openCity/add")
    public R<?> add(@Valid @RequestBody OpenCityAddDTO dto) {
        xpOpenCityService.add(dto);
        return R.ok();
    }
    /**
     * 管理后台-开通城市管理-编辑开通城市
     * @param dto
     * @return
     */
    @ApiOperation(value = "编辑开通城市", tags = {"管理后台-开通城市管理"})
    @PostMapping("/api/v1/openCity/edit")
    public R<?> add(@Valid @RequestBody OpenCityEditDTO dto) {
        xpOpenCityService.edit(dto);
        return R.ok();
    }
    /**
     * 管理后台-开通城市管理-删除开通城市
     * @param id
     * @return
     */
    @ApiOperation(value = "删除开通城市", tags = {"管理后台-开通城市管理"})
    @DeleteMapping("/api/v1/openCity/delete/{id}")
    public R<?> deleteById(@ApiParam(name = "id", value = "开通城市ID") @PathVariable Long id) {
        xpOpenCityService.deleteById(id);
        return R.ok();
    }
    /**
     * 管理后台-开通城市管理-启用/禁用
     * @param id
     * @param status
     * @return
     */
    @ApiOperation(value = "启用/禁用", tags = {"管理后台-开通城市管理"})
    @PostMapping("/api/v1/openCity/upDown")
    public R<?> upDown(Long id, Integer status) {
        xpOpenCityService.upDown(id, status);
        return R.ok();
    }
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/dto/OpenCityAddDTO.java
New file
@@ -0,0 +1,45 @@
package com.xiaopeng.operation.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
 * @author MiTao
 * @date 2026-02-12 22:23
 *
 */
@Data
@ApiModel("新增开通城市数据传输对象")
public class OpenCityAddDTO {
    @ApiModelProperty(value = "省份名称")
    @NotBlank(message = "省份名称不能为空")
    private String provinceName;
    @ApiModelProperty(value = "省份code")
    @NotBlank(message = "省份code名称不能为空")
    private String provinceCode;
    @ApiModelProperty(value = "城市名称")
    @NotBlank(message = "城市名称名称不能为空")
    private String cityName;
    @ApiModelProperty(value = "城市code")
    @NotBlank(message = "城市code名称不能为空")
    private String cityCode;
    @ApiModelProperty(value = "区县名称")
    private String districtName;
    @ApiModelProperty(value = "区县code")
    private String districtCode;
    @ApiModelProperty(value = "状态 1=启用 0=禁用")
    @NotNull(message = "状态不能为空")
    private Integer status;
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/dto/OpenCityEditDTO.java
New file
@@ -0,0 +1,22 @@
package com.xiaopeng.operation.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotNull;
/**
 * @author MiTao
 * @date 2026-02-12 22:25
 *
 */
@Data
@EqualsAndHashCode(callSuper = true)
@ApiModel("开通城市编辑数据传输对象")
public class OpenCityEditDTO extends OpenCityAddDTO{
    @ApiModelProperty(value = "ID")
    @NotNull(message = "ID不能为空")
    private Long id;
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/query/OpenCityPageQuery.java
New file
@@ -0,0 +1,25 @@
package com.xiaopeng.operation.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
 * @date 2026-02-12 22:13
 *
 */
@Data
@EqualsAndHashCode(callSuper = true)
@ApiModel("开通城市分页查询对象")
public class OpenCityPageQuery extends BasePage {
    @ApiModelProperty(value = "城市名称")
    private String cityName;
    @ApiModelProperty(value = "状态 1=启用 0=禁用")
    private Integer status;
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/XpOpenCityService.java
@@ -3,9 +3,14 @@
import com.baomidou.mybatisplus.extension.service.IService;
import com.xiaopeng.api.model.operation.XpOpenCity;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.operation.dto.OpenCityAddDTO;
import com.xiaopeng.operation.dto.OpenCityEditDTO;
import com.xiaopeng.operation.query.OpenCityPageQuery;
import com.xiaopeng.operation.vo.OpenCityListVO;
import com.xiaopeng.operation.vo.XpOpenCityVo;
import javax.validation.Valid;
import java.util.List;
/**
@@ -28,4 +33,38 @@
     */
    List<OpenCityListVO> getOpenCityListForAdmin();
    /**
     * 开通城市分页列表
     * @return
     */
    PageInfo<XpOpenCity> getPageList(OpenCityPageQuery query);
    /**
     * 新增开通城市
     *
     * @param dto
     */
    void add(@Valid OpenCityAddDTO dto);
    /**
     * 编辑开通城市
     *
     * @param dto
     */
    void edit(@Valid OpenCityEditDTO dto);
    /**
     * 删除开通城市
     * @param id
     */
    void deleteById(Long id);
    /**
     * 管理后台-开通城市管理-启用/禁用
     *
     * @param id
     * @param status
     * @return
     */
    void upDown(Long id, Integer status);
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpOpenCityServiceImpl.java
@@ -1,11 +1,19 @@
package com.xiaopeng.operation.service.impl;
import cn.hutool.core.bean.BeanUtil;
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.common.redis.service.RedisService;
import com.xiaopeng.operation.mapper.XpOpenCityMapper;
import com.xiaopeng.api.model.operation.XpOpenCity;
import com.xiaopeng.common.core.exception.ServiceException;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.common.security.utils.SecurityUtils;
import com.xiaopeng.operation.constant.I18nKeyConstant;
import com.xiaopeng.operation.dto.OpenCityAddDTO;
import com.xiaopeng.operation.dto.OpenCityEditDTO;
import com.xiaopeng.operation.mapper.XpOpenCityMapper;
import com.xiaopeng.operation.query.OpenCityPageQuery;
import com.xiaopeng.operation.service.XpOpenCityService;
import com.xiaopeng.operation.vo.OpenCityListVO;
import com.xiaopeng.operation.vo.XpOpenCityNextVo;
@@ -13,9 +21,9 @@
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
@@ -80,4 +88,58 @@
                })
                .collect(Collectors.toList());
    }
    @Override
    public PageInfo<XpOpenCity> getPageList(OpenCityPageQuery query) {
        Page<XpOpenCity> page = lambdaQuery().like(StringUtils.isNotBlank(query.getCityName()), XpOpenCity::getCityName, query.getCityName())
                .eq(Objects.nonNull(query.getStatus()), XpOpenCity::getStatus, query.getStatus())
                .orderByDesc(XpOpenCity::getCreateTime)
                .page(new Page<>(query.getPageNum(), query.getPageSize()));
        PageInfo<XpOpenCity> pageInfo = new PageInfo<>();
        pageInfo.setRecords(page.getRecords());
        page.setTotal(page.getTotal());
        return pageInfo;
    }
    @Override
    public void add(OpenCityAddDTO dto) {
        checkIfExist(dto, null);
        XpOpenCity xpOpenCity = BeanUtil.copyProperties(dto, XpOpenCity.class);
        xpOpenCity.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
        save(xpOpenCity);
    }
    /**
     * 校验开通城市是否已添加
     * @param dto
     * @param excludeOpenCityId
     */
    private void checkIfExist(OpenCityAddDTO dto, Long excludeOpenCityId) {
        Long count = lambdaQuery().eq(XpOpenCity::getProvinceCode, dto.getProvinceCode())
                .eq(XpOpenCity::getCityCode, dto.getCityCode())
                .eq(StringUtils.isNotBlank(dto.getDistrictCode()), XpOpenCity::getDistrictCode, dto.getDistrictCode())
                .ne(Objects.nonNull(excludeOpenCityId), XpOpenCity::getId, excludeOpenCityId)
                .count();
        if (count > 0) {
            throw new ServiceException("该城市已存在", I18nKeyConstant.OPEN_CITY_EXISTS);
        }
    }
    @Override
    public void edit(OpenCityEditDTO dto) {
        checkIfExist(dto, dto.getId());
        XpOpenCity xpOpenCity = BeanUtil.copyProperties(dto, XpOpenCity.class);
        xpOpenCity.setUpdateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
        updateById(xpOpenCity);
    }
    @Override
    public void deleteById(Long id) {
        removeById(id);
    }
    @Override
    public void upDown(Long id, Integer status) {
        lambdaUpdate().eq(XpOpenCity::getId, id).set(XpOpenCity::getStatus, status).update();
    }
}
xp-robotaxi-operation-boot/src/main/resources/i18n/messages.properties
@@ -11,4 +11,5 @@
fence.structure.not.exist=围栏构成不存在
fence.not.exist=围栏不存在
fence.status.cannot.copied=围栏启用状态不可复制;
order.create.fail=订单创建失败
order.create.fail=订单创建失败
open.city.exists=该城市已存在
xp-robotaxi-operation-boot/src/main/resources/i18n/messages_en_US.properties
@@ -11,4 +11,5 @@
fence.structure.not.exist=The fence composition does not exist\
fence.status.cannot.copied=The enabled state of the fence cannot be copied;
fence.not.exist=The fence does not exist.
order.create.fail=Order creation failed
order.create.fail=Order creation failed
open.city.exists=This city already exists
xp-robotaxi-operation-boot/src/main/resources/i18n/messages_zh_CN.properties
@@ -11,4 +11,5 @@
fence.structure.not.exist=围栏构成不存在
fence.not.exist=围栏不存在
fence.status.cannot.copied=围栏启用状态不可复制
order.create.fail=订单创建失败
order.create.fail=订单创建失败
open.city.exists=该城市已存在
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/config/DataUpdateHandlerConfig.java
New file
@@ -0,0 +1,72 @@
package com.xiaopeng.vehicleConvoy.config;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.xiaopeng.common.core.utils.StringUtils;
import com.xiaopeng.common.security.utils.SecurityUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.context.annotation.Configuration;
import java.time.LocalDateTime;
/**
 * @author xiaochen
 * @ClassName DataUpdateInterceptor
 * @Description 数据更新操作处理
 * @date 2021-12-15
 * <p>
 * 注意,之前在此处注入了 JwtTokenUtils
 * <p>
 * 造成spring循环依赖,项目支棱不起来
 */
@Slf4j
@Configuration
public class DataUpdateHandlerConfig implements MetaObjectHandler {
    /**
     * 新增数据执行
     *
     * @param metaObject
     */
    @Override
    public void insertFill(MetaObject metaObject) {
        String userName = "";
        try{
            //  获取登录信息
            userName = SecurityUtils.getLoginUser().getSysUser().getNickName();
            log.info("DataUpdateInterceptor insertFill");
        } catch (Exception e) {
            log.error("DataUpdateInterceptor insertFill error:{}", e.getMessage());
        }
        if (StringUtils.isNotBlank(userName)) {
            this.setFieldValByName("createBy", userName, metaObject);
            this.setFieldValByName("updateBy", userName, metaObject);
        } else {
            this.setFieldValByName("createBy", userName, metaObject);
            this.setFieldValByName("updateBy", userName, metaObject);
        }
        this.setFieldValByName("createTime", LocalDateTime.now(), metaObject);
        this.setFieldValByName("updateTime", LocalDateTime.now(), metaObject);
        this.setFieldValByName("createBy", userName, metaObject);
    }
    /**
     * 修改数据执行
     *
     * @param metaObject
     */
    @Override
    public void updateFill(MetaObject metaObject) {
        String userName = "";
        try{
            //  获取登录信息
            userName = SecurityUtils.getLoginUser().getSysUser().getNickName();
            log.info("DataUpdateInterceptor insertFill");
        } catch (Exception e) {
            log.error("DataUpdateInterceptor insertFill error:{}", e.getMessage());
        }
        this.setFieldValByName("updateTime", LocalDateTime.now(), metaObject);
        this.setFieldValByName("updateBy", userName, metaObject);
    }
}
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpFleetController.java
@@ -56,7 +56,7 @@
     * @param dto 添加车队DTO
     * @return 操作结果
     */
    @ApiOperation(value = "添加车队", tags = {"管理后台-车队管理"})
    @ApiOperation(value = "添加车队", tags = {"管理后台-车队管理"}, notes = "打卡地列表接口在xp-robotaxi-maintenance-boot,人员列表在xp-robotaxi-account-boot")
    @PostMapping("/api/v1/fleet/add")
    public R<Void> add(@Valid @RequestBody FleetAddDTO dto) {
        return xpFleetService.add(dto);
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpFleetVehicleController.java
@@ -2,7 +2,6 @@
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.vehicleConvoy.service.IXpFleetVehicleService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.web.bind.annotation.GetMapping;
@@ -21,7 +20,6 @@
 * @since 2026-02-03
 */
@RestController
@Api(tags = "车队车辆管理")
public class XpFleetVehicleController {
    @Resource
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpVehicleController.java
@@ -7,6 +7,8 @@
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.maintenance.XpChargingRecordClient;
import com.xiaopeng.api.feignClient.maintenance.XpVehiclePreparationClient;
@@ -23,12 +25,10 @@
import com.xiaopeng.vehicleConvoy.model.exportExcel.XpVehicleExportExcel;
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 io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
@@ -487,6 +487,14 @@
        VehicleTemperatureDto vehicleTemperatureDto = xpVehicleService.queryTemperatureByOrderId(orderId,uid);
        return R.ok(vehicleTemperatureDto);
    }
    /**
     * 获取车辆不分页列表
     *
     * @param plateNumber
     * @param fleetName
     * @return
     */
    @ApiOperation(value = "获取车辆不分页列表", tags = {"管理后台-车队管理"})
    @PostMapping("/api/v1/vehicle/list")
    @ApiImplicitParams({
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/mapper/XpVehicleMapper.java
@@ -87,5 +87,5 @@
     * @param fleetName
     * @return
     */
    List<XpVehicleVO> getList(String plateNumber, String fleetName);
    List<XpVehicleVO> getList(@Param("plateNumber") String plateNumber, @Param("fleetName") String fleetName);
}
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpFleetServiceImpl.java
@@ -85,8 +85,8 @@
        // 2. 校验运维人员绑定
        validateUserBinding(dto.getOperationsUserIds(), null);
        // 3. 校验车辆绑定
        validateVehicleBinding(dto.getVehicleIds(), null);
        // 3. 处理车辆绑定(自动解绑已绑定的车辆)
        handleVehicleBinding(dto.getVehicleIds(), null);
        // 4. 插入车队主表记录
        XpFleet fleet = new XpFleet();
@@ -189,12 +189,12 @@
    }
    /**
     * 校验车辆绑定
     * 处理车辆绑定(自动解绑已绑定的车辆)
     *
     * @param vehicleIds     车辆ID列表
     * @param excludeFleetId 排除的车队ID(编辑时使用)
     */
    private void validateVehicleBinding(List<Long> vehicleIds, Long excludeFleetId) {
    private void handleVehicleBinding(List<Long> vehicleIds, Long excludeFleetId) {
        if (CollectionUtils.isEmpty(vehicleIds)) {
            return;
        }
@@ -207,15 +207,8 @@
            }
            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());
                // 车辆已绑定其他车队,自动解绑
                xpFleetVehicleService.removeById(fleetVehicle.getId());
            }
        }
    }
@@ -472,13 +465,24 @@
    @Override
    public void addVehicle(Long fleetId, Long vehicleId) {
        // 查询是否已关联
        // 1. 检查是否已关联当前车队
        Long count = xpFleetVehicleService.lambdaQuery().eq(XpFleetVehicle::getFleetId, fleetId)
                .eq(XpFleetVehicle::getVehicleId, vehicleId).count();
        if (count > 0) {
            throw new ServiceException("当前车队已和该车辆关联", I18nKeyConstant.FLEET_VEHICLE_BOUND_V2);
        }
        //保存关联关系
        // 2. 检查是否已绑定其他车队,如果是则自动解绑
        XpFleetVehicle existingBinding = xpFleetVehicleService.lambdaQuery()
                .eq(XpFleetVehicle::getVehicleId, vehicleId)
                .ne(XpFleetVehicle::getFleetId, fleetId)
                .one();
        if (existingBinding != null) {
            // 车辆已绑定其他车队,自动解绑
            xpFleetVehicleService.removeById(existingBinding.getId());
        }
        // 3. 保存新的关联关系
        XpFleetVehicle xpFleetVehicle = new XpFleetVehicle();
        xpFleetVehicle.setFleetId(fleetId);
        xpFleetVehicle.setVehicleId(vehicleId);
xp-robotaxi-vehicleConvoy-boot/src/main/resources/mapper/vehicleConvoy/XpVehicleMapper.xml
@@ -109,7 +109,51 @@
        ORDER BY create_time DESC
    </select>
    <select id="getList" resultType="com.xiaopeng.vehicleConvoy.model.vo.XpVehicleVO">
        select xv.id,
        xv.vehicle_code,
        xv.vehicle_vin,
        xv.plate_number,
        xv.vehicle_model,
        xv.vehicle_color,
        xv.vehicle_pictures,
        xv.procurement_source,
        xv.remarks,
        xv.annual_inspection_date,
        xv.insurance_company,
        xv.insurance_phone,
        xv.insurance_end_time,
        xv.inspection_attachments,
        xv.policy_information,
        xv.electronic_id,
        xv.operation_qualification,
        xv.qualification_expire_time,
        xv.state,
        xv.status,
        xv.operating_status,
        xv.warehousing_time,
        xv.vehicle_type,
        xv.accept_or_test,
        xv.accept_or_test_status,
        xv.current_electricity,
        xv.is_deleted,
        xv.create_time,
        xv.update_time,
        xv.create_by,
        xv.update_by,
        xf.fleet_name
        from xp_vehicle xv
        left join xp_fleet_vehicle xfv on xv.id = xfv.vehicle_id
        left join xp_fleet xf on xfv.fleet_id = xf.id
        <where>
            xv.is_deleted = 0
            <if test="plateNumber != null and plateNumber != ''">
                and xv.plate_number like concat('%', #{plateNumber}, '%')
            </if>
            <if test="fleetName != null and fleetName != ''">
                and xf.fleet_name like concat('%', #{fleetName}, '%')
            </if>
        </where>
        order by xv.create_time desc
    </select>
</mapper>