package com.zy.acs.manager.manager.controller; import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.zy.acs.common.utils.GsonUtils; import com.zy.acs.framework.common.Cools; import com.zy.acs.framework.common.R; import com.zy.acs.framework.common.SnowflakeIdWorker; import com.zy.acs.framework.exception.CoolException; import com.zy.acs.manager.common.constant.MapItemType; import com.zy.acs.manager.common.domain.MapAgvDto; import com.zy.acs.manager.common.domain.MapCodeDto; import com.zy.acs.manager.common.domain.MapDto; import com.zy.acs.manager.common.domain.MapRouteDto; import com.zy.acs.manager.common.exception.BusinessException; import com.zy.acs.manager.core.domain.BackpackDto; import com.zy.acs.manager.core.service.MapService; import com.zy.acs.manager.core.service.floyd.FloydNavigateService; import com.zy.acs.manager.manager.controller.param.MapDataParam; import com.zy.acs.manager.manager.controller.param.MapParam; import com.zy.acs.manager.manager.controller.result.MapAgvVo; import com.zy.acs.manager.manager.controller.result.MapPointVo; import com.zy.acs.manager.manager.controller.result.MapRouteVo; import com.zy.acs.manager.manager.entity.NavMap; import com.zy.acs.manager.manager.entity.*; import com.zy.acs.manager.manager.enums.AgvStsType; import com.zy.acs.manager.manager.enums.TaskStsType; import com.zy.acs.manager.manager.mapper.NavMapMapper; import com.zy.acs.manager.manager.service.*; import com.zy.acs.manager.system.controller.BaseController; import com.zy.acs.manager.system.service.ConfigService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; import java.util.*; import java.util.stream.Collectors; /** * Created by vincent on 2023/6/1 */ @RestController @RequestMapping("/api/map") public class MapController extends BaseController { @Autowired private CodeService codeService; @Autowired private RouteService routeService; @Autowired private CodeGapService codeGapService; @Autowired private AgvService agvService; @Autowired private AgvDetailService agvDetailService; @Autowired private FloydNavigateService floydNavigateService; @Autowired private MapService mapService; @Autowired private TaskService taskService; @Autowired private NavMapMapper navMapMapper; @Autowired private SnowflakeIdWorker snowflakeIdWorker; @Autowired private LocService locService; @Autowired private ConfigService configService; @PreAuthorize("hasAuthority('manager:loc:update')") @PostMapping("/startupOrShutdown") public synchronized R startupOrShutdown() { Boolean taskAssignMode = configService.getVal("TaskAssignMode", Boolean.class); return configService.setVal("TaskAssignMode", !taskAssignMode) ? R.ok() : R.error(); } @PreAuthorize("hasAuthority('manager:loc:list')") @PostMapping("/data/fetch") public R fetch(@RequestParam(required = false) Long zoneId, @RequestParam(required = false) Integer floor) { // code List codeList = codeService.list(new LambdaQueryWrapper().eq(Code::getStatus, 1)); List mapCodeItems = new ArrayList<>(); codeList.forEach(code -> { MapItem mapItem = new MapItem(); mapItem.setType(MapItemType.POINT.toString()); mapItem.setNo(code.getData()); mapItem.setUuid(code.getUuid()); mapItem.setPositionX(code.getX()); mapItem.setPositionY(code.getY()); mapCodeItems.add(mapItem); }); // common NavMap activeNavMap = navMapMapper.selectActive(zoneId, floor); return R.ok().add(Cools .add("rcsStatus", configService.getVal("TaskAssignMode", Boolean.class)) .add("point", GsonUtils.toJson(mapCodeItems)) .add("common", activeNavMap.getData()) ); } @PreAuthorize("hasAuthority('manager:loc:update')") @PostMapping("/data/save") @Transactional public R save(@RequestBody MapDataParam param) { Date now = new Date(); Long userId = getLoginUserId(); // previous NavMap previousNavMap = navMapMapper.selectActive(param.getZoneId(), param.getFloor()); if (null != previousNavMap) { previousNavMap.setActive(0); previousNavMap.setUpdateTime(now); previousNavMap.setUpdateBy(userId); if (0 == navMapMapper.updateById(previousNavMap)) { throw new CoolException("Save Fail"); } } // current NavMap navMap = new NavMap(); navMap.setUuid(String.valueOf(snowflakeIdWorker.nextId()).substring(3)); navMap.setZoneId(param.getZoneId()); navMap.setFloor(param.getFloor()); navMap.setData(GsonUtils.toJson(param.getItemList())); navMap.setActive(1); navMap.setUpdateBy(userId); navMap.setCreateBy(userId); if (0 == navMapMapper.insert(navMap)) { throw new CoolException("Save Fail"); } return R.ok("Save Success"); } @PostMapping("/shelf/group") public R shelfGroup(@RequestParam(required = false) Integer row, @RequestParam(required = false) Integer bay) { if (null == row || null == bay) { return R.error(); } List locList = locService.list(new LambdaQueryWrapper().eq(Loc::getRow, row).eq(Loc::getBay, bay).orderByAsc(Loc::getLev)); return R.ok().add(locList); } @PostMapping("/agv/info") public R agvInfo(@RequestParam(required = false) String agvNo) { if (Cools.isEmpty(agvNo)) { return R.error(); } Agv agv = agvService.selectByUuid(agvNo); AgvDetail agvDetail = agvDetailService.selectByAgvNo(agvNo); MapAgvVo vo = new MapAgvVo(); vo.setAgvId(agv.getId()); vo.setAgvNo(agv.getUuid()); vo.setStatus(agv.getStatus()); if (null != agvDetail) { vo.setOnline(agvService.judgeOnline(agvDetail.getAgvId())); vo.setAgvStatus(agvDetail.getStatusDesc()); vo.setVol(String.valueOf(agvDetail.getVol())); vo.setSoc(String.valueOf(agvDetail.getSoc())); vo.setPos(agvDetail.getPos() != null && agvDetail.getPos() == 1); vo.setCode(codeService.getById(agvDetail.getRecentCode()).getData()); vo.setDirection(agvDetail.getAgvAngle()); vo.setBackpack(GsonUtils.fromJsonToList(agvDetail.getBackpack(), BackpackDto.class)); } List tasks = taskService.selectInSts(agv.getId(), TaskStsType.WAITING, TaskStsType.ASSIGN, TaskStsType.PROGRESS); if (!Cools.isEmpty(tasks)) { vo.setTaskIds(tasks.stream().map(Task::getId).collect(Collectors.toList())); } return R.ok().add(vo); } @PostMapping("/point/info") public R pointInfo(@RequestParam(required = false) String codeData) { if (Cools.isEmpty(codeData)) { return R.error(); } Code code = codeService.selectByData(codeData); MapPointVo vo = new MapPointVo(); vo.setCodeId(code.getId()); vo.setCodeData(code.getData()); vo.setStatus(code.getStatus()); return R.ok().add(vo); } @PostMapping("/route/list") public R routeList(@RequestParam(required = false) Long zoneId) { List result = new ArrayList<>(); List routeList = routeService.list(new LambdaQueryWrapper().eq(Route::getStatus, 1)); for (Route route : routeList) { MapRouteVo vo = new MapRouteVo(); vo.setRouteId(route.getId()); vo.setStartCode(route.getStartCode()); vo.setStartCodeStr(route.getStartCode$()); vo.setEndCode(route.getEndCode()); vo.setEndCodeStr(route.getEndCode$()); vo.setDirection(route.getDirection()); result.add(vo); } return R.ok().add(result); } @PreAuthorize("hasAuthority('map:save')") @PostMapping("/save") @Transactional public R save(@RequestBody MapParam param) { Date now = new Date(); // code ----------------------------------------------------------------- List codes = codeService.list(); List codeArr = param.getCodeArr(); for (Code code : codeArr) { Code one = codeService.selectByData(code.getData()); if (one == null) { if (!codeService.save(code)) { throw new BusinessException(code.getData()+" save fail![Code]"); } } else { one.setUpdateTime(now); if (!codeService.updateById(one)) { throw new BusinessException(code.getData()+" update fail![Code]"); } } codes.removeIf(next -> code.getData().equals(next.getData())); } for (Code code : codes) { if (!codeService.removeById(code.getId())) { throw new BusinessException(code.getData()+" remove fail![Code]"); } } // code ----------------------------------------------------------------- // gap ----------------------------------------------------------------- List routes = routeService.list(); List codeGaps = codeGapService.list(); List routeArr = param.getRouteArr(); for (MapParam.Route paramRoute : routeArr) { Code startCode = codeService.selectByData(paramRoute.getStartCode()); Code endCode = codeService.selectByData(paramRoute.getEndCode()); Route route = routeService.findByCodeOfBoth(startCode.getId(), endCode.getId()); if (route == null) { route = new Route(); route.setUuid(startCode.getData()+"-"+endCode.getData()); route.setStartCode(startCode.getId()); route.setEndCode(endCode.getId()); route.setDirection(paramRoute.getType()); route.setCodeArr(JSON.toJSONString(Arrays.asList(startCode.getId(), endCode.getId()))); if (!routeService.save(route)) { throw new BusinessException(route.getUuid()+" save fail![Route]"); } } else { route.setUpdateTime(now); if (!routeService.updateById(route)) { throw new BusinessException(route.getUuid()+" update fail![Route]"); } } Iterator iterator = routes.iterator(); while (iterator.hasNext()) { Route next = iterator.next(); if ((next.getStartCode().equals(route.getStartCode()) && next.getEndCode().equals(route.getEndCode())) || (next.getStartCode().equals(route.getEndCode()) && next.getEndCode().equals(route.getStartCode()))) { iterator.remove(); break; } } CodeGap codeGap = codeGapService.findByCodeOfBoth(startCode.getId(), endCode.getId()); double distance = mapService.calculateDistance(startCode.getX(), startCode.getY(), endCode.getX(), endCode.getY()); if (null == codeGap) { codeGap = new CodeGap(); codeGap.setCode0(startCode.getId()); codeGap.setCode1(endCode.getId()); codeGap.setDistance(distance); if (!codeGapService.save(codeGap)) { throw new BusinessException(route.getUuid()+" save fail![CodeGap]"); } } else { codeGap.setDistance(distance); if (!codeGapService.updateById(codeGap)) { throw new BusinessException(route.getUuid()+" update fail![CodeGap]"); } } Iterator gapIterator = codeGaps.iterator(); while (gapIterator.hasNext()) { CodeGap next = gapIterator.next(); if ((next.getCode0().equals(route.getStartCode()) && next.getCode1().equals(route.getEndCode())) || (next.getCode0().equals(route.getEndCode()) && next.getCode1().equals(route.getStartCode()))) { gapIterator.remove(); break; } } } for (Route route : routes) { if (!routeService.removeById(route.getId())) { throw new BusinessException(route.getUuid()+" remove fail![Route]"); } } for (CodeGap codeGap : codeGaps) { if (!codeGapService.removeById(codeGap.getId())) { throw new BusinessException(codeGap.getId()+" remove fail![CodeGap]"); } } // agv ----------------------------------------------------------------- List agvList = agvService.list(); List agvArr = param.getAgvArr(); for (MapParam.Agv agvParam : agvArr) { if (Cools.isEmpty(agvParam.getPos())) { throw new BusinessException(agvParam.getAgvNo() + " agv not in position!"); } Code code = codeService.selectByData(agvParam.getPos()); Agv agv = agvService.selectByUuid(agvParam.getAgvNo()); if (agv == null) { agv = new Agv(); agv.setAgvSts(AgvStsType.IDLE.val()); agv.setUuid(agvParam.getAgvNo()); agv.setStage(agvParam.getStage()); agv.setMemo(agvParam.getMemo()); if (!agvService.save(agv)) { throw new BusinessException(agv.getUuid()+" save fail![Agv]"); } agvDetailService.removeByAgvId(agv.getId()); AgvDetail agvDetail = new AgvDetail(); agvDetail.setAgvId(agv.getId()); agvDetail.setPos(1); agvDetail.setCode(code.getId()); if (!agvDetailService.save(agvDetail)) { throw new BusinessException(agv.getUuid()+" save fail![AgvDetail]"); } } else { agv.setStage(agvParam.getStage()); agv.setMemo(agvParam.getMemo()); agv.setUpdateTime(now); if (!agvService.updateById(agv)) { throw new BusinessException(agv.getUuid()+" update fail![Agv]"); } AgvDetail agvDetail = agvDetailService.selectByAgvId(agv.getId()); if (null == agvDetail) { agvDetail = new AgvDetail(); agvDetail.setAgvId(agv.getId()); agvDetail.setPos(1); agvDetail.setCode(code.getId()); if (!agvDetailService.save(agvDetail)) { throw new BusinessException(agv.getUuid()+" save fail![AgvDetail]"); } } else { agvDetail.setPos(1); agvDetail.setCode(code.getId()); agvDetail.setUpdateTime(now); if (!agvDetailService.updateById(agvDetail)) { throw new BusinessException(agv.getUuid()+" update fail![AgvDetail]"); } } } agvList.removeIf(next -> agvParam.getAgvNo().equals(next.getUuid())); } for (Agv agv : agvList) { if (!agvService.removeById(agv.getId())) { throw new BusinessException(agv.getUuid()+" remove fail![Agv]"); } } floydNavigateService.generateMatrix(); return R.ok("保存成功"); } @PreAuthorize("hasAuthority('map:load')") @GetMapping("/load") public R load() { MapDto mapDto = new MapDto(); List codeList = codeService.list(new LambdaQueryWrapper().eq(Code::getStatus, 1)); for (Code code : codeList) { MapCodeDto codeDto = new MapCodeDto(); codeDto.setData(code.getData()); codeDto.setScale(JSON.parseObject(code.getScale())); codeDto.setX(code.getX()); codeDto.setY(code.getY()); codeDto.setMemo(code.getMemo()); mapDto.getCodeList().add(codeDto); } List routeList = routeService.list(new LambdaQueryWrapper().eq(Route::getStatus, 1)); for (Route route : routeList) { MapRouteDto routeDto = new MapRouteDto(); routeDto.setUuid(route.getUuid()); routeDto.setStartCode(route.getStartCode$()); routeDto.setEndCode(route.getEndCode$()); routeDto.setDirection(route.getDirection()); mapDto.getRouteList().add(routeDto); } List agvList = agvService.list(new LambdaQueryWrapper().ne(Agv::getAgvSts, AgvStsType.DISABLED.val()).eq(Agv::getStatus, 1)); for (Agv agv : agvList) { AgvDetail agvDetail = agvDetailService.selectByAgvId(agv.getId()); if (null == agvDetail) { continue; } Code currCode = codeService.getById(agvDetail.getCode()); MapAgvDto agvDto = new MapAgvDto(); agvDto.setUuid(agv.getUuid()); agvDto.setCurrCode(currCode==null?null:currCode.getData()); agvDto.setStage(agv.getStage()); mapDto.getAgvList().add(agvDto); } return R.ok().add(mapDto); } }