package com.zy.acs.manager.manager.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.zy.acs.framework.common.Cools; import com.zy.acs.framework.exception.CoolException; import com.zy.acs.manager.common.exception.BusinessException; import com.zy.acs.manager.core.service.MapService; import com.zy.acs.manager.manager.controller.result.MissionVo; import com.zy.acs.manager.manager.entity.*; import com.zy.acs.manager.manager.enums.*; import com.zy.acs.manager.manager.service.*; import org.apache.ibatis.session.SqlSession; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.*; import java.util.stream.Collectors; /** * Created by vincent on 9/27/2024 */ @Service("missionService") public class MissionServiceImpl implements MissionService { @Autowired private SegmentService segmentService; @Autowired private ActionService actionService; @Autowired private CodeService codeService; @Autowired private AgvDetailService agvDetailService; @Autowired private TaskService taskService; @Autowired private BusService busService; @Autowired private SqlSession sqlSession; @Override public List getList(Long agvId, String groupNo) { List result = new ArrayList<>(); List runningGroupNos = segmentService.getGroupNo(SegmentStateType.RUNNING, agvId, groupNo); for (String runningGroupNo : runningGroupNos) { MissionVo vo = generateVo(runningGroupNo); if (null != vo) { result.add(vo); } } return result; } @Override public MissionVo generateVo(String groupNo) { if (Cools.isEmpty(groupNo)) { return null; } // segment ------------------------------- List list = segmentService.list(new LambdaQueryWrapper().eq(Segment::getGroupId, groupNo).orderByAsc(Segment::getSerial)); if (Cools.isEmpty(list)) { return null; } Segment segment = list.get(0); // agv ------------------------------- AgvDetail agvDetail = agvDetailService.selectByAgvId(segment.getAgvId()); Long recentCode = agvDetail.getRecentCode(); String currCode = null; if (null != recentCode) { Code cacheById = codeService.getCacheById(recentCode); if (cacheById != null) { currCode = cacheById.getData(); } else { throw new CoolException(segment.getAgvId() + "小车还在删除的点位中"); } } // action ------------------------------- List actionList = actionService.list(new LambdaQueryWrapper() .eq(Action::getGroupId, groupNo).ne(Action::getActionSts, ActionStsType.EXPIRED.val()).orderByDesc(Action::getPriority)); if (Cools.isEmpty(actionList)) { return null; } MissionVo vo = new MissionVo(); vo.setGroupNo(groupNo); vo.setId(segment.getId()); vo.setPosType(segment.getPosType()); vo.setAgv(segment.getAgvId$()); vo.setTaskNos(list.stream().map(Segment::getTaskId$).collect(Collectors.toList())); vo.setBackpack(segment.getBackpack()); vo.setDestCode(segment.getEndNode$()); vo.setCurrCode(currCode); vo.setProgress(calcProgress(currCode, actionList)); return vo; } @Override public MissionVo generateVoMoreInfo(String groupNo) { MissionVo vo = generateVo(groupNo); if (null == vo) { return vo; } List list = segmentService.list(new LambdaQueryWrapper().eq(Segment::getGroupId, groupNo).orderByAsc(Segment::getSerial)); if (Cools.isEmpty(list)) { return null; } List actionList = actionService.list(new LambdaQueryWrapper() .eq(Action::getGroupId, groupNo).ne(Action::getActionSts, ActionStsType.EXPIRED.val()).orderByDesc(Action::getPriority)); if (Cools.isEmpty(actionList)) { return null; } Segment segment = list.get(0); Action action = actionList.get(0); Task task = taskService.getById(segment.getTaskId()); // vo.setSendTime(action.getStartTime()); vo.setBusNo(task.getBusId$()); vo.setActionCount(actionList.size()); vo.setTaskIds(list.stream().map(Segment::getTaskId).collect(Collectors.toList())); vo.setCodeList(actionList.stream().map(Action::getCode).distinct().collect(Collectors.toList())); vo.setActionIds(actionList.stream().map(Action::getId).collect(Collectors.toList())); return vo; } @Override @Transactional public Boolean resend(List actionList) { if (Cools.isEmpty(actionList)) { return Boolean.FALSE; } Date now = new Date(); List actionIds = actionList.stream().map(Action::getId).collect(Collectors.toList()); Action firstAction = actionService.getById(actionIds.get(0)); if (firstAction == null) { return Boolean.FALSE; } String actionGroupId = firstAction.getGroupId(); actionService.updateStsByGroupId(actionGroupId, ActionStsType.EXPIRED.val()); // if firstAction is not turn, insert a new turn action Action prependTurn = null; if (!firstAction.getActionType().equals(ActionTypeType.TurnCorner.val())) { String codeData = firstAction.getCode(); Code code = codeService.getCacheByData(codeData); AgvDetail agvDetail = agvDetailService.selectMajorByAgvId(firstAction.getAgvId()); Double lastDirection = MapService.mapToNearest(agvDetail.getAgvAngle()); List fullActionList = actionService.list(new LambdaQueryWrapper() .eq(Action::getGroupId, actionGroupId) .select(Action::getId, Action::getActionType, Action::getPriority) .orderByDesc(Action::getPriority) ); int idx = -1; for (int k = 0; k < fullActionList.size(); k++) { if (fullActionList.get(k).getId().equals(firstAction.getId())) { idx = k; break; } } if (idx > 0) { Long turnActionId = null; // find out turn action for (int k = idx - 1; k >= 0; k--) { Action a = fullActionList.get(k); if (a.getActionType().equals(ActionTypeType.TurnCorner.val())) { turnActionId = a.getId(); break; } } if (null != turnActionId) { Action turn = actionService.getById(turnActionId); Double direction = Double.parseDouble(turn.getParams()); // new turn action prependTurn = new Action( null, // 编号 firstAction.getBusId(), // 总线 firstAction.getTaskId(), // 任务 null, // 动作号 null, // 优先级 ActionTypeType.TurnCorner.desc, // 名称 (double) MapService.calcSpinDirection(code, lastDirection, direction).val, // 属性值 code.getData(), // 地面码 String.valueOf(direction), // 动作参数 ActionTypeType.TurnCorner.val(), // 动作类型 ActionStsType.PREPARE.val(), // 动作进度 firstAction.getAgvId(), // AGV now // 工作时间 ); } } } List newActionList = new ArrayList<>(); if (prependTurn != null) { prependTurn.setGroupId(actionGroupId); prependTurn.setCreateTime(now); prependTurn.setUpdateTime(now); newActionList.add(prependTurn); } for (Long actionId : actionIds) { sqlSession.clearCache(); Action action = actionService.getById(actionId); action.setActionSts(ActionStsType.PREPARE.val()); action.setIoTime(now); action.setUpdateTime(now); newActionList.add(action); } int i = newActionList.size(); for (Action action : newActionList) { action.setId(null); action.setPriority(i); if (!actionService.save(action)) { throw new BusinessException(action.getName() + " Action Save Fail!"); } i -= 1; } Set busIds = new HashSet<>(); List taskIds = actionService.selectTaskIdsByGroupId(actionGroupId); for (Long taskId : taskIds) { Task task = taskService.getById(taskId); if (null != task) { task.setTaskSts(TaskStsType.ASSIGN.val()); task.setUpdateTime(now); task.setIoTime(now); if (!taskService.updateById(task)) { throw new BusinessException(task.getUuid() + " Task Update Fail!"); } busIds.add(task.getBusId()); } } for (Long busId : busIds) { Bus bus = busService.getById(busId); if (null != bus) { bus.setBusSts(BusStsType.PROGRESS.val()); bus.setUpdateTime(now); if (!busService.updateById(bus)) { throw new BusinessException(bus.getUuid() + " Bus Update Fail!"); } } } return Boolean.TRUE; } public Double calcProgress(String currCode, List actionList) { double progress = 0D; if (Cools.isEmpty(actionList, currCode)) { return progress; } List codeList = actionList.stream().map(Action::getCode).distinct().collect(Collectors.toList()); int totalCodes = codeList.size(); int currentIndex = codeList.indexOf(currCode); if (currentIndex >= 0) { progress = (currentIndex + 1) * 100.0 / totalCodes; } return progress; } }