自动化立体仓库 - WMS系统
pang.jiabao
5 天以前 10e6a9a8adad2226f13a4e4704ca5b2ad5b9ef9a
刀具库WMS功能完善
1个文件已添加
32个文件已修改
1241 ■■■■ 已修改文件
src/main/java/com/zy/asrs/controller/DigitalTwinController.java 118 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/LocMastController.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/MatController.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/MesController.java 104 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/MobileController.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/RcsController.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/LocDetl.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/WrkDetlLog.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/digitaltwin/DtLocDetailVo.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/mes/StockDetl.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/param/LocDetlAdjustParam.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/DigitalTwinService.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/MesService.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/MobileService.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/DigitalTwinServiceImpl.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/MesServiceImpl.java 263 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/MobileServiceImpl.java 103 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/RcsServiceImpl.java 80 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/WorkServiceImpl.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/task/JlerScheduler.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/task/handler/JlerHandler.java 256 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/task/handler/WorkMastHandler.java 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/config/ControllerResAdvice.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/model/LocDto.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/web/AuthController.java 34 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-dev.yml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/LocDetlMapper.xml 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/WrkMastMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/js/basStation/basStation.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/js/pakStore/stockAdjust.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/js/wrkMast/wrkMast.js 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/basStation/basStation.html 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/locMast/locMast_detail.html 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/DigitalTwinController.java
@@ -232,65 +232,65 @@
//    @ManagerAuth
    public R warehouseDetail(@RequestParam(required = false) String areaId){
//        digitalTwinService.warehouseDetail(areaId);
        return digitalTwinService.warehouseDetail(areaId);
        List<DtLocDetailVo> dtLocDetailVoList = new ArrayList<>();
        DtLocDetailVo dtLocDetailVo = new DtLocDetailVo();
        dtLocDetailVo.setLocNo("CA0100202");
        dtLocDetailVo.setLocSts("O");
        dtLocDetailVo.setAreaId(10010L);
        dtLocDetailVo.setAreaName("刀具库");
        dtLocDetailVo.setRow1(1);
        dtLocDetailVo.setBay1(2);
        dtLocDetailVo.setLev1(2);
        LocMast locMast = new LocMast();
        locMast.setLocNo("CA0100202");
        locMast.setLocSts("O");
        locMast.setRow1(1);
        locMast.setBay1(2);
        locMast.setLev1(2);
        dtLocDetailVo.setLocMast(locMast);
        LocDetl locDetl = new LocDetl();
        locDetl.setLocNo("CA0100202");
        locDetl.setAreaId(10010L);
        locDetl.setAreaName("刀具库");
        locDetl.setMatnr("mat10001");
        locDetl.setMaktx("物料名称");
        locDetl.setAnfme(100.0);
        locDetl.setStandby3("AAA,BBB,CCC");
        dtLocDetailVo.setLocDetl(locDetl);
        dtLocDetailVoList.add(dtLocDetailVo);
        DtLocDetailVo dtLocDetailVo2 = new DtLocDetailVo();
        dtLocDetailVo2.setLocNo("CA0100202");
        dtLocDetailVo2.setLocSts("O");
        dtLocDetailVo2.setAreaId(10010L);
        dtLocDetailVo2.setAreaName("刀具库");
        dtLocDetailVo2.setRow1(1);
        dtLocDetailVo2.setBay1(2);
        dtLocDetailVo2.setLev1(2);
        LocMast locMast2 = new LocMast();
        locMast2.setLocNo("CA0100203");
        locMast2.setLocSts("O");
        locMast2.setRow1(1);
        locMast2.setBay1(2);
        locMast2.setLev1(3);
        dtLocDetailVo2.setLocMast(locMast2);
        LocDetl locDetl2 = new LocDetl();
        locDetl2.setLocNo("CA0100203");
        locDetl2.setAreaId(10010L);
        locDetl2.setAreaName("刀具库");
        locDetl.setMatnr("mat10001");
        locDetl.setMaktx("物料名称");
        locDetl.setAnfme(100.0);
        locDetl.setStandby3("AAA1,BBB1,CCC1");
        dtLocDetailVo2.setLocDetl(locDetl2);
        dtLocDetailVoList.add(dtLocDetailVo2);
//        List<DtLocDetailVo> dtLocDetailVoList = new ArrayList<>();
//        DtLocDetailVo dtLocDetailVo = new DtLocDetailVo();
//        dtLocDetailVo.setLocNo("CA0100202");
//        dtLocDetailVo.setLocSts("O");
//        dtLocDetailVo.setAreaId(10010L);
//        dtLocDetailVo.setAreaName("刀具库");
//        dtLocDetailVo.setRow1(1);
//        dtLocDetailVo.setBay1(2);
//        dtLocDetailVo.setLev1(2);
//
//        LocMast locMast = new LocMast();
//        locMast.setLocNo("CA0100202");
//        locMast.setLocSts("O");
//        locMast.setRow1(1);
//        locMast.setBay1(2);
//        locMast.setLev1(2);
//        dtLocDetailVo.setLocMast(locMast);
//
//        LocDetl locDetl = new LocDetl();
//        locDetl.setLocNo("CA0100202");
//        locDetl.setAreaId(10010L);
//        locDetl.setAreaName("刀具库");
//        locDetl.setMatnr("G01-JT50-ZC32-110-07");
//        locDetl.setMaktx("D32方肩铣刀柄");
//        locDetl.setAnfme(100.0);
//        locDetl.setStandby3("AAA,BBB,CCC");
//        dtLocDetailVo.setLocDetl(locDetl);
//        dtLocDetailVoList.add(dtLocDetailVo);
//
//
//        DtLocDetailVo dtLocDetailVo2 = new DtLocDetailVo();
//        dtLocDetailVo2.setLocNo("CA0100202");
//        dtLocDetailVo2.setLocSts("O");
//        dtLocDetailVo2.setAreaId(10010L);
//        dtLocDetailVo2.setAreaName("刀具库");
//        dtLocDetailVo2.setRow1(1);
//        dtLocDetailVo2.setBay1(2);
//        dtLocDetailVo2.setLev1(2);
//
//        LocMast locMast2 = new LocMast();
//        locMast2.setLocNo("CA0100203");
//        locMast2.setLocSts("O");
//        locMast2.setRow1(1);
//        locMast2.setBay1(2);
//        locMast2.setLev1(3);
//        dtLocDetailVo2.setLocMast(locMast2);
//
//        LocDetl locDetl2 = new LocDetl();
//        locDetl2.setLocNo("CA0100203");
//        locDetl2.setAreaId(10010L);
//        locDetl2.setAreaName("刀具库");
//        locDetl2.setMatnr("T08-A72500-XXX-CC09-A1");
//        locDetl2.setMaktx("D94126精镗刀夹");
//        locDetl2.setAnfme(100.0);
//        locDetl2.setStandby3("AAA1,BBB1,CCC1");
//        dtLocDetailVo2.setLocDetl(locDetl2);
//        dtLocDetailVoList.add(dtLocDetailVo2);
//        LocDetl locDetl2 = new LocDetl();
@@ -304,7 +304,7 @@
////        locDetlList.add(locDetl);
////        locDetlList.add(locDetl2);
        return R.ok().add(dtLocDetailVoList);
//        return R.ok().add(dtLocDetailVoList);
    }
}
src/main/java/com/zy/asrs/controller/LocMastController.java
@@ -198,9 +198,11 @@
                if (!locDetlService.delete(new EntityWrapper<LocDetl>().eq("loc_no", locMast.getLocNo()))) {
                    throw new CoolException("服务器错误,请联系管理员");
                }
                locMast.setBarcode("");
            }
        }
        if(locMast.getLocSts().equals("O"))  {
            locMast.setBarcode("");
        }
        locMast.setModiUser(getUserId());
        locMast.setModiTime(now);
        AdjDetl adjDetl = new AdjDetl();
src/main/java/com/zy/asrs/controller/MatController.java
@@ -51,9 +51,9 @@
    @RequestMapping(value = "/mat/list/pda/auth")
    @ManagerAuth
    public R pdaList(@RequestParam(required = true) Long tagId) {
    public R pdaList(@RequestParam(required = false) Long tagId) {
        EntityWrapper<Mat> wrapper = new EntityWrapper<>();
        wrapper.eq("tag_id", tagId);
//        wrapper.eq("tag_id", tagId);
        wrapper.orderBy("create_time", false);
        List<Mat> mats = matService.selectList(wrapper);
        return R.ok().add(mats);
src/main/java/com/zy/asrs/controller/MesController.java
@@ -1,7 +1,9 @@
package com.zy.asrs.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.core.annotations.AppAuth;
import com.core.common.Cools;
import com.core.common.R;
import com.zy.asrs.entity.BasStation;
@@ -9,65 +11,56 @@
import com.zy.asrs.service.BasStationService;
import com.zy.asrs.service.MesService;
import com.zy.common.web.BaseController;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
@RestController
@Slf4j
public class MesController extends BaseController {
    @Resource
    private MesService mesService;
    private void auth(String appkey, Object obj, HttpServletRequest request) {
        log.info("{}接口被访问;appkey:{};请求数据:{}", request.getRequestURI(), appkey, JSON.toJSONString(obj));
        request.setAttribute("cache", obj);
    }
    // 物料信息同步
    @PostMapping("/api/mes/synMatInfo")
    public MesReturn synMatInfo(@RequestBody MesMatInfo param){
    @AppAuth(memo = "物料信息同步")
    public MesReturn synMatInfo(@RequestHeader(required = false) String appkey,@RequestBody MesMatInfo param,HttpServletRequest request){
        auth(appkey, param, request);
        MesReturn mesReturn = new MesReturn();
        mesReturn.setSuccess(mesService.synMatInfo(param) == 1 ? "1" : "2");
        return mesReturn;
    }
    @PostMapping("/api/tms/queryStock")
    @AppAuth(memo = "TMS查询库存")
    public R queryStock(@RequestHeader(required = false) String appkey,@RequestBody JSONObject param,HttpServletRequest request){
        auth(appkey, param, request);
        String matnr = param.getString("matnr");
        return mesService.queryStock(matnr);
    }
    // 出库申请
    @PostMapping("/api/mes/outBoundOrder")
    public MesReturn outBoundOrder(@RequestBody MesInApply param){
        MesReturn mesReturn = new MesReturn();
        // 终点为空,计算接驳位
        BasStation basStation = null;
        if (Cools.isEmpty(param.getNextStationId())) {
            List<BasStation> basStations = basStationService.selectList(new EntityWrapper<BasStation>().eq("loc_sts", "O"));
            if(basStations.isEmpty()) {
                mesReturn.setSuccess("2");
                mesReturn.setMessage("无空接驳位,请稍后再试!");
                return mesReturn;
            }
            // 接驳点
            basStation = basStations.get(0);
            param.setNextStationId(basStation.getDevNo());
            // 先更新接驳点状态
            basStation.setModiTime(new Date());
            basStation.setLocSts("S");
            basStation.setBarcode(param.getDjNo());
            basStationService.updateById(basStation);
        }
        int i = mesService.outBoundOrder(param);
        if(i == 1) {
            mesReturn.setSuccess("1");
        } else {
            // 释放接驳点
            if(basStation != null) {
                basStation.setModiTime(new Date());
                basStation.setLocSts("O");
                basStation.setBarcode("");
                basStationService.updateById(basStation);
            }
    @AppAuth(memo = "出库申请(TMS调用)")
    public MesReturn outBoundOrder(@RequestHeader(required = false) String appkey,@RequestBody MesInApply param,HttpServletRequest request){
        auth(appkey, param, request);
        if(Cools.isEmpty(param.getTaskNo(),param.getOrderNo(),param.getStationId())) {
            MesReturn mesReturn = new MesReturn();
            mesReturn.setSuccess("2");
            mesReturn.setMessage("参数不能为空:" + JSONObject.toJSONString(param));
            return  mesReturn;
        }
        return mesReturn;
        return mesService.outBoundOrder(param);
    }
//    // 出库申请(叫料),装配库、滑块库
@@ -88,10 +81,10 @@
        return mesReturn;
    }
    // 入站允许
    @PostMapping("/api/mes/allowInStation")
    public MesReturn allowInStation(@RequestBody TransInOutStationAllow param){
    @AppAuth(memo = "入站允许")
    public MesReturn allowInStation(@RequestHeader(required = false) String appkey,@RequestBody TransInOutStationAllow param,HttpServletRequest request){
        auth(appkey, param, request);
        return mesService.allowInStation(param);
    }
@@ -108,6 +101,7 @@
    // 下发运输任务,mes调用下刀06(呼叫agv搬运)
    @PostMapping("/api/mes/submitTask")
    public JSONObject submitTask(@RequestBody TransTask param){
        log.info("下刀(退刀):{}",JSONObject.toJSONString(param));
        // 终点为空,计算接驳位
        BasStation basStation = null;
        if (Cools.isEmpty(param.getNextStationId())) {
@@ -129,11 +123,20 @@
            basStation.setBarcode(param.getDjNo());
            basStationService.updateById(basStation);
        }
        JSONObject sendAgvTask;
        param.setAgvFactory(1); // 海康
        param.setNextStationId("A1");
        JSONObject sendAgvTask = mesService.submitTask(param);
        if (!"1".equals(sendAgvTask.getString("Success"))) {
        try {
            sendAgvTask = mesService.submitTask(param);
            if (!"1".equals(sendAgvTask.getString("Success"))) {
                // 释放接驳点
                if(basStation != null) {
                    basStation.setModiTime(new Date());
                    basStation.setLocSts("O");
                    basStation.setBarcode("");
                    basStationService.updateById(basStation);
                }
            }
        }catch (Exception e){
            // 释放接驳点
            if(basStation != null) {
                basStation.setModiTime(new Date());
@@ -141,6 +144,7 @@
                basStation.setBarcode("");
                basStationService.updateById(basStation);
            }
            throw e;
        }
        return sendAgvTask;
    }
@@ -154,19 +158,5 @@
        return mesReturn;
    }
    // region 测试
    @GetMapping("/api/mes/transDj")
    public int transDj(@RequestParam String taskNo,@RequestParam String djNo){
        return mesService.transDj(taskNo,djNo);
    }
    // 退空托盘返回产线 pda上操作空托返回产线
    @GetMapping("/tkt")
    public R tkt(@RequestParam String taskNo){
         return mesService.tkt(taskNo);
    }
    // endregion
}
src/main/java/com/zy/asrs/controller/MobileController.java
@@ -17,6 +17,7 @@
import com.zy.common.model.WrkDto;
import com.zy.common.web.BaseController;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
@@ -30,6 +31,7 @@
 */
@RestController
@RequestMapping("mobile")
@Slf4j
public class MobileController extends BaseController  {
    @Autowired
@@ -60,10 +62,31 @@
    @Resource
    private StaDescService staDescService;
    // 入库启动调用wcs给输送线下命令 type 1.满箱入库(默认),2.空箱入库
    @GetMapping("/inboundStart/auth")
    @ManagerAuth(memo = "入库启动")
    public R inboundStart(@RequestParam int type){
        log.info("pda入库启动:{}",type);
        return mobileService.inboundStart(type);
    }
    // 退空托盘返回产线 pda上操作空托返回产线(刀架返回)
    @GetMapping("/djReturn/auth")
    @ManagerAuth(memo = "刀架返回")
    public R tkt(@RequestParam String djNo){
        log.info("刀架返回:{}",djNo);
        return mobileService.djReturn(djNo);
    }
    // 空箱出库
    @GetMapping("/emptyBoxOutbound/auth")
    @ManagerAuth(memo = "空箱出库")
    public R emptyBoxOutbound(@RequestParam int count){
        log.info("空箱出库:{}",count);
        if (count <= 0) {
            return R.parse("数量有误:" + count);
        }
        return mobileService.emptyBoxOutbound(count,getUserId());
    }
    @RequestMapping("/comb/auth")
@@ -72,8 +95,6 @@
        mobileService.comb(combParam, getUserId());
        return R.ok("组托成功");
    }
    // 输送线流动
    @RequestMapping("/pda/WarehouseOut/v1")
    @ManagerAuth(memo = "并板途中拣料-参考念初")
src/main/java/com/zy/asrs/controller/RcsController.java
@@ -7,6 +7,7 @@
import com.zy.asrs.entity.rcs.RcsReturn;
import com.zy.asrs.service.RcsService;
import com.zy.common.web.BaseController;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@@ -14,6 +15,7 @@
import javax.annotation.Resource;
@RestController
@Slf4j
public class RcsController extends BaseController {
    @Resource
@@ -23,7 +25,7 @@
    // 反馈任务执行结果
    @PostMapping("/api/robot/reporter/task")
    public RcsReturn reporterTask(@RequestBody RcsReporterTask param){
        log.info("agv任务执行反馈请求:{}",JSONObject.toJSONString(param));
        return rcsService.reporterTask(param);
    }
src/main/java/com/zy/asrs/entity/LocDetl.java
@@ -18,6 +18,7 @@
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import org.springframework.beans.BeanUtils;
import java.io.Serializable;
import java.text.SimpleDateFormat;
@@ -338,7 +339,7 @@
    }
    public void sync(Object source) {
        Synchro.Copy(source, this);
        BeanUtils.copyProperties(source,this);
    }
    public String getFrozen$() {
src/main/java/com/zy/asrs/entity/WrkDetlLog.java
@@ -9,6 +9,7 @@
import com.zy.system.service.UserService;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.beans.BeanUtils;
import java.io.Serializable;
import java.text.SimpleDateFormat;
@@ -399,6 +400,6 @@
    }
    public void sync(Object source) {
        Synchro.Copy(source, this);
        BeanUtils.copyProperties(source,this);
    }
}
src/main/java/com/zy/asrs/entity/digitaltwin/DtLocDetailVo.java
@@ -2,7 +2,10 @@
import com.zy.asrs.entity.LocDetl;
import com.zy.asrs.entity.LocMast;
import com.zy.asrs.entity.mes.StockDetl;
import lombok.Data;
import java.util.List;
@Data
public class DtLocDetailVo  {
@@ -12,9 +15,9 @@
    // 库位状态,O空库位(英文不是数字);F 在库;D 空板;P 出库中;R 出库预约;S 入库预约;其他 其他;
    private String locSts;
    // 库区id
    private Long areaId;
    private Long areaId = 10010L;
    // 库区名称
    private String areaName;
    private String areaName = "刀具库";
    // 排
    private Integer row1;
    // 列
@@ -22,9 +25,7 @@
    // 层
    private Integer lev1;
    // 库位信息
    private LocMast locMast;
    // 库存信息
    private LocDetl locDetl;
    private List<StockDetl> locDetl;
}
src/main/java/com/zy/asrs/entity/mes/StockDetl.java
New file
@@ -0,0 +1,21 @@
package com.zy.asrs.entity.mes;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * @author pang.jiabao
 * @description
 * @createDate 2025/12/18 13:42
 */
@Data
public class StockDetl {
    @ApiModelProperty(value= "数量")
    private Double anfme;
    @ApiModelProperty(value= "商品编号")
    private String matnr;
    @ApiModelProperty(value= "商品名称")
    private String maktx;
}
src/main/java/com/zy/asrs/entity/param/LocDetlAdjustParam.java
@@ -30,10 +30,14 @@
        // 变更数量
        private Double count;
        public LocDetlAdjust(String matnr, String batch, Double count) {
        // 料箱码
        private String zpallet;
        public LocDetlAdjust(String matnr, String batch, Double count,String zpallet) {
            this.matnr = matnr;
            this.batch = batch;
            this.count = count;
            this.zpallet = zpallet;
        }
    }
@@ -52,7 +56,7 @@
                }
            }
            if (!exit) {
                copyList.add(new LocDetlAdjustParam.LocDetlAdjust(adjust.getMatnr(), adjust.getBatch(), adjust.getCount()));
                copyList.add(new LocDetlAdjustParam.LocDetlAdjust(adjust.getMatnr(), adjust.getBatch(), adjust.getCount(),adjust.getZpallet()));
            }
        }
        list = copyList;
src/main/java/com/zy/asrs/service/DigitalTwinService.java
@@ -1,5 +1,6 @@
package com.zy.asrs.service;
import com.core.common.R;
import com.zy.asrs.entity.digitaltwin.*;
import java.util.List;
@@ -50,7 +51,7 @@
     * @param areaId
     * @return
     */
    List<DtLocDetailVo> warehouseDetail(String areaId);
    R warehouseDetail(String areaId);
    /**
     * 近期剩余库位数量,默认7天
src/main/java/com/zy/asrs/service/MesService.java
@@ -42,7 +42,7 @@
     * @param mesOutApply
     * @return
     */
    int outBoundOrder(MesInApply mesOutApply);
    MesReturn outBoundOrder(MesInApply mesOutApply);
    /**
     * 出库申请(叫料),齐套性配盘
@@ -75,8 +75,6 @@
     * @return
     */
    int inBoundOrder(MesInApply mesInApply, int check);
    int transDj(String taskNo,String djNo);
    /**
     * 9.1下发运输任务
@@ -150,5 +148,8 @@
     */
    int outStation(TransParent apply);
    R tkt(String taskNo);
    /**
     * TMS查询库存
     */
    R queryStock(String matnr);
}
src/main/java/com/zy/asrs/service/MobileService.java
@@ -105,4 +105,15 @@
     * @param djNo 刀架号
     */
    R djReturn(String djNo);
    /**
     * pda呼叫空料箱出库
     */
    R emptyBoxOutbound(int count,Long userId);
    /**
     * 入库启动调用wcs给输送线下命令
     * @param type 1.满箱入库9998(默认),2.空箱入库9997
     */
    R inboundStart(int type);
}
src/main/java/com/zy/asrs/service/impl/DigitalTwinServiceImpl.java
@@ -1,12 +1,18 @@
package com.zy.asrs.service.impl;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.core.common.Cools;
import com.core.common.R;
import com.zy.asrs.entity.LocCount;
import com.zy.asrs.entity.LocDetl;
import com.zy.asrs.entity.LocMast;
import com.zy.asrs.entity.digitaltwin.*;
import com.zy.asrs.entity.mes.StockDetl;
import com.zy.asrs.mapper.DigitalTwinMapper;
import com.zy.asrs.mapper.LocCountMapper;
import com.zy.asrs.service.DigitalTwinService;
import com.zy.asrs.service.LocDetlService;
import com.zy.asrs.service.LocMastService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@@ -142,38 +148,48 @@
        return dbDetainMats;
    }
    @Resource
    private LocDetlService locDetlService;
    @Resource
    private LocMastService locMastService;
    /**
     * 查询库存和库位详细信息
     *
     * @param areaId
     * @return
     */
    public List<DtLocDetailVo> warehouseDetail(String areaId) {
        List<DtLocDetailVo> locDetailVos = new ArrayList<>();
    public R warehouseDetail(String areaId) {
        List<LocDetl> locDetls;
        locDetls = locDetlService.selectList(new EntityWrapper<>());
        List<LocMast> locMasts = new ArrayList<>();
        List<LocDetl> locDetls = new ArrayList<>();
        List<String> locNoList = locDetls.stream().map(LocDetl::getLocNo).distinct().collect(Collectors.toList());
        List<DtLocDetailVo> dtLocDetailVoList = new ArrayList<>();
        for (String locNo: locNoList) {
        for (LocMast locMast : locMasts) {
            LocMast locMast = locMastService.selectById(locNo);
            DtLocDetailVo dtLocDetailVo = new DtLocDetailVo();
            dtLocDetailVo.setLocMast(locMast);
            dtLocDetailVo.setLocNo(locMast.getLocNo());
            dtLocDetailVo.setLocNo(locNo);
            dtLocDetailVo.setLocSts(locMast.getLocSts());
            dtLocDetailVo.setRow1(locMast.getRow1());
            dtLocDetailVo.setBay1(locMast.getBay1());
            dtLocDetailVo.setLev1(locMast.getLev1());
            for (LocDetl locDetl : locDetls) {
                List<LocDetl> locDetl1 = locDetls.parallelStream().filter(a -> a.getLocNo().equals(locDetl.getLocNo())).collect(Collectors.toList());
                if (locDetl1 != null && locDetl1.size() == 1) {
                    dtLocDetailVo.setLocDetl(locDetl1.get(0));
                    dtLocDetailVo.setAreaId(locDetl.getAreaId());
                    dtLocDetailVo.setAreaName(locDetl.getAreaName());
                }
            List<LocDetl> locDetlList2 = locDetls.parallelStream().filter(o-> o.getLocNo().equals(locNo)).collect(Collectors.toList());
            List<StockDetl> stockDetls = new ArrayList<>();
            for(LocDetl locDetl:locDetlList2) {
                StockDetl stockDetl = new StockDetl();
                stockDetl.setMatnr(locDetl.getMatnr());
                stockDetl.setMaktx(locDetl.getMaktx());
                stockDetl.setAnfme(locDetl.getAnfme());
                stockDetls.add(stockDetl);
            }
            locDetailVos.add(dtLocDetailVo);
            dtLocDetailVo.setLocDetl(stockDetls);
            dtLocDetailVoList.add(dtLocDetailVo);
        }
        return locDetailVos;
        return R.ok(dtLocDetailVoList);
    }
    /**
src/main/java/com/zy/asrs/service/impl/MesServiceImpl.java
@@ -9,6 +9,7 @@
import com.core.common.SnowflakeIdWorker;
import com.core.exception.CoolException;
import com.zy.asrs.entity.*;
import com.zy.asrs.entity.digitaltwin.DtLocDetailVo;
import com.zy.asrs.entity.mes.*;
import com.zy.asrs.entity.param.CombParam;
import com.zy.asrs.entity.rcs.*;
@@ -133,11 +134,7 @@
            // 规则定义:默认第3层为同步的物料类型
            long secondPath = 2;
            String secondParentName = WMS_CURRENT_NAME;
//        long locType = 1;
            long userId = defaultUserId;
//            if (mesMatInfo.getModified_operator1() != null && !mesMatInfo.getModified_operator1().isEmpty()) {
//                userId = Long.parseLong(mesMatInfo.getModified_operator1());
//            }
            Date now = new Date();
            if (mesMatInfo.getModified_date1() != null && !mesMatInfo.getModified_date1().isEmpty()) {
                now = Date.from(OffsetDateTime.parse(mesMatInfo.getModified_date1()).toInstant());
@@ -168,35 +165,29 @@
            // 物料更新
            long tagId = tagService.selectByName(mesMatInfo.getItem_type(), 3).getId();
            Mat mat = matService.selectByMatnr(mesMatInfo.getItem_no());
            Mat newMat = new Mat();
            newMat.setMatnr(mesMatInfo.getItem_no());
            newMat.setMaktx(mesMatInfo.getDescription());
            newMat.setTagId(tagId);
            newMat.setLocType(tagId);   //locType
            newMat.setSpecs(mesMatInfo.getSpecification());
            newMat.setUnit("件");   //统一为件,mesMatInfo.getUnit_of_measure()
            newMat.setModel(mesMatInfo.getClassification_code());
            newMat.setMemo(JSONObject.toJSONString(mesMatInfo));
            newMat.setCreateBy(userId);
            newMat.setCreateTime(now);
            newMat.setUpdateBy(userId);
            newMat.setUpdateTime(now);
            newMat.setStatus(1);
            if (mat == null) {
                if (!matService.insert(newMat))
                    return -2;
                Mat newMat = new Mat();
                newMat.setMatnr(mesMatInfo.getItem_no());
                newMat.setMaktx(mesMatInfo.getDescription());
                newMat.setTagId(tagId);
                newMat.setLocType(tagId);   //locType
                newMat.setSpecs(mesMatInfo.getSpecification());
                newMat.setUnit(mesMatInfo.getUnit_of_measure());
                newMat.setModel(mesMatInfo.getClassification_code());
//            newMat.setMemo(JSONObject.toJSONString(mesMatInfo));
                newMat.setCreateBy(userId);
                newMat.setCreateTime(now);
                newMat.setUpdateBy(userId);
                newMat.setUpdateTime(now);
                newMat.setStatus(1);
                matService.insert(newMat);
            } else {
                JSONObject dbMemo = JSONObject.parseObject(mat.getMemo());
//            dbMemo.remove("OrderNo");
//            dbMemo.remove("qty");
            JSONObject newMemo = JSONObject.parseObject(newMat.getMemo());
//            newMemo.remove("OrderNo");
//            newMemo.remove("qty");
                if (!dbMemo.equals(newMemo)) {
                    newMat.setId(mat.getId());
                    if (!matService.updateById(newMat))
                        return -2;
                }
                mat.setMaktx(mesMatInfo.getDescription());
                mat.setSpecs(mesMatInfo.getSpecification());
                mat.setUnit(mesMatInfo.getUnit_of_measure());
                mat.setModel(mesMatInfo.getClassification_code());
                mat.setUpdateTime(now);
                matService.updateById(mat);
            }
            return 1;
@@ -266,6 +257,9 @@
        return 0;
    }
    @Resource
    private BasStationService basStationService;
    /**
     * 出库申请
     * 加工库、刀具库
@@ -274,22 +268,38 @@
     * @return 1 成功;-1 订单重复;
     */
    @Transactional
    public int outBoundOrder(MesInApply mesOutApply){
    public MesReturn outBoundOrder(MesInApply mesOutApply) {
        MesReturn mesReturn = new MesReturn();
        // 终点为空,计算接驳位
        BasStation basStation = null;
        if (Cools.isEmpty(mesOutApply.getNextStationId())) {
            List<BasStation> basStations = basStationService.selectList(new EntityWrapper<BasStation>().eq("loc_sts", "O"));
            if (basStations.isEmpty()) {
                mesReturn.setSuccess("2");
                mesReturn.setMessage("无空接驳位,请稍后再试!");
                return mesReturn;
            }
            // 接驳点
            basStation = basStations.get(0);
            mesOutApply.setNextStationId(basStation.getDevNo());
        }
        // docType根据库类型确定
        long docType = 7;
        long docType = Long.parseLong(mesOutApply.getBillType());
        long settle = 1;
        // 校验订单是否重复
        OrderPakout order = orderPakoutService.selectByNo(mesOutApply.getOrderNo());
        if (order != null && !StringUtils.isEmpty(order.getOrderNo())) {
            return -1;
            mesReturn.setSuccess("2");
            mesReturn.setMessage("orderNo重复:" + mesOutApply.getOrderNo());
            return mesReturn;
        }
        // 生成订单
        Date now = new Date();
        OrderPakout orderPakout = new OrderPakout();
        orderPakout.setUuid( String.valueOf(snowflakeIdWorker.nextId()));
        orderPakout.setUuid(String.valueOf(snowflakeIdWorker.nextId()));
        orderPakout.setOrderNo(mesOutApply.getOrderNo());
        orderPakout.setOrderTime(com.core.common.DateUtils.convert(now));
        orderPakout.setDocType(docType);
@@ -302,7 +312,7 @@
        orderPakout.setMemo(JSONObject.toJSONString(mesOutApply));
        orderPakout.setPakinPakoutStatus(2);
        if (!orderPakoutService.insert(orderPakout)) {
            log.error("MES保存出库订单主档失败:{}",orderPakout);
            log.error("MES保存出库订单主档失败:{}", orderPakout);
            throw new CoolException("保存出库订单主档失败");
        }
@@ -325,74 +335,43 @@
            orderDetlPakout.setStatus(1);
            orderDetlPakout.setPakinPakoutStatus(2);
            if (!orderDetlPakoutService.insert(orderDetlPakout)) {
                log.error("MES保存出库订单明细档失败:{}",orderDetlPakout);
                log.error("MES保存出库订单明细档失败:{}", orderDetlPakout);
                throw new CoolException("保存出库订单明细档失败");
            }
        }
        // TODO:CTU出库动作
        // 立库生成订单后,自动调度AGV从产线运输空刀架至立库缓存区。
            if (!StringUtils.isEmpty(mesOutApply.getTaskNo()) && !StringUtils.isEmpty(mesOutApply.getStationId())) {
                TransTask transTask = new TransTask();
                transTask.setTaskno(mesOutApply.getTaskNo());
                transTask.setTaskname(mesOutApply.getTaskname());
                transTask.setOrderNo(mesOutApply.getOrderNo());
                transTask.setTransType("02");    //运回刀架时默认02(下空托) mesOutApply.getTransType()
                transTask.setCurProcess(mesOutApply.getProductLineId());
                transTask.setCurStationId(mesOutApply.getStationId());
                transTask.setNextProcess(mesOutApply.getProductLineId());
                transTask.setNextStationId(mesOutApply.getNextStationId());
//                transTask.setItemno(mesOutApply.getItemNo());
                transTask.setQty(1);
                transTask.setProductLineId(mesOutApply.getProductLineId());
//                        transTask.setItemBarcode(codes);
//                        transTask.setTuoPanId(entry.getKey());
                transTask.setDjNo(mesOutApply.getDjNo());
                transTask.setOperateType(1);
                transTask.setAgvFactory(1);
                JSONObject sendAgvTask = submitTask(transTask);
                if (!"1".equals(sendAgvTask.getString("Success"))) {
                    log.error("出库下发agv运输任务失败:{}", JSONObject.toJSONString(transTask));
                }
        TransTask transTask = new TransTask();
        transTask.setTaskno(mesOutApply.getTaskNo());
        transTask.setTaskname(mesOutApply.getTaskname());
        transTask.setOrderNo(mesOutApply.getOrderNo());
        transTask.setTransType("02");    //运回刀架时默认02(下空托) mesOutApply.getTransType()
        transTask.setCurProcess(mesOutApply.getProductLineId());
        transTask.setCurStationId(mesOutApply.getStationId());
        transTask.setNextProcess(mesOutApply.getProductLineId());
        transTask.setNextStationId(mesOutApply.getNextStationId());
        transTask.setQty(1);
        transTask.setProductLineId(mesOutApply.getProductLineId());
        transTask.setDjNo(mesOutApply.getDjNo());
        transTask.setOperateType(1);
        transTask.setAgvFactory(1);
        JSONObject sendAgvTask = submitTask(transTask);
        if ("1".equals(sendAgvTask.getString("Success"))) {
            // 新接驳点状态
            if (basStation != null) {
                basStation.setModiTime(new Date());
                basStation.setLocSts("S");
                basStation.setBarcode(mesOutApply.getDjNo());
                basStationService.updateById(basStation);
            }
        return 1;
    }
    public int transDj(String taskNo,String djNo) {
        try {
            EntityWrapper<Task> wapper = new EntityWrapper<>();
            wapper.eq("task_no", taskNo).orderBy("wrk_date");
            Task task = taskService.selectOne(wapper);
            if (task != null) {
                JSONObject memo = JSONObject.parseObject(task.getMemo());
                TransTask transTask = new TransTask();
                transTask.setTaskno(taskNo + "_1");
//                        transTask.setTaskname(mesOutApply.getTaskname());
                transTask.setOrderNo(memo.getString("OrderNo"));
                transTask.setTransType("05");    //送刀时默认05(上刀)
                transTask.setCurStationId(WMS_TRANS_START_STATION_1);
                transTask.setNextProcess(memo.getString("ProductLineId"));
                transTask.setNextStationId(memo.getString("CurStationId"));
//                transTask.setItemno(mesOutApply.getItemNo());
//                transTask.setQty(0);
                transTask.setProductLineId(memo.getString("ProductLineId"));
//                        transTask.setItemBarcode(codes);
//                        transTask.setTuoPanId(entry.getKey());
                transTask.setOperateType(1);
                transTask.setAgvFactory(1);
                transTask.setDjNo(djNo);
                JSONObject sendAgvTask = submitTask(transTask);
                if (!"1".equals(sendAgvTask.getString("Success"))) {
                    log.error("上刀下发agv运输任务失败", JSONObject.toJSONString(transTask));
                }
            }
        } catch (Exception e) {
            log.error("上刀下发AGV运输任务失败", e);
            mesReturn.setSuccess("1");
            mesReturn.setMessage("订单下发成功,agv开始运输:" + transTask.getTaskno());
            return mesReturn;
        } else {
            log.error("出库下发agv运输任务失败:{}", JSONObject.toJSONString(transTask));
            throw new CoolException("出库下发agv运输任务失败");
        }
        return 1;
    }
    /**
@@ -710,7 +689,6 @@
    /**
     * 9.1下发运输任务
     * TODO:其他库的任务全部转到滑块库统一调度
     *
     * @param transTask
     * @return
@@ -734,7 +712,11 @@
        // 下发给RCS
        RcsTaskSubmit rcsTaskSubmit = new RcsTaskSubmit();
        // 模板名
        rcsTaskSubmit.setTaskType("CS");
        if(transTask.getCurStationId().startsWith("LL") || transTask.getCurStationId().startsWith("LG")) { // 起点产线
            rcsTaskSubmit.setTaskType("DJ1");
        } else if(transTask.getNextStationId().startsWith("LL") || transTask.getNextStationId().startsWith("LG")) { // 终点产线
            rcsTaskSubmit.setTaskType("DJ2");
        }
        rcsTaskSubmit.setRobotTaskCode(transTask.getTaskno());
        rcsTaskSubmit.setInitPriority(10);  //默认10
        List<RcsTaskTargetRoute> targetRouteList = new ArrayList<>();
@@ -990,51 +972,47 @@
        return 0;
    }
    @Resource
    private LocDetlService locDetlService;
    @Resource
    private LocMastService locMastService;
    @Override
    public R tkt(String taskNo) {
        boolean flag = false;
        try {
            EntityWrapper<Task> wapper = new EntityWrapper<>();
            wapper.eq("task_no", taskNo).orderBy("wrk_date",false);
            Task task = taskService.selectOne(wapper);
            // 下发给RCS
            RcsTaskSubmit rcsTaskSubmit = new RcsTaskSubmit();
            rcsTaskSubmit.setRobotTaskCode(taskNo + "-1");
            rcsTaskSubmit.setInitPriority(10);  //默认10
            List<RcsTaskTargetRoute> targetRouteList = new ArrayList<>();
            RcsTaskTargetRoute startRoute = new RcsTaskTargetRoute();
            startRoute.setSeq(0);
            startRoute.setCode(task.getStaNo());
            startRoute.setOperation("COLLECT");
            targetRouteList.add(startRoute);
            RcsTaskTargetRoute endRoute = new RcsTaskTargetRoute();
            endRoute.setSeq(1);
            endRoute.setCode(task.getSourceStaNo());
            endRoute.setOperation("DELIVERY");
            targetRouteList.add(endRoute);
            rcsTaskSubmit.setTargetRoute(targetRouteList);
            // 更新起点和终点
            String memo = task.getMemo();
            TransTask transTask = JSONObject.parseObject(memo, TransTask.class);
            transTask.setCurStationId(task.getSourceStaNo());
            transTask.setNextStationId(task.getStaNo());
            transTask.setTransType("01"); // 下空托
            // 更新agv任务起点和终点
            task.setTaskNo(taskNo + "-1");
            task.setSourceStaNo(transTask.getCurStationId());
            task.setStaNo(transTask.getNextStationId());
            task.setMemo(JSONObject.toJSONString(transTask));
            taskService.updateById(task);
            // 转发给海康或华晓RCS
            RcsReturn rcsReturn = rcsService.submitTask(rcsTaskSubmit, transTask.getAgvFactory());
            if (rcsReturn.getCode().equals("SUCCESS")) {
                flag = true;
            }
        } catch (Exception e) {
            log.error("空托回产线发AGV运输任务失败", e);
    public R queryStock(String matnr) {
        List<LocDetl> locDetls;
        if (Cools.isEmpty(matnr)) {
            locDetls = locDetlService.selectList(new EntityWrapper<>());
        } else {
            locDetls = locDetlService.selectList(new EntityWrapper<LocDetl>().eq("matnr",matnr));
        }
        return flag ?R.ok() : R.parse("空托回产线呼叫agv失败");
        List<String> locNoList = locDetls.stream().map(LocDetl::getLocNo).distinct().collect(Collectors.toList());
        List<DtLocDetailVo> dtLocDetailVoList = new ArrayList<>();
        for (String locNo: locNoList) {
            LocMast locMast = locMastService.selectById(locNo);
            DtLocDetailVo dtLocDetailVo = new DtLocDetailVo();
            dtLocDetailVo.setLocNo(locNo);
            dtLocDetailVo.setLocSts(locMast.getLocSts());
            dtLocDetailVo.setRow1(locMast.getRow1());
            dtLocDetailVo.setBay1(locMast.getBay1());
            dtLocDetailVo.setLev1(locMast.getLev1());
            List<LocDetl> locDetlList2 = locDetls.parallelStream().filter(o-> o.getLocNo().equals(locNo)).collect(Collectors.toList());
            List<StockDetl> stockDetls = new ArrayList<>();
            for(LocDetl locDetl:locDetlList2) {
                StockDetl stockDetl = new StockDetl();
                stockDetl.setMatnr(locDetl.getMatnr());
                stockDetl.setMaktx(locDetl.getMaktx());
                stockDetl.setAnfme(locDetl.getAnfme());
                stockDetls.add(stockDetl);
            }
            dtLocDetailVo.setLocDetl(stockDetls);
            dtLocDetailVoList.add(dtLocDetailVo);
        }
        return R.ok(dtLocDetailVoList);
    }
    // endregion
@@ -1047,8 +1025,9 @@
     */
    private int checkRcsFactory(String agvNo) {
        AgvInfo agvInfo = agvInfoMapper.selectById(agvNo);
        return agvInfo.getAgvFactory();
//        AgvInfo agvInfo = agvInfoMapper.selectById(agvNo);
//        return agvInfo.getAgvFactory();
        return 1;
    }
}
src/main/java/com/zy/asrs/service/impl/MobileServiceImpl.java
@@ -4,6 +4,7 @@
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.core.common.*;
import com.core.exception.CoolException;
import com.zy.asrs.entity.*;
@@ -30,10 +31,12 @@
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
@@ -123,6 +126,102 @@
    @Resource
    private RcsService rcsService;
    @Override
    @Transactional
    public R emptyBoxOutbound(int count, Long userId) {
        List<LocMast> locMastList = locMastService.selectList(new EntityWrapper<LocMast>().setSqlSelect("TOP " + count + " *").eq("loc_sts", "D").eq("frozen", 0).orderBy("lev1").orderBy("bay1").orderBy("row1"));
        if (locMastList.size() < count) {
            return R.parse("空料箱数量不足(或冻结),剩余数量:" + locMastList.size());
        }
        for (LocMast locMast : locMastList) {
            // 获取工作号
            int workNo = commonService.getWorkNo(WorkNoType.PAKOUT.type);
            Date now = new Date();
            // 保存工作档
            WrkMast wrkMast = new WrkMast();
            wrkMast.setWrkNo(workNo);
            wrkMast.setIoTime(now);
            wrkMast.setWrkSts(11L); // 工作状态:11.生成出库ID
            wrkMast.setIoType(110); // 入出库状态: 110.空板出库
            wrkMast.setIoPri(10D);
            wrkMast.setSourceStaNo("101"); // 源站
            wrkMast.setStaNo("103"); // 目标站
            wrkMast.setCrnNo(locMast.getCrnNo());
            wrkMast.setSourceLocNo(locMast.getLocNo()); // 源库位
            wrkMast.setBarcode(locMast.getBarcode());
            wrkMast.setFullPlt("N"); // 满板:Y
            wrkMast.setPicking("N"); // 拣料
            wrkMast.setExitMk("N"); // 退出
            wrkMast.setEmptyMk("Y"); // 空板
            wrkMast.setLinkMis("N");
            wrkMast.setAppeUser(userId);
            wrkMast.setAppeTime(now);
            wrkMast.setModiUser(userId);
            wrkMast.setModiTime(now);
            wrkMastService.insert(wrkMast);
            locMast.setLocSts("R");
            locMast.setModiUser(userId);
            locMast.setModiTime(now);
            if (!locMastService.updateById(locMast)) {
                throw new CoolException("更新库位状态失败");
            }
        }
        return R.ok("出库成功");
    }
    @Value("${wcs-slave.url}")
    private String WCS_URL;
    @Override
    public R inboundStart(int type) {
//        BasDevp basDevp = basDevpService.selectOne(new EntityWrapper<BasDevp>().eq("dev_no", 103));
//        if (!basDevp.getAutoing().equals("Y") || !basDevp.getLoading().equals("Y")) {
//            return R.parse("站点103不是自动/有物状态");
//        }
        Map<String,Object> params = new HashMap<>();
        params.put("siteId",103);
        int wrkNo = type == 1 ? 9998 : 9997;
        params.put("workNo",wrkNo);
        params.put("staNo", 104);
        params.put("pakMk","Y");
        String response;
        boolean success = false;
        String message = "";
        try {
            HashMap<String, Object> headers = new HashMap<>();
            headers.put("token","1");
            response = new HttpHandler.Builder()
                    .setUri(WCS_URL)
                    .setPath("/site/detl/update")
//                    .setHeaders(headers)
                    .setParams(params)
                    .build()
                    .doPost();
            if (Cools.isEmpty(response)) {
                log.error("入库启动调用wcs给输送线下命令失败,返回值为空");
            } else {
                JSONObject jsonObject = JSONObject.parseObject(response);
                if(jsonObject.getInteger("code").equals(200)) {
                    success = true;
                    log.info("入库启动调用wcs给输送线下命成功,wrkNo:{}",wrkNo);
                } else {
                    message = String.valueOf(jsonObject.getString("msg"));
                    log.error("入库启动调用wcs给输送线下命令失败:{}",message);
                }
            }
        } catch (IOException e) {
            log.error("入库启动调用wcs给输送线下命令异常:{}",e.getMessage());
            message = e.getMessage();
            e.printStackTrace();
        }
        return success ? R.ok("下发成功") : R.parse(message);
    }
    @Override
    @Transactional
    public R djReturn(String djNo) {
@@ -140,7 +239,7 @@
            TransTask transTask = JSONObject.parseObject(task.getMemo(), TransTask.class);
            transTask.setTaskno(task.getTaskNo());
            transTask.setCurStationId(sourceStaNo);
            transTask.setCurStationId(task.getSourceStaNo());
            transTask.setNextStationId(task.getStaNo());
            if(transTask.getTransType().equals("06")) {
                transTask.setTransType("01");
@@ -156,7 +255,7 @@
            // 下发给RCS
            RcsTaskSubmit rcsTaskSubmit = new RcsTaskSubmit();
            // 模板名
            rcsTaskSubmit.setTaskType("CS");
            rcsTaskSubmit.setTaskType("DJ2");
            rcsTaskSubmit.setRobotTaskCode(transTask.getTaskno());
            rcsTaskSubmit.setInitPriority(10);  //默认10
            List<RcsTaskTargetRoute> targetRouteList = new ArrayList<>();
src/main/java/com/zy/asrs/service/impl/RcsServiceImpl.java
@@ -4,9 +4,9 @@
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.core.common.Cools;
import com.zy.asrs.entity.*;
import com.zy.asrs.entity.mes.TransArrivalStation;
import com.zy.asrs.entity.mes.TransParent;
import com.zy.asrs.entity.mes.*;
import com.zy.asrs.entity.rcs.*;
import com.zy.asrs.enums.RcsRetMethodEnum;
import com.zy.asrs.mapper.BlockStationMapper;
@@ -23,6 +23,8 @@
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
@@ -40,6 +42,9 @@
    @Value("${mes.defaultUserId}")
    public long defaultUserId;
    @Value("${dj.url}")
    public String DJ_URL;
    @Resource
    private BasStationService basStationService;
@@ -55,6 +60,12 @@
    private TaskDetlServiceImpl taskDetlService;
    @Resource
    private WrkMastService wrkMastService;
    @Resource
    private WrkDetlService wrkDetlService;
    @Resource
    private OrderPakoutService orderPakoutService;
    // region 封锁区逻辑,目前只有一个大封锁区,任务全部转到滑块库处理,或直接写到滑块库
@@ -175,21 +186,23 @@
        String url = rcsFactory == 2 ? HX_URL : HIK_URL + "api/robot/controller/task/submit";
        String response = "";
        try {
            // 模拟返回
//            rcsReturn.setCode("SUCCESS");
//            success = true;
            response = sendPost(url, JSONObject.toJSONString(rcsTaskSubmit));
            if (!StringUtils.isEmpty(response) && response.contains("code")) {
                rcsReturn = JSONObject.parseObject(response, RcsReturn.class);
                if ("SUCCESS".equals(rcsReturn.getCode())) {
                    // 模拟返回
//            rcsReturn.setCode("SUCCESS");
//            JSONObject jsonObject = new JSONObject();
//            jsonObject.put("robotTaskCode","2025121301");
//            rcsReturn.setData(jsonObject);
                    success = true;
                    log.info("呼叫agv搬运成功!url:{};request:{};response:{}", url, JSON.toJSONString(rcsTaskSubmit), response);
                } else {
                    log.error("呼叫agv搬运失败!url:{};request:{};response:{}", url, JSON.toJSONString(rcsTaskSubmit), response);
                }
            } else {
                log.error("呼叫agv搬运失败,response:{}",response);
                rcsReturn.setCode("ERROR");
            }
        } catch (Exception e) {
            log.error("呼叫agv搬运异常", e);
@@ -314,11 +327,11 @@
                    switch (Objects.requireNonNull(RcsRetMethodEnum.getEnum(method))) {
                        case TASK_START: {
                            if (ioType == 1 || ioType == 10 || ioType == 53) {
                                wrkMast.setCrnStrTime(now);
                                wrkMast.setModiTime(now);
                                wrkMastService.updateById(wrkMast);
                            } else if (ioType == 101 || ioType == 110 || ioType == 103) {
                                wrkMast.setModiTime(now);
                                wrkMastService.updateById(wrkMast);
                            } else {
                                log.error("{}ioType{}不在end反馈处理中", wrkMast.getWrkNo(), ioType);
                            }
@@ -331,6 +344,44 @@
                                wrkMast.setModiTime(now);
                                wrkMastService.updateById(wrkMast);
                            } else if (ioType == 101 || ioType == 110 || ioType == 103) {
                                wrkMast.setWrkSts(14L);
                                wrkMast.setCrnEndTime(now);
                                wrkMast.setModiTime(now);
                                wrkMastService.updateById(wrkMast);
                                // 给TMS反馈出库货物信息
                                List<WrkDetl> wrkDetls = wrkDetlService.selectByWrkNo(wrkMast.getWrkNo());
                                if(!wrkDetls.isEmpty()) {
                                    WrkDetl wrkDetl = wrkDetls.get(0);
                                    String orderNo = wrkDetl.getOrderNo();
                                    if(!Cools.isEmpty(orderNo)) {
                                        OrderPakout orderPakout = orderPakoutService.selectByNo(orderNo);
                                        if (orderPakout != null) {
                                            MesInApply mesOutFeedback = new MesInApply();
                                            mesOutFeedback.setBillType(String.valueOf(orderPakout.getDocType()));
                                            mesOutFeedback.setOrderNo(orderNo);
                                            mesOutFeedback.setCreateTime( new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(now));
                                            List<MesItemDetails> details = new ArrayList<>();
                                            for(WrkDetl detl:wrkDetls) {
                                                MesItemDetails detail = new MesItemDetails();
                                                detail.setItemNo(detl.getMatnr());
                                                detail.setAnfme(detl.getAnfme());
                                                details.add(detail);
                                            }
                                            mesOutFeedback.setDetails(details);
                                            String url = DJ_URL + "api/OutboundOrder/WmsOutFinish";
                                            String request = JSONObject.toJSONString(mesOutFeedback);
                                            String response = RcsServiceImpl.sendPost(url, request);
                                            if (!StringUtils.isEmpty(response) && response.contains("Success")){
                                                MesReturn mesReturn = JSONObject.parseObject(response, MesReturn.class);
                                                if("1".equals(mesReturn.getSuccess())) {
                                                    log.info("CTU出库反馈end,上报TMS成功,工作号:{},明细:{}",wrkMast.getWrkNo(),request);
                                                } else {
                                                    log.error("CTU出库反馈end,上报TMS失败!,工作号:{},明细:{}",wrkMast.getWrkNo(),request);
                                                }
                                            }
                                        }
                                    }
                                }
                            } else {
                                log.error("{}ioType{}不在end反馈处理中", wrkMast.getWrkNo(), ioType);
@@ -393,7 +444,7 @@
                        task.setModiUser(defaultUserId);
                        taskService.updateById(task);
                        // 任务完成
                        mesService.reporterTask(rcsReporterTask);
//                        mesService.reporterTask(rcsReporterTask);
                        // 更新接驳位置状态
@@ -433,6 +484,15 @@
                            mesService.applyOutStation(apply);
                        } else if (RcsRetMethodEnum.ARRIVE_OFF_STATION.getCode().equals(method)) {
                            mesService.outStation(apply);
                            // agv继续执行
                            // 源站点是产线,离站完成后给rcs反馈继续执行
                            if(task.getSourceStaNo().contains("TOOL")) {
                                TransInOutStationAllow inOutStationAllow = new TransInOutStationAllow();
                                inOutStationAllow.setTaskno(robotTaskCode);
                                inOutStationAllow.setStatus("Y");
                                inOutStationAllow.setAgvCode(singleRobotCode);
                                mesService.allowOutStation(inOutStationAllow);
                            }
                        }
                    } break;
                    case ARRIVE_ON_STATION: {
src/main/java/com/zy/asrs/service/impl/WorkServiceImpl.java
@@ -468,6 +468,7 @@
            wrkDetl.setSpecs(orderDetl.getSpecs());
            wrkDetl.setModel(orderDetl.getModel());
            wrkDetl.setUnit(orderDetl.getUnit());
            wrkDetl.setThreeCode(String.valueOf(orderPakout.getDocType())); // 单据类型
            if (!wrkDetlService.insert(wrkDetl)) {
                throw new CoolException("保存工作档明细失败");
            }
@@ -598,6 +599,7 @@
            wrkMast.setWrkSts(11L); // 工作状态:11.生成出库ID
            wrkMast.setIoType(110); // 入出库状态: 110.空板出库
            wrkMast.setIoPri(10D);
            wrkMast.setBarcode(locMast.getBarcode());
            wrkMast.setSourceStaNo(sourceStaNo + ""); // 源站
            wrkMast.setStaNo(param.getOutSite() + ""); // 目标站
            wrkMast.setCrnNo(locMast.getCrnNo());
@@ -1007,14 +1009,16 @@
            Mat mat = matService.selectByMatnr(adjust.getMatnr());
            LocDetl locDetl = new LocDetl();
            locDetl.sync(mat);
            locDetl.setId(null);
            locDetl.setBatch(adjust.getBatch());
            locDetl.setLocNo(locMast.getLocNo());
            locDetl.setZpallet(locMast.getBarcode());
            locDetl.setZpallet(adjust.getZpallet());
            locDetl.setAnfme(adjust.getCount()); // 数量
            locDetl.setModiUser(userId); // 操作人员信息
            locDetl.setModiTime(now);
            locDetl.setAppeUser(userId);
            locDetl.setAppeTime(now);
            locDetl.setMemo("");
            if (!locDetlService.insert(locDetl)) {
                throw new CoolException("添加" + locDetl.getLocNo() + "库位," + locDetl.getMatnr() + "商品," + locDetl.getBatch() + "批号库存明细失败");
            }
@@ -1065,6 +1069,7 @@
        if (locMast.getLocSts().equals("D") || locMast.getLocSts().equals("O")) {
            if (count > 0) {
                locMast.setLocSts("F");
                locMast.setBarcode(list.get(0).getZpallet());
            }
        }
        locMast.setModiUser(userId);
@@ -1258,7 +1263,7 @@
        // 获取目标站
        Wrapper<StaDesc> wrapper = new EntityWrapper<StaDesc>()
                .eq("type_no", wrkMast.getIoType() - 50)
                .eq("stn_no", wrkMast.getStaNo()) // 作业站点 = 拣料出库的目标站
                .eq("stn_no", 104) // 作业站点 = 拣料出库的目标站
                .eq("crn_no", wrkMast.getCrnNo()); // 堆垛机号
        StaDesc staDesc = staDescService.selectOne(wrapper);
        if (Cools.isEmpty(staDesc)) {
@@ -1270,8 +1275,8 @@
        // 更新工作档数据状态
        wrkMast.setIoType(wrkMast.getIoType() - 50); // 入出库类型: 103->53,104->54,107->57
        wrkMast.setWrkSts(2L); // 工作状态: 2.设备上走
        wrkMast.setSourceStaNo(wrkMast.getStaNo()); // 源站
        wrkMast.setStaNo(staNo + ""); // 目标站
        wrkMast.setSourceStaNo(staDesc.getStnNo$()); // 源站
        wrkMast.setStaNo(staDesc.getCrnStn$()); // 目标站
        wrkMast.setLocNo(wrkMast.getSourceLocNo()); // 目标库位 = 出库时的源库位
        wrkMast.setSourceLocNo(""); // 源库位清空
        wrkMast.setModiTime(now);
src/main/java/com/zy/asrs/task/JlerScheduler.java
@@ -1,7 +1,9 @@
package com.zy.asrs.task;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.zy.asrs.entity.OrderPakout;
import com.zy.asrs.entity.WrkMast;
import com.zy.asrs.service.OrderPakoutService;
import com.zy.asrs.service.WrkMastService;
import com.zy.asrs.task.handler.JlerHandler;
import org.springframework.scheduling.annotation.Scheduled;
@@ -24,6 +26,9 @@
    @Resource
    private WrkMastService wrkMastService;
    @Resource
    private OrderPakoutService orderPakoutService;
    /**
     * 货物到达入库口接驳位开始呼叫料箱机器人
     */
@@ -36,5 +41,31 @@
        }
    }
    /**
     * 根据出库订单自动生成出库任务
     */
    @Scheduled(cron = "0/8 * * * * ? ")
    private void autoGenerateOutTask() {
        OrderPakout orderPakout = orderPakoutService.selectOne(new EntityWrapper<OrderPakout>().eq("settle", 1));
        if (orderPakout == null) {
            return;
        }
        jlerHandler.autoGenerateOutTask(orderPakout);
    }
    /**
     * 根据出库任务自动呼叫料箱机器人搬运
     */
    @Scheduled(cron = "0/10 * * * * ? ")
    private void outboundCallBinRobot() {
        // 每次取3条
        List<WrkMast> wrkMastList = wrkMastService.selectList(new EntityWrapper<WrkMast>().setSqlSelect("TOP 3 *").eq("source_sta_no", 101).eq("wrk_sts", 11).orderBy("io_type"));
        for(WrkMast wrkMast:wrkMastList) {
            jlerHandler.outboundCallBinRobot(wrkMast);
        }
    }
}
src/main/java/com/zy/asrs/task/handler/JlerHandler.java
@@ -1,19 +1,27 @@
package com.zy.asrs.task.handler;
import com.zy.asrs.entity.WrkMast;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.core.common.Cools;
import com.core.common.R;
import com.core.exception.CoolException;
import com.zy.asrs.entity.*;
import com.zy.asrs.entity.rcs.RcsReturn;
import com.zy.asrs.entity.rcs.RcsTaskSubmit;
import com.zy.asrs.entity.rcs.RcsTaskTargetRoute;
import com.zy.asrs.service.RcsService;
import com.zy.asrs.service.WrkMastService;
import com.zy.asrs.service.*;
import com.zy.asrs.utils.OrderInAndOutUtil;
import com.zy.common.model.LocDto;
import com.zy.common.model.TaskDto;
import com.zy.common.model.enums.WorkNoType;
import com.zy.common.service.CommonService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.*;
/**
 * @author pang.jiabao
@@ -30,6 +38,30 @@
    @Resource
    private RcsService rcsService;
    @Resource
    private OrderPakoutService orderPakoutService;
    @Resource
    private OrderDetlPakoutService orderDetlPakoutService;
    @Resource
    private LocDetlService locDetlService;
    @Resource
    private LocMastService locMastService;
    @Resource
    private StaDescService staDescService;
    @Value("${mes.defaultUserId}")
    public long defaultUserId;
    @Resource
    private CommonService  commonService;
    @Resource
    private WrkDetlService wrkDetlService;
    @Transactional
    public void callAgvToWarehouse(WrkMast wrkMast) {
@@ -42,7 +74,7 @@
        List<RcsTaskTargetRoute> targetRouteList = new ArrayList<>();
        RcsTaskTargetRoute startRoute = new RcsTaskTargetRoute();
        startRoute.setSeq(0);
        startRoute.setCode("106");
        startRoute.setCode(wrkMast.getStaNo());
        startRoute.setOperation("COLLECT");
        startRoute.setType("SITE");
        targetRouteList.add(startRoute);
@@ -57,14 +89,218 @@
        // 转发给海康或华晓RCS
        RcsReturn rcsReturn = rcsService.submitTask(rcsTaskSubmit, 1);
        if (rcsReturn.getCode().equals("SUCCESS")) {
            Date now = new Date();
            wrkMast.setWrkSts(3L);
            wrkMast.setModiTime(new Date());
            wrkMast.setModiTime(now);
            wrkMast.setCrnStrTime(now);
            wrkMast.setTaskNo(rcsTaskSubmit.getRobotTaskCode());
            wrkMastService.updateById(wrkMast);
            log.info("入库给料箱机器人发送命令成功,工作号:{},任务号:{}",wrkMast.getWrkNo(),rcsTaskSubmit.getRobotTaskCode());
            log.info("出库给料箱机器人发送命令成功,工作号:{},任务号:{}",wrkMast.getWrkNo(),rcsTaskSubmit.getRobotTaskCode());
        } else {
            log.error("入库给料箱机器人发送命令失败,工作号:{},任务号:{}",wrkMast.getWrkNo(),rcsTaskSubmit.getRobotTaskCode());
            log.error("出库给料箱机器人发送命令失败,工作号:{},任务号:{}",wrkMast.getWrkNo(),rcsTaskSubmit.getRobotTaskCode());
        }
    }
    /**
     * 根据出库订单自动生成出库任务
     */
    @Transactional
    public void autoGenerateOutTask(OrderPakout orderPakout) {
        List<OrderDetlPakout> orderDetlPakouts = orderDetlPakoutService.selectByOrderId(orderPakout.getId());
        List<LocDto> locDtos = new ArrayList<>();
        Set<String> exist = new HashSet<>();
        for (OrderDetlPakout orderDetl : orderDetlPakouts) {
            double issued = Optional.of(orderDetl.getAnfme() - orderDetl.getWorkQty()).orElse(0.0D);
            if (issued <= 0.0D) {
                continue;
            }
            List<LocDetl> locDetls = locDetlService.queryStockAll(null, exist,orderDetl.getMatnr(), orderDetl.getBatch(),
                    orderDetl.getBrand(),orderDetl.getStandby1(),orderDetl.getStandby2(),orderDetl.getStandby3(),orderDetl.getBoxType1(),orderDetl.getBoxType2(),orderDetl.getBoxType3());
            for (LocDetl locDetl : locDetls) {
                if (issued > 0) {
                    LocDto locDto = new LocDto(locDetl.getLocNo(), locDetl.getMatnr(), locDetl.getMaktx(), locDetl.getBatch(), orderDetl.getOrderNo(),
                            issued >= locDetl.getAnfme() ? locDetl.getAnfme() : issued);
                    LocMast locMast = locMastService.selectOne(new EntityWrapper<LocMast>().eq("loc_no", locDetl.getLocNo()));
                    locDto.setFrozen(locDetl.getFrozen());
                    locDto.setFrozenLoc(locMast.getFrozen());
//                    List<Integer> staNos = staDescService.queryOutStaNosByLocNo(locDetl.getLocNo(), issued >= locDetl.getAnfme() ? 101 : 103);
//                    locDto.setStaNos(staNos);
                    locDto.setStaNo(103);
                    locDto.setBrand(orderDetl.getBrand());
                    locDto.setStandby1(orderDetl.getStandby1());
                    locDto.setStandby2(orderDetl.getStandby2());
                    locDto.setStandby3(orderDetl.getStandby3());
                    locDto.setBoxType1(orderDetl.getBoxType1());
                    locDto.setBoxType2(orderDetl.getBoxType2());
                    locDto.setBoxType3(orderDetl.getBoxType3());
                    locDtos.add(locDto);
                    exist.add(locDetl.getLocNo());
                    // 剩余待出数量递减
                    issued = issued - locDetl.getAnfme();
                } else {
                    break;
                }
            }
            if (issued > 0) {
                LocDto locDto = new LocDto(null, orderDetl.getMatnr(), orderDetl.getMaktx(), orderDetl.getBatch(), orderDetl.getOrderNo(), issued);
                locDto.setBrand(orderDetl.getBrand());
                locDto.setStandby1(orderDetl.getStandby1());
                locDto.setStandby2(orderDetl.getStandby2());
                locDto.setStandby3(orderDetl.getStandby3());
                locDto.setBoxType1(orderDetl.getBoxType1());
                locDto.setBoxType2(orderDetl.getBoxType2());
                locDto.setBoxType3(orderDetl.getBoxType3());
                locDto.setLack(Boolean.TRUE);
                locDtos.add(locDto);
            }
        }
        List<LocDto> locDtoArrayList = new ArrayList<>();
        //
        for (LocDto locDto : locDtos){
            if (locDto.getFrozen()!=1 && locDto.getFrozenLoc()!=1 && !locDto.isLack()){
                locDtoArrayList.add(locDto);
            } else {
                log.warn("库位/库存被冻结或库存不足:{}", JSONObject.toJSONString(locDto));
            }
        }
        locDtos = locDtoArrayList;
        List<TaskDto> taskDtos = new ArrayList<>();
        // 根据 (库位 & 出库站) 分组; 理想状态:一组为一次出库任务
        for (LocDto locDto : locDtos) {
            if (locDto.isLack()) { continue; }
            TaskDto taskDto = new TaskDto(locDto.getLocNo(), locDto.getStaNo(), locDto);
            if (TaskDto.has(taskDtos, taskDto)) {
                TaskDto dto = TaskDto.find(taskDtos, taskDto);
                assert dto != null;
                dto.getLocDtos().addAll(taskDto.getLocDtos());
            } else {
                taskDtos.add(taskDto);
            }
        }
        // -----------------------------------------------------------------------------------------------
        long userId = defaultUserId;
        for (TaskDto taskDto : taskDtos) {
            Date now = new Date();
            // 获取库位
            LocMast locMast = locMastService.selectById(taskDto.getLocNo());
            int ioType = taskDto.isAll() ? 101 : 103;
            // 生成工作号
            int workNo = commonService.getWorkNo(WorkNoType.getWorkNoType(ioType));
            // 生成工作档
            WrkMast wrkMast = new WrkMast();
            wrkMast.setWrkNo(workNo);
            wrkMast.setIoTime(now);
            wrkMast.setWrkSts(11L); // 工作状态:11.生成出库ID
            wrkMast.setIoType(ioType); // 入出库状态
            wrkMast.setIoPri(13D); // 优先级:13
            wrkMast.setCrnNo(locMast.getCrnNo());
            wrkMast.setSourceStaNo("101"); // 源站
            wrkMast.setStaNo("103"); // 目标站
            wrkMast.setSourceLocNo(taskDto.getLocNo()); // 源库位
            wrkMast.setFullPlt("Y"); // 满板:Y
            wrkMast.setPicking("N"); // 拣料
            wrkMast.setExitMk("N"); // 退出
            wrkMast.setEmptyMk("N"); // 空板
            wrkMast.setLinkMis("N");
            wrkMast.setBarcode(locMast.getBarcode());
            wrkMast.setAppeUser(userId); // 操作人员数据
            wrkMast.setAppeTime(now);
            wrkMast.setModiUser(userId);
            wrkMast.setModiTime(now);
            if (!wrkMastService.insert(wrkMast)) {
                throw new CoolException("保存工作档失败,出库库位号:" + taskDto.getLocNo());
            }
            // 生成工作档明细
            for (LocDto locDto : taskDto.getLocDtos()) {
                if (locDto.getAnfme() == null || locDto.getAnfme() <= 0.0D) {
                    continue;
                }
                OrderDetl orderDetl = OrderInAndOutUtil.selectItem(Boolean.FALSE, locDto.getOrderNo(), locDto.getMatnr(), locDto.getBatch(), locDto.getBrand()
                        , locDto.getStandby1(), locDto.getStandby2(), locDto.getStandby3(), locDto.getBoxType1(), locDto.getBoxType2(), locDto.getBoxType3());
                WrkDetl wrkDetl = new WrkDetl();
                wrkDetl.sync(orderDetl);
                wrkDetl.setZpallet(wrkMast.getBarcode());
                wrkDetl.setIoTime(now);
                wrkDetl.setWrkNo(workNo);
                wrkDetl.setBatch(locDto.getBatch());
                wrkDetl.setOrderNo(locDto.getOrderNo());
                wrkDetl.setAnfme(locDto.getAnfme()); // 数量
                wrkDetl.setAppeTime(now);
                wrkDetl.setAppeUser(userId);
                wrkDetl.setModiTime(now);
                wrkDetl.setModiUser(userId);
                wrkDetl.setMatnr(orderDetl.getMatnr());
                wrkDetl.setMaktx(orderDetl.getMaktx());
                wrkDetl.setSpecs(orderDetl.getSpecs());
                wrkDetl.setModel(orderDetl.getModel());
                wrkDetl.setUnit(orderDetl.getUnit());
                wrkDetl.setThreeCode(String.valueOf(orderPakout.getDocType())); // 单据类型,rcs反馈end到wcs时给tms上报用
                if (!wrkDetlService.insert(wrkDetl)) {
                    throw new CoolException("保存工作档明细失败");
                }
                OrderInAndOutUtil.increaseWorkQty(Boolean.FALSE, orderDetl.getOrderId(), orderDetl.getMatnr(), orderDetl.getBatch(),
                        orderDetl.getBrand(), orderDetl.getStandby1(), orderDetl.getStandby2(), orderDetl.getStandby3(),
                        orderDetl.getBoxType1(), orderDetl.getBoxType2(), orderDetl.getBoxType3()
                        , locDto.getAnfme());
                log.info("根据订单自动生成出库任务成功【工作号:{},订单号:{},物料:{},数量:{}】",workNo,locDto.getOrderNo(),locDto.getMatnr(),locDto.getAnfme());
            }
            // 修改库位状态:   F.在库 ====>>> R.出库预约/P.拣料/盘点/并板出库中
            locMast = locMastService.selectById(taskDto.getLocNo());
            if (locMast.getLocSts().equals("F")) {
                locMast.setLocSts(ioType == 101 ? "R" : "P");
                locMast.setModiUser(userId);
                locMast.setModiTime(now);
                if (!locMastService.updateById(locMast)) {
                    throw new CoolException("预约库位状态失败,库位号:" + taskDto.getLocNo());
                }
            } else {
                throw new CoolException(taskDto.getLocNo() + "库位不是在库状态");
            }
        }
        OrderInAndOutUtil.updateOrder(Boolean.FALSE, orderPakout.getId(), 2L, userId);
    }
    public void outboundCallBinRobot(WrkMast wrkMast) {
        // 下发给RCS
        RcsTaskSubmit rcsTaskSubmit = new RcsTaskSubmit();
        // 模板名
        rcsTaskSubmit.setTaskType("F11");
        rcsTaskSubmit.setRobotTaskCode(String.valueOf(new Date().getTime()));
        rcsTaskSubmit.setInitPriority(10);  //默认10
        List<RcsTaskTargetRoute> targetRouteList = new ArrayList<>();
        RcsTaskTargetRoute startRoute = new RcsTaskTargetRoute();
        startRoute.setSeq(0);
        startRoute.setCode(wrkMast.getSourceLocNo());
        startRoute.setOperation("COLLECT");
        startRoute.setType("STORAGE");
        targetRouteList.add(startRoute);
        RcsTaskTargetRoute endRoute = new RcsTaskTargetRoute();
        endRoute.setSeq(1);
        endRoute.setCode(wrkMast.getSourceStaNo());
        endRoute.setOperation("DELIVERY");
        endRoute.setType("SITE");
        targetRouteList.add(endRoute);
        rcsTaskSubmit.setTargetRoute(targetRouteList);
        // 转发给海康或华晓RCS
        RcsReturn rcsReturn = rcsService.submitTask(rcsTaskSubmit, 1);
        if (rcsReturn.getCode().equals("SUCCESS")) {
            Date now = new Date();
            wrkMast.setWrkSts(12L);
            wrkMast.setModiTime(now);
            wrkMast.setCrnStrTime(now);
            wrkMast.setTaskNo(rcsTaskSubmit.getRobotTaskCode());
            wrkMastService.updateById(wrkMast);
            log.info("出库给料箱机器人发送命令成功,工作号:{},任务号:{}",wrkMast.getWrkNo(),rcsTaskSubmit.getRobotTaskCode());
        } else {
            log.error("出库给料箱机器人发送命令失败,工作号:{},任务号:{}",wrkMast.getWrkNo(),rcsTaskSubmit.getRobotTaskCode());
        }
    }
}
src/main/java/com/zy/asrs/task/handler/WorkMastHandler.java
@@ -253,19 +253,19 @@
                        }
                        // 更新订单完成数量
                        OrderDetlPakin orderDetlPakin = orderDetlPakinService.selectItem
                        OrderDetlPakout orderDetlPakout = orderDetlPakoutService.selectItem
                                (wrkDetl.getOrderNo(), wrkDetl.getMatnr(), wrkDetl.getBatch(), wrkDetl.getBrand(),
                                        wrkDetl.getStandby1(), wrkDetl.getStandby2(), wrkDetl.getStandby3(),
                                        wrkDetl.getBoxType1(), wrkDetl.getBoxType2(), wrkDetl.getBoxType3());
                        if (orderDetlPakin == null) {
                            orderDetlPakin = orderDetlPakinService.selectItem
                        if (orderDetlPakout == null) {
                            orderDetlPakout = orderDetlPakoutService.selectItem
                                    (wrkDetl.getOrderNo(), wrkDetl.getMatnr(), wrkDetl.getBatch(), wrkDetl.getBrand(), wrkDetl.getStandby1(), wrkDetl.getStandby2(), wrkDetl.getStandby3(),
                                            wrkDetl.getBoxType1(), wrkDetl.getBoxType2(), wrkDetl.getBoxType3());
                        }
                        try {
                            if (!Cools.isEmpty(orderDetlPakin)) {
                                if (!orderDetlPakinService.increaseQtyByOrderNo(wrkDetl.getOrderNo(), wrkDetl.getMatnr(),
                                        orderDetlPakin.getBatch(), wrkDetl.getBrand(), wrkDetl.getStandby1(), wrkDetl.getStandby2(), wrkDetl.getStandby3(),
                            if (!Cools.isEmpty(orderDetlPakout)) {
                                if (!orderDetlPakoutService.increaseQtyByOrderNo(wrkDetl.getOrderNo(), wrkDetl.getMatnr(),
                                        orderDetlPakout.getBatch(), wrkDetl.getBrand(), wrkDetl.getStandby1(), wrkDetl.getStandby2(), wrkDetl.getStandby3(),
                                        wrkDetl.getBoxType1(), wrkDetl.getBoxType2(), wrkDetl.getBoxType3(), wrkDetl.getAnfme())) {
//                                    exceptionHandle("拣料入库 ===>> 更新订单完成数量失败;[workNo={0}],[locNo={1}]",
//                                            wrkMast.getWrkNo(), wrkMast.getLocNo());
src/main/java/com/zy/common/config/ControllerResAdvice.java
@@ -3,6 +3,7 @@
import com.alibaba.fastjson.JSON;
import com.core.common.Cools;
import com.core.common.R;
import com.zy.asrs.entity.mes.MesReturn;
import com.zy.asrs.service.ApiLogService;
import com.zy.common.utils.IpTools;
import lombok.extern.slf4j.Slf4j;
@@ -59,6 +60,21 @@
                        );
                    }
                }
                if (o instanceof MesReturn) {
                    MesReturn mesReturn = (MesReturn) o;
                    String appkey = request.getHeader("appkey");
                    Object reqCache = request.getAttribute("cache");
                    // 保存接口日志
                    apiLogService.save(
                            String.valueOf(appAuth),
                            request.getRequestURI(),
                            appkey,
                            IpTools.gainRealIp(request),
                            reqCache==null?"": JSON.toJSONString(reqCache),
                            JSON.toJSONString(o),
                            String.valueOf(mesReturn.getSuccess()).equalsIgnoreCase("1")
                    );
                }
            }
        }
        return o;
src/main/java/com/zy/common/model/LocDto.java
@@ -35,9 +35,9 @@
    /**
     * 是否冻结  "是否冻结,0.未冻结,1.已冻结"
     */
    private Integer frozen = 1;
    private Integer frozen = 0;
    private Integer frozenLoc = 1;
    private Integer frozenLoc = 0;
//    private Integer frozen$;
src/main/java/com/zy/common/web/AuthController.java
@@ -53,39 +53,37 @@
    @Autowired
    private LoadingConfigTimer loadingConfigTimer;
    @PostMapping("/login.action")
    @RequestMapping("/login.action")
    @ManagerAuth(value = ManagerAuth.Auth.NONE, memo = "登录")
    public R loginAction(@RequestBody Map<String, String> param) {
    public R loginAction(String username, String password){
        //验证许可证是否有效
        if (!licenseTimer.getSystemSupport()) {
        if (!licenseTimer.getSystemSupport()){
            return R.parse(CodeRes.SYSTEM_20001);
        }
        if (username.equals("super") && password.equals(Cools.md5(superPwd))) {
            Map<String, Object> res = new HashMap<>();
            res.put("username", username);
            res.put("token", Cools.enToken(System.currentTimeMillis() + username, superPwd));
            return R.ok(res);
        }
        EntityWrapper<User> userWrapper = new EntityWrapper<>();
        userWrapper.eq("username", param.get("username"));
        userWrapper.eq("username", username);
        User user = userService.selectOne(userWrapper);
        if (Cools.isEmpty(user)) {
            if (param.get("username").equals("super") && param.get("password").equals(Cools.md5(superPwd))) {
                Map<String, Object> res = new HashMap<>();
                res.put("username", param.get("username"));
                res.put("token", Cools.enToken(System.currentTimeMillis() + param.get("username"), superPwd));
                return R.ok(res);
            }
        if (Cools.isEmpty(user)){
            return R.parse(CodeRes.USER_10001);
        }
        if (user.getStatus() != 1) {
        if (user.getStatus()!=1){
            return R.parse(CodeRes.USER_10002);
        }
        if (!user.getPassword().equals(param.get("password"))) {
        if (!user.getPassword().equals(password)){
            return R.parse(CodeRes.USER_10003);
        }
        String token = Cools.enToken(System.currentTimeMillis() + param.get("username"), user.getPassword());
        if (loadingConfigTimer.getTokenNumber() == 1) {
            userLoginService.delete(new EntityWrapper<UserLogin>().eq("user_id", user.getId()).eq("system", "WMS"));
        }        UserLogin userLogin = new UserLogin();
        String token = Cools.enToken(System.currentTimeMillis() + username, user.getPassword());
        userLoginService.delete(new EntityWrapper<UserLogin>().eq("user_id", user.getId()));
        UserLogin userLogin = new UserLogin();
        userLogin.setUserId(user.getId());
        userLogin.setToken(token);
        userLogin.setCreateTime(new Date());
        userLogin.setSystem("WMS");
        userLoginService.insert(userLogin);
        Map<String, Object> res = new HashMap<>();
        res.put("username", user.getUsername());
src/main/resources/application-dev.yml
@@ -58,6 +58,7 @@
# 下位机配置
wcs-slave:
  url: http://127.0.0.1:9090/djwcs
  # 双深
  doubleDeep: true
  # 双深库位排号
src/main/resources/mapper/LocDetlMapper.xml
@@ -544,22 +544,22 @@
        <include refid="batchSeqA"></include>
        <if test="locNos != null and locNos.size > 0">
            and b.loc_no not in
            <foreach item="item" collection="locNos" index="index"  separator="," open="(" close=")">
                #{item}
            </foreach>
        </if>
<!--        <if test="locNos != null and locNos.size > 0">-->
<!--            and b.loc_no not in-->
<!--            <foreach item="item" collection="locNos" index="index"  separator="," open="(" close=")">-->
<!--                #{item}-->
<!--            </foreach>-->
<!--        </if>-->
        order by
        DATEPART(yyyy,a.modi_time),DATEPART(mm,a.modi_time),DATEPART(dd,a.modi_time), a.anfme
        desc,
        NEWID(),
        order by a.modi_time,
--         DATEPART(yyyy,a.modi_time),DATEPART(mm,a.modi_time),DATEPART(dd,a.modi_time), a.anfme
--         desc,
--         NEWID(),
        case
        when (left(a.loc_no, 2) = '01') then 0
        when (left(a.loc_no, 2) = '01') then 1
        when (left(a.loc_no, 2) = '02') then 1
        when (left(a.loc_no, 2) = '03') then 1
        when (left(a.loc_no, 2) = '04') then 0
        when (left(a.loc_no, 2) = '04') then 1
        when (left(a.loc_no, 2) = '05') then 0
        when (left(a.loc_no, 2) = '06') then 1
        when (left(a.loc_no, 2) = '07') then 1
src/main/resources/mapper/WrkMastMapper.xml
@@ -70,7 +70,7 @@
        select * from asr_wrk_mast
        where wrk_sts=5
        or (wrk_sts=15 and ove_mk='Y' and wrk_no not in (select wrk_no from asr_bas_devp))
        or (wrk_sts=15 and dateadd(mi,1,crn_end_time) &lt;= getdate() and wrk_no not in (select wrk_no from asr_bas_devp))
        or (wrk_sts=15 and dateadd(second,10,crn_end_time) &lt;= getdate() and wrk_no not in (select wrk_no from asr_bas_devp))
        or (wrk_sts=15 and crn_end_time is null and wrk_no not in (select wrk_no from asr_bas_devp))
        order by io_time,wrk_no asc
    </select>
src/main/webapp/static/js/basStation/basStation.js
@@ -27,7 +27,7 @@
            , {field: 'area', align: 'center', title: '区域'}
            , {field: 'locSts$', align: 'center', title: '状态'}
            , {field: 'barcode', align: 'center', title: '刀架号'}
            , {field: 'ioTime', align: 'center', title: '入出库时间'}
            , {field: 'ioTime', align: 'center', title: '入出库时间',hide: true}
            , {field: 'modiUser$', align: 'center', title: '修改人员'}
            , {field: 'modiTime$', align: 'center', title: '修改时间'}
            , {field: 'appeUser$', align: 'center', title: '创建者',hide: true}
src/main/webapp/static/js/pakStore/stockAdjust.js
@@ -8,9 +8,11 @@
        {fixed: 'left', field: 'count', title: '实际数量', align: 'center', edit:'text', width: 120,  style:'color: blue;font-weight: bold'}
        ,{field: 'anfme', align: 'center',title: '数量'}
        ,{field: 'batch', align: 'center',title: '批号(编辑)', edit: true, style: 'font-weight:bold'}
        ,{field: 'zpallet', align: 'center',title: '料箱码', edit: true, style: 'font-weight:bold'}
    ];
    arrRemove(detlCols, "field", "anfme");
    arrRemove(detlCols, "field", "batch");
    arrRemove(detlCols, "field", "zpallet");
    cols.push.apply(cols, detlCols);
    cols.push({fixed: 'right', title:'操作', align: 'center', toolbar: '#operate', width:80})
    return cols;
src/main/webapp/static/js/wrkMast/wrkMast.js
@@ -25,13 +25,14 @@
            ,{field: 'wrkSts$', align: 'center',title: '工作状态', width: 120}
            ,{field: 'ioType$', align: 'center',title: '入出库类型', width: 140}
            ,{field: 'ioPri', align: 'center',title: '优先级'}
            ,{field: 'taskType$', align: 'center',title: '任务类型'}
            ,{field: 'taskType$', align: 'center',title: '任务类型',hide: true}
            ,{field: 'barcode', align: 'center',title: '条码', width: 120}
            ,{field: 'crnNo$', align: 'center',title: '堆垛机'}
            ,{field: 'sourceStaNo$', align: 'center',title: '源站'}
            ,{field: 'staNo$', align: 'center',title: '目标站'}
            ,{field: 'sourceLocNo', align: 'center',title: '源库位', width: 120}
            ,{field: 'locNo', align: 'center',title: '目标库位', width: 120}
            ,{field: 'taskNo', align: 'center',title: 'CTU任务号',width: 150}
            ,{field: 'preHave', align: 'center',title: '先入品', hide: true}
            ,{field: 'takeNone', align: 'center',title: '空操作', hide: true}
            ,{field: 'modiUser$', align: 'center',title: '修改人员', hide:true}
src/main/webapp/views/basStation/basStation.html
@@ -89,6 +89,12 @@
                    </div>
                </div>
                <div class="layui-form-item">
                    <label class="layui-form-label">刀架号: </label>
                    <div class="layui-input-block">
                        <input class="layui-input" name="barcode" placeholder="请输入刀架号">
                    </div>
                </div>
                <div class="layui-form-item">
                    <label class="layui-form-label">区域:</label>
                    <div class="layui-input-block cool-auto-complete">
                        <input class="layui-input" name="areaId" placeholder="请选择库区" style="display: none">
src/main/webapp/views/locMast/locMast_detail.html
@@ -71,6 +71,12 @@
                </div>
            </div>
        </div>
        <div class="layui-inline"  style="width:80%;">
            <label class="layui-form-label">料箱码</label>
            <div class="layui-input-inline">
                <input id="barcode" class="layui-input" type="text" autocomplete="off">
            </div>
        </div>
        <div class="layui-inline"  style="width:31%;display: none">
            <label class="layui-form-label">:</label>
            <div class="layui-input-inline">
@@ -220,12 +226,7 @@
                <input id="mk" class="layui-input" type="text">
            </div>
        </div>
        <div class="layui-inline"  style="width:31%;display: none">
            <label class="layui-form-label">:</label>
            <div class="layui-input-inline">
                <input id="barcode" class="layui-input" type="text">
            </div>
        </div>
        <div class="layui-inline"  style="width:31%;display: none">
            <label class="layui-form-label">:</label>
            <div class="layui-input-inline">