自动化立体仓库 - WMS系统
pang.jiabao
2025-11-20 2101fe61627cad7329376f61f7265af824c459b5
agv相关接口流程修改
3个文件已添加
19个文件已修改
718 ■■■■ 已修改文件
src/main/java/com/zy/asrs/controller/MobileController.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/OpenController.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/Task.java 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/TaskLog.java 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/param/CallAgvParam.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/mapper/BasDevpMapper.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/mapper/BasStationMapper.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/mapper/WrkMastMapper.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/MobileService.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/MobileServiceImpl.java 111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/OpenServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/task/AgvScheduler.java 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/task/handler/AgvHandler.java 220 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/constant/ApiInterfaceConstant.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/BasDevpMapper.xml 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/TaskLogMapper.xml 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/TaskMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/WrkMastMapper.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/js/task/task.js 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/js/taskLog/taskLog.js 26 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/taskLog/taskLog.html 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
version/v1.0.0/truncate.sql 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/MobileController.java
@@ -73,6 +73,16 @@
    @Autowired
    private OrderDetlPakoutService orderDetlPakoutService;
    @PostMapping("/agv/start")
    @ManagerAuth(memo = "pda呼叫agv入库")
    public R inLocCallAgv(@RequestBody CallAgvParam param) {
        if (Cools.isEmpty(param, param.getType(), param.getBarcode(), param.getSourceSite())) {
            return R.parse("请检查参数是否完整!");
        }
        return mobileService.inLocCallAgv(param, getUserId());
    }
    @RequestMapping("/pda/WarehouseOut/v1")
    @ManagerAuth(memo = "并板途中拣料-参考念初")
src/main/java/com/zy/asrs/controller/OpenController.java
@@ -64,6 +64,15 @@
        return R.ok();
    }
    //呼叫agv测试接口
    @PostMapping("/api/entity/create/one")
    @AppAuth(memo = "呼叫agv测试接口")
    public synchronized R create(@RequestHeader(required = false) String appkey,
                                               @RequestBody(required = false) MesPakoutParam param,
                                               HttpServletRequest request) {
        return R.ok();
    }
    @PostMapping("/order/matSync/default/v2")
//    @AppAuth(memo = "商品信息同步接口")
    public synchronized R syncMatInfoV2(@RequestHeader(required = false) String appkey,
src/main/java/com/zy/asrs/entity/Task.java
@@ -43,7 +43,7 @@
    @TableField("wrk_no")
    private Integer wrkNo;
    @ApiModelProperty(value = "")
    @ApiModelProperty(value = "agv号")
    @TableField("inv_wh")
    private String invWh;
@@ -78,7 +78,7 @@
    @TableField("crn_no")
    private Integer crnNo;
    @ApiModelProperty(value = "rgv")
    @ApiModelProperty(value = "")
    @TableField("sheet_no")
    private String sheetNo;
@@ -337,6 +337,17 @@
    public Task() {
    }
    public Task(Integer wrkNo,Long wrkSts,Integer ioType,
                String sourceStaNo,String staNo,Long appeUser,String barcode) {
         this.wrkNo = wrkNo;
         this.wrkSts = wrkSts;
         this.ioType = ioType;
         this.sourceStaNo = sourceStaNo;
         this.staNo = staNo;
         this.appeUser = appeUser;
         this.barcode = barcode;
    }
    public String getYmd$() {
        if (Cools.isEmpty(this.ymd)) {
            return "";
src/main/java/com/zy/asrs/entity/TaskLog.java
@@ -55,7 +55,7 @@
     */
    @ApiModelProperty(value = "工作状态")
    @TableField("wrk_sts")
    private Integer wrkSts;
    private Long wrkSts;
    /**
     * 入出库类型
@@ -99,14 +99,14 @@
     */
    @ApiModelProperty(value = "目标站")
    @TableField("sta_no")
    private Integer staNo;
    private String staNo;
    /**
     * 源站
     */
    @ApiModelProperty(value = "源站")
    @TableField("source_sta_no")
    private Integer sourceStaNo;
    private String sourceStaNo;
    /**
     * 源库位
@@ -344,15 +344,15 @@
        this.ymd = ymd;
        this.mk = mk;
        this.whsType = whsType;
        this.wrkSts = wrkSts;
        this.wrkSts = Long.valueOf(wrkSts);
        this.ioType = ioType;
        this.crnNo = crnNo;
        this.sheetNo = sheetNo;
        this.ioPri = ioPri;
        this.wrkDate = wrkDate;
        this.locNo = locNo;
        this.staNo = staNo;
        this.sourceStaNo = sourceStaNo;
        this.staNo = String.valueOf(staNo);
        this.sourceStaNo = String.valueOf(sourceStaNo);
        this.sourceLocNo = sourceLocNo;
        this.locSts = locSts;
        this.picking = picking;
src/main/java/com/zy/asrs/entity/param/CallAgvParam.java
New file
@@ -0,0 +1,28 @@
package com.zy.asrs.entity.param;
import lombok.Data;
/**
 * @author pang.jiabao
 * @description pda呼叫AGV搬运入库参数
 * @createDate 2025/11/13 15:09
 */
@Data
public class CallAgvParam {
    /**
     * 入库类型 1.组托入库,2.捡选回库,3.空托入库
     */
    private int type;
    /**
     * 托盘条码
     */
    private String barcode;
    /**
     * agv搬运起始站点
     */
    private int sourceSite;
}
src/main/java/com/zy/asrs/mapper/BasDevpMapper.java
@@ -4,6 +4,7 @@
import com.zy.asrs.entity.BasDevp;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Update;
import org.springframework.stereotype.Repository;
import java.util.List;
@@ -15,4 +16,12 @@
    List<Integer> getAvailableInSite(@Param("typeNo") Integer typeNo);
    List<Integer> getAvailableOutSite(@Param("typeNo") Integer typeNo);
    /**
     * 获取没有出库任务的站点
     */
    List<Integer> getCanInSites(List<Integer> sites);
    @Update("UPDATE asr_bas_devp SET in_qty = in_qty + 1 WHERE dev_no = #{site}")
    void incrementInQty(@Param("site") int sourceStaNo);
}
src/main/java/com/zy/asrs/mapper/BasStationMapper.java
@@ -3,10 +3,28 @@
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.zy.asrs.entity.BasStation;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Update;
import org.springframework.stereotype.Repository;
import java.util.List;
@Mapper
@Repository
public interface BasStationMapper extends BaseMapper<BasStation> {
    /**
     * 更新库位状态
     */
    @Update({
            "<script>",
            "UPDATE agv_bas_station",
            "SET loc_sts = #{sts}",
            "WHERE dev_no IN",
            "<foreach collection='siteList' item='item' open='(' separator=',' close=')'>",
            "#{item}",
            "</foreach>",
            "</script>"
    })
    void updateLocStsBatch(@Param("siteList") List<String> siteList, @Param("sts") String sts);
}
src/main/java/com/zy/asrs/mapper/WrkMastMapper.java
@@ -25,4 +25,8 @@
            , @Param("standby1") String standby1, @Param("standby2") String standby2, @Param("standby3") String standby3
            , @Param("boxType1") String boxType1, @Param("boxType2") String boxType2, @Param("boxType3") String boxType3, @Param("crnNo") Integer crnNo);
    /**
     * 按任务号更新呼叫agv状态
     */
    void updateAgvCallByWrkNos(@Param("wrkNoList") List<Integer> wrkNoList);
}
src/main/java/com/zy/asrs/service/MobileService.java
@@ -12,6 +12,11 @@
public interface MobileService {
    /**
     * pda呼叫agv入库
     */
    R inLocCallAgv(CallAgvParam param,Long userId);
    /**
     * 并板途中拣料
     */
    R WarehouseOutV1(CombParam combParam, Long hostId, Long userId);
src/main/java/com/zy/asrs/service/impl/MobileServiceImpl.java
@@ -9,10 +9,14 @@
import com.zy.asrs.entity.*;
import com.zy.asrs.entity.param.*;
import com.zy.asrs.enums.LocStsType;
import com.zy.asrs.mapper.BasDevpMapper;
import com.zy.asrs.mapper.BasStationMapper;
import com.zy.asrs.mapper.LocMastMapper;
import com.zy.asrs.mapper.ManLocDetlMapper;
import com.zy.asrs.service.*;
import com.zy.asrs.task.core.ReturnT;
import com.zy.asrs.utils.MatUtils;
import com.zy.common.constant.ApiInterfaceConstant;
import com.zy.common.constant.MesConstant;
import com.zy.common.entity.Parameter;
import com.zy.common.model.DetlDto;
@@ -21,6 +25,7 @@
import com.zy.common.service.CommonService;
import com.zy.common.utils.HttpHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -109,6 +114,106 @@
    private BasStationService basStationService;
    @Autowired
    private BasContainerService basContainerService;
    @Resource
    private BasStationMapper basStationMapper;
    @Resource
    private BasDevpMapper basDevpMapper;
    @Override
    public R inLocCallAgv(CallAgvParam param,Long userId) {
        int type = param.getType();
        int sourceSite = param.getSourceSite();
        String barcode = param.getBarcode();
        int ioType;
        switch (type) {
            case 1:
                // 判断有没有组托
                int count = waitPakinService.selectCount(new EntityWrapper<WaitPakin>().eq("zpallet", barcode));
                if (count == 0) {
                    throw new CoolException("条码未组托:" + barcode);
                }
                ioType = 1;
                break;
            case 2:
                // 判断是拣选回库托盘
                WrkMast wrkMast = wrkMastService.selectOne(new EntityWrapper<WrkMast>().eq("barcode", barcode));
                if (wrkMast == null) {
                    throw new CoolException("条码不存在:" + barcode);
                }
                if (wrkMast.getIoType() != 103 && wrkMast.getIoType() != 107) {
                    throw new CoolException("条码不需要回库:" + barcode);
                }
                ioType = wrkMast.getIoType() - 50;
                break;
            case 3:
                // 判断条码在wms不存在,是空托盘
                // 已组托
                int waitPakInCount = waitPakinService.selectCount(new EntityWrapper<WaitPakin>().eq("zpallet", barcode));
                if (waitPakInCount != 0) {
                    throw new CoolException("条码组托档已存在:" + barcode);
                }
                // 有任务
                int wrkMastCount = wrkMastService.selectCount(new EntityWrapper<WrkMast>().eq("barcode", barcode));
                if (wrkMastCount != 0) {
                    throw new CoolException("条码任务档已存在:" + barcode);
                }
                // 有库存
                int locDetlCount = locDetlService.selectCount(new EntityWrapper<LocDetl>().eq("zpallet", barcode));
                if (locDetlCount != 0) {
                    throw new CoolException("条码库存已存在:" + barcode);
                }
                ioType = 10;
                break;
            default:
                throw new CoolException("入库类型错误,type:" + type);
        }
        // 条码存在agv任务
        int count = taskService.selectCount(new EntityWrapper<Task>().eq("barcode", barcode));
        if (count > 0) {
            throw new CoolException(barcode+ ":条码存在agv搬运任务!");
        }
        // 判断能入站点
        List<Integer> sites = basDevpMapper.selectList(
                new EntityWrapper<BasDevp>()
                        .eq("canining", "Y")
                        .in("dev_no", type == 1 ? Arrays.asList(1003, 1005, 1007) : Arrays.asList(1044, 1046, 1048))
        ).stream().map(BasDevp::getDevNo).collect(Collectors.toList());
        if (sites.isEmpty()) {
            throw new CoolException("没有能入站点,type:" + type);
        }
        // 获取没有出库任务的站点
        List<Integer> canInSites = basDevpMapper.getCanInSites(sites);
        if (canInSites.isEmpty()) {
            throw new CoolException("请等待出库完成,type:" + type);
        }
        // 寻找入库任务最少的站点
        List<BasDevp> devList = basDevpMapper.selectList(new EntityWrapper<BasDevp>().in("dev_no", canInSites));
        // 入库任务数排序
        devList.sort(Comparator.comparing(BasDevp::getInQty));
        // 取入库任务最少站点
        BasDevp basDevp = devList.get(0);
        int endSite = basDevp.getDevNo();
        // 入库暂存+1
        basDevpMapper.incrementInQty(endSite);
        // 插入agv任务
        Task task = new Task(0, 7L, ioType, String.valueOf(sourceSite), String.valueOf(endSite), userId, barcode);
        taskService.insert(task);
        // 更新暂存位状态为 R.出库预约
        basStationMapper.updateLocStsBatch( Collections.singletonList(String.valueOf(sourceSite)), "R");
        return R.ok("agv任务生成成功!");
    }
    @Override
    @Transactional
@@ -601,9 +706,9 @@
                if (Cools.isEmpty(mat)) {
                    throw new CoolException(detlDto.getMatnr() + "商品档案不存在");
                }
                if (mat.getUpQty().compareTo(detlDto.getAnfme()) < 0) {
                    throw new CoolException("物料:" + detlDto.getMatnr() + "单次最大组托上限为:" + mat.getUpQty());
                }
//                if (mat.getUpQty().compareTo(detlDto.getAnfme()) < 0) {
//                    throw new CoolException("物料:" + detlDto.getMatnr() + "单次最大组托上限为:" + mat.getUpQty());
//                }
                WaitPakin waitPakin = new WaitPakin();
                BeanUtils.copyProperties(mat, waitPakin);
                waitPakin.setBatch(detlDto.getBatch());
src/main/java/com/zy/asrs/service/impl/OpenServiceImpl.java
@@ -67,7 +67,7 @@
        }
        switch (param.getStatus()) {
            case "Assigned":task.setSheetNo(param.getRobotName());break;
            case "Assigned":task.setInvWh(param.getRobotName());break;
            case "Done":task.setWrkSts(9L);break;
            case "Failed":
            case "Cancelled":
src/main/java/com/zy/asrs/task/AgvScheduler.java
New file
@@ -0,0 +1,97 @@
package com.zy.asrs.task;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.core.common.Cools;
import com.zy.asrs.entity.Task;
import com.zy.asrs.entity.WrkMast;
import com.zy.asrs.mapper.WrkMastMapper;
import com.zy.asrs.service.TaskService;
import com.zy.asrs.task.handler.AgvHandler;
import com.zy.system.entity.Config;
import com.zy.system.service.ConfigService;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
 * @author pang.jiabao
 * @description AGV交互相关定时任务
 * @createDate 2025/11/18 14:18
 */
@Component
public class AgvScheduler {
    @Resource
    private ConfigService configService;
    @Resource
    private AgvHandler agvHandler;
    @Resource
    private TaskService taskService;
    @Resource
    private WrkMastMapper wrkMastMapper;
    /**
     * 呼叫agv搬运
     */
    @Scheduled(cron = "0/5 * * * * ? ")
    private void callAgv() {
        // 查询待呼叫agv任务
        List<Task> taskList = taskService.selectList(new EntityWrapper<Task>().eq("wrk_sts", 7));
        if(taskList.isEmpty()) {
            return;
        }
        agvHandler.callAgv(taskList);
    }
    /**
     * 货物到达出库口,生成agv任务
     */
    @Scheduled(cron = "0/3 * * * * ? ")
    private void createAgvOutTasks() {
        // 获取呼叫agv配置
        List<Config> configs = configService.selectList(new EntityWrapper<Config>().in("code", "eastCallAgvControl", "westCallAgvControl").eq("status", 1));
        if(configs.isEmpty()) {
            return;
        }
        // 获取agv出库可用站点
        List<String> sites = new ArrayList<>();
        for(Config config: configs) {
            String value = config.getValue();
            if(Cools.isEmpty(value)) {
                continue;
            }
            String[] split = value.split(";");
            sites.addAll(Arrays.asList(split));
        }
        if(sites.isEmpty()) {
            return;
        }
        agvHandler.createAgvOutTasks(sites);
    }
    /**
     * 任务完成转历史
     */
    @Scheduled(cron = "0/10 * * * * ? ")
    private void moveTaskToHistory() {
        List<Task> taskList = taskService.selectList(new EntityWrapper<Task>().eq("wrk_sts", 9));
        if(taskList.isEmpty()) {
            return;
        }
        agvHandler.moveTaskToHistory(taskList);
    }
}
src/main/java/com/zy/asrs/task/handler/AgvHandler.java
New file
@@ -0,0 +1,220 @@
package com.zy.asrs.task.handler;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.core.common.R;
import com.zy.asrs.entity.Task;
import com.zy.asrs.entity.TaskLog;
import com.zy.asrs.entity.WrkMast;
import com.zy.asrs.mapper.BasStationMapper;
import com.zy.asrs.mapper.WrkMastMapper;
import com.zy.asrs.service.ApiLogService;
import com.zy.asrs.service.TaskLogService;
import com.zy.asrs.service.TaskService;
import com.zy.common.constant.ApiInterfaceConstant;
import com.zy.common.utils.HttpHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
/**
 * @author pang.jiabao
 * @description AGV交互相关定时任务处理类
 * @createDate 2025/11/18 14:42
 */
@Slf4j
@Service
public class AgvHandler {
    @Resource
    private WrkMastMapper wrkMastMapper;
    @Resource
    private ApiLogService apiLogService;
    @Resource
    private TaskService taskService;
    @Resource
    private TaskLogService taskLogService;
    @Resource
    private BasStationMapper basStationMapper;
    /**
     * 呼叫agv搬运
     */
    public void callAgv(List<Task> taskList) {
        for (Task task : taskList) {
            // 呼叫agv
            String response = "";
            boolean success = false;
            String url = ApiInterfaceConstant.AGV_IP + ApiInterfaceConstant.AGV_CALL_CARRY_PATH;
            String namespace = "";
            switch (task.getIoType()) {
                case 1:
                case 10:
                case 53:
                case 57:
                    namespace = "入库";
                    break;
                case 3:
                    namespace = "转移";
                    break;
                case 101:
                case 110:
                case 103:
                case 107:
                    namespace = "出库";
                    break;
                default:
            }
            String body = getRequest(task,namespace);
            try {
                response = new HttpHandler.Builder()
                        .setUri(ApiInterfaceConstant.AGV_IP)
                        .setPath(ApiInterfaceConstant.AGV_CALL_CARRY_PATH)
                        .setJson(body)
                        .build()
                        .doPost();
                JSONObject jsonObject = JSON.parseObject(response);
                if (jsonObject.getInteger("code").equals(200)) {
                    success = true;
                    task.setWrkSts(8L);
                    taskService.updateById(task);
                    log.info(namespace + "呼叫agv搬运成功:{}", task.getId());
                } else {
                    log.error(namespace + "呼叫agv搬运失败!!!url:{};request:{};response:{}", url, body, response);
                }
            } catch (Exception e) {
                log.error(namespace + "呼叫agv搬运异常", e);
            } finally {
                try {
                    // 保存接口日志
                    apiLogService.save(
                            namespace + "呼叫agv搬运",
                            url,
                            null,
                            "127.0.0.1",
                            body,
                            response,
                            success
                    );
                } catch (Exception e) {
                    log.error(namespace + "呼叫agv保存接口日志异常:", e);
                }
            }
        }
    }
    /**
     * 构造请求内容
     */
    private String getRequest(Task task, String nameSpace) {
        JSONObject object = new JSONObject();
        object.put("entityName", "ContainerTransportOrder");
        JSONObject entityValue = new JSONObject();
        entityValue.put("id", task.getId());
        String kind = "";
        switch (nameSpace) {
            case "入库":
                kind = "inBound";
                break;
            case "出库":
                kind = "outBound";
                break;
            case "转移":
                kind = "moveBound";
                break;
            default:
        }
        entityValue.put("kind", kind);
        entityValue.put("status", "Created");
        entityValue.put("priority", 0);
        entityValue.put("container", task.getBarcode());
        entityValue.put("fromBin", task.getSourceStaNo());
        entityValue.put("toBin", task.getStaNo());
        entityValue.put("emptyFlag", task.getIoType() == 10 ? 1 : 2); // 空托1,满托2 agv带着告诉输送线plc
        object.put("entityValue", entityValue.toJSONString());
        return object.toJSONString();
    }
    /**
     * 任务完成转历史 释放暂存点
     */
    @Transactional(rollbackFor = Exception.class)
    public void moveTaskToHistory(List<Task> taskList) {
        // 写入历史表
        for (Task task : taskList) {
            TaskLog log = new TaskLog();
            BeanUtils.copyProperties(task, log);
            taskLogService.insert(log);
        }
        // 批量删除原任务
        List<Long> taskIds = taskList.stream().map(Task::getId).collect(Collectors.toList());
        taskService.delete(new EntityWrapper<Task>().in("id",taskIds));
        // 批量更新暂存点状态
        List<String> locOList = new ArrayList<>();
        List<String> locFList = new ArrayList<>();
        for (Task task : taskList) {
            String sourceStaNo = task.getSourceStaNo();
            String staNo = task.getStaNo();
            if (task.getIoType() == 3) {
                locOList.add(sourceStaNo);
                locFList.add(staNo);
            } else if (task.getIoType() < 100) {
                locOList.add(sourceStaNo);
            } else {
                locFList.add(staNo);
            }
        }
        if (!locOList.isEmpty()) {
            basStationMapper.updateLocStsBatch(locOList, "O");
        }
        if (!locFList.isEmpty()) {
            basStationMapper.updateLocStsBatch(locFList, "F");
        }
        log.info("agv任务档转历史成功:{}", taskIds);
    }
    /**
     * 货物到达出库口,生成agv任务
     */
    public void createAgvOutTasks(List<String> sites) {
        // 获取到可用出库站点的任务
        List<WrkMast> wrkMastList = wrkMastMapper.selectList(new EntityWrapper<WrkMast>().eq("call_agv", 1).in("sta_no",sites));
        for(WrkMast wrkMast:wrkMastList) {
            // todo 计算agv目标暂存位
            int endSite = 2004;
            // 插入agv任务
            Task task = new Task(wrkMast.getWrkNo(), 7L, wrkMast.getIoType(), String.valueOf(wrkMast.getStaNo()), String.valueOf(endSite), null, wrkMast.getBarcode());
            taskService.insert(task);
            // 更新任务档agv搬运标识
            wrkMast.setCallAgv(2);
            wrkMastMapper.updateById(wrkMast);
            // 更新暂存位状态 S.入库预约
            basStationMapper.updateLocStsBatch( Collections.singletonList(String.valueOf(endSite)), "S");
        }
    }
}
src/main/java/com/zy/common/constant/ApiInterfaceConstant.java
@@ -31,11 +31,13 @@
    /**
     * AGV对接基础地址
     */
    public static final String AGV_IP = "http://192.168.99.130:80";
//    public static final String AGV_IP = "http://192.168.99.130:80";
    // 测试地址
    public static final String AGV_IP = "http://127.0.0.1:8080/yhfzwms/open/asrs";
    /**
     * 入库呼叫AGV取货
     * 呼叫AGV搬运
     */
    public static final String AGV_CALL_IN_PATH = "mes/api/zy/v1/packDown/sendList";
    public static final String AGV_CALL_CARRY_PATH = "/api/entity/create/one";
}
src/main/resources/mapper/BasDevpMapper.xml
@@ -65,5 +65,27 @@
        -- and abd.out_enable = 'Y'
        group by abd.dev_no
    </select>
    <select id="getCanInSites" resultType="java.lang.Integer">
        SELECT d.dev_no
        FROM asr_bas_devp d
        WHERE d.dev_no IN
        <foreach collection="list" item="dev" open="(" separator="," close=")">
            #{dev}
        </foreach>
        AND d.canining = 'Y'
        AND NOT EXISTS (
        SELECT 1
        FROM asr_wrk_mast w
        WHERE w.sta_no = d.dev_no
        AND (
        w.wrk_sts &lt; 14
        OR EXISTS (
        SELECT 1
        FROM asr_bas_devp d2
        WHERE d2.wrk_no = w.wrk_no
        )
        )
        )
    </select>
</mapper>
src/main/resources/mapper/TaskLogMapper.xml
@@ -2,69 +2,4 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zy.asrs.mapper.TaskLogMapper">
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.zy.asrs.entity.TaskLog">
        <result column="id" property="id" />
        <result column="wrk_no" property="wrkNo" />
        <result column="log_id" property="logId" />
        <result column="inv_wh" property="invWh" />
        <result column="ymd" property="ymd" />
        <result column="mk" property="mk" />
        <result column="whs_type" property="whsType" />
        <result column="wrk_sts" property="wrkSts" />
        <result column="io_type" property="ioType" />
        <result column="crn_no" property="crnNo" />
        <result column="sheet_no" property="sheetNo" />
        <result column="io_pri" property="ioPri" />
        <result column="wrk_date" property="wrkDate" />
        <result column="loc_no" property="locNo" />
        <result column="sta_no" property="staNo" />
        <result column="source_sta_no" property="sourceStaNo" />
        <result column="source_loc_no" property="sourceLocNo" />
        <result column="loc_sts" property="locSts" />
        <result column="picking" property="picking" />
        <result column="link_mis" property="linkMis" />
        <result column="online_yn" property="onlineYn" />
        <result column="upd_mk" property="updMk" />
        <result column="exit_mk" property="exitMk" />
        <result column="plt_type" property="pltType" />
        <result column="empty_mk" property="emptyMk" />
        <result column="io_time" property="ioTime" />
        <result column="ctn_type" property="ctnType" />
        <result column="packed" property="packed" />
        <result column="ove_mk" property="oveMk" />
        <result column="mtn_type" property="mtnType" />
        <result column="user_no" property="userNo" />
        <result column="crn_str_time" property="crnStrTime" />
        <result column="crn_end_time" property="crnEndTime" />
        <result column="plc_str_time" property="plcStrTime" />
        <result column="crn_pos_time" property="crnPosTime" />
        <result column="load_time" property="loadTime" />
        <result column="exp_time" property="expTime" />
        <result column="ref_wrkno" property="refWrkno" />
        <result column="ref_iotime" property="refIotime" />
        <result column="modi_user" property="modiUser" />
        <result column="modi_time" property="modiTime" />
        <result column="appe_user" property="appeUser" />
        <result column="appe_time" property="appeTime" />
        <result column="pause_mk" property="pauseMk" />
        <result column="error_time" property="errorTime" />
        <result column="error_memo" property="errorMemo" />
        <result column="ctn_kind" property="ctnKind" />
        <result column="manu_type" property="manuType" />
        <result column="memo_m" property="memoM" />
        <result column="sc_weight" property="scWeight" />
        <result column="log_mk" property="logMk" />
        <result column="log_err_time" property="logErrTime" />
        <result column="log_err_memo" property="logErrMemo" />
        <result column="barcode" property="barcode" />
        <result column="Pdc_type" property="PdcType" />
        <result column="ctn_no" property="ctnNo" />
        <result column="full_plt" property="fullPlt" />
        <result column="pre_have" property="preHave" />
        <result column="take_none" property="takeNone" />
        <result column="line_number" property="lineNumber" />
    </resultMap>
</mapper>
src/main/resources/mapper/TaskMapper.xml
@@ -2,12 +2,7 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zy.asrs.mapper.TaskMapper">
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.zy.asrs.entity.Task">
        <id column="id" property="id" />
        <result column="task_type" property="taskType" />
    </resultMap>
    <select id="selectToBeCompleteData" resultType="com.zy.asrs.entity.Task">
        select * from agv_task where ((wrk_sts = 4 Or wrk_sts = 14 ) and io_type != 103 and io_type != 104 and io_type != 107 ) or (wrk_sts = 2 and io_type=6) order by upd_mk,error_time,io_time,wrk_no
    </select>
src/main/resources/mapper/WrkMastMapper.xml
@@ -64,6 +64,13 @@
        <result column="take_none" property="takeNone" />
        <result column="call_agv" property="callAgv" />
    </resultMap>
    <update id="updateAgvCallByWrkNos">
        update asr_wrk_mast set call_agv = 2 where
        wrk_no in
        <foreach collection="wrkNoList" item="item" index="index" separator="," open="(" close=")">
            #{item}
        </foreach>
    </update>
    <select id="selectToBeCompleteData" resultMap="BaseResultMap">
        select * from asr_wrk_mast where ((wrk_sts = 4 Or wrk_sts = 14 ) and io_type != 103 and io_type != 104 and io_type != 107 ) or (wrk_sts = 2 and io_type=6) order by upd_mk,error_time,io_time,wrk_no
src/main/webapp/static/js/task/task.js
@@ -22,22 +22,26 @@
        height: 'full-120',
        cols: [[
            {type: 'checkbox'}
            , {field: 'wrkNo', align: 'center', title: '工作号', sort: true, width: 105}
            , {field: 'ioTime$', align: 'center', title: '工作时间', width: 160}
            , {field: 'wrkSts$', align: 'center', title: '工作状态', width: 150}
            , {field: 'ioType$', align: 'center', title: '入出库类型', width: 150}
            , {field: 'ioPri', align: 'center', title: '优先级', width: 80}
            , {field: 'taskType$', align: 'center', title: '任务类型'}
            , {field: 'crnNo$', align: 'center', title: '堆垛机', hide: true}
            , {field: 'sourceStaNo$', align: 'center', title: '源站'}
            , {field: 'staNo$', align: 'center', title: '目标站', width: 120}
            , {field: 'sourceLocNo', align: 'center', title: '源库位', width: 120}
            , {field: 'locNo', align: 'center', title: '目标库位', width: 120}
            , {field: 'barcode', align: 'center', title: '条码', width: 110}
            , {field: 'preHave', align: 'center', title: '先入品', hide: true}
            , {field: 'takeNone', align: 'center', title: '空操作', hide: true}
            , {field: 'id', align: 'center', title: 'id'}
            , {field: 'wrkNo', align: 'center', title: '任务号'}
            , {field: 'ioType$', align: 'center', title: '入出库类型',}
            , {field: 'wrkSts$', align: 'center', title: '工作状态'}
            , {field: 'ioPri', align: 'center', title: '优先级',hide: true}
            , {field: 'sourceStaNo', align: 'center', title: '源站'}
            , {field: 'staNo', align: 'center', title: '目标站'}
            , {field: 'invWh', align: 'center', title: 'agv'}
            , {field: 'barcode', align: 'center', title: '条码'}
            , {field: 'appeUser$', align: 'center', title: '创建人'}
            , {field: 'appeTime$', align: 'center', title: '创建时间',width: 170}
            , {field: 'modiUser$', align: 'center', title: '修改人员', hide: true}
            , {field: 'modiTime$', align: 'center', title: '修改时间', hide: true, width: 160}
            , {field: 'modiTime$', align: 'center', title: '修改时间', hide: true,width: 170}
            // , {field: 'taskType$', align: 'center', title: '任务类型'}
            // , {field: 'crnNo$', align: 'center', title: '堆垛机', hide: true}
            // , {field: 'sourceLocNo', align: 'center', title: '源库位', width: 120}
            // , {field: 'locNo', align: 'center', title: '目标库位', width: 120}
            // , {field: 'preHave', align: 'center', title: '先入品', hide: true}
            // , {field: 'takeNone', align: 'center', title: '空操作', hide: true}
            , {fixed: 'right', title: '操作', align: 'center', toolbar: '#operate', width: 200}
        ]],
        request: {
src/main/webapp/static/js/taskLog/taskLog.js
@@ -20,20 +20,19 @@
        toolbar: '#toolbar',
        cellMinWidth: 50,
        cols: [[
            {field: 'wrkNo', align: 'center', title: '工作号', event: 'wrkNo', sort: true}
            , {field: 'ioTime$', align: 'center', title: '工作时间', width: 160, sort: true}
            , {field: 'wrkSts$', align: 'center', title: '工作状态', width: 160}
            , {field: 'ioType$', align: 'center', title: '入出库类型', width: 160}
            , {field: 'ioPri', align: 'center', title: '优先级'}
            , {field: 'crnNo$', align: 'center', title: '堆垛机号'}
            , {field: 'sourceStaNo$', align: 'center', title: '源站'}
            , {field: 'staNo$', align: 'center', title: '目标站'}
            , {field: 'sourceLocNo$', align: 'center', title: '源库位'}
            , {field: 'locNo$', align: 'center', title: '目标库位'}
            , {field: 'modiUser$', align: 'center', title: '修改人员', hide: true}
            , {field: 'modiTime$', align: 'center', title: '修改时间', hide: true}
            {field: 'id', align: 'center', title: 'id'}
            , {field: 'wrkNo', align: 'center', title: '任务号'}
            , {field: 'ioType$', align: 'center', title: '入出库类型',}
            , {field: 'wrkSts$', align: 'center', title: '工作状态'}
            , {field: 'ioPri', align: 'center', title: '优先级',hide: true}
            , {field: 'sourceStaNo', align: 'center', title: '源站'}
            , {field: 'staNo', align: 'center', title: '目标站'}
            , {field: 'invWh', align: 'center', title: 'agv'}
            , {field: 'barcode', align: 'center', title: '条码'}
            , {fixed: 'right', title: '操作', align: 'center', toolbar: '#operate', width: 80}
            , {field: 'appeUser$', align: 'center', title: '创建人'}
            , {field: 'appeTime$', align: 'center', title: '创建时间',width: 170}
            , {field: 'modiUser$', align: 'center', title: '修改人员', hide: true}
            , {field: 'modiTime$', align: 'center', title: '修改时间', hide: true,width: 170}
        ]],
        request: {
            pageName: 'curr',
@@ -227,6 +226,7 @@
    // 搜索栏搜索事件
    form.on('submit(search)', function (data) {
        console.log('1111')
        pageCurr = 1;
        tableReload(false);
    });
src/main/webapp/views/taskLog/taskLog.html
@@ -72,7 +72,7 @@
<!-- 表格 -->
<div class="layui-form">
    <table class="layui-hide" id="wrkMastLog" lay-filter="wrkMastLog"></table>
    <table class="layui-hide" id="taskLog" lay-filter="taskLog"></table>
</div>
<script type="text/html" id="toolbar">
    <div class="layui-btn-container">
@@ -89,7 +89,7 @@
<script type="text/javascript" src="../../static/layui/layui.js" charset="utf-8"></script>
<script type="text/javascript" src="../../static/js/common.js" charset="utf-8"></script>
<script type="text/javascript" src="../../static/js/cool.js" charset="utf-8"></script>
<script type="text/javascript" src="../../static/js/wrkMastLog/wrkMastLog.js" charset="utf-8"></script>
<script type="text/javascript" src="../../static/js/taskLog/taskLog.js" charset="utf-8"></script>
<iframe id="detail-iframe" scrolling="auto" style="display:none;"></iframe>
version/v1.0.0/truncate.sql
@@ -26,4 +26,9 @@
TRUNCATE table man_order_pakout
TRUNCATE table man_order_detl_pakout
TRUNCATE table man_order_log_pakout
TRUNCATE table man_order_detl_log_pakout
TRUNCATE table man_order_detl_log_pakout
TRUNCATE table agv_task
TRUNCATE table agv_task_log
TRUNCATE table agv_task_detl
TRUNCATE table agv_task_detl_log