AcsServiceImpl.java 18.1 KB
package com.huaheng.api.acs.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.huaheng.api.acs.domain.AgvDomain;
import com.huaheng.common.constant.HttpConstant;
import com.huaheng.common.constant.QuantityConstant;
import com.huaheng.common.exception.service.ServiceException;
import com.huaheng.common.utils.StringUtils;
import com.huaheng.common.utils.http.OkHttpUtils;
import com.huaheng.common.utils.restful.RestUtil;
import com.huaheng.framework.aspectj.lang.annotation.ApiLogger;
import com.huaheng.framework.web.domain.AjaxResult;
import com.huaheng.pc.config.address.service.AddressService;
import com.huaheng.pc.config.location.domain.Location;
import com.huaheng.pc.config.location.service.LocationService;
import com.huaheng.pc.task.agvTask.domain.AgvTask;
import com.huaheng.pc.task.agvTask.service.AgvTaskService;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName AcsServiceImpl
 * @Description TODO
 * @Author youjie
 * @Date 2019/12/2615:38
 */
@Service
public class AcsServiceImpl implements AcsService {

    @Resource
    private AgvTaskService agvTaskService;
    @Resource
    private AddressService addressService;
    @Resource
    private LocationService locationService;


    @Override
    public AjaxResult createAGVTask(AgvTask agvTask) {
        return null;
    }

    @Override
    @ApiLogger(apiName = "执行AGV任务", from="acs")
    public AjaxResult executeAGVTask(AgvTask agvTask) {
        String toLocationCode = agvTask.getToPort();
        String fromLocationCode = agvTask.getFromPort();
        if(StringUtils.isEmpty(fromLocationCode)) {
           return AjaxResult.error("创建AGV任务失败,起点为空");
        }

        if(StringUtils.isEmpty(toLocationCode)) {
            return AjaxResult.error("创建AGV任务失败,终点为空");
        }

        AgvDomain agvDomain = new AgvDomain();
        Location fromLocation = locationService.getLocationByCode(
                fromLocationCode, QuantityConstant.DEFAULT_WAREHOUSE);
        int preTaskNo = 0;
        if(fromLocation != null) {
            String zoneCode  = fromLocation.getZoneCode();
            if(zoneCode.equals(QuantityConstant.ZONE_RECEIPT_MANY_CONTAINER) ||
                zoneCode.equals(QuantityConstant.ZONE_RECEIPT_CACHE)) {
                AjaxResult ajaxResult = fromReceiptZone(fromLocation);  //起点是入库缓存区、空托盘组区
                if (ajaxResult.hasErr()) {
                    return ajaxResult;
                }
                preTaskNo = (int) ajaxResult.getData();
            }
        }
        Location toLocation = locationService.getLocationByCode(
                toLocationCode, QuantityConstant.DEFAULT_WAREHOUSE);
        if(toLocation != null) {
            String zoneCode  = toLocation.getZoneCode();
            if(zoneCode.equals(QuantityConstant.ZONE_RECEIPT_MANY_CONTAINER) ||
                    zoneCode.equals(QuantityConstant.ZONE_RECEIPT_CACHE)) {
                AjaxResult ajaxResult = toReceiptZone(toLocation); //终点是入库缓存区、空托盘组区
                if (ajaxResult.hasErr()) {
                    return ajaxResult;
                }
                preTaskNo = (int) ajaxResult.getData();
            } else if(zoneCode.equals(QuantityConstant.ZONE_STOCK_UP)) {
                AjaxResult ajaxResult = toStockUpZone(toLocation); //终点是备货区、空托盘组区
                if (ajaxResult.hasErr()) {
                    return ajaxResult;
                }
                preTaskNo = (int) ajaxResult.getData();
            }
        }

        if(preTaskNo != 0) {
            agvDomain.setPreTaskNo(preTaskNo);
        }
        agvDomain.setTaskNo(String.valueOf(agvTask.getId()));
        agvDomain.setTaskType(agvTask.getTaskType());
        agvDomain.setFromPort(agvTask.getFromPort());
        agvDomain.setToPort(agvTask.getToPort());
        agvDomain.setPriority(agvTask.getPriority());
        agvDomain.setCreatedBy(agvTask.getCreatedBy());
        agvDomain.setQty(agvTask.getQty());
//        agvDomain.setCreatedTime(agvTask.getCreated());
        agvDomain.setContainerCode(agvTask.getContainerCode());
        String warehouseCode = agvTask.getWarehouseCode();
        String url = addressService.selectAddress(QuantityConstant.ADDRESS_AGV_TASK_ASSIGN,
                warehouseCode, null);
        String jsonParam = JSON.toJSONString(agvDomain);
        String result = OkHttpUtils.bodypost(url, jsonParam);
        if(StringUtils.isEmpty(result)) {
            throw new ServiceException("接口地址错误或返回为空");
        }
        AjaxResult ajaxResult = JSON.parseObject(result, AjaxResult.class);
        if(ajaxResult.getCode() != HttpConstant.OK) {
            return AjaxResult.error(ajaxResult.getMsg());
        }
        return AjaxResult.success("创建AGV任务成功");
    }

    private AjaxResult toStockUpZone(Location toLocation) {
        int layer = toLocation.getILayer();    //层
        int column = toLocation.getIColumn();  //列
        int row = toLocation.getIRow();        //行
        String zoneCode = toLocation.getZoneCode();  //库区
        int preTaskNo = 0;
        if(layer == 2) {
            // 搬到入库缓存区搬走货,需要先搬下层托盘
            Location location = getLocation(zoneCode, row, column, 1);
            if (location != null) {
                String locationCode = location.getCode();
                AgvTask agvTask1 = getAgvTask(locationCode, null);
                if (agvTask1 != null) {
                    preTaskNo = agvTask1.getId();
                }
            }
        }
        // 搬到入库缓存区搬走货,需要先搬内侧托盘
        Location location = getLocation(zoneCode, row, column-1, true);
        if(location != null) {
            String locationCode = location.getCode();
            AgvTask agvTask1 = getAgvTask(locationCode, null);
            if (agvTask1 != null) {
                preTaskNo = agvTask1.getId();
            }
        }
        LambdaQueryWrapper<Location> locationLambdaQueryWrapper = Wrappers.lambdaQuery();
        locationLambdaQueryWrapper.eq(Location::getZoneCode, zoneCode)
                .eq(Location::getIRow, row)
                .ne(Location::getContainerCode, "")
                .le(Location::getIColumn, column + 2);
        List<Location> locationList = locationService.list(locationLambdaQueryWrapper);
        if(locationList.size() > 0) {
            return AjaxResult.error("创建AGV任务失败,前方有库位挡住");
        }
        locationLambdaQueryWrapper = Wrappers.lambdaQuery();
        locationLambdaQueryWrapper.eq(Location::getZoneCode, zoneCode)
                .eq(Location::getIRow, row)
                .eq(Location::getStatus, QuantityConstant.STATUS_LOCATION_EMPTY)
                .ne(Location::getContainerCode, "")
                .le(Location::getIColumn, column + 1);
        locationList = locationService.list(locationLambdaQueryWrapper);
        if(locationList.size() > 0) {
            return AjaxResult.error("创建AGV任务失败,前方有库位挡住");
        }
        if(layer == 2) {
            locationLambdaQueryWrapper = Wrappers.lambdaQuery();
            locationLambdaQueryWrapper.eq(Location::getZoneCode, zoneCode)
                    .eq(Location::getIRow, row)
                    .eq(Location::getILayer, 1)
                    .eq(Location::getIColumn, column)
                    .eq(Location::getStatus, QuantityConstant.STATUS_LOCATION_EMPTY)
                    .eq(Location::getContainerCode, "");
            locationList = locationService.list(locationLambdaQueryWrapper);
            if (locationList.size() > 0) {
                return AjaxResult.error("创建AGV任务失败,库位下方没有货");
            }
        }
        return AjaxResult.success("创建AGV任务成功").setData(preTaskNo);
    }

    private AjaxResult toReceiptZone(Location toLocation) {
        int layer = toLocation.getILayer();    //层
        int column = toLocation.getIColumn();  //列
        int row = toLocation.getIRow();        //行
        String zoneCode = toLocation.getZoneCode();  //库区
        int preTaskNo = 0;
        if(layer == 2) {
            // 搬到入库缓存区搬走货,需要先搬下层托盘
            Location location = getLocation(zoneCode, row, column, 1);
            if (location != null) {
                String locationCode = location.getCode();
                AgvTask agvTask1 = getAgvTask(locationCode, null);
                if (agvTask1 != null) {
                    preTaskNo = agvTask1.getId();
                }
            }
        }

        // 搬到入库缓存区搬走货,需要先搬内侧托盘
        Location location = getLocation(zoneCode, row, column+1, true);
        if(location != null) {
            String locationCode = location.getCode();
            AgvTask agvTask1 = getAgvTask(locationCode, null);
            if (agvTask1 != null) {
                preTaskNo = agvTask1.getId();
            }
        }

        LambdaQueryWrapper<Location> locationLambdaQueryWrapper = Wrappers.lambdaQuery();
        locationLambdaQueryWrapper.eq(Location::getZoneCode, zoneCode)
                .eq(Location::getIRow, row)
                .ne(Location::getContainerCode, "")
                .le(Location::getIColumn, column - 2);
        List<Location> locationList = locationService.list(locationLambdaQueryWrapper);
        if(locationList.size() > 0) {
            return AjaxResult.error("创建AGV任务失败,前方有库位挡住");
        }
        locationLambdaQueryWrapper = Wrappers.lambdaQuery();
        locationLambdaQueryWrapper.eq(Location::getZoneCode, zoneCode)
                .eq(Location::getIRow, row)
                .eq(Location::getStatus, QuantityConstant.STATUS_LOCATION_EMPTY)
                .ne(Location::getContainerCode, "")
                .le(Location::getIColumn, column - 1);
        locationList = locationService.list(locationLambdaQueryWrapper);
        if(locationList.size() > 0) {
            return AjaxResult.error("创建AGV任务失败,前方有库位挡住");
        }
        if(layer == 2) {
            locationLambdaQueryWrapper = Wrappers.lambdaQuery();
            locationLambdaQueryWrapper.eq(Location::getZoneCode, zoneCode)
                    .eq(Location::getIRow, row)
                    .eq(Location::getILayer, 1)
                    .eq(Location::getIColumn, column)
                    .eq(Location::getStatus, QuantityConstant.STATUS_LOCATION_EMPTY)
                    .eq(Location::getContainerCode, "");
            locationList = locationService.list(locationLambdaQueryWrapper);
            if (locationList.size() > 0) {
                return AjaxResult.error("创建AGV任务失败,库位下方没有货");
            }
        }
        return AjaxResult.success("创建AGV任务成功").setData(preTaskNo);
    }

    private AjaxResult fromReceiptZone(Location fromLocation) {
        int layer = fromLocation.getILayer();    //层
        int column = fromLocation.getIColumn();  //列
        int row = fromLocation.getIRow();        //行
        String zoneCode = fromLocation.getZoneCode();  //库区
        int preTaskNo = 0;
        if(layer == 1) {
            // 从入库缓存区搬走货,需要先搬走上层托盘
            Location location = getLocation(zoneCode, row, column, 2);
            if(location != null) {
                String locationCode = location.getCode();
                AgvTask agvTask1 = getAgvTask(locationCode, null);
                if (agvTask1 != null) {
                    preTaskNo = agvTask1.getId();
                }
            }
        }
        // 从入库缓存区搬走货,需要先搬走前方托盘
        Location location = getLocation(zoneCode, row, column-1, false);
        if(location != null) {
            String locationCode = location.getCode();
            AgvTask agvTask1 = getAgvTask(locationCode, null);
            if (agvTask1 != null) {
                preTaskNo = agvTask1.getId();
            }
        }
        LambdaQueryWrapper<Location> locationLambdaQueryWrapper = Wrappers.lambdaQuery();
        locationLambdaQueryWrapper.eq(Location::getZoneCode, zoneCode)
                .eq(Location::getIRow, row)
                .ne(Location::getContainerCode, "")
                .le(Location::getIColumn, column - 2);
        List<Location> locationList = locationService.list(locationLambdaQueryWrapper);
        if(locationList.size() > 0) {
            return AjaxResult.error("创建AGV任务失败,前方有库位挡住");
        }
        locationLambdaQueryWrapper = Wrappers.lambdaQuery();
        locationLambdaQueryWrapper.eq(Location::getZoneCode, zoneCode)
                .eq(Location::getIRow, row)
                .eq(Location::getStatus, QuantityConstant.STATUS_LOCATION_EMPTY)
                .ne(Location::getContainerCode, "")
                .le(Location::getIColumn, column - 1);
        locationList = locationService.list(locationLambdaQueryWrapper);
        if(locationList.size() > 0) {
            return AjaxResult.error("创建AGV任务失败,前方有库位挡住");
        }
        if(layer == 1) {
            locationLambdaQueryWrapper = Wrappers.lambdaQuery();
            locationLambdaQueryWrapper.eq(Location::getZoneCode, zoneCode)
                    .eq(Location::getIRow, row)
                    .eq(Location::getILayer, 2)
                    .eq(Location::getIColumn, column)
                    .eq(Location::getStatus, QuantityConstant.STATUS_LOCATION_EMPTY)
                    .ne(Location::getContainerCode, "");
            locationList = locationService.list(locationLambdaQueryWrapper);
            if (locationList.size() > 0) {
                return AjaxResult.error("创建AGV任务失败,库位上方有货挡住");
            }
        }
        return AjaxResult.success("创建AGV任务成功").setData(preTaskNo);
    }

    private AgvTask getAgvTask(String fromLocationCode, String toLocationCode) {
        LambdaQueryWrapper<AgvTask> agvTaskLambdaQueryWrapper = Wrappers.lambdaQuery();
        agvTaskLambdaQueryWrapper.eq(StringUtils.isEmpty(fromLocationCode), AgvTask::getFromPort, fromLocationCode)
                                .eq(StringUtils.isEmpty(toLocationCode), AgvTask::getToPort, toLocationCode)
                                .lt(AgvTask::getStatus, QuantityConstant.TASK_STATUS_COMPLETED);
        AgvTask agvTask = agvTaskService.getOne(agvTaskLambdaQueryWrapper);
        return agvTask;
    }

    private Location getLocation(String zoneCode, int row, int column, boolean asc) {
        LambdaQueryWrapper<Location> locationLambdaQueryWrapper = Wrappers.lambdaQuery();
        locationLambdaQueryWrapper.eq(Location::getIRow, row)
                .eq(Location::getZoneCode, zoneCode)
                .eq(Location::getIColumn, column);
        if(asc) {
            locationLambdaQueryWrapper.orderByAsc(Location::getILayer);
        } else {
            locationLambdaQueryWrapper.orderByDesc(Location::getILayer);
        }
        locationLambdaQueryWrapper.last(" limit 1");
        Location location = locationService.getOne(locationLambdaQueryWrapper);
        return location;
    }

    private Location getLocation(String zoneCode, int row, int column, int layer) {
        LambdaQueryWrapper<Location> locationLambdaQueryWrapper = Wrappers.lambdaQuery();
        locationLambdaQueryWrapper.eq(Location::getIRow, row)
                                .eq(Location::getZoneCode, zoneCode)
                                .eq(Location::getIColumn, column)
                                .eq(Location::getILayer, layer);
        Location location = locationService.getOne(locationLambdaQueryWrapper);
        return location;
    }

    @Override
    public AjaxResult cancelAGVTask(AgvTask agvTask) {
        List<String> ids = new ArrayList<String>();
        ids.add(String.valueOf(agvTask.getId()));
        AgvDomain agvDomain = new AgvDomain();
        agvDomain.setTaskNo(String.valueOf(agvTask.getId()));
        String url = addressService.selectAddress(QuantityConstant.ADDRESS_AGV_TASK_CANCEL);
        String jsonParam = JSON.toJSONString(agvDomain);
        String result = OkHttpUtils.bodypost(url, jsonParam);
        if(StringUtils.isEmpty(result)) {
            throw new ServiceException("接口地址错误或返回为空");
        }
        AjaxResult ajaxResult = JSON.parseObject(result, AjaxResult.class);
        if(ajaxResult.getCode() != HttpConstant.OK) {
            return AjaxResult.error(ajaxResult.getMsg());
        }
        return AjaxResult.success("取消AGV任务成功");
    }

    @Override
    public AjaxResult updateAGVTask(AgvTask agvTask) {
        AgvDomain agvDomain = new AgvDomain();
        agvDomain.setTaskNo(String.valueOf(agvTask.getId()));
        agvDomain.setPriority(agvTask.getPriority());
        String url = addressService.selectAddress(QuantityConstant.ADDRESS_AGV_TASK_UPDATE);
        String jsonParam = JSON.toJSONString(agvDomain);
        String result = OkHttpUtils.bodypost(url, jsonParam);
        if(StringUtils.isEmpty(result)) {
            throw new ServiceException("接口地址错误或返回为空");
        }
        AjaxResult ajaxResult = JSON.parseObject(result, AjaxResult.class);
        if(ajaxResult.getCode() != HttpConstant.OK) {
            return AjaxResult.error(ajaxResult.getMsg());
        }
        return AjaxResult.success("更新AGV任务成功");
    }

    @Override
    public AjaxResult notifyAGVTask(String taskNo, String carNo, int status, String updateBy) {
        AgvTask agvTask = agvTaskService.getById(taskNo);
        if(agvTask == null) {
            return AjaxResult.error("没有找到对应AGV任务,任务号为" + taskNo);
        }
        agvTask.setStatus(status);
        agvTask.setCarNo(carNo);
        agvTask.setLastUpdatedBy(updateBy);
        boolean result = agvTaskService.updateById(agvTask);
        if(!result) {
            return AjaxResult.error("更新任务信息失败 ");
        }
        return AjaxResult.success("更新任务信息成功");
    }
}