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.*;
|
import java.util.stream.Collectors;
|
|
/**
|
* <p>
|
* 车队管理 服务实现类
|
* </p>
|
*
|
* @author mitao
|
* @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) {
|
if (CollectionUtils.isEmpty(ids)) {
|
return new ArrayList<>();
|
}
|
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);
|
}
|
}
|