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.enums.AgvStatusType;
|
import com.zy.acs.framework.common.Cools;
|
import com.zy.acs.manager.common.utils.CommonUtil;
|
import com.zy.acs.manager.manager.entity.*;
|
import com.zy.acs.manager.manager.enums.FuncStaType;
|
import com.zy.acs.manager.manager.enums.StatusType;
|
import com.zy.acs.manager.manager.enums.TaskStsType;
|
import com.zy.acs.manager.manager.enums.TaskTypeType;
|
import com.zy.acs.manager.manager.mapper.FuncStaMapper;
|
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.Collections;
|
import java.util.Comparator;
|
import java.util.List;
|
import java.util.stream.Collectors;
|
|
@Service("funcStaService")
|
public class FuncStaServiceImpl extends ServiceImpl<FuncStaMapper, FuncSta> implements FuncStaService {
|
|
@Autowired
|
private CodeService codeService;
|
@Autowired
|
private AgvService agvService;
|
@Autowired
|
private AgvDetailService agvDetailService;
|
@Autowired
|
private AgvModelService agvModelService;
|
@Autowired
|
private TaskService taskService;
|
|
@Override
|
public FuncSta getByCodeAndType(Long codeId, String type) {
|
List<FuncSta> list = this.list(new LambdaQueryWrapper<FuncSta>().eq(FuncSta::getCode, codeId).eq(FuncSta::getType, type));
|
if (Cools.isEmpty(list)) {
|
return null;
|
}
|
return list.stream().findFirst().orElse(null);
|
}
|
|
@Override
|
public FuncSta query(Long agvId, Long codeId, String type) {
|
List<FuncSta> list = this.list(new LambdaQueryWrapper<FuncSta>()
|
.eq(FuncSta::getAgvId, agvId)
|
.eq(FuncSta::getCode, codeId)
|
.eq(FuncSta::getType, type)
|
);
|
return list.stream().findFirst().orElse(null);
|
}
|
|
@Override
|
public List<FuncSta> findInIdleStatus(FuncStaType type, Long agvId) {
|
LambdaQueryWrapper<FuncSta> wrapper = new LambdaQueryWrapper<FuncSta>()
|
.eq(FuncSta::getType, type).eq(FuncSta::getStatus, StatusType.ENABLE.val);
|
List<FuncSta> funcStaList = this.list(wrapper);
|
|
if (Cools.isEmpty(funcStaList)) {
|
return new ArrayList<>();
|
}
|
|
Collections.shuffle(funcStaList);
|
// filter idle
|
funcStaList = funcStaList.stream().filter(funcSta -> {
|
|
Long code = funcSta.getCode();
|
if (null == code) {
|
return false;
|
}
|
|
Agv agv = agvService.findByPosition(code);
|
|
if (funcSta.getType().equals(FuncStaType.CHARGE.toString())) {
|
// if the type of this funSta is charge and the existing agv is in charge status, then that means this funSta is occupied
|
if (null != agv) {
|
AgvModel agvModel = agvModelService.getById(agv.getAgvModel());
|
AgvDetail agvDetail = agvDetailService.selectByAgvId(agv.getId());
|
if (agvDetail.getAgvStatus().equals(AgvStatusType.CHARGE)) {
|
if (agvDetail.getVol() < agvModel.getQuaBattery()) {
|
return false;
|
}
|
} else {
|
Task latestTask = taskService.findLatestTask(agv.getId(), null);
|
if (null != latestTask
|
&& latestTask.getTaskType().equals(TaskTypeType.TO_CHARGE.val())
|
&& latestTask.getDestCode().equals(funcSta.getCode())
|
) {
|
// avoid the agv already be full battery but there was no task assign to it, so that not in charge status and battery had down
|
if (agvDetailService.isPowerLoss(agv, agvDetail, agvModel)) {
|
return false;
|
}
|
}
|
}
|
}
|
|
// if there is a running task whose destination is this funSta, then that means this funSta is occupied
|
if (0 < taskService.count(new LambdaQueryWrapper<Task>()
|
.eq(Task::getTaskType, TaskTypeType.TO_CHARGE.val())
|
.in(Task::getTaskSts, TaskStsType.ASSIGN.val(), TaskStsType.PROGRESS.val())
|
.eq(Task::getDestCode, code)
|
)) {
|
return false;
|
}
|
|
}
|
|
if (funcSta.getType().equals(FuncStaType.STANDBY.toString())) {
|
|
if (null == agv) {
|
// if there is a running task whose destination is this funSta, then that means this funSta is occupied
|
if (0 < taskService.count(new LambdaQueryWrapper<Task>()
|
.eq(Task::getTaskType, TaskTypeType.TO_STANDBY.val())
|
.in(Task::getTaskSts, TaskStsType.ASSIGN.val(), TaskStsType.PROGRESS.val())
|
.eq(Task::getDestCode, code)
|
)) {
|
return false;
|
}
|
|
} else {
|
// if there is an agv on the code of this funSta, should we let this agv leave?
|
// we need to judge whether the agv went to this funSta based on a task which in GO_STANDBY type
|
|
// Task latestTaskByAgv = taskService.findLatestTask(existAgv.getId());
|
|
}
|
}
|
|
return true;
|
}).collect(Collectors.toList());
|
|
return funcStaList;
|
}
|
|
@Override
|
public FuncSta checkoutClosestFunSta(Long codeId, List<FuncSta> funcStaList) {
|
if (Cools.isEmpty(funcStaList)) {
|
return null;
|
}
|
|
if (null != codeId) {
|
Code currCode = codeService.getById(codeId);
|
Double[] startPos = new Double[]{currCode.getX(), currCode.getY()};
|
|
// checkout one funSta which is the closest
|
|
// compare => compare返回负数,则排在集合前面 (asc)
|
funcStaList.sort(new Comparator<FuncSta>() {
|
@Override
|
public int compare(FuncSta o1, FuncSta o2) {
|
Code o1Code = codeService.getById(o1.getCode());
|
int o1Distance = CommonUtil.calcDistance(startPos, new Double[]{o1Code.getX(), o1Code.getY()});
|
|
Code o2Code = codeService.getById(o2.getCode());
|
int o2Distance = CommonUtil.calcDistance(startPos, new Double[]{o2Code.getX(), o2Code.getY()});
|
|
return o1Distance - o2Distance;
|
}
|
});
|
|
}
|
|
return funcStaList.stream().findFirst().orElse(null);
|
}
|
|
}
|