package com.zy.acs.manager.manager.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.zy.acs.common.utils.News; import com.zy.acs.framework.common.Cools; import com.zy.acs.manager.core.integrate.conveyor.ConveyorStationService; import com.zy.acs.manager.core.domain.TaskPosDto; import com.zy.acs.manager.manager.entity.*; import com.zy.acs.manager.manager.enums.*; import com.zy.acs.manager.manager.mapper.StaMapper; import com.zy.acs.manager.manager.service.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; @Service("staService") public class StaServiceImpl extends ServiceImpl implements StaService { @Autowired private AgvService agvService; @Autowired private AgvDetailService agvDetailService; @Autowired private SegmentService segmentService; @Autowired private TravelService travelService; @Autowired private StaReserveService staReserveService; @Autowired private TaskService taskService; @Autowired private ConveyorStationService conveyorStationService; @Override public Sta selectByStaNo(String staNo) { return this.getOne(new LambdaQueryWrapper() .eq(Sta::getStaNo, staNo).eq(Sta::getStatus, StatusType.ENABLE.val)); } @Override public Sta selectByCode(Long codeId, StaTypeType type) { if (Cools.isEmpty(codeId, type)) { return null; } List list = this.list(new LambdaQueryWrapper() .eq(Sta::getCode, codeId).eq(Sta::getStaType, type.val()).eq(Sta::getStatus, StatusType.ENABLE.val)); return list.stream().findFirst().orElse(null); } @Override public List queryAvailableOutSta(Integer minAvailableQty) { long rollerStaType = StaTypeType.ROLLER.val(); List list = new ArrayList<>(); list.addAll(this.baseMapper.selectAvailableOutStaRoller(rollerStaType, minAvailableQty)); list.addAll(this.baseMapper.selectAvailableOutStaCommon(rollerStaType, minAvailableQty)); list.sort(Comparator.comparing(Sta::getStaNo, Comparator.nullsLast(String::compareTo))); return list; } @Override public List queryAvailableInSta(Integer minAvailableQty) { long rollerStaType = StaTypeType.ROLLER.val(); List list = new ArrayList<>(); list.addAll(this.baseMapper.selectAvailableInStaRoller(rollerStaType, minAvailableQty)); list.addAll(this.baseMapper.selectAvailableInStaCommon(rollerStaType, minAvailableQty)); list.sort(Comparator.comparing(Sta::getStaNo, Comparator.nullsLast(String::compareTo))); return list; } @Override public Task checkoutTask(Long staId) { StaReserve reserve = staReserveService.getOne(new LambdaQueryWrapper() .eq(StaReserve::getStaId, staId) .eq(StaReserve::getState, StaReserveStateType.CONFIRMED.toString()) .eq(StaReserve::getType, StaReserveType.IN.toString()) .eq(StaReserve::getStatus, StatusType.ENABLE.val) .orderByDesc(StaReserve::getConfirmedAt) .last("limit 1") ); if (null == reserve) { return null; } return taskService.getById(reserve.getTaskId()); } @Override public boolean isRoller(Long staId) { if (staId == null) { return false; } Sta sta = this.getById(staId); return StaTypeType.ROLLER.equals(resolveStaType(sta)); } @Override public StaTypeType resolveStaType(Sta sta) { if (sta == null || Cools.isEmpty(sta.getStaType())) { return null; } for (StaTypeType value : StaTypeType.values()) { if (value.val() == sta.getStaType()) { return value; } } return null; } @Override public boolean allowAgvWorkAtSta(String agvNo, Sta sta, Task task, Segment seg, StaReserveType type) { if (sta == null) { return false; } if (!staReserveService.waitingStaReserve(sta, task, seg, 1, type)) { return false; } StaTypeType staType = resolveStaType(sta); if (staType == null) { News.warn("AGV [{}] station [{}] has unknown sta type, validation bypassed", agvNo, sta.getStaNo()); return true; } switch (staType) { case ROLLER: if (!conveyorStationService.allowAgvWork(sta, task, seg, type)) { staReserveService.rollbackWaitingToReserved(sta, task, type); return false; } News.info("AGV [{}] work permitted at conveyor station [{}], type=[{}]", agvNo, sta.getStaNo(), type); return true; case RACK: case TRANSFER: default: News.info("AGV [{}] work permitted at station [{}], staType=[{}], validation bypassed", agvNo, sta.getStaNo(), staType); return true; } } @Override public Boolean hasWorkingAgv(Long staId) { Sta sta = this.getById(staId); Long codeId = sta.getCode(); if (null == codeId) { return false; } List agvIds = agvService.list(new LambdaQueryWrapper() .select(Agv::getId) .eq(Agv::getStatus, StatusType.ENABLE.val)) .stream().map(Agv::getId).collect(Collectors.toList()); if (Cools.isEmpty(agvIds)) { return false; } for (Long agvId : agvIds) { Code currentCode = agvDetailService.getCurrentCode(agvId); if (null == currentCode) { continue; } if (!currentCode.getId().equals(codeId)) { continue; } // if hit return true Segment lastSeg = segmentService.getOne(new LambdaQueryWrapper() .eq(Segment::getAgvId, agvId).eq(Segment::getEndNode, codeId) .orderByDesc(Segment::getId).last("LIMIT 1")); if (null == lastSeg) { return false; } Travel travel = travelService.getById(lastSeg.getTravelId()); if (travel.getState().equals(TravelStateType.FINISH.toString())) { return false; } // running travel List segments = segmentService.list(new LambdaQueryWrapper() .eq(Segment::getTravelId, travel.getId())); for (Segment segment : segments) { if (segment.getEndNode().equals(codeId) && segment.getState().equals(SegmentStateType.RUNNING.toString()) && (segment.getPosType().equals(TaskPosDto.PosType.ORI_STA.toString()) || segment.getPosType().equals(TaskPosDto.PosType.DEST_STA.toString())) ) { return 0 < staReserveService.count(new LambdaQueryWrapper() .eq(StaReserve::getStaId, staId) .eq(StaReserve::getTaskId, segment.getTaskId()) .eq(StaReserve::getSegmentId, segment.getId()) .eq(StaReserve::getState, StaReserveStateType.WAITING.toString()) // .eq(StaReserve::getType, StaReserveType.IN.toString()) .eq(StaReserve::getStatus, StatusType.ENABLE.val) .orderByDesc(StaReserve::getUpdateTime) // .last("limit 1") ); } } } return false; } }