#
Junjie
2025-04-29 5f1280f3724da083732e858dec95bd7f3d14c8f9
src/main/java/com/zy/asrs/controller/OpenController.java
@@ -3,35 +3,48 @@
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.BaseRes;
import com.core.common.Cools;
import com.core.common.R;
import com.core.exception.CoolException;
import com.zy.asrs.domain.dto.NotifyCustomDataDto;
import com.zy.asrs.domain.enums.NotifyMsgType;
import com.zy.asrs.domain.enums.TaskStatusType;
import com.zy.asrs.domain.enums.WorkNoType;
import com.zy.asrs.entity.*;
import com.zy.asrs.entity.param.TaskOverParam;
import com.zy.asrs.entity.param.WMSAndAGVInterfaceParam;
import com.zy.asrs.entity.param.taskCreateParam;
import com.zy.asrs.entity.param.*;
import com.zy.asrs.service.*;
import com.zy.asrs.utils.NotifyUtils;
import com.zy.asrs.utils.Utils;
import com.zy.common.service.CommonService;
import com.zy.common.utils.HttpHandler;
import com.zy.common.web.BaseController;
import com.zy.core.cache.MessageQueue;
import com.zy.core.enums.SlaveType;
import com.zy.core.model.Task;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.ReactiveRedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.text.SimpleDateFormat;
import java.util.*;
@Slf4j
@RestController
@RequestMapping("/open")
public class OpenController extends BaseController {
    @Value("${wms.url}")
    private String wmsUrl;
    @Value("${wms.inboundTaskApplyPath}")
    private String inboundTaskApplyPath;
    @Value("${wms.TaskExecCallback}")
    private String TaskExecCallback;
    @Autowired
    private OpenService openService;
@@ -42,61 +55,136 @@
    @Autowired
    private TaskWrkController taskWrkController;
    @Autowired
    private BasDevpService basDevpService;
    @Autowired
    private ApiLogService apiLogService;
    @Autowired
    private BasCrnpService basCrnpService;
    @Autowired
    private StaDescService staDescService;
    @Value("${wms.url}")
    private String wmsUrl;
    @Autowired
    private LocMastService locMastService;
    @Autowired
    private BasCrnErrorService basCrnErrorService;
    @Autowired
    private CommonService commonService;
    @Autowired
    private NotifyUtils notifyUtils;
    private static final boolean auth = true;
    public static final ArrayList<String> APP_KEY_LIST = new ArrayList<String>() {{
        add("ea1f0459efc02a79f046f982767939ae");
    }};
    //agv任务完成
    @PostMapping("/toAgvTaskOver")
    @AppAuth(memo = "agv任务完成接口")
    public R getAgvTaskOver(@RequestHeader String appkey,
                           @RequestBody TaskOverParam param,
                           HttpServletRequest request){
        auth(appkey, param, request);
        if (Cools.isEmpty(param)) {
            return R.parse(BaseRes.PARAM);
    @Autowired
    private ReactiveRedisTemplate reactiveRedisTemplate;
    private void auth(String appkey, Object obj, HttpServletRequest request) {
        log.info("{}接口被访问;appkey:{};请求数据:{}", request.getServletPath(), appkey, JSON.toJSONString(obj));
        request.setAttribute("cache", obj);
        if (Cools.isEmpty(appkey)) {
            throw new CoolException("认证失败,请确认appkey无误!");
        }
        if (Cools.isEmpty(param.getWharfCode())){
            return R.error("码头[wharfCode]不能为空");
        if (!APP_KEY_LIST.contains(appkey)) {
            throw new CoolException("认证失败,请确认appkey无误!");
        }
        if (Cools.isEmpty(param.getStatus())){
            return R.error("完成标记[status]不能为空");
        }
        openService.getAgvTaskOver(param);
        return R.ok();
    }
    //创建任务
    @PostMapping("/taskCreate")
    @Transactional
    public R taskCreate(@RequestHeader String appkey,
                          @RequestBody taskCreateParam param,
                          @RequestBody TaskCreateParam param,
                          HttpServletRequest request) {
        auth(appkey, param, request);
        if (Cools.isEmpty(param)) {
            return R.parse(BaseRes.PARAM);
        R result = null;
        try{
            if (Cools.isEmpty(param)) {
                result = R.parse(BaseRes.PARAM);
                return result;
            }
            if (Cools.isEmpty(param.getTaskNo())) {
                result = R.error("任务号[taskNo]不能为空");
                return result;
            }
            if (Cools.isEmpty(param.getIoType())) {
                result = R.error("任务类型[ioType]不能为空");
                return result;
            }
            if (Cools.isEmpty(param.getBarcode())) {
                result = R.error("条码[barcode]不能为空");
                return result;
            }
            String locNo=null;
            if (param.getIoType() == 1) {
                locNo = param.getTargetPoint();
            } else {
                locNo = param.getStartPoint();
            }
            try {
                LocMast locMast = locMastService.selectOne(new EntityWrapper<LocMast>()
                        .eq("loc_no", locNo).ne("loc_sts", "X"));
                if (Cools.isEmpty(locMast)) {
                    log.error("库位号不存在" + locNo);
                    result = R.error("库位号不存在" + locNo).add("库位号不存在" + locNo);
                    return result;
                }
            } catch (Exception e) {
                log.error("库位号检测程序异常==》异常信息" + e);
                result = R.error("库位号检测程序异常").add("库位号检测程序异常==》异常信息" + e);
                return result;
            }
            LocMast locMast = locMastService.selectOne(new EntityWrapper<LocMast>()
                    .eq("loc_sts", "F")
                    .eq("loc_no", locNo)
                    .eq("barcode", param.getBarcode()));
            if(Cools.isEmpty(locMast)){
                result = R.error("该库位不满足出库条件" + param.getTargetPoint());
                return result;
            }
            result = openService.taskCreate(param);
            return result;
        }catch (Exception e){
            log.error("任务下发异常" + e);
            return R.error();
        }finally {
            apiLogService.save("wms任务下发接口"
                    ,request.getRemoteAddr()+request.getRequestURI()
                    ,""
                    ,request.getRemoteAddr()
                    ,JSON.toJSONString(param)
                    ,JSON.toJSONString(result)
                    ,true
            );
        }
        if (Cools.isEmpty(param.getTaskNo())) {
            return R.error("任务号[taskNo]不能为空");
    }
    //创建入库任务
    @PostMapping("/taskCreateIn")
    @Transactional
    public R taskCreateIn(@RequestHeader String appkey,
                        @RequestBody TaskCreateInParam param,
                        HttpServletRequest request) {
        auth(appkey, param, request);
        try{
            if (Cools.isEmpty(param)) {
                return R.parse(BaseRes.PARAM);
            }
            if (Cools.isEmpty(param.getTaskNo())) {
                return R.error("任务号[taskNo]不能为空");
            }
            if (Cools.isEmpty(param.getIoType())) {
                return R.error("任务类型[ioType]不能为空");
            }
            if (Cools.isEmpty(param.getBarcode())) {
                return R.error("条码[barcode]不能为空");
            }
            return openService.taskCreateIn(param);
        }catch (Exception e){
            log.error("任务下发异常"+e);
        }
        if (Cools.isEmpty(param.getIoType())) {
            return R.error("任务类型[ioType]不能为空");
        }
        if (Cools.isEmpty(param.getBarcode())) {
            return R.error("条码[barcode]不能为空");
        }
        openService.taskCreate(param);
        return R.ok();
        return R.error();
    }
    //查询任务详情
@@ -127,218 +215,98 @@
        return R.ok().add(commandInfos);
    }
    private void auth(String appkey, Object obj, HttpServletRequest request) {
        log.info("{}接口被访问;appkey:{};请求数据:{}", request.getServletPath(), appkey, JSON.toJSONString(obj));
        request.setAttribute("cache", obj);
        if (Cools.isEmpty(appkey)) {
            throw new CoolException("认证失败,请确认appkey无误!");
        }
        if (!APP_KEY_LIST.contains(appkey)) {
            throw new CoolException("认证失败,请确认appkey无误!");
        }
    }
    //AGV请求入库码头接口
    @PostMapping("/targetWharfApply")
    @AppAuth(memo = "AGV请求入库码头接口")
    public R targetWharfApply(@RequestHeader String appkey,
                              @RequestBody WMSAndAGVInterfaceParam param,
                              HttpServletRequest request) throws IOException {
        auth(appkey,param,request);
        if (Cools.isEmpty(param)){
            return R.error("参数为空!");
        } else if (Cools.isEmpty(param.getTaskNo())){
            return R.error("工作号为空!");
        } else if (Cools.isEmpty(param.getContainerCode())){
            return R.error("托盘编码为空!");
        } else if (Cools.isEmpty(param.getWharfSource())){
            return R.error("源码头为空!");
        } else if (Cools.isEmpty(param.getFreeWharfs()) || param.getFreeWharfs().size()==0){
            return R.error("空闲的入库码头(AGV)为空!");
        }
        R r = openService.AgvToWCSToWms(param);
        apiLogService.save("AGV请求入库码头接口"
                ,request.getRemoteAddr()+request.getRequestURI()
                ,appkey
                ,request.getRemoteAddr()
                ,JSON.toJSONString(param)
                ,r.toString()
                ,true
        );
        return r;
    }
    //AGV请求动作接口
    @PostMapping("/agvTaskRequest")
    @AppAuth(memo = "AGV请求动作接口")
    public R agvTaskRequest(@RequestHeader String appkey,
                              @RequestBody WMSAndAGVInterfaceParam param,
                              HttpServletRequest request) {
        auth(appkey, param, request);
        if (Cools.isEmpty(param)){
            return R.error("参数为空!");
        } else if (Cools.isEmpty(param.getRequestType())){
            return R.error("请求类型为空!");
        } else if (Cools.isEmpty(param.getWharfCode())){
            return R.error("码头编号为空!");
        }
        Map<String,Integer> map = new HashMap<>();
        map.put("J-1101",102);map.put("J-1102",101);
        map.put("J-1103",106);map.put("J-1104",105);
        map.put("J-1105",110);map.put("J-1106",109);
        map.put("J-1107",114);map.put("J-1108",113);
        map.put("J-1109",118);map.put("J-1110",117);
        map.put("J-1111",122);map.put("J-1112",121);
        map.put("H-1102",300);map.put("H-1101",305);
        map.put("G-1102",400);map.put("G-1101",405);
//        StaDesc staDesc = staDescService.selectOne(new EntityWrapper<StaDesc>()
//                .eq("stn_desc", param.getWharfCode()));
//
//        if (Cools.isEmpty(staDesc)){
//            return R.error("程序报错,未查询到站点");
//        }
        if (Cools.isEmpty(map.get(param.getWharfCode()))){
            return R.error("未查询到站点");
        }
        BasDevp basDevp = basDevpService.selectById(map.get(param.getWharfCode()));
//        BasDevp basDevp = basDevpService.selectById(staDesc.getStnNo());
        if (basDevp.getAutoing().equals("Y") && (basDevp.getInEnable().equals("Y") || basDevp.getOutEnable().equals("Y"))){
            apiLogService.save("AGV请求入库码头接口"
                    ,request.getRemoteAddr()+request.getRequestURI()
                    ,appkey
                    ,request.getRemoteAddr()
                    ,JSON.toJSONString(param)
                    ,R.ok().toString()
                    ,true
            );
            return R.ok("可入");
        }else {
            apiLogService.save("AGV请求入库码头接口"
                    ,request.getRemoteAddr()+request.getRequestURI()
                    ,appkey
                    ,request.getRemoteAddr()
                    ,JSON.toJSONString(param)
                    ,R.error("站点状态不可入").toString()
                    ,true
            );
            return R.error("站点状态不可入");
        }
    }
    //任务下发接口
    @PostMapping("/outboundTaskSend")
    @Transactional
    public R outboundTaskSend(@RequestHeader String appkey,
                              @RequestBody List<WMSAndAGVInterfaceParam> params,
                              HttpServletRequest request) {
        auth(appkey, params, request);
        List<WMSAndAGVInterfaceParam> params1 =new ArrayList<>();
        for (WMSAndAGVInterfaceParam param:params){
                if (Cools.isEmpty(param)){
                    return R.error("参数为空!");
                } else if (Cools.isEmpty(param.getTaskNo())){
                    return R.error("任务号为空!");
                } else if (Cools.isEmpty(param.getTaskType())){
                    return R.error("任务类型为空!");
                } else if (Cools.isEmpty(param.getWarehouseId())){
                    return R.error("仓库标识为空!");
                }
                if (Cools.isEmpty(param.getTaskPriority())){
                    param.setTaskPriority(1);
                }
                if (Cools.isEmpty(param.getContainerCode())){
                    return R.error("容器编码(托盘码)为空!");
                }
                if (Cools.isEmpty(param.getEmptyContainer())){
                    return R.error("是否空托盘信号为空!");
                }
                if (!param.getTaskType().equals("YK")){
                    if (Cools.isEmpty(param.getTargetWharf())){
                        return R.error("目标码头区域为空!");//G开头=7车间,H开头=8层,J开头=9车间
                    }
                }
                StaDesc staDesc = new StaDesc();
                if (param.getTaskType().equals("CK") && param.getTargetWharf().contains("J")){
                    staDesc = staDescService.selectOne(new EntityWrapper<StaDesc>()
                            .eq("crn_no", param.getTaskTunnel()).eq("type_no",2).lt("crn_stn", 200));
                }else {
                    staDesc = staDescService.selectOne(new EntityWrapper<StaDesc>()
                            .eq("crn_no", param.getTaskTunnel()).eq("type_no",2).ge("crn_stn", 200));
                }
                param.setTargetLocationCode(staDesc.getStnNo().toString());
                R r = openService.taskCreate(new taskCreateParam(param));
                apiLogService.save("Wms任务下发接口"
                        ,request.getRemoteAddr()+request.getRequestURI()
                        ,appkey
                        ,request.getRemoteAddr()
                        ,JSON.toJSONString(param)
                        ,r.toString()
                        ,true
                );
                return r;
    public HashMap<String, Object> outboundTaskSend(@RequestBody TaskCreateParam param) {
        if (Cools.isEmpty(param)){
            return R.error("参数为空");
        }
        return null;
        if (param.getTaskNo() == null){
            return R.error("任务号为空");
        }
        if (param.getIoType() == null){
            return R.error("任务类型为空");
        }
        LocMast locMast = locMastService.selectByLocNo(param.getStartPoint());
        if(locMast == null){
            return R.error("初始库位无法找到");
        }
        if (!locMast.getLocSts().equals("F")) {
            return R.error("库位不处于在库状态");
        }
        R result = null;
        if(param.getIoType() == 1){
            //出库任务创建
            StaDesc staDesc = staDescService.selectOne(new EntityWrapper<StaDesc>()
                    .eq("type_no", 2)
                    .eq("crn_no", locMast.getCrnNo())
                    .eq("stn_no", param.getTargetPoint()));
            if(Cools.isEmpty(staDesc)){
                return R.error("出库路径不存在");
            }
            param.setIoType(2);
            result = openService.taskCreate(param);
        }
        apiLogService.save("wms任务下发接口"
                ,request.getRemoteAddr()+request.getRequestURI()
                ,""
                ,request.getRemoteAddr()
                ,JSON.toJSONString(param)
                ,JSON.toJSONString(result)
                ,true
        );
        return result;
    }
    //任务取消接口
    @PostMapping("/taskCancel")
    public R taskCancel(@RequestHeader String appkey,
                               @RequestBody WMSAndAGVInterfaceParam param,
                               @RequestBody TaskCancelParam param,
                               HttpServletRequest request) {
        if (Cools.isEmpty(param)){
        auth(appkey, param, request);
        if (Cools.isEmpty(param)) {
            return R.error("参数为空!");
        } else if (Cools.isEmpty(param.getTaskNo())){
        } else if (Cools.isEmpty(param.getTaskNo())) {
            return R.error("工作号为空!");
        } else if (Cools.isEmpty(param.getTaskStatus())){
        } else if (Cools.isEmpty(param.getIoType())) {
            return R.error("操作类型为空!");
        } else if (Cools.isEmpty(param.getBarcode())) {
            return R.error("托盘码不能为空!");
        }
//        else if (Cools.isEmpty(param.getWarehouseId())){
//            return R.error("仓库标识为空!");
//        }
        TaskWrk taskWrk = taskWrkService.selectOne(new EntityWrapper<TaskWrk>().eq("task_no", param.getTaskNo()));
        TaskWrk taskWrk = taskWrkService.selectOne(new EntityWrapper<TaskWrk>()
                .eq("task_no", param.getTaskNo())
                .eq("io_type", param.getIoType())
                .eq("barcode", param.getBarcode()));
        if (Cools.isEmpty(taskWrk)){
            return R.error("未查到当前任务");
            return R.error("未查到当前任务---" + param);
        }
        boolean sign =false;
        switch (param.getTaskStatus()){
        switch (param.getTaskStatus()) {
            case 1://正常取消
                if (taskWrk.getWrkSts()>1){
                if (taskWrk.getStatus() > 1) {
                    return R.error("任务已开始执行");
                }
            case 2://强制取消
                if (taskWrk.getWrkSts()>3){
                    return R.error("任务已执行完成");
                }
                break;
            case 3://正常完成
                if (taskWrk.getWrkSts()>11){
            case 2://正常完成
                if (taskWrk.getStatus() > 1) {
                    return R.error("任务已开始执行");
                }
            case 4://强制完成
                if (taskWrk.getWrkSts()>14){
                    return R.error("任务已执行完成");
                }
                sign=true;
                sign = true;
                break;
            default:
                return R.error("未知操作");
        }
        return taskWrkOperate(taskWrk,sign);
        return taskWrkOperate(taskWrk, sign);
    }
    //任务操作
@@ -354,6 +322,150 @@
        }
    }
    //设备状态查询接口
    @GetMapping("/deviceStatus")
    @Transactional
    public R deviceStatus() {
        List<CrnStatusParam> crnStatusParams=new ArrayList<>();
        List<BasCrnp> basCrnps = basCrnpService.selectList(new EntityWrapper<>());
        for (BasCrnp basCrnp:basCrnps){
            CrnStatusParam crnStatusParam=new CrnStatusParam();
            crnStatusParam.setCrnNo(basCrnp.getCrnNo());
            crnStatusParam.setCrnSts(basCrnp.getCrnSts());
            crnStatusParam.setErrorCode(basCrnp.getCrnErr());
            BasCrnError error=basCrnErrorService.selectOne(new EntityWrapper<BasCrnError>().eq("error_code",basCrnp.getCrnErr()));
            if(Cools.isEmpty(error)){
                crnStatusParam.setErrorMsg("");
            }else {
                crnStatusParam.setErrorMsg(error.getErrName());
            }
            crnStatusParams.add(crnStatusParam);
        }
        return R.ok(crnStatusParams);
    }
    //模拟输送线入库
    @PostMapping("/simulationDevpIn")
    @Transactional
    public R simulationDevpIn(@RequestBody SimulationDevpInParam param) {
        String barcode = param.getBarcode();
        Integer staNo = param.getStaNo();
        Boolean back = param.getBack();
        String errMsg = param.getErrMsg();
        TaskWrk taskWrk1 = taskWrkService.selectOne(new EntityWrapper<TaskWrk>().eq("barcode", barcode));
        if (taskWrk1 != null) {
            log.info("托盘码:" + barcode + "任务档存在");
            return R.error();
        }
        HashMap<String, Object> requestParam = new HashMap<>();
        requestParam.put("barcode", barcode);//托盘码
        requestParam.put("stationCode", staNo);//入库口
        if (back) {
            requestParam.put("wcsStatus", 1);//失败
            requestParam.put("wcsErrorMessage", errMsg);//失败原因
        }else {
            requestParam.put("wcsStatus", 0);//成功
        }
        String response = "";
        Boolean success = false;
        try {
            response = new HttpHandler.Builder()
                    .setUri(wmsUrl)
                    .setPath(inboundTaskApplyPath)
                    .setJson(JSON.toJSONString(requestParam))
                    .build()
                    .doPost();
            JSONObject jsonObject = JSON.parseObject(response);
            if (jsonObject.getInteger("code") != 200) {
                log.info("条码:" + barcode + "申请WMS失败,response=" + JSON.toJSONString(jsonObject));
                return R.error();
            }
            JSONObject result = jsonObject.getJSONObject("data");
            Integer resultWrkNo = result.getInteger("wrkNo");
            Integer resultStaNo = result.getInteger("stnNo");
            String resultLocNo = result.getString("locNo");
            // 创新一个入库工作档
            TaskWrk taskWrk = taskWrkService.selectByTaskNo(String.valueOf(resultWrkNo));
            if(taskWrk != null) {
                log.info("任务:" + resultWrkNo + "已经存在");
                return R.error();
            }
            LocMast locMast = locMastService.selectByLocNo(resultLocNo);
            if (locMast == null) {
                log.info(resultLocNo + "库位不存在");
                return R.error();
            }
            if (!locMast.getLocSts().equals("O")) {
                log.info(resultLocNo + "库位不处于空库位");
                return R.error();
            }
            Date now = new Date();
            taskWrk = new TaskWrk();
            taskWrk.setTaskNo(String.valueOf(resultWrkNo));//任务号
            taskWrk.setWrkNo(commonService.getWorkNo(WorkNoType.PAKIN.type));//获取入库工作号
            taskWrk.setStatus(TaskStatusType.RECEIVE.id);//任务状态:接收
            taskWrk.setWrkSts(2);//2.设备上走
            taskWrk.setCreateTime(now);
            taskWrk.setIoType(1);//任务类型
            taskWrk.setIoPri(13);//优先级
            taskWrk.setBarcode(barcode);//条码
            taskWrk.setCrnNo(locMast.getCrnNo());
            taskWrk.setTargetPoint(resultLocNo);
            taskWrk.setStartPoint(String.valueOf(staNo));
            if (!Cools.isEmpty(taskWrk.getTargetPoint())) {
                taskWrk.setOriginTargetPoint(taskWrk.getTargetPoint());
            }
            if (!taskWrkService.insert(taskWrk)) {
                log.info("任务:" + resultWrkNo + "任务创建失败");
                return R.error();
            }
            locMast.setLocSts("S");
            locMast.setModiTime(new Date());
            locMastService.updateById(locMast);
            //上报
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:ss:mm");
            HashMap<String, Object> hashMap = new HashMap<>();
            hashMap.put("taskNo", taskWrk.getTaskNo());
            hashMap.put("status", TaskStatusType.DISTRIBUTE.id);
            hashMap.put("ioType", 2);
            hashMap.put("barcode", taskWrk.getBarcode());
            hashMap.put("reportTime", format.format(new Date()));
            NotifyCustomDataDto customDataDto = new NotifyCustomDataDto();
            customDataDto.setUri(wmsUrl);
            customDataDto.setPath(TaskExecCallback);
            customDataDto.setData(JSON.toJSONString(hashMap));
            boolean notifyResult = notifyUtils.notify("task", 1, String.valueOf(taskWrk.getWrkNo()), taskWrk.getTaskNo(), NotifyMsgType.TASK_START, JSON.toJSONString(taskWrk), true, customDataDto);
            if(notifyResult) {
                taskWrk.setStatus(TaskStatusType.DISTRIBUTE.id);//任务派发
                taskWrkService.updateById(taskWrk);
            }
        } catch (Exception e) {
            log.error("请求入库调用接口失败");
            log.error("异常信息打印:" + e);
        } finally {
            apiLogService.save("wms请求入库货位接口"
                    , wmsUrl + inboundTaskApplyPath
                    , null
                    , "127.0.0.1"
                    , JSON.toJSONString(requestParam)
                    , response
                    , success
            );
        }
        log.info("入库请求参数=" + JSON.toJSONString(barcode));
        log.info("入库请求返回参数=" + JSON.toJSONString(response));
        return R.ok();
    }
}