| | |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.xiaopeng.api.feignClient.vehicleConvoy.XpFleetClient; |
| | | import com.xiaopeng.api.feignClient.vehicleConvoy.XpFleetVehicleClient; |
| | | import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient; |
| | | import com.xiaopeng.api.model.operation.XpCruisePlan; |
| | | import com.xiaopeng.api.model.operation.XpCruisePlanPoint; |
| | | import com.xiaopeng.api.model.operation.XpCruisePlanVehicle; |
| | | import com.xiaopeng.api.model.operation.XpPoint; |
| | | import com.xiaopeng.api.model.vehicleConvoy.XpFleet; |
| | | import com.xiaopeng.api.model.vehicleConvoy.XpVehicle; |
| | | 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.common.security.utils.SecurityUtils; |
| | | import com.xiaopeng.operation.constant.I18nKeyConstant; |
| | | import com.xiaopeng.operation.dto.XpCruisePlanAddDTO; |
| | | import com.xiaopeng.operation.dto.XpCruisePlanEditDTO; |
| | | import com.xiaopeng.operation.mapper.XpCruisePlanMapper; |
| | | import com.xiaopeng.operation.query.CruisePlanQuery; |
| | | import com.xiaopeng.operation.service.IXpCruisePlanPointService; |
| | | import com.xiaopeng.operation.service.IXpCruisePlanService; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.xiaopeng.operation.service.IXpCruisePlanVehicleService; |
| | | import com.xiaopeng.operation.service.IXpPointService; |
| | | import com.xiaopeng.operation.vo.XpCruisePlanDetailVO; |
| | | import com.xiaopeng.operation.vo.XpCruisePlanPointVO; |
| | | import com.xiaopeng.operation.vo.XpCruisePlanVehicleVO; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.springframework.context.annotation.Lazy; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | |
| | | |
| | | private final IXpCruisePlanPointService xpCruisePlanPointService; |
| | | private final IXpCruisePlanVehicleService xpCruisePlanVehicleService; |
| | | |
| | | private final IXpPointService xpPointService; |
| | | private final XpVehicleClient xpVehicleClient; |
| | | private final XpFleetVehicleClient xpFleetVehicleClient; |
| | | private final XpFleetClient xpFleetClient; |
| | | @Override |
| | | public PageInfo<XpCruisePlan> getPageList(CruisePlanQuery query) { |
| | | PageInfo<XpCruisePlan> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize()); |
| | |
| | | pageInfo.setRecords(page.getRecords()); |
| | | return pageInfo; |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void add(XpCruisePlanAddDTO dto) { |
| | | //1.校验巡游计划名称 |
| | | validatePlanName(dto.getPlanName(), null); |
| | | //2.校验点位参数 |
| | | validatePointList(dto.getPointList()); |
| | | Set<Long> vehicleIdSet = validateVehicleList(dto.getVehicleIdList()); |
| | | //3.校验车辆是否已绑定其他巡游计划 |
| | | validateVehicleBind(vehicleIdSet, null); |
| | | XpCruisePlan plan = new XpCruisePlan(); |
| | | plan.setPlanName(dto.getPlanName()); |
| | | plan.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName()); |
| | | boolean planSaved = save(plan); |
| | | if (!planSaved || plan.getId() == null) { |
| | | throw new ServiceException("新增巡游计划失败", I18nKeyConstant.CRUISE_PLAN_ADD_FAIL); |
| | | } |
| | | List<XpCruisePlanPoint> pointList = buildPointList(plan.getId(), dto.getPointList()); |
| | | boolean pointSaved = xpCruisePlanPointService.saveBatch(pointList); |
| | | if (!pointSaved) { |
| | | throw new ServiceException("新增巡游计划失败", I18nKeyConstant.CRUISE_PLAN_ADD_FAIL); |
| | | } |
| | | List<XpCruisePlanVehicle> vehicleList = buildVehicleList(plan.getId(), dto.getVehicleIdList()); |
| | | boolean vehicleSaved = xpCruisePlanVehicleService.saveBatch(vehicleList); |
| | | if (!vehicleSaved) { |
| | | throw new ServiceException("新增巡游计划失败", I18nKeyConstant.CRUISE_PLAN_ADD_FAIL); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void edit(XpCruisePlanEditDTO dto) { |
| | | if (dto.getId() == null) { |
| | | throw new ServiceException("巡游计划ID不能为空", I18nKeyConstant.CRUISE_PLAN_ID_EMPTY); |
| | | } |
| | | XpCruisePlan plan = getById(dto.getId()); |
| | | if (plan == null) { |
| | | throw new ServiceException("巡游计划不存在", I18nKeyConstant.CRUISE_PLAN_NOT_EXIST); |
| | | } |
| | | validatePlanName(dto.getPlanName(), dto.getId()); |
| | | validatePointList(dto.getPointList()); |
| | | Set<Long> vehicleIdSet = validateVehicleList(dto.getVehicleIdList()); |
| | | validateVehicleBind(vehicleIdSet, dto.getId()); |
| | | plan.setPlanName(dto.getPlanName()); |
| | | plan.setUpdateBy(SecurityUtils.getLoginUser().getSysUser().getNickName()); |
| | | boolean planUpdated = updateById(plan); |
| | | if (!planUpdated) { |
| | | throw new ServiceException("编辑巡游计划失败", I18nKeyConstant.CRUISE_PLAN_EDIT_FAIL); |
| | | } |
| | | xpCruisePlanPointService.lambdaUpdate() |
| | | .eq(XpCruisePlanPoint::getCruisePlanId, dto.getId()) |
| | | .remove(); |
| | | xpCruisePlanVehicleService.lambdaUpdate() |
| | | .eq(XpCruisePlanVehicle::getCruisePlanId, dto.getId()) |
| | | .remove(); |
| | | List<XpCruisePlanPoint> pointList = buildPointList(dto.getId(), dto.getPointList()); |
| | | boolean pointSaved = xpCruisePlanPointService.saveBatch(pointList); |
| | | if (!pointSaved) { |
| | | throw new ServiceException("编辑巡游计划失败", I18nKeyConstant.CRUISE_PLAN_EDIT_FAIL); |
| | | } |
| | | List<XpCruisePlanVehicle> vehicleList = buildVehicleList(dto.getId(), dto.getVehicleIdList()); |
| | | boolean vehicleSaved = xpCruisePlanVehicleService.saveBatch(vehicleList); |
| | | if (!vehicleSaved) { |
| | | throw new ServiceException("编辑巡游计划失败", I18nKeyConstant.CRUISE_PLAN_EDIT_FAIL); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void deleteById(Long id) { |
| | | xpCruisePlanPointService.lambdaUpdate() |
| | | .eq(XpCruisePlanPoint::getCruisePlanId, id) |
| | | .remove(); |
| | | xpCruisePlanVehicleService.lambdaUpdate() |
| | | .eq(XpCruisePlanVehicle::getCruisePlanId, id) |
| | | .remove(); |
| | | removeById(id); |
| | | } |
| | | |
| | | @Override |
| | | public XpCruisePlanDetailVO detail(Long id) { |
| | | if (id == null) { |
| | | throw new ServiceException("巡游计划ID不能为空", I18nKeyConstant.CRUISE_PLAN_ID_EMPTY); |
| | | } |
| | | XpCruisePlan plan = getById(id); |
| | | if (plan == null) { |
| | | throw new ServiceException("巡游计划不存在", I18nKeyConstant.CRUISE_PLAN_NOT_EXIST); |
| | | } |
| | | List<XpCruisePlanPoint> planPoints = xpCruisePlanPointService.lambdaQuery() |
| | | .eq(XpCruisePlanPoint::getCruisePlanId, id) |
| | | .orderByAsc(XpCruisePlanPoint::getSortOrder) |
| | | .list(); |
| | | List<Long> pointIds = planPoints.stream() |
| | | .map(XpCruisePlanPoint::getPointId) |
| | | .filter(Objects::nonNull) |
| | | .map(Integer::longValue) |
| | | .collect(Collectors.toList()); |
| | | Map<Long, XpPoint> pointMap = CollUtil.isNotEmpty(pointIds) |
| | | ? xpPointService.listByIds(pointIds).stream() |
| | | .collect(Collectors.toMap(XpPoint::getId, v -> v)) |
| | | : Collections.emptyMap(); |
| | | List<XpCruisePlanPointVO> pointList = planPoints.stream().map(planPoint -> { |
| | | XpCruisePlanPointVO vo = new XpCruisePlanPointVO(); |
| | | vo.setPointId(planPoint.getPointId()); |
| | | vo.setSortOrder(planPoint.getSortOrder()); |
| | | XpPoint point = pointMap.get(planPoint.getPointId() == null ? null : planPoint.getPointId().longValue()); |
| | | if (point != null) { |
| | | vo.setPointName(point.getPointName()); |
| | | vo.setPointAddress(point.getPointAddress()); |
| | | } |
| | | return vo; |
| | | }).collect(Collectors.toList()); |
| | | |
| | | List<XpCruisePlanVehicle> planVehicles = xpCruisePlanVehicleService.lambdaQuery() |
| | | .eq(XpCruisePlanVehicle::getCruisePlanId, id) |
| | | .list(); |
| | | List<Long> vehicleIds = planVehicles.stream() |
| | | .map(XpCruisePlanVehicle::getVehicleId) |
| | | .filter(Objects::nonNull) |
| | | .collect(Collectors.toList()); |
| | | Map<Long, XpVehicle> vehicleMap; |
| | | if (CollUtil.isNotEmpty(vehicleIds)) { |
| | | R<List<XpVehicle>> vehicleResult = xpVehicleClient.listByIds(vehicleIds); |
| | | if (vehicleResult != null && CollUtil.isNotEmpty(vehicleResult.getData())) { |
| | | vehicleMap = vehicleResult.getData().stream() |
| | | .collect(Collectors.toMap(XpVehicle::getId, v -> v)); |
| | | } else { |
| | | vehicleMap = Collections.emptyMap(); |
| | | } |
| | | } else { |
| | | vehicleMap = Collections.emptyMap(); |
| | | } |
| | | Map<Long, Long> vehicleFleetIdMap = new HashMap<>(); |
| | | if (CollUtil.isNotEmpty(vehicleIds)) { |
| | | for (Long vehicleId : vehicleIds) { |
| | | R<Long> fleetIdResult = xpFleetVehicleClient.getFleetIdByVehicleId(vehicleId); |
| | | if (fleetIdResult != null && fleetIdResult.getData() != null) { |
| | | vehicleFleetIdMap.put(vehicleId, fleetIdResult.getData()); |
| | | } |
| | | } |
| | | } |
| | | Map<Long, String> fleetNameMap; |
| | | if (!vehicleFleetIdMap.isEmpty()) { |
| | | List<Long> fleetIds = vehicleFleetIdMap.values().stream().distinct().collect(Collectors.toList()); |
| | | R<List<XpFleet>> fleetResult = xpFleetClient.listByIds(fleetIds); |
| | | if (fleetResult != null && CollUtil.isNotEmpty(fleetResult.getData())) { |
| | | fleetNameMap = fleetResult.getData().stream() |
| | | .collect(Collectors.toMap(XpFleet::getId, XpFleet::getFleetName, (a, b) -> a)); |
| | | } else { |
| | | fleetNameMap = Collections.emptyMap(); |
| | | } |
| | | } else { |
| | | fleetNameMap = Collections.emptyMap(); |
| | | } |
| | | List<XpCruisePlanVehicleVO> vehicleList = planVehicles.stream().map(planVehicle -> { |
| | | XpCruisePlanVehicleVO vo = new XpCruisePlanVehicleVO(); |
| | | vo.setVehicleId(planVehicle.getVehicleId()); |
| | | XpVehicle vehicle = vehicleMap.get(planVehicle.getVehicleId()); |
| | | if (vehicle != null) { |
| | | vo.setVehicleCode(vehicle.getVehicleCode()); |
| | | vo.setPlateNumber(vehicle.getPlateNumber()); |
| | | vo.setVehicleModel(vehicle.getVehicleModel()); |
| | | } |
| | | Long fleetId = vehicleFleetIdMap.get(planVehicle.getVehicleId()); |
| | | if (fleetId != null) { |
| | | vo.setFleetName(fleetNameMap.get(fleetId)); |
| | | } |
| | | return vo; |
| | | }).collect(Collectors.toList()); |
| | | |
| | | XpCruisePlanDetailVO detailVO = new XpCruisePlanDetailVO(); |
| | | detailVO.setId(plan.getId()); |
| | | detailVO.setPlanName(plan.getPlanName()); |
| | | detailVO.setPointNum(planPoints.size()); |
| | | detailVO.setVehicleNum(planVehicles.size()); |
| | | detailVO.setCreateTime(plan.getCreateTime()); |
| | | detailVO.setPointList(pointList); |
| | | detailVO.setVehicleList(vehicleList); |
| | | return detailVO; |
| | | } |
| | | |
| | | /** |
| | | * 校验巡游计划名称 |
| | | * @param planName |
| | | * @param excludePlanId |
| | | */ |
| | | private void validatePlanName(String planName, Long excludePlanId) { |
| | | if (StringUtils.isBlank(planName)) { |
| | | throw new ServiceException("计划名称不能为空", I18nKeyConstant.CRUISE_PLAN_NAME_EMPTY); |
| | | } |
| | | Long count = lambdaQuery() |
| | | .eq(XpCruisePlan::getPlanName, planName) |
| | | .ne(excludePlanId != null, XpCruisePlan::getId, excludePlanId) |
| | | .count(); |
| | | if (count > 0) { |
| | | throw new ServiceException("计划名称已存在", I18nKeyConstant.CRUISE_PLAN_NAME_EXISTS); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 校验关联点位列表 |
| | | * @param pointList |
| | | */ |
| | | private void validatePointList(List<XpCruisePlanAddDTO.CruisePlanPointDTO> pointList) { |
| | | if (CollUtil.isEmpty(pointList)) { |
| | | throw new ServiceException("关联点位列表不能为空", I18nKeyConstant.CRUISE_PLAN_POINT_EMPTY); |
| | | } |
| | | Set<Integer> pointIdSet = new HashSet<>(); |
| | | for (XpCruisePlanAddDTO.CruisePlanPointDTO pointDTO : pointList) { |
| | | if (pointDTO.getPointId() == null || pointDTO.getSortOrder() == null || pointDTO.getStopFlag() == null) { |
| | | throw new ServiceException("点位参数不完整", I18nKeyConstant.CRUISE_PLAN_POINT_INCOMPLETE); |
| | | } |
| | | if (pointDTO.getStopFlag() != 0 && pointDTO.getStopFlag() != 1) { |
| | | throw new ServiceException("点位停车标识不合法", I18nKeyConstant.CRUISE_PLAN_STOP_FLAG_INVALID); |
| | | } |
| | | if (!pointIdSet.add(pointDTO.getPointId())) { |
| | | throw new ServiceException("点位ID重复", I18nKeyConstant.CRUISE_PLAN_POINT_DUPLICATE); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 校验关联车辆列表 |
| | | * @param vehicleIdList |
| | | * @return |
| | | */ |
| | | private Set<Long> validateVehicleList(List<Long> vehicleIdList) { |
| | | if (CollUtil.isEmpty(vehicleIdList)) { |
| | | throw new ServiceException("关联车辆列表不能为空", I18nKeyConstant.CRUISE_PLAN_VEHICLE_EMPTY); |
| | | } |
| | | Set<Long> vehicleIdSet = new HashSet<>(); |
| | | for (Long vehicleId : vehicleIdList) { |
| | | if (vehicleId == null) { |
| | | throw new ServiceException("车辆参数不完整", I18nKeyConstant.CRUISE_PLAN_VEHICLE_INCOMPLETE); |
| | | } |
| | | if (!vehicleIdSet.add(vehicleId)) { |
| | | throw new ServiceException("车辆ID重复", I18nKeyConstant.CRUISE_PLAN_VEHICLE_DUPLICATE); |
| | | } |
| | | } |
| | | return vehicleIdSet; |
| | | } |
| | | |
| | | /** |
| | | * 校验车辆是否已绑定其他巡游计划 |
| | | * @param vehicleIdSet |
| | | * @param excludePlanId |
| | | */ |
| | | private void validateVehicleBind(Set<Long> vehicleIdSet, Long excludePlanId) { |
| | | List<XpCruisePlanVehicle> boundVehicles = xpCruisePlanVehicleService.lambdaQuery() |
| | | .in(XpCruisePlanVehicle::getVehicleId, vehicleIdSet) |
| | | .ne(excludePlanId != null, XpCruisePlanVehicle::getCruisePlanId, excludePlanId) |
| | | .list(); |
| | | if (CollUtil.isNotEmpty(boundVehicles)) { |
| | | throw new ServiceException("车辆已关联其他巡游计划", I18nKeyConstant.CRUISE_PLAN_VEHICLE_ALREADY_BOUND); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 构建巡游计划点位列表 |
| | | * @param planId |
| | | * @param pointList |
| | | * @return |
| | | */ |
| | | private List<XpCruisePlanPoint> buildPointList(Long planId, List<XpCruisePlanAddDTO.CruisePlanPointDTO> pointList) { |
| | | List<XpCruisePlanPoint> result = new ArrayList<>(pointList.size()); |
| | | for (XpCruisePlanAddDTO.CruisePlanPointDTO pointDTO : pointList) { |
| | | XpCruisePlanPoint point = new XpCruisePlanPoint(); |
| | | point.setCruisePlanId(planId); |
| | | point.setPointId(pointDTO.getPointId()); |
| | | point.setSortOrder(pointDTO.getSortOrder()); |
| | | point.setStopFlag(pointDTO.getStopFlag()); |
| | | result.add(point); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | /** |
| | | * 构建巡游计划车辆列表 |
| | | * @param planId |
| | | * @param vehicleIdList |
| | | * @return |
| | | */ |
| | | private List<XpCruisePlanVehicle> buildVehicleList(Long planId, List<Long> vehicleIdList) { |
| | | List<XpCruisePlanVehicle> result = new ArrayList<>(vehicleIdList.size()); |
| | | for (Long vehicleId : vehicleIdList) { |
| | | XpCruisePlanVehicle vehicle = new XpCruisePlanVehicle(); |
| | | vehicle.setCruisePlanId(planId); |
| | | vehicle.setVehicleId(vehicleId); |
| | | result.add(vehicle); |
| | | } |
| | | return result; |
| | | } |
| | | } |