Compare commits

...

26 Commits

Author SHA1 Message Date
FT577-Server
ccbf7a9580 巷道口输送机下发读值校验优化 2026-10-23 17:29:39 +08:00
FT577-Server
47bdc6484c 巷道口输送机下发读值校验 2026-10-22 14:47:24 +08:00
FT577-Server
122ac6b34a 巷道口输送机下发读值校验 2026-10-19 10:59:31 +08:00
FT577-Server
5edf4a62b9 运行调整 2026-10-16 09:48:33 +08:00
lsymicc
efaf0d670e 现场调试修改 2026-10-10 13:31:02 +08:00
FT577-Server
d7d618c1bd 运行调整 2026-10-08 08:59:04 +08:00
FT577-Server
69efb3236b 运行调整 2026-10-08 08:58:36 +08:00
FT577
45be4cb428 现场运行调整 2026-09-21 11:01:26 +08:00
FT577
2f862358ad 现场运行调整 2026-09-21 08:41:38 +08:00
FT577
a6a9fc15f2 现场运行调整 2026-09-18 20:57:11 +08:00
lsymicc
c67d2b127b 现场调试修改 2026-09-16 11:38:54 +08:00
lsymicc
92b12ee49e 现场调试修改 2026-09-16 11:28:31 +08:00
lsymicc
674a910df6 现场调试修改 2026-09-16 10:58:32 +08:00
lsymicc
5f8add5b10 现场调试修改 2026-09-12 09:33:11 +08:00
lsymicc
7a7532f8bd 现场调试修改 2026-09-08 22:23:58 +08:00
lsymicc
f944d7fef5 修改接口 2026-07-17 15:41:48 +08:00
lsymicc
415543a723 初始化 2026-06-29 15:29:20 +08:00
CTOS
4c590f515f 文本优化,部分接口地址修正 2026-06-04 14:45:09 +08:00
lsymicc
d468c3a1a5 任务表查询排序 2026-06-04 14:31:33 +08:00
lsymicc
e77ed70162 任务表查询排序 2026-06-04 14:28:47 +08:00
lsymicc
43417820b1 任务表查询排序 2026-06-04 14:19:54 +08:00
lsymicc
135f082e16 任务表查询排序 2026-06-04 10:58:00 +08:00
lsymicc
361ec0dcb6 优化 2026-06-02 16:28:23 +08:00
lsymicc
c3689b2a6c 日志显示优化 2026-06-02 14:49:55 +08:00
lsymicc
8b2433c5a1 推送货位参数校验 2026-06-02 11:37:58 +08:00
lsymicc
5c6361217f 推送货位参数校验 2026-06-02 10:29:04 +08:00
43 changed files with 3540 additions and 1154 deletions

View File

@@ -1,6 +1,9 @@
package com.ruoyi;
import cn.hutool.core.bean.BeanUtil;
import com.ruoyi.job.service.IMydoJobService;
import com.ruoyi.queue.ddj.domain.DdjDeviceExecutionQueue;
import com.ruoyi.queue.ddj.domain.DdjDeviceExecutionQueueFinish;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;

View File

@@ -100,7 +100,7 @@ public class AgvController extends BaseController {
//取消rcs中指定的agv任务
CancelTaskResponse cancelTaskResponse = apiService.cancelTask(cancelTaskRequest);
if(cancelTaskResponse.getCode() == 0 && "成功".equals(cancelTaskResponse.getMessage()) && cancelTaskResponse.getReqCode() == cancelTaskRequest.getReqCode()){
if(cancelTaskResponse.getCode() == 0 && "成功".equals(cancelTaskResponse.getMsg()) && cancelTaskResponse.getReqCode() == cancelTaskRequest.getReqCode()){
return AjaxResult.success("AGV任务队列取消成功!", cancelTaskResponse);
}

View File

@@ -2,16 +2,14 @@ package com.ruoyi.api.controller;
import com.ruoyi.api.domain.wcs2wms.JobParam;
import com.ruoyi.api.domain.wcs2wms.ReceiveJob;
import com.ruoyi.api.domain.wcs2wms.stockout.StockoutReceive;
import com.ruoyi.api.service.IApiService;
import com.ruoyi.api.service.IRequestLogService;
import com.ruoyi.bas.port.domain.WcsPort;
import com.ruoyi.bas.port.service.IWcsPortService;
import com.ruoyi.common.core.domain.AjaxResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/wcs2wms/api")
public class Wcs2WmsController {
@@ -20,30 +18,58 @@ public class Wcs2WmsController {
private IApiService apiService;
@Autowired
private IWcsPortService wcsPortService;
@Autowired
IRequestLogService requestLogService;
/**
* 接收wms出库任务
*
* @param stockoutReceive
* @param receiveJob
* @return
*/
@PostMapping("/receiveOutMydoJob")
public AjaxResult receiveOutMydoJob(@RequestBody StockoutReceive stockoutReceive) {
return apiService.receiveOutMydoJob(stockoutReceive);
public AjaxResult receiveOutMydoJob(@RequestBody ReceiveJob receiveJob) {
return apiService.receiveOutMydoJob(receiveJob);
}
/**
* 接收入库任务
*
* @param receiveInJob
* @param receiveJob
* @return
*/
@PostMapping("/receiveInMydoJob")
public AjaxResult receiveInMydoJob(@RequestBody ReceiveJob receiveInJob) {
return apiService.receiveInMydoJob(receiveInJob);
public AjaxResult receiveInMydoJob(@RequestBody ReceiveJob receiveJob) {
return apiService.receiveInMydoJob(receiveJob);
}
/**
* 接收移库任务
*
* @param receiveJob
* @return
*/
@PostMapping("/receiveMoveMydoJob")
public AjaxResult receiveMoveMydoJob(@RequestBody ReceiveJob receiveJob) {
return apiService.receiveMoveMydoJob(receiveJob);
}
/**
* 接收盘点任务
*
* @param receiveJob
* @return
*/
@PostMapping("/receiveInventoryMydoJob")
public AjaxResult receiveInventoryMydoJob(@RequestBody ReceiveJob receiveJob) {
return apiService.receiveInventoryMydoJob(receiveJob);
}
/**
* wms取消任务
@@ -52,7 +78,39 @@ public class Wcs2WmsController {
*/
@PostMapping("/cancelMydoJob")
public AjaxResult cancelMydoJob(@RequestBody JobParam jobParam) {
return apiService.cancelMydoJob(jobParam);
return apiService.cancelTask(jobParam.getJobId());
}
/**
* wms取消任务
* @param jobId
* @return
*/
@GetMapping("/cancelMydoJob")
public AjaxResult cancelMydoJob(@RequestParam("jobId") String jobId) {
return apiService.cancelTask(jobId);
}
/**
* wms手动完成任务 - 根据任务号
* @param jobParam
* @return
*/
@PostMapping("/manualCompeleteMydoJobByTaskNo")
public AjaxResult manualCompeleteMydoJobByTaskNo(@RequestBody JobParam jobParam) {
return apiService.manualCompeleteTaskByTaskNo(jobParam.getTaskNo());
}
/**
* wms手动完成任务 - 根据作业号
* @param jobParam
* @return
*/
@PostMapping("/manualCompeleteMydoJobByJobId")
public AjaxResult manualCompeleteMydoJobByTJobId(@RequestBody JobParam jobParam) {
return apiService.manualCompeleteTaskByTaskNo(jobParam.getTaskNo());
}
@@ -66,6 +124,7 @@ public class Wcs2WmsController {
return apiService.selectWcsPort(wcsPort);
}
/**
* 修改缓存点状态
* @param wcsPort

View File

@@ -11,7 +11,7 @@ public class ResponseBase {
/**
* 返回消息
*/
private String message;
private String msg;
/**
* 自定义返回
*/

View File

@@ -8,6 +8,7 @@ import lombok.NoArgsConstructor;
@AllArgsConstructor
@NoArgsConstructor
public class JobParam {
/**
* 作业号
*/
@@ -23,5 +24,10 @@ public class JobParam {
*/
private String taskNo;
/**
* 货位号
*/
private String cargoSpaceId;
}

View File

@@ -3,11 +3,23 @@ package com.ruoyi.api.domain.wcs2wms;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import reactor.util.annotation.Nullable;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ReceiveJob {
/**
* 请求码
*/
private String reqCode;
/**
* 作业号
*/
private String jobId;
/**
* 任务号
*/
@@ -18,9 +30,20 @@ public class ReceiveJob {
*/
private String cargoSpaceId;
/** 货位(移库使用) */
@Nullable
private String targetCargoSpaceId;
/**
* 入口
*/
@Nullable
private String entranceId;
/**
* 出口
*/
@Nullable
private String exitId;
/**
@@ -28,28 +51,23 @@ public class ReceiveJob {
*/
private String trayCode;
/**
* 入口
*/
private String entranceId;
/**
* 任务类型
*/
private String inOrOut;
/**
* 作业号
*/
private String jobId;
/**
* 巷道号
*/
@Nullable
private String roadwayId;
/**
*
* 优先级
*/
private String departmentId;
@Nullable
private Integer priority;
}

View File

@@ -7,37 +7,41 @@ import lombok.NoArgsConstructor;
/**
* 入库请求返回
*
* 【常见错误】
* 任务类型不可为空 未传 taskTypeCode
* 该任务类型未配置 taskTypeCode 在系统中不存在
* 该任务类型无点位配置信息 任务类型缺少点位模板
* 该任务类型未开启 任务类型状态为禁用
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class StockinReceive {
/**
* 系统生成的任务编号(唯一)/wms下发的任务号
*/
private String taskCode;
/**
* 请求时传入的 reqCode,原样回传
*/
private String reqCode;
/**
* 容器编号(containerCode)
* 系统生成的任务编号(唯一)/wms下发的任务号
*/
private String cntCode;
private String taskNo;
/**
* 终点库位编号
* 系统生成的任务编号(唯一)/wms下发的作业号
*/
private String siteCode;
private String jobId;
/**
* 容器编号
*/
private String trayCode;
/**
* 分配货位编号
*/
private String cargoSpaceId;
/**
* 任务类型
*/
private String inOrOut;
}

View File

@@ -5,23 +5,16 @@ import com.ruoyi.api.domain.agv.agvCallback.AgvCallbackRequest;
import com.ruoyi.api.domain.agv.agvCallback.AgvCallbackResponse;
import com.ruoyi.api.domain.agv.cancelTask.CancelTaskRequest;
import com.ruoyi.api.domain.agv.cancelTask.CancelTaskResponse;
import com.ruoyi.api.domain.agv.continueTask.ContinueTaskRequest;
import com.ruoyi.api.domain.agv.continueTask.ContinueTaskResponse;
import com.ruoyi.api.domain.agv.genAgvSchedulingTask.GenAgvSchedulingTaskRequest;
import com.ruoyi.api.domain.agv.genAgvSchedulingTask.GenAgvSchedulingTaskResponse;
import com.ruoyi.api.domain.wcs2wms.JobParam;
import com.ruoyi.api.domain.wcs2wms.ReceiveJob;
import com.ruoyi.api.domain.wcs2wms.exception.TaskExceptionRequest;
import com.ruoyi.api.domain.wcs2wms.stockout.StockoutReceive;
import com.ruoyi.bas.port.domain.WcsPort;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.exception.job.TaskException;
import com.ruoyi.job.domain.MydoJob;
import com.ruoyi.queue.agv.domain.AgvQueue;
import org.aspectj.weaver.loadtime.Aj;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
@@ -33,6 +26,101 @@ import java.util.Map;
public interface IApiService
{
/**
* 任务到达拣选口
* @param param
* @return
*/
RequestLog finishMydoJob(Map<String, Object> param);
AjaxResult selectWcsPort(WcsPort wcsPort);
AjaxResult updateWcsPort(WcsPort wcsPort);
/**
* 放货有货,重新分配货位
* @param jobParam
* @return
*/
AjaxResult reAssign(JobParam jobParam);
/**
* 取货无货,重新分配单据
* @param jobParam
* @return
*/
AjaxResult reMaterial(JobParam jobParam);
/**
* @@@ FT568 入库请求生成作业 处理了请求响应,适应wms的自定义响应格式
*/
AjaxResult createMydoJobForStockin(Map<String, Object> param);
/**
* 入库请求wms参数 - 作业号、货位
*/
// AjaxResult requestMydoJobParamForWms(Map<String, Object> param);
/**
* 入库请求作业异常反馈(扫码失败、外形、称重等异常)
*/
AjaxResult createInMydoJobException(Map<String, Object> param);
AjaxResult selectMydoJobByNoTrayCode(Map<String, Object> param);
/**
* 接受出库作业
* @param receiveJob
* @return
*/
AjaxResult receiveOutMydoJob(ReceiveJob receiveJob);
/**
* 接受入库作业
* @param receiveJob
* @return
*/
AjaxResult receiveInMydoJob(ReceiveJob receiveJob);
/**
* 接受移库作业
* @param receiveJob
* @return
*/
AjaxResult receiveMoveMydoJob(ReceiveJob receiveJob);
/**
* 接收盘点作业
* @param receiveInventoryJob
* @return
*/
AjaxResult receiveInventoryMydoJob(ReceiveJob receiveInventoryJob);
AjaxResult selectMydoJobByTrayCodeAndEntranceId(HashMap<String, Object> paramMap);
AjaxResult requestWmsSpace(MydoJob mydoJob);
AjaxResult manualCompeleteTaskByTaskNo(String taskNo);
AjaxResult manualCompeleteTaskByJobId(String taskNo);
AjaxResult cancelTask(String jobId);
//=============================================AGV相关=============================================
//=============================================AGV相关=============================================
//=============================================AGV相关=============================================
/**
* 生成agv队列
* @param code1 起点
@@ -82,19 +170,7 @@ public interface IApiService
*/
AjaxResult receiveAgvMoveJob(Map<String, String> param);
/**
* 任务到达拣选口
* @param param
* @return
*/
RequestLog finishMydoJob(Map<String, Object> param);
/**
* @@@ FT568 任务完成回传 适应wms的自定义响应格式
* @param param
* @return
*/
RequestLog finishMydoJobForResponseResult(Map<String, Object> param);
AjaxResult deleteAgvTray(AgvQueue agvQueue);
/**
* 下发agv任务
@@ -103,7 +179,6 @@ public interface IApiService
*/
public GenAgvSchedulingTaskResponse requestAgvQueue(AgvQueue agvQueue);
/**
* 取消ctu任务
* @param jobParam
@@ -111,69 +186,5 @@ public interface IApiService
*/
AjaxResult cancelMydoJob(JobParam jobParam);
AjaxResult selectWcsPort(WcsPort wcsPort);
AjaxResult updateWcsPort(WcsPort wcsPort);
/**
* 放货有货,重新分配货位
* @param jobParam
* @return
*/
AjaxResult reAssign(JobParam jobParam);
/**
* 放货有货 (参数类型TaskExceptionRequest)
* @param taskExceptionRequest
* @return
*/
AjaxResult reAssign(TaskExceptionRequest taskExceptionRequest);
/**
* 取货无货,重新分配单据
* @param jobParam
* @return
*/
AjaxResult reMaterial(JobParam jobParam);
/**
* 取货无货(参数类型TaskExceptionRequest)
* @param taskExceptionRequest
* @return
*/
AjaxResult reMaterial(TaskExceptionRequest taskExceptionRequest);
/**
* 入库请求生成作业
*/
AjaxResult createInMydoJob(Map<String, Object> param);
/**
* @@@ FT568 入库请求生成作业 处理了请求响应,适应wms的自定义响应格式
*/
AjaxResult createMydoJobForStockin(Map<String, Object> param);
/**
* 入库请求作业异常反馈(扫码失败、外形、称重等异常)
*/
AjaxResult createInMydoJobException(Map<String, Object> param);
AjaxResult selectMydoJobByNoTrayCode(Map<String, Object> param);
AjaxResult receiveOutMydoJob(StockoutReceive stockoutReceive);
AjaxResult receiveInMydoJob(ReceiveJob receiveInJob);
AjaxResult selectMydoJobByTrayCodeAndEntranceId(HashMap<String, Object> paramMap);
AjaxResult deleteAgvTray(AgvQueue agvQueue);
AjaxResult requestWmsSpace(MydoJob mydoJob);
}

View File

@@ -2,6 +2,7 @@ package com.ruoyi.api.service;
import java.util.List;
import com.ruoyi.api.domain.RequestLog;
import com.ruoyi.common.core.domain.AjaxResult;
/**
* 接口记录Service接口
@@ -83,6 +84,16 @@ public interface IRequestLogService
public RequestLog getRequestLog(String param, String endPoint);
/**
* 接收接口记录
*
* @param param
* @param remark
* @return
*/
public RequestLog getRequestLog(String param, String remark, AjaxResult ajaxResult);
RequestLog getRequestLog2(String url, String param, String endPoint);
/**

View File

@@ -14,6 +14,7 @@ import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.ruoyi.api.domain.InterfaceReceive;
import com.ruoyi.api.domain.wcs2wms.ResponseResult;
import com.ruoyi.common.core.domain.AjaxResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -145,14 +146,13 @@ public class RequestLogServiceImpl implements IRequestLogService
requestLog.setRequestUrl(url);
Date responseTime =new Date();
try {
// String resStr = HttpUtil.post(url, param);
String resStr = HttpRequest.post(url)
.body(param)
.header("X-Service-Secret", HEADER_TOKEN)
.execute()
.body();
// String resStr = HttpRequest.post(url)
// .body(param)
// .header("X-Service-Secret", HEADER_TOKEN)
// .execute()
// .body();
String resStr = HttpUtil.post(url, param);
requestLog.setResponseBody(resStr);
InterfaceReceive bean = JSONUtil.toBean(resStr, InterfaceReceive.class);
@@ -250,7 +250,7 @@ public class RequestLogServiceImpl implements IRequestLogService
// String resStr = HttpUtil.post(url, param, header, 3000);
String resStr = HttpRequest.post(url)
.body(param)
.header("X-Service-Secret", HEADER_TOKEN) // 向wms请求头必需添加的token
// .header("X-Service-Secret", HEADER_TOKEN) // 向wms请求头必需添加的token
.execute()
.body();
requestLog.setResponseBody(resStr);
@@ -303,6 +303,32 @@ public class RequestLogServiceImpl implements IRequestLogService
}
/**
* 插入请求日志
*
* @return requestLog
*/
@Override
public RequestLog getRequestLog(String param, String remark,AjaxResult ajaxResult) {
RequestLog requestLog = new RequestLog();
requestLog.setRequestTime(DateUtil.formatDateTime(new Date()));
requestLog.setRequestBody(param);
requestLog.setSourceSystem("wcs");
requestLog.setTargetSystem("wms");
requestLog.setEndpoint(remark);
requestLog.setRequestMethod("post");
requestLog.setResponseTime(DateUtil.formatDateTime(new Date()));
requestLog.setDuration(Convert.toStr(DateUtil.between(Convert.toDate(requestLog.getRequestTime()), Convert.toDate(requestLog.getResponseTime()), DateUnit.MS)));
requestLog.setResponseStatus("1");
if (ajaxResult.isSuccess()){
requestLog.setIsSuccessful("1");
}else {
requestLog.setIsSuccessful("0");
}
requestLog.setResponseBody(Convert.toStr(ajaxResult.get("msg")));
return requestLog;
}
/**
* @@@ FT568 将wms自定义的响应格式解析为本地响应格式(减少其他改动)

View File

@@ -3,8 +3,8 @@ package com.ruoyi.common;
public class Constant {
public static final String LOCAL_URL = "http://127.0.0.1:8084";
public static final String WMS_BASE_URL = "http://10.88.10.69:8290/service";
public static final String LOCAL_URL = "http://127.0.0.1:8084/api/wmsService/wcs/";
public static final String WMS_BASE_URL = "http://127.0.0.1:8084/api/external";
public static final String RCS_BASE_URL = "http://192.168.58.101:8182/rcms/services/rest/hikRpcService/";
public static final String HEADER_TOKEN = "fed3d1511a5a474b9e1f9c56246cb1ec";
@@ -16,16 +16,25 @@ public class Constant {
public static final String CONTINUE_TASK_URL = RCS_BASE_URL+"continueTask";
public static final String DELETE_BIN_URL = RCS_BASE_URL+"bindCtnrAndBin";
public static final String JOB_FINISH_URL = WMS_BASE_URL+"jobFinish";
public static final String CREATE_IN_MYDO_JOB_URL = WMS_BASE_URL+"requestEnterByTrayCode";
public static final String REQUEST_MYDO_JOB_URL = WMS_BASE_URL+"requestByNoTrayCode";
public static final String RE_ASSIGN_URL = WMS_BASE_URL+"reAssign";
public static final String RE_MATERIAL_URL = WMS_BASE_URL+"reMaterial";
public static final String REQUEST_ENTER_URL = WMS_BASE_URL+"requestEnterByTrayCodeAndEntranceId";
public static final String REQUEST_IN_SPACE_URL = WMS_BASE_URL+"requestInSpace";
//#endregion
/**
* 任务完成回传
*/
public static final String WMS_JOB_FINISH_URL = LOCAL_URL + "jobFinish";
/**
* 请求创建入库任务
*/
public static final String WMS_CREATE_IN_MYDO_JOB_URL = LOCAL_URL + "requestMydoJobByTrayCode";
public static final String WMS_REQUEST_MYDO_JOB_URL = LOCAL_URL + "requestMydoJobByNoTrayCode";
public static final String WMS_RE_ASSIGN_URL = LOCAL_URL + "reAssign";
public static final String WMS_RE_MATERIAL_URL = LOCAL_URL + "reMaterial";
public static final String WMS_REQUEST_ENTER_URL = LOCAL_URL + "requestMydoJobByTrayCodeAndEntranceId";
public static final String WMS_REQUEST_IN_SPACE_URL = LOCAL_URL + "requestInSpace";
/**
* 本地测试wms服务端url
*/
@@ -36,16 +45,16 @@ public class Constant {
/**
* 向wms请求入库url
*/
public static final String WMS_STOCKIN_MYDOJOB = WMS_BASE_URL + "/api/external/taskIssue";
public static final String WMS_STOCKIN_MYDOJOB = LOCAL_URL + "requestMydoJobByTrayCode";
/**
* 出入库回传url
*/
public static final String WMS_TASK_FINISH = WMS_BASE_URL + "/api/external/taskIssue";
public static final String WMS_TASK_FINISH = LOCAL_URL + "/api/external/taskIssue";
/**
* 异常信息回传url
*/
public static final String WMS_TASK_EXCEPTION = WMS_BASE_URL + "/api/external/taskIssue";
public static final String WMS_TASK_EXCEPTION = LOCAL_URL + "/api/external/taskIssue";
}

View File

@@ -1,19 +1,99 @@
package com.ruoyi.common;
import java.util.HashMap;
import java.util.Map;
import static java.util.Map.entry;
public class ConvType {
/**
* 出库输送机(到位位置)
* 1#巷道出库输送机(出口到位位置)
*/
public static final String CONV_STOCKOUT = "TD1001";
public static final String ROADWAY1_EXIT = "L1001";
/**
* 入库输送机(到位位置)
* 1#巷道入库输送机(入口源位置)
*/
public static final String CONV_STOCKIN = "G1004";
public static final String ROADWAY1_ENTRANCE = "L1003";
/**
* 1#巷道口输送机(到位位置)
* 2#巷道输送口-1(双向输送机巷道位置)
*/
public static final String CONV_ROAD_1 = "L1001";
public static final String ROADWAY2_PORTCONV_2 = "L1004";
/**
* 2#巷道输送口-3(双向输送机出入口位置)
*/
public static final String ROADWAY2_ROADCONV_2 = "L1005";
/**
* 2#巷道输送口-3(双向输送机巷道位置)
*/
public static final String ROADWAY2_PORTCONV_3 = "L1006";
/**
* 2#巷道输送口-4(双向输送机出入口位置)
*/
public static final String ROADWAY2_ROADCONV_4 = "L1007";
/**
* 3#巷道出库输送机(出口到位位置)
*/
public static final String ROADWAY3_EXIT = "L1008";
/**
* 3#巷道入库输送机(入口源位置)
*/
public static final String ROADWAY3_ENTRANCE = "L1010";
//-----------------------------
/**
* 输送机对应巷道
*/
public static final Map<String,Object> CONV_ROAD_ROADWAY = new HashMap<>(Map.ofEntries(
entry("L1001", 1),
entry("L1002", 1),
entry("L1003", 1),
entry("L1004", 2),
entry("L1005", 2),
entry("L1006", 2),
entry("L1007", 2),
entry("L1008", 3),
entry("L1009", 3),
entry("L1010", 3)
));
/**
* 输送机对应区域
*/
public static final Map<String,Object> CONV_ROAD_AREA = new HashMap<>(Map.ofEntries(
entry("L1001", "01"),
entry("L1002", "01"),
entry("L1003", "01"),
entry("L1004", "02"),
entry("L1005", "02"),
entry("L1006", "03"),
entry("L1007", "03"),
entry("L1008", "04"),
entry("L1009", "04"),
entry("L1010", "04")
));
/**
* 巷道对应入口货位
*/
public static final Map<String,String> CONV_ROAD_CARGO = new HashMap<>(Map.ofEntries(
entry("L1001", "010200001"),
entry("L1003", "010300001"),
entry("L1005", "010500001"),
entry("L1007", "010700001"),
entry("L1010", "011000001"),
entry("L1008", "011100001")
));
}

View File

@@ -8,15 +8,15 @@ public class GoodsType {
/**
* 默认
*/
public static final String TYPE_DEFAULT = "0";
public static final Integer TYPE_DEFAULT = 0;
/**
* 高度1
*/
public static final String TYPE_HEIGHT_1 = "1";
public static final Integer TYPE_HEIGHT_1 = 4;
/**
* 高度2
*/
public static final String TYPE_HEIGHT_2 = "0";
public static final Integer TYPE_HEIGHT_2 = 6;
}

View File

@@ -30,12 +30,12 @@ public class TaskStatusCode {
/**
* 任务状态-手动完成
*/
public static final String TASK_STATUS_FINISH_MANUAL = "5";
public static final String TASK_STATUS_FINISH_MANUAL = "4";
/**
* 任务状态-作废
*/
public static final String TASK_STATUS_INVALID = "6";
public static final String TASK_STATUS_INVALID = "5";
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 【执行阶段】 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
@@ -57,7 +57,7 @@ public class TaskStatusCode {
public static final String TASK_EP_AGV = "2";
/**
* 任务执行阶段 入口输送机
* 任务执行阶段 入口输送机到位
*/
public static final String TASK_EP_SSJ = "3";
@@ -67,29 +67,53 @@ public class TaskStatusCode {
public static final String TASK_EP_ROADWAY_SSJ = "4";
/**
* 任务执行阶段 堆垛机执行
* 任务执行阶段 堆垛机入库取货完成(仅取货)
*/
public static final String TASK_EP_DDJ = "5";
public static final String TASK_EP_DDJ_PICK = "5";
/**
* 任务执行阶段 堆垛机放货完成
* 任务执行阶段 堆垛机入库放货(仅放货)
*/
public static final String TASK_EP_DDJ_FINISH = "6";
// public static final String TASK_EP_DDJ_PUT = "6";
/**
* 任务执行阶段 输送机出库到位-出库完成
* 任务执行阶段 堆垛机执行(入库放货/出库取放)
*/
public static final String TASK_EP_SSJ_STOCKOUT_FINISH = "6";
public static final String TASK_EP_DDJ = "6";
/**
* 任务执行阶段 任务自动完成
* 任务执行阶段 堆垛机入库放货完成
*/
public static final String TASK_EP_FINISH = "6";
public static final String TASK_EP_DDJ_FINISH = "7";
/**
* 任务执行阶段 输送机出库输送机到位-出库完成
*/
public static final String TASK_EP_SSJ_STOCKOUT_FINISH = "7";
/**
* 任务执行阶段 任务自动完成 (如果不想区分出入库完成可以直接统一使用【自动完成】)
*/
public static final String TASK_EP_FINISH = "7";
/**
* 任务执行阶段 输送机出库到位-盘点出库阶段完成
*/
public static final String TASK_EP_SSJ_INVENTORY_STOCKOUT_FINISH = "8";
/**
* 任务执行阶段 堆垛机入库放货完成-盘点回库阶段完成
*/
public static final String TASK_EP_SSJ_INVENTORY_STOCKIN_FINISH = "9";
/**
* 任务执行阶段 任务超时-自动结束当前任务
*/
public static final String TASK_EP_DDJ_FINISH_TIMEOUT = "6_TIMEOUT_FINISH";
public static final String TASK_EP_DDJ_FINISH_TIMEOUT = "TIMEOUT_FINISH";
/**
* 入库异常 - 放货有货
@@ -106,10 +130,7 @@ public class TaskStatusCode {
*/
public static final String TASK_EXCEPTION_PUT_REASSIGN = "STOCKIN_FAULT_REASSIGN";
/**
* 任务执行阶段 回传wms完成
*/
public static final String TASK_EP_WMS_FINISH = "9";
}

View File

@@ -8,19 +8,64 @@ public class TaskType {
/**
* 默认类型
*/
public static final int STACKER_TYPE_DEFAULT = 0;
public static final int TASKTYPE_DEFAULT = 0;
public static final String TASKTYPE_DEFAULT_STR = "0";
/**
* 1-二楼入出
* 常规入库
*/
public static final int DDJ_RWLX_1 = 1;
public static final int TASKTYPE_STOCKIN = 1;
public static final String TASKTYPE_STOCKIN_STR = "1";
/**
* 2-一楼出库
* 常规入库
*/
public static final int DDJ_RWLX_2 = 2;
public static final int TASKTYPE_MOVE = 5;
public static final String TASKTYPE_MOVE_STR = "5";
/**
* 3-一楼入库
* 拣选回流
*/
public static final int DDJ_RWLX_3 = 3;
public static final int TASKTYPE_STOCKIN_RETURN = 3;
public static final String TASKTYPE_STOCKIN_RETURN_STR = "3";
/**
* 常规出库
*/
public static final int TASKTYPE_STOCKOUT = 20;
public static final String TASKTYPE_STOCKOUT_STR = "20";
/**
* 拣选出库
*/
public static final int TASKTYPE_STOCKOUT_PICK = 21;
public static final String TASKTYPE_STOCKOUT_PICK_STR = "21";
/**
* 空容器出库
*/
public static final int TASKTYPE_STOCKOUT_EMPTY_TRAY = 22;
public static final String TASKTYPE_STOCKOUT_EMPTY_TRAY_STR = "22";
/**
* 指定货位出库
*/
public static final int TASKTYPE_STOCKOUT_MANUAL = 23;
public static final String TASKTYPE_STOCKOUT_MANUAL_STR = "23";
/**
* 有托盘余位的容器出库
*/
public static final int TASKTYPE_STOCKOUT_CONTAINER = 27;
public static final String TASKTYPE_STOCKOUT_CONTAINER_STR = "27";
/**
* 盘点出库
*/
public static final int TASKTYPE_INVENTORY = 26;
public static final String TASKTYPE_INVENTORY_STR = "26";
}

View File

@@ -100,6 +100,10 @@ public class MsgDdj extends BaseEntity
@Excel(name = "货叉状态")
private Integer hczt;
/** 载货高度 */
@Excel(name = "载货高度")
private Integer height;
// /** 备用字段1 */
// @Excel(name = "备用字段1")
// private Integer spare1;

View File

@@ -114,12 +114,23 @@ public class MydoJobController extends BaseController
@PreAuthorize("@ss.hasAnyPermi('job:mydoJob:outhandFinish')")
@Log(title = "出库手动完成", businessType = BusinessType.OTHER)
@RequestMapping("/outhandFinish")
public AjaxResult manualCompleted(@RequestParam("jobIds")String[] jobIds)
@RequestMapping("/manualCompleted")
public AjaxResult manualCompleted(@RequestParam String[] jobIds)
{
return mydoJobService.outhandFinish(jobIds);
}
/**
* 取消作业
*/
@PreAuthorize("@ss.hasPermi('job:mydoJob:remove')")
@Log(title = "手动取消作业", businessType = BusinessType.DELETE)
@DeleteMapping("/cancelMydoJob")
public AjaxResult cancelMydoJob(@RequestParam String[] jobIds)
{
return mydoJobService.cancelTask(jobIds);
}
@PreAuthorize("@ss.hasAnyPermi('job:mydoJob:resendTaskToEntrance')")
@Log(title = "入口输送机重新下发", businessType = BusinessType.OTHER)
@PutMapping("/resendTaskToEntrance")

View File

@@ -1,5 +1,6 @@
package com.ruoyi.job.domain;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
@@ -21,13 +22,14 @@ import java.util.List;
@NoArgsConstructor
@ToString
@Builder
//@TableName("mydo_job_wcs")
@TableName("mydo_job_wcs")
public class MydoJob extends BaseEntity
{
@TableField(exist = false)
private static final long serialVersionUID = 1L;
/** 任务ID */
// @TableId
@TableId
private String jobId;
/** 任务状态 */
@@ -56,7 +58,7 @@ public class MydoJob extends BaseEntity
/** 优先级 */
@Excel(name = "优先级")
private Long priority;
private Integer priority;
/** 执行阶段 */
@Excel(name = "执行阶段")
@@ -96,7 +98,7 @@ public class MydoJob extends BaseEntity
private String flag;
private String traySize;
private Integer traySize;
private List<String> epList;

View File

@@ -90,7 +90,17 @@ public interface IMydoJobService
AjaxResult outhandFinish(String[] jobIds);
AjaxResult ManuelTaskFinish(String taskNo);
AjaxResult manualCompeleteTaskByTaskNo(String taskNo);
public AjaxResult manualCompeleteTaskByJobId(String jobId);
AjaxResult manualCompeleteTask(String[] jobIds);
AjaxResult cancelTask(String jobId);
AjaxResult cancelTask(String[] JobIds);
AjaxResult compeleteTimeoutTask(String taskNo);
List<MydoJob> getInJobByEntranceId(String exitId);
@@ -99,6 +109,8 @@ public interface IMydoJobService
MydoJob selectMydoJobByWmsTaskNo(String wmsTaskNo);
/** 根据条码获取托盘类型(尺寸) */
Integer getTraytypeByTrayCode(String trayCode);
/**
* 获取本地生成作业号

View File

@@ -104,19 +104,23 @@ public class JobCallBackServiceImpl implements IJobCallBackService
@Override
public void jobCallBack() {
//获取【刚刚创建】和【请求失败】的回传记录
//获取【刚刚创建<1>】和【请求失败<99>】的回传记录
List<JobCallBack> jobCallBackList = jobCallBackMapper.selectJobCallBackListNoSuccess();
for (JobCallBack jobCallBack : jobCallBackList) {
//设定请求参数
Map<String, Object> param = new HashMap<>();
param.put("taskTypeCode", jobCallBack.getTaskTypeCode());
param.put("reqCode", UUID.randomUUID().toString().replace("-", ""));
param.put("taskCode", jobCallBack.getTaskCode());
param.put("jobId", jobCallBack.getMydoJobId());
param.put("taskNo", jobCallBack.getTaskNo());
param.put("wmsType", jobCallBack.getType());
// param.put("trayCode", jobCallBack.getType());
//请求回传
// RequestLog requestLog = apiService.finishMydoJob(param);
RequestLog requestLog = apiService.finishMydoJobForResponseResult(param);//@@@ FT568 返回自定义的wms响应格式
RequestLog requestLog = apiService.finishMydoJob(param);
// RequestLog requestLog = apiService.finishMydoJobForResponseResult(param);//@@@ FT568 返回自定义的wms响应格式
if ("1".equals(requestLog.getIsSuccessful())){
jobCallBack.setStatus("1");
}else{
@@ -126,26 +130,5 @@ public class JobCallBackServiceImpl implements IJobCallBackService
jobCallBackMapper.updateJobCallBack(jobCallBack);
}
// List<JobCallBack> list = jobCallBackMapper.getTopJobCallBack();
// if(list != null && list.size() > 0){
// JobCallBack jobCallBack = list.get(0);
// Map<String, Object> param = new HashMap<>();
// param.put("jobId", jobCallBack.getMydojobId());
// param.put("taskNo", jobCallBack.getTaskNo());
// param.put("wmsType", jobCallBack.getType());
// RequestLog requestLog = apiService.finishMydoJob(param);
// if ("0".equals(requestLog.getIsSuccessful())){
// jobCallBack.setStatus("1");
// jobCallBackMapper.updateJobCallBack(jobCallBack);
// }else{
// if(Integer.parseInt(jobCallBack.getSpare1()) < 2){
// jobCallBack.setSpare1(String.valueOf(Integer.parseInt(jobCallBack.getSpare1())+1));
// jobCallBackMapper.updateJobCallBack(jobCallBack);
// }else{
// jobCallBack.setStatus("2");
// jobCallBackMapper.updateJobCallBack(jobCallBack);
// }
// }
// }
}
}

View File

@@ -4,12 +4,17 @@ import java.util.Date;
import java.util.HashMap;
import java.util.List;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.UUID;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.job.domain.JobCallBack;
import com.ruoyi.job.service.IJobCallBackService;
import com.ruoyi.queue.ddj.domain.DdjDeviceExecutionQueue;
import com.ruoyi.queue.ddj.domain.DdjDeviceExecutionQueueFinish;
import com.ruoyi.queue.ddj.service.IDdjDeviceExecutionQueueFinishService;
import com.ruoyi.queue.ddj.service.IDdjDeviceExecutionQueueService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@@ -19,6 +24,8 @@ import com.ruoyi.job.mapper.MydoJobMapper;
import com.ruoyi.job.domain.MydoJob;
import com.ruoyi.job.service.IMydoJobService;
import static com.ruoyi.common.TaskStatusCode.TASK_STATUS_FINISH_MANUAL;
import static com.ruoyi.common.TaskStatusCode.TASK_STATUS_INVALID;
import static com.ruoyi.common.WmsTaskTypeCode.*;
/**
@@ -37,6 +44,8 @@ public class MydoJobServiceImpl implements IMydoJobService
private IJobCallBackService jobCallBackService;
@Autowired
private IDdjDeviceExecutionQueueService ddjDeviceExecutionQueueService;
@Autowired
private IDdjDeviceExecutionQueueFinishService ddjDeviceExecutionQueueServiceFinishService;
/**
* 查询作业信息
@@ -84,8 +93,8 @@ public class MydoJobServiceImpl implements IMydoJobService
@Override
public int updateMydoJob(MydoJob mydoJob)
{
long priority = mydoJob.getPriority();
mydoJob.setPriority(Math.abs(priority));
Integer priority = mydoJob.getPriority();
mydoJob.setPriority(priority);
return mydoJobMapper.updateMydoJob(mydoJob);
}
@@ -98,16 +107,13 @@ public class MydoJobServiceImpl implements IMydoJobService
@Override
public int deleteMydoJobByJobIds(String[] jobIds)
{
MydoJob mydojob;
for (String jobId : jobIds) {
mydojob = selectMydoJobByJobId(jobId);
mydoJobMapper.insertHistory(jobId);
//当执行任务的【删除】操作时(特殊场景需要手动处理异常导致不需要入库时,此时不需要向回传异常)
// 此处顺便处理对应任务号生成的堆垛机执行队列,省去sql直接表中删记录的操作
if (selectMydoJobByJobId(jobId) != null){
String taskNo = selectMydoJobByJobId(jobId).getTaskNo();
if (ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueByTaskNo(taskNo) != null) {
ddjDeviceExecutionQueueService.deleteDdjDeviceExecutionQueueByTaskNo(taskNo);
}
}
mydojob.setStatus(TASK_STATUS_INVALID);
updateMydoJob(mydojob);
}
return mydoJobMapper.deleteMydoJobByJobIds(jobIds);
@@ -143,33 +149,57 @@ public class MydoJobServiceImpl implements IMydoJobService
throw new RuntimeException(map.get("v_result").toString());
}
}
/**
* 任务自动完成
* @param rwh
* @return
*/
@Override
public boolean taskFinish(Long rwh) {
MydoJob task = selectMydoJobByTaskNo(rwh);
insertHistory(task.getJobId());
deleteMydoJobByJobId(task.getJobId());
ddjDeviceExecutionQueueService.deleteDdjDeviceExecutionQueueByTaskNo(task.getTaskNo());
MydoJob mydoJob = selectMydoJobByTaskNo(rwh);
mydoJob.setFinishTime(DateUtil.now());
//插入历史表
insertHistory(mydoJob.getJobId());
//删除执行中的作业
deleteMydoJobByJobId(mydoJob.getJobId());
//移除“可能存在”的堆垛机队列
DdjDeviceExecutionQueue queue = ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueByTaskNo(mydoJob.getTaskNo());
if (queue != null){
ddjDeviceExecutionQueueService.deleteDdjDeviceExecutionQueueByTaskNo(mydoJob.getTaskNo());
}
//插入回传表
JobCallBack jobCallBack = new JobCallBack();
jobCallBack.setType(Integer.valueOf(task.getInOrOut()) < 20 ? "1" : "2");
jobCallBack.setMydoJobId(task.getJobId());
jobCallBack.setType(mydoJob.getInOrOut());
jobCallBack.setMydoJobId(mydoJob.getJobId());
jobCallBack.setStatus("0");
jobCallBack.setTaskNo(Convert.toLong(task.getTaskNo()));
jobCallBack.setTaskNo(Convert.toLong(mydoJob.getTaskNo()));
jobCallBack.setCreateTime(new Date());
jobCallBack.setTaskTypeCode(WMS_TASK_TYPE_FINISH);
jobCallBack.setReqCode(UUID.randomUUID().toString().replace("-", ""));
jobCallBack.setTaskCode(task.getWmsTaskNo());
jobCallBack.setTaskCode(mydoJob.getWmsTaskNo());
jobCallBackService.insertJobCallBack(jobCallBack);
log.info("【任务自动完成】生成历史记录,插入回传列表,作业号:{},wcs任务号:{}", mydoJob.getJobId(), rwh);
return true;
}
@Override
public boolean InvalidMydoJob(Long rwh, Integer id) {
HashMap<String, Object> map = new HashMap<>();
map.put("v_rwh", rwh);
map.put("v_ddj_id", id);
mydoJobMapper.InvalidMydoJob(map);
log.info("【人工操作】手动作废wcs任务并移除执行中的堆垛机队列,wcs任务号:{}", rwh);
if (Convert.toInt(map.get("v_result")) == 10){
return true;
}else {
@@ -177,21 +207,25 @@ public class MydoJobServiceImpl implements IMydoJobService
}
}
@Override
public MydoJob selectMydoJobByExitList(List<String> exitList ) {
return mydoJobMapper.selectMydoJobByExitList(exitList);
}
@Override
public MydoJob selectMydoJobByExitList1(String exitId ,String roadwayId) {
return mydoJobMapper.selectMydoJobByExitList1(exitId,roadwayId);
}
@Override
public void insertHistory(String jobId) {
mydoJobMapper.insertHistory(jobId);
}
@Override
public List<MydoJob> selectInOrOutMydoJobList(MydoJob mydoJob) {
return mydoJobMapper.selectInOrOutMydoJobList(mydoJob);
@@ -217,42 +251,51 @@ public class MydoJobServiceImpl implements IMydoJobService
//获取所有符合【任务单号】的作业
for (String jobId : jobIds) {
//插入历史表
mydoJobMapper.insertHistory(jobId);
//生成回传记录
MydoJob mydoJob = mydoJobMapper.selectMydoJobByJobId(jobId);
JobCallBack jobCallBack = new JobCallBack();
jobCallBack.setType(mydoJob.getInOrOut());
jobCallBack.setTaskTypeCode(WMS_TASK_TYPE_FINISH);// wms自定义的任务类型
jobCallBack.setMydoJobId(mydoJob.getJobId());
jobCallBack.setStatus("0");
jobCallBack.setTaskNo(Convert.toLong(mydoJob.getTaskNo()));
jobCallBack.setCreateTime(new Date());
jobCallBack.setTaskCode(mydoJob.getWmsTaskNo());
jobCallBack.setRetry(0);
mydoJob.setFinishTime(DateUtil.now());
mydoJob.setStatus(TASK_STATUS_FINISH_MANUAL);
updateMydoJob(mydoJob);
jobCallBack.setReqCode(UUID.randomUUID().toString());
jobCallBackService.insertJobCallBack(jobCallBack);
//移除实时任务
mydoJobMapper.deleteMydoJobByJobId(jobId);
}
return AjaxResult.success("操作成功");
}
/**
* 手动处理指定【任务号】的作业
* 手动完成指定【任务号】的作业
* @param taskNo
* @return
*/
@Override
public AjaxResult ManuelTaskFinish(String taskNo) {
public AjaxResult manualCompeleteTaskByTaskNo(String taskNo) {
//获取所有符合【任务号】的作业
MydoJob mydoJob = mydoJobMapper.selectMydoJobByTaskNo(taskNo);
mydoJobMapper.insertHistory(mydoJob.getInOrOut());
if (mydoJob == null){
return AjaxResult.error("无该任务号的执行作业,请确认该任务是否已经处理和进行其他操作");
}
//标记状态为【手动完成】插入历史表
mydoJob.setStatus(TASK_STATUS_FINISH_MANUAL);
mydoJob.setFinishTime(DateUtil.now());
updateMydoJob(mydoJob);
mydoJobMapper.insertHistory(mydoJob.getJobId());
try {
//处理堆垛机执行队列和历史记录
DdjDeviceExecutionQueue queue = ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueByTaskNo(mydoJob.getTaskNo());
if (queue != null){
DdjDeviceExecutionQueueFinish queueFinish = BeanUtil.copyProperties(queue, DdjDeviceExecutionQueueFinish.class);
ddjDeviceExecutionQueueServiceFinishService.insertDdjDeviceExecutionQueueFinish(queueFinish);
ddjDeviceExecutionQueueService.deleteDdjDeviceExecutionQueueByTaskNo(mydoJob.getTaskNo());
}
} catch (Exception e) {
log.warn("【人工操作】手动完成操作失败:{}", e.getMessage());
}
JobCallBack jobCallBack = new JobCallBack();
jobCallBack.setType(mydoJob.getInOrOut());
jobCallBack.setTaskTypeCode(WMS_TASK_TYPE_FINISH);// wms下发的任务类型
@@ -267,11 +310,234 @@ public class MydoJobServiceImpl implements IMydoJobService
mydoJobMapper.deleteMydoJobByTaskNo(taskNo);
log.info("【任务手动完成】生成历史记录,插入回传列表,作业号:{},wcs任务号:{}", mydoJob.getJobId(), taskNo);
return AjaxResult.success("操作成功");
}
/**
* 手动完成指定【作业号】的作业(数组类型参数)
* @param jobIds
* @return
*/
@Override
public AjaxResult manualCompeleteTask(String[] jobIds) {
for (String jobId : jobIds) {
//获取所有符合【任务号】的作业
MydoJob mydoJob = mydoJobMapper.selectMydoJobByJobId(jobId);
if (mydoJob == null){
return AjaxResult.error("无该任务号的执行作业,请确认该任务是否已经处理和进行其他操作");
}
//标记状态为【手动完成】插入历史表
mydoJob.setStatus(TASK_STATUS_FINISH_MANUAL);
updateMydoJob(mydoJob);
mydoJobMapper.insertHistory(jobId);
try {
//处理堆垛机执行队列和历史记录
DdjDeviceExecutionQueue queue = ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueByTaskNo(mydoJob.getTaskNo());
if (queue != null){
DdjDeviceExecutionQueueFinish queueFinish = BeanUtil.copyProperties(queue, DdjDeviceExecutionQueueFinish.class);
ddjDeviceExecutionQueueServiceFinishService.insertDdjDeviceExecutionQueueFinish(queueFinish);
ddjDeviceExecutionQueueService.deleteDdjDeviceExecutionQueueByTaskNo(mydoJob.getTaskNo());
}
} catch (Exception e) {
log.warn("【人工操作】手动完成操作失败:{}", e.getMessage());
}
JobCallBack jobCallBack = new JobCallBack();
jobCallBack.setType(mydoJob.getInOrOut());
jobCallBack.setTaskTypeCode(WMS_TASK_TYPE_FINISH);// wms下发的任务类型
jobCallBack.setMydoJobId(jobId);
jobCallBack.setStatus("0");
jobCallBack.setTaskNo(Convert.toLong(mydoJob.getTaskNo()));
jobCallBack.setCreateTime(new Date());
jobCallBack.setTaskCode(mydoJob.getWmsTaskNo());
jobCallBack.setRetry(0);
jobCallBack.setReqCode(UUID.randomUUID().toString());
jobCallBackService.insertJobCallBack(jobCallBack);
mydoJobMapper.deleteMydoJobByJobId(jobId);
log.info("【任务手动完成】生成历史记录,插入回传列表,作业号:{},wcs任务号:{}", jobId, mydoJob.getTaskNo());
}
return AjaxResult.success("操作成功");
}
/**
* 手动完成指定【作业号】的作业
* @param jobId
* @return
*/
@Override
public AjaxResult manualCompeleteTaskByJobId(String jobId) {
//获取所有符合【任务号】的作业
MydoJob mydoJob = mydoJobMapper.selectMydoJobByJobId(jobId);
if (mydoJob == null){
return AjaxResult.error("无该任务号的执行作业,请确认该任务是否已经处理和进行其他操作");
}
//标记状态为【手动完成】插入历史表
mydoJob.setStatus(TASK_STATUS_FINISH_MANUAL);
mydoJob.setFinishTime(DateUtil.now());
updateMydoJob(mydoJob);
mydoJobMapper.insertHistory(jobId);
try {
//处理堆垛机执行队列和历史记录
DdjDeviceExecutionQueue queue = ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueByTaskNo(mydoJob.getTaskNo());
if (queue != null){
DdjDeviceExecutionQueueFinish queueFinish = BeanUtil.copyProperties(queue, DdjDeviceExecutionQueueFinish.class);
ddjDeviceExecutionQueueServiceFinishService.insertDdjDeviceExecutionQueueFinish(queueFinish);
ddjDeviceExecutionQueueService.deleteDdjDeviceExecutionQueueByTaskNo(mydoJob.getTaskNo());
}
} catch (Exception e) {
log.warn("【人工操作】手动完成操作失败:{}", e.getMessage());
}
JobCallBack jobCallBack = new JobCallBack();
jobCallBack.setType(mydoJob.getInOrOut());
jobCallBack.setTaskTypeCode(WMS_TASK_TYPE_FINISH);// wms下发的任务类型
jobCallBack.setMydoJobId(jobId);
jobCallBack.setStatus("0");
jobCallBack.setTaskNo(Convert.toLong(mydoJob.getTaskNo()));
jobCallBack.setCreateTime(new Date());
jobCallBack.setTaskCode(mydoJob.getWmsTaskNo());
jobCallBack.setRetry(0);
jobCallBack.setReqCode(UUID.randomUUID().toString());
jobCallBackService.insertJobCallBack(jobCallBack);
mydoJobMapper.deleteMydoJobByJobId(jobId);
log.info("【任务手动完成】生成历史记录,插入回传列表,作业号:{},wcs任务号:{}", jobId, mydoJob.getTaskNo());
return AjaxResult.success("操作成功");
}
/**
* 手动作废指定【任务号】的作业
* @param jobId
* @return
*/
@Override
public AjaxResult cancelTask(String jobId) {
//获取所有符合【任务号】的作业
MydoJob mydoJob = mydoJobMapper.selectMydoJobByJobId(jobId);
if (mydoJob == null){
return AjaxResult.error("无该任务号的执行作业,请确认该任务是否已经处理和进行其他操作");
}
//标记状态为【手动作废】插入历史表
mydoJob.setStatus(TASK_STATUS_INVALID);
mydoJob.setFinishTime(DateUtil.now());
updateMydoJob(mydoJob);
mydoJobMapper.insertHistory(mydoJob.getJobId());
try {
//处理堆垛机执行队列和历史记录
DdjDeviceExecutionQueue queue = ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueByTaskNo(mydoJob.getTaskNo());
if (queue != null){
DdjDeviceExecutionQueueFinish queueFinish = BeanUtil.copyProperties(queue, DdjDeviceExecutionQueueFinish.class);
ddjDeviceExecutionQueueServiceFinishService.insertDdjDeviceExecutionQueueFinish(queueFinish);
ddjDeviceExecutionQueueService.deleteDdjDeviceExecutionQueueByTaskNo(mydoJob.getTaskNo());
}
} catch (Exception e) {
log.warn("【人工操作】手动作废操作失败:{}", e.getMessage());
}
// JobCallBack jobCallBack = new JobCallBack();
// jobCallBack.setType(mydoJob.getInOrOut());
// jobCallBack.setTaskTypeCode(WMS_TASK_TYPE_FINISH);// wms下发的任务类型
// jobCallBack.setMydoJobId(mydoJob.getJobId());
// jobCallBack.setStatus("0");
// jobCallBack.setTaskNo(Convert.toLong(mydoJob.getTaskNo()));
// jobCallBack.setCreateTime(new Date());
// jobCallBack.setTaskCode(mydoJob.getWmsTaskNo());
// jobCallBack.setRetry(0);
// jobCallBack.setReqCode(UUID.randomUUID().toString());
// jobCallBackService.insertJobCallBack(jobCallBack);
mydoJobMapper.deleteMydoJobByJobId(jobId);
log.info("【任务手动取消】生成历史记录,插入回传列表,作业号:{}", jobId);
return AjaxResult.success("操作成功");
}
/**
* 手动作废指定【任务号】的作业(数组类型参数)
* @param JobIds
* @return
*/
@Override
public AjaxResult cancelTask(String[] JobIds) {
for (String jobId : JobIds) {
//获取所有符合【任务号】的作业
MydoJob mydoJob = mydoJobMapper.selectMydoJobByJobId(jobId);
if (mydoJob == null){
return AjaxResult.error("无该任务号的执行作业,请确认该任务是否已经处理和进行其他操作");
}
//标记状态为【手动作废】插入历史表
mydoJob.setStatus(TASK_STATUS_INVALID);
mydoJob.setFinishTime(DateUtil.now());
updateMydoJob(mydoJob);
mydoJobMapper.insertHistory(jobId);
try {
//处理堆垛机执行队列和历史记录
DdjDeviceExecutionQueue queue = ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueByTaskNo(mydoJob.getTaskNo());
if (queue != null){
DdjDeviceExecutionQueueFinish queueFinish = BeanUtil.copyProperties(queue, DdjDeviceExecutionQueueFinish.class);
ddjDeviceExecutionQueueServiceFinishService.insertDdjDeviceExecutionQueueFinish(queueFinish);
ddjDeviceExecutionQueueService.deleteDdjDeviceExecutionQueueByTaskNo(mydoJob.getTaskNo());
}
} catch (Exception e) {
log.warn("【人工操作】手动作废操作失败:{}", e.getMessage());
}
JobCallBack jobCallBack = new JobCallBack();
jobCallBack.setType(mydoJob.getInOrOut());
jobCallBack.setTaskTypeCode(WMS_TASK_TYPE_FINISH);// wms下发的任务类型
jobCallBack.setMydoJobId(jobId);
jobCallBack.setStatus("0");
jobCallBack.setTaskNo(Convert.toLong(mydoJob.getTaskNo()));
jobCallBack.setCreateTime(new Date());
jobCallBack.setTaskCode(mydoJob.getWmsTaskNo());
jobCallBack.setRetry(0);
jobCallBack.setReqCode(UUID.randomUUID().toString());
jobCallBackService.insertJobCallBack(jobCallBack);
mydoJobMapper.deleteMydoJobByJobId(jobId);
log.info("【任务手动取消】生成历史记录,插入回传列表,作业号:{},wcs任务号:{}", jobId, mydoJob.getTaskNo());
}
return AjaxResult.success("操作成功");
}
/**
* 遗留任务超时自动完成
* @param taskNo
* @return
*/
@Override
public AjaxResult compeleteTimeoutTask(String taskNo) {
//todo
return null;
}
@Override
public List<MydoJob> getInJobByEntranceId(String exitId) {
return mydoJobMapper.getInJobByEntranceId(exitId);
@@ -307,6 +573,24 @@ public class MydoJobServiceImpl implements IMydoJobService
return mydoJobMapper.selectJobByTaskNo(taskNo);
}
/** 根据条码获取托盘类型(尺寸) */
@Override
public Integer getTraytypeByTrayCode(String trayCode){
if (trayCode.startsWith("A")){
return 1;
}else if (trayCode.startsWith("B")){
return 2;
}else if (trayCode.startsWith("C")){
return 3;
}else{
return 0;
}
}
/**
* 获取本地生成作业号
* @param type RK-入库 CK-出库

View File

@@ -1,9 +1,6 @@
package com.ruoyi.queue.ddj.domain;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import lombok.*;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.annotation.Excel;
@@ -19,6 +16,7 @@ import com.ruoyi.common.core.domain.BaseEntity;
@NoArgsConstructor
@Data
@ToString
@Builder
public class DdjDeviceExecutionQueue extends BaseEntity
{
private static final long serialVersionUID = 1L;
@@ -86,11 +84,11 @@ public class DdjDeviceExecutionQueue extends BaseEntity
@Excel(name = "结束时间")
private String jssj;
/** 命令方式 */
/** 命令方式 3-取货 4-放货 5-取放 */
@Excel(name = "命令方式")
private Integer mlfs;
/** $column.columnComment */
/** $column.columnComment @@@FT577-托盘尺寸 */
@Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
private String spare1;

View File

@@ -1,6 +1,9 @@
package com.ruoyi.queue.ddj.service.impl;
import java.util.List;
import com.ruoyi.queue.ddj.domain.DdjDeviceExecutionQueue;
import com.ruoyi.queue.ddj.service.IDdjDeviceExecutionQueueService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.queue.ddj.mapper.DdjDeviceExecutionQueueFinishMapper;
@@ -19,6 +22,9 @@ public class DdjDeviceExecutionQueueFinishServiceImpl implements IDdjDeviceExecu
@Autowired
private DdjDeviceExecutionQueueFinishMapper ddjDeviceExecutionQueueFinishMapper;
@Autowired
private IDdjDeviceExecutionQueueService ddjDeviceExecutionQueueService;
/**
* 查询堆垛机完成队列
*

View File

@@ -11,6 +11,8 @@ import com.ruoyi.schedule.plcRead.ddj.PlcDdj2Read;
import com.ruoyi.schedule.plcRead.ssj.PlcSsjRead;
import com.ruoyi.common.domain.CustomThread;
import com.ruoyi.schedule.scheduleTask.ddj.DdjThread;
import com.ruoyi.schedule.scheduleTask.ddj.DdjThread_1;
import com.ruoyi.schedule.scheduleTask.ddj.DdjThread_2;
import com.ruoyi.schedule.scheduleTask.monit.MonitoringThread;
import com.ruoyi.schedule.scheduleTask.ssj.PortConvThread;
import com.ruoyi.schedule.scheduleTask.ssj.RoadConvThread;
@@ -34,19 +36,22 @@ public class ScheduleThread {
public CustomThread<PlcSsjRead> plcSsjReadCustomThread;
public CustomThread<PlcDdj1Read> plcDdj1ReadCustomThread;
// public CustomThread<PlcDdj2Read> plcDdj2ReadCustomThread;
public CustomThread<PlcDdj2Read> plcDdj2ReadCustomThread;
public CustomThread<PortConvThread> portConvCustomThread;
public CustomThread<RoadConvThread> roadConvCustomThread;
public CustomThread<MonitoringThread> monitoringCustomThread;
public CustomThread<DdjThread> ddj1CustomThread;
public CustomThread<DdjThread> ddjCustomThread;
public CustomThread<DdjThread_1> ddj1CustomThread;
public CustomThread<DdjThread_2> ddj2CustomThread;
@Autowired
private IDeviceSsjService deviceSsjService;
@Autowired
private IMsgDdjService msgDdjService;
private boolean isRun = false;
// private boolean isRun1 = false;
private boolean isRun2 = false;
/**
@@ -78,8 +83,10 @@ public class ScheduleThread {
RoadConvThread roadConvThread = new RoadConvThread();
roadConvCustomThread = new CustomThread<RoadConvThread>(new Thread(roadConvThread), roadConvThread);
DdjThread ddj1Thread = new DdjThread();
ddj1CustomThread = new CustomThread<DdjThread>(new Thread(ddj1Thread), ddj1Thread);
DdjThread_1 ddj1Thread = new DdjThread_1();
DdjThread_2 ddj2Thread = new DdjThread_2();
ddj1CustomThread = new CustomThread<DdjThread_1>(new Thread(ddj1Thread), ddj1Thread);
ddj2CustomThread = new CustomThread<DdjThread_2>(new Thread(ddj2Thread), ddj2Thread);
}
/**
@@ -99,7 +106,7 @@ public class ScheduleThread {
//获取堆垛机
ConcurrentHashMap<String, MsgDdj> ddj1List = new ConcurrentHashMap<>();
// ConcurrentHashMap<String, MsgDdj> ddj2List = new ConcurrentHashMap<>();
ConcurrentHashMap<String, MsgDdj> ddj2List = new ConcurrentHashMap<>();
List<MsgDdj> msgDdjs = msgDdjService.selectMsgDdjList(new MsgDdj());
for (MsgDdj msgDdj : msgDdjs) {
msgDdj.setPlcDbReadAddress(msgDdj.getPlcDbReadAddress());
@@ -111,13 +118,13 @@ public class ScheduleThread {
ddj1List.put("ddj1", msgDdj);
PlcDdj1Read.deviceDdjMap = ddj1List;
break;
// case 2:
// PlcDdj2Read plcDdj2Read = new PlcDdj2Read(msgDdj, new PlcConnectInfo(msgDdj.getIp(), Convert.toInt(msgDdj.getPort())));
// Thread plcDdj2ReadThread = new Thread(plcDdj2Read);
// plcDdj2ReadCustomThread = new CustomThread<PlcDdj2Read>(plcDdj2ReadThread, plcDdj2Read);
// ddj2List.put("ddj2", msgDdj);
// PlcDdj2Read.deviceDdjMap = ddj2List;
// break;
case 2:
PlcDdj2Read plcDdj2Read = new PlcDdj2Read(msgDdj, new PlcConnectInfo(msgDdj.getIp(), Convert.toInt(msgDdj.getPort())));
Thread plcDdj2ReadThread = new Thread(plcDdj2Read);
plcDdj2ReadCustomThread = new CustomThread<PlcDdj2Read>(plcDdj2ReadThread, plcDdj2Read);
ddj2List.put("ddj2", msgDdj);
PlcDdj2Read.deviceDdjMap = ddj2List;
break;
}
}
}
@@ -128,7 +135,7 @@ public class ScheduleThread {
public void startAllThread() {
plcSsjReadCustomThread.getThread().start();
plcDdj1ReadCustomThread.getThread().start();
// plcDdj2ReadCustomThread.getThread().start();
plcDdj2ReadCustomThread.getThread().start();
isRun = true;
}
@@ -140,6 +147,7 @@ public class ScheduleThread {
portConvCustomThread.thread.start();
roadConvCustomThread.thread.start();
ddj1CustomThread.thread.start();
ddj2CustomThread.thread.start();
isRun2 = true;
}
@@ -149,7 +157,7 @@ public class ScheduleThread {
public void stopAllThread() {
plcSsjReadCustomThread.runnable.isRun = false;
plcDdj1ReadCustomThread.runnable.isRun = false;
// plcDdj2ReadCustomThread.runnable.isRun = false;
plcDdj2ReadCustomThread.runnable.isRun = false;
plcReadInit();
isRun = false;
}
@@ -163,6 +171,7 @@ public class ScheduleThread {
roadConvCustomThread.runnable.isRun = false;
ddj1CustomThread.runnable.isRun = false;
ddj2CustomThread.runnable.isRun = false;
scheduleInit();
isRun2 = false;
}

View File

@@ -39,8 +39,9 @@ public class PlcDdj1Read extends Thread {
try {
if (IsConnect()) {
readPlcDdj(msgDdj);
Thread.sleep(800);
Thread.sleep(1000);
} else {
Thread.sleep(2000);
reConnect();
}
} catch (InterruptedException e) {
@@ -54,7 +55,7 @@ public class PlcDdj1Read extends Thread {
}
private void readPlcDdj(MsgDdj msgDdj) {
OperateResultExOne<byte[]> read2 = readWriteNet.Read(msgDdj.getPlcDbReadAddress(), Convert.toShort("38"));
OperateResultExOne<byte[]> read2 = readWriteNet.Read(msgDdj.getPlcDbReadAddress(), Convert.toShort("32"));
String ddsx = "0";
if (read2.IsSuccess) {
ddsx = SoftBasic.ByteToHexString(read2.Content);
@@ -71,6 +72,7 @@ public class PlcDdj1Read extends Thread {
msgDdj.setMbch(ParseUtil.optInt(22, ddsx));
msgDdj.setYxxf(ParseUtil.optInt(24, ddsx));
msgDdj.setXtxh(ParseUtil.optInt(26, ddsx));
msgDdj.setHeight(ParseUtil.optInt(30, ddsx));
msgDdj.setCurrentRow(ParseUtil.optInt(12, ddsx));
msgDdj.setCurrentColumn(ParseUtil.optInt(14, ddsx));

View File

@@ -39,8 +39,9 @@ public class PlcDdj2Read extends Thread {
try {
if (IsConnect()) {
readPlcDdj(msgDdj);
Thread.sleep(800);
Thread.sleep(1000);
} else {
Thread.sleep(2000);
reConnect();
}
} catch (InterruptedException e) {
@@ -54,7 +55,7 @@ public class PlcDdj2Read extends Thread {
}
private void readPlcDdj(MsgDdj msgDdj) {
OperateResultExOne<byte[]> read2 = readWriteNet.Read(msgDdj.getPlcDbReadAddress(), Convert.toShort("38"));
OperateResultExOne<byte[]> read2 = readWriteNet.Read(msgDdj.getPlcDbReadAddress(), Convert.toShort("34"));
String ddsx = "0";
if (read2.IsSuccess) {
ddsx = SoftBasic.ByteToHexString(read2.Content);
@@ -71,10 +72,12 @@ public class PlcDdj2Read extends Thread {
msgDdj.setMbch(ParseUtil.optInt(22, ddsx));
msgDdj.setYxxf(ParseUtil.optInt(24, ddsx));
msgDdj.setXtxh(ParseUtil.optInt(26, ddsx));
msgDdj.setDqxd(ParseUtil.optInt(30, ddsx));
msgDdj.setHeight(ParseUtil.optInt(32, ddsx));
msgDdj.setCurrentRow(ParseUtil.optInt(26, ddsx));
msgDdj.setCurrentColumn(ParseUtil.optInt(26, ddsx));
msgDdj.setCurrentFloor(ParseUtil.optInt(26, ddsx));
msgDdj.setCurrentRow(ParseUtil.optInt(12, ddsx));
msgDdj.setCurrentColumn(ParseUtil.optInt(14, ddsx));
msgDdj.setCurrentFloor(ParseUtil.optInt(16, ddsx));
}
}

View File

@@ -53,15 +53,16 @@ public class PlcSsjRead implements Runnable {
DeviceSsj ssjDevice = deviceSsjMap.get(ssjCode);
switch (ssjDevice.getType()) {
case "1":
readPlcInOutSsj(ssjDevice);//出入口输送机
readPlcInSsj(ssjDevice);//出库输送机
break;
case "2":
readPlcRoadWaySsj(ssjDevice);//巷道输送机
readPlcRoadWaySsj(ssjDevice);//巷道输送机(入库)
break;
}
}
Thread.sleep(800);
Thread.sleep(1000);
} else {
Thread.sleep(2000);
reConnect();
}
} catch (InterruptedException e) {
@@ -77,29 +78,30 @@ public class PlcSsjRead implements Runnable {
/**
* 其他输送机
* 出库输送机 1001 1004 1006 1008
*
* @param ssjDevice
*/
private void readPlcOtherSsj(DeviceSsj ssjDevice) {
OperateResultExOne<byte[]> read2 = readWriteNet.Read(ssjDevice.getPlcDbReadAddress(), Short.parseShort("10"));
private void readPlcInSsj(DeviceSsj ssjDevice) {
OperateResultExOne<byte[]> read2 = readWriteNet.Read(ssjDevice.getPlcDbReadAddress(), Short.parseShort("12"));
String ddsx1 = "0";
if (read2.IsSuccess) {
ddsx1 = SoftBasic.ByteToHexString(read2.Content);
ssjDevice.setKx(ParseUtil.optInt(0, ddsx1));
ssjDevice.setDw(ParseUtil.optInt(2, ddsx1));
ssjDevice.setSszt(ParseUtil.optInt(0, ddsx1));
ssjDevice.setKx(ParseUtil.optInt(2, ddsx1));
ssjDevice.setDw(ParseUtil.optInt(4, ddsx1));
ssjDevice.setTaskNo(ParseUtil.optDInt(6, ddsx1));
}
}
/**
* 入出库输送机
* 入库输送机 1003 1005 1007 1010
*
* @param ssjDevice
*/
private void readPlcInOutSsj(DeviceSsj ssjDevice) {
OperateResultExOne<byte[]> read2 = readWriteNet.Read(ssjDevice.getPlcDbReadAddress(), Short.parseShort("30"));
private void readPlcRoadWaySsj(DeviceSsj ssjDevice) {
OperateResultExOne<byte[]> read2 = readWriteNet.Read(ssjDevice.getPlcDbReadAddress(), Short.parseShort("26"));
String ddsx1 = "0";
if (read2.IsSuccess) {
ddsx1 = SoftBasic.ByteToHexString(read2.Content);
@@ -110,19 +112,19 @@ public class PlcSsjRead implements Runnable {
ssjDevice.setRkqq(ParseUtil.optInt(10, ddsx1));
ssjDevice.setHeight(ParseUtil.optInt(12, ddsx1));
ssjDevice.setTraySize(ParseUtil.optInt(12, ddsx1)); //此处不修改device_ssj表,把托盘尺寸值当作高度使用
ssjDevice.setTrayCode(ParseUtil.optString(14, ddsx1).replaceAll("\\s", ""));
ssjDevice.setMode(ParseUtil.optInt(24, ddsx1));//todo 输送机操作模式
ssjDevice.setException(ParseUtil.optInt(28, ddsx1));
ssjDevice.setException(ParseUtil.optInt(14, ddsx1));
ssjDevice.setTrayCode(ParseUtil.optString(18, ddsx1).replaceAll("\\s", ""));
// ssjDevice.setMode(ParseUtil.optInt(24, ddsx1));//todo 输送机操作模式
}
}
/**
* 巷道输送机
* 出入口输送机
*
* @param ssjDevice
*/
private void readPlcRoadWaySsj(DeviceSsj ssjDevice) {
private void readPlcInOutSsj(DeviceSsj ssjDevice) {
OperateResultExOne<byte[]> read2 = readWriteNet.Read(ssjDevice.getPlcDbReadAddress(), Short.parseShort("10"));
String ddsx1 = "0";
if (read2.IsSuccess) {

View File

@@ -46,7 +46,7 @@ public class ParseUtil {
*/
public static String optString(int start, String data) {
byte[] bytes = SoftBasic.HexStringToBytes(data.substring(start * 2, (start + 7) * 2));
byte[] bytes = SoftBasic.HexStringToBytes(data.substring(start * 2, (start + 8) * 2));
return Tools.bytetostringtool(bytes);
}

View File

@@ -1,28 +1,43 @@
package com.ruoyi.schedule.scheduleTask;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjUtil;
import com.alibaba.fastjson2.JSON;
import com.ruoyi.api.domain.agv.ResponseBase;
import com.ruoyi.api.domain.wcs2wms.JobParam;
import com.ruoyi.api.domain.wcs2wms.exception.TaskExceptionReceive;
import com.ruoyi.api.domain.wcs2wms.exception.TaskExceptionRequest;
import com.ruoyi.api.domain.wcs2wms.stockin.StockinReceive;
import com.ruoyi.api.service.IApiService;
import com.ruoyi.api.service.IRequestLogService;
import com.ruoyi.bas.cargospace.domain.BasCargoSpace;
import com.ruoyi.bas.cargospace.service.IBasCargoSpaceService;
import com.ruoyi.common.ConvType;
import com.ruoyi.common.TaskType;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.device.ddj.domain.MsgDdj;
import com.ruoyi.device.ddj.service.IMsgDdjService;
import com.ruoyi.job.domain.MydoJob;
import com.ruoyi.job.service.IJobCallBackService;
import com.ruoyi.job.service.IMydoJobService;
import com.ruoyi.queue.ddj.domain.DdjDeviceExecutionQueue;
import com.ruoyi.queue.ddj.domain.DdjDeviceExecutionQueueFinish;
import com.ruoyi.queue.ddj.service.IDdjDeviceExecutionQueueFinishService;
import com.ruoyi.queue.ddj.service.IDdjDeviceExecutionQueueService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.List;
import static com.ruoyi.common.TaskExceptionType.TASK_EXCEPTION_STOCKIN_OCCUPIED;
import static com.ruoyi.common.TaskStatusCode.*;
import static com.ruoyi.common.WmsTaskTypeCode.WMS_TASK_TYPE_EXCEPTION;
/**
* 处理wcs执行作业的定时任务类
@@ -41,40 +56,39 @@ public class TaskHandler {
private IApiService apiService;
@Autowired
private IDdjDeviceExecutionQueueService ddjDeviceExecutionQueueService;
@Autowired
IDdjDeviceExecutionQueueFinishService ddjDeviceExecutionQueueFinishService;
@Autowired
IMsgDdjService ddjService;
@Autowired
IRequestLogService requestLogService;
private static final int DEFAULTTIMEINTERVAL = 2000;
// private SiemensS7Net siemens = new SiemensS7Net(SiemensPLCS.S1500, "192.168.56.60");
private static final int TIMEINTERVAL_DEFAULT = 2000;
private static final int TIMEINTERVAL_3000 = 3000;
private static final int TIMEINTERVAL_5000 = 5000;
private static final int TIMEINTERVAL_10000 = 10000;
/**
* 处理未正常移除的【堆垛机执行完成】或【出库到位】的遗留任务
* 【自动完成】 - 处理标记为自动完成的任务
*/
// @Scheduled(fixedDelay = 3000)
public void mydoJobHandler() {
@Scheduled(fixedDelay = TIMEINTERVAL_DEFAULT)
public void mydoJobAutoFinish() {
//查询所有标记为【已完成】的任务
List<MydoJob> jobs = mydoJobService.selectMydoJobList(
new MydoJob().builder().executionPhase(TASK_EP_FINISH).build()
);
if (!jobs.isEmpty()) {
for (MydoJob job : jobs) {
mydoJobService.taskFinish(Long.valueOf(job.getTaskNo()));
}
}
}
/**
* 【手动作废】 - 查询并处理标记为已经作废的任务
*/
//@Scheduled(fixedDelay = 3000)
public void cancelMydoJob(){
List<MydoJob> jobs = mydoJobService.selectInOrOutMydoJobList(
new MydoJob().builder().status(TASK_STATUS_INVALID).build()
);
if (!jobs.isEmpty()) {
for (MydoJob job : jobs) {
mydoJobService.ManuelTaskFinish(job.getTaskNo());
if (!job.getInOrOut().equals(TaskType.TASKTYPE_STOCKOUT) &&
!job.getInOrOut().equals(TaskType.TASKTYPE_STOCKOUT_PICK) &&
!job.getInOrOut().equals(TaskType.TASKTYPE_STOCKOUT_MANUAL)) {
mydoJobService.taskFinish(Long.valueOf(job.getTaskNo()));
}
}
}
}
@@ -83,15 +97,49 @@ public class TaskHandler {
/**
* 【手动完成】 - 查询并处理标记为已经手动完成的任务
*/
//@Scheduled(fixedDelay = 3000)
public void finishMydoJob(){
List<MydoJob> jobs = mydoJobService.selectInOrOutMydoJobList(
@Scheduled(fixedDelay = TIMEINTERVAL_DEFAULT)
public void manualFinishmydoJob() {
//查询所有标记为【已完成】的任务
List<MydoJob> jobs = mydoJobService.selectMydoJobList(
new MydoJob().builder().status(TASK_STATUS_FINISH_MANUAL).build()
);
if (!jobs.isEmpty()) {
for (MydoJob job : jobs) {
mydoJobService.manualCompeleteTaskByJobId(job.getJobId());
}
}
}
/**
* 【手动作废】 - 查询并处理标记为已经作废的任务
*/
@Scheduled(fixedDelay = TIMEINTERVAL_DEFAULT)
public void cancelMydoJob(){
List<MydoJob> jobs = mydoJobService.selectMydoJobList(
new MydoJob().builder().status(TASK_STATUS_INVALID).build()
);
if (!jobs.isEmpty()) {
for (MydoJob job : jobs) {
mydoJobService.ManuelTaskFinish(job.getTaskNo());
mydoJobService.cancelTask(job.getJobId());
}
}
}
/**
* 【超时自动完成】 - 处理未正常移除的【堆垛机执行完成】或【出库到位】的遗留任务
*/
// @Scheduled(fixedDelay = TIMEINTERVAL_10000)
public void finishMydoJobTimeout(){
List<MydoJob> jobs = mydoJobService.selectMydoJobList(
new MydoJob().builder().status(TASK_EP_DDJ_FINISH_TIMEOUT).build()
);
if (!jobs.isEmpty()) {
for (MydoJob job : jobs) {
mydoJobService.compeleteTimeoutTask(job.getTaskNo());
}
}
}
@@ -100,87 +148,43 @@ public class TaskHandler {
/**
* 定时扫描未回传或回传异常的任务记录
*/
@Scheduled(fixedDelay = 3000)
@Scheduled(fixedDelay = TIMEINTERVAL_DEFAULT)
public void jobCallBack() {
jobCallBackService.jobCallBack();
}
/**
* 【入库异常-请求重分】 - 【放货有货】处理方法
*/
@Scheduled(fixedDelay = DEFAULTTIMEINTERVAL)
public void stockinExceptionHandler() {
List<MydoJob> jobs = mydoJobService.selectInOrOutMydoJobList(
new MydoJob().builder().executionPhase(TASK_EXCEPTION_PUT).build()
);
if (!jobs.isEmpty()) {
for (MydoJob job : jobs) {
String oldCargo = job.getCargoSpaceId();
//上报异常 - 向wms请求重分接口
TaskExceptionRequest taskExceptionRequest = new TaskExceptionRequest();
taskExceptionRequest.setTaskClass(job.getInOrOut().substring(0, 1));
taskExceptionRequest.setType(String.valueOf(TASK_EXCEPTION_STOCKIN_OCCUPIED));
taskExceptionRequest.setTaskCode(job.getWmsTaskNo());
taskExceptionRequest.setTaskTypeCode(WMS_TASK_TYPE_EXCEPTION);//wms自定义文本
taskExceptionRequest.setReqCode(UUID.randomUUID().toString().replace("-", ""));
taskExceptionRequest.setAdverseCauses("当前位置已有货物,盘点后重新分配货位");
AjaxResult ajaxResult = apiService.reAssign(taskExceptionRequest);
if (ajaxResult.isSuccess()){
//获取返回的任务号和新分配的货位
TaskExceptionReceive mydoJobReAssign = BeanUtil.toBean(ajaxResult.get("data"), TaskExceptionReceive.class);
MydoJob wmsJob = new MydoJob();
wmsJob.setWmsTaskNo(mydoJobReAssign.getTaskCode());
if (mydoJobService.selectMydoJobList(wmsJob).size() == 0) {
log.warn("【响应异常】该任务不存在,任务号:{}", mydoJobReAssign.getTaskCode());
return;
}
//更新任务参数
job = mydoJobService.selectMydoJobByTaskNo(Long.valueOf(job.getTaskNo()));
job.setCargoSpaceId(mydoJobReAssign.getSiteCode());
job.setExecutionPhase(TASK_EXCEPTION_PUT_REASSIGN);
job.setFaultFlag("2");
mydoJobService.updateMydoJob(job);
log.info("【入库异常】请求wms重分货位成功,异常货位:{},新货位:{},任务号:{}", oldCargo, mydoJobReAssign.getSiteCode(), job.getTaskNo());
}else{
log.info("【入库异常】请求wms重分货位异常,异常上报请求失败,请咨询操作管理员,异常货位:{},当前任务号:{}", oldCargo, job.getTaskNo());
}
}
}
}
/**
* 【出库异常】 - 【取货无货】处理方法
*/
@Scheduled(fixedDelay = DEFAULTTIMEINTERVAL)
@Scheduled(fixedDelay = TIMEINTERVAL_DEFAULT)
public void stockoutExceptionHandler() {
List<MydoJob> jobs = mydoJobService.selectInOrOutMydoJobList(
List<MydoJob> jobs = mydoJobService.selectMydoJobList(
new MydoJob().builder().executionPhase(TASK_EXCEPTION_PICK).build()
);
if (!jobs.isEmpty()) {
for (MydoJob job : jobs) {
//向wms返回异常信息
TaskExceptionRequest taskExceptionRequest = new TaskExceptionRequest();
taskExceptionRequest.setTaskClass(job.getInOrOut().substring(0, 1));
taskExceptionRequest.setType(String.valueOf(TASK_EXCEPTION_STOCKIN_OCCUPIED));
taskExceptionRequest.setTaskCode(String.valueOf(job.getWmsTaskNo()));
taskExceptionRequest.setTaskTypeCode(WMS_TASK_TYPE_EXCEPTION);//todo 不知道填什么
taskExceptionRequest.setReqCode(UUID.randomUUID().toString().replace("-", ""));
taskExceptionRequest.setAdverseCauses("取货位置空,盘点后作废该任务");
// TaskExceptionRequest taskExceptionRequest = new TaskExceptionRequest();
// taskExceptionRequest.setTaskClass(job.getInOrOut().substring(0, 1));
// taskExceptionRequest.setType(String.valueOf(TASK_EXCEPTION_STOCKIN_OCCUPIED));
// taskExceptionRequest.setTaskCode(String.valueOf(job.getWmsTaskNo()));
// taskExceptionRequest.setTaskTypeCode(WMS_TASK_TYPE_EXCEPTION);//todo 不知道填什么
// taskExceptionRequest.setReqCode(UUID.randomUUID().toString().replace("-", ""));
// taskExceptionRequest.setAdverseCauses("取货位置空,盘点后作废该任务");
AjaxResult ajaxResult = apiService.reMaterial(taskExceptionRequest);
JobParam param = new JobParam();
param.setJobId(job.getJobId());
param.setTaskNo(job.getTaskNo());
param.setTrayCode(job.getTrayCode());
param.setCargoSpaceId(job.getCargoSpaceId());
AjaxResult ajaxResult = apiService.reMaterial(param);
if (ajaxResult.isSuccess()){
mydoJobService.InvalidMydoJob(Long.valueOf(job.getTaskNo()), Integer.valueOf(job.getRoadwayId()));
// mydoJobService.InvalidMydoJob(Long.valueOf(job.getTaskNo()), Integer.valueOf(job.getRoadwayId()));
mydoJobService.cancelTask(job.getJobId());
//清空/重置【取货无货】的出库异常货位库存信息
basCargoSpaceService.resetCargoSpaceByStockoutException(job.getCargoSpaceId());
@@ -196,12 +200,74 @@ public class TaskHandler {
}
/**
* 【入库异常-请求重分】 - 【放货有货】处理方法
*/
@Scheduled(fixedDelay = TIMEINTERVAL_DEFAULT)
public void stockinExceptionHandler() {
List<MydoJob> jobs = mydoJobService.selectMydoJobList(
new MydoJob().builder().executionPhase(TASK_EXCEPTION_PUT).build()
);
if (!jobs.isEmpty()) {
for (MydoJob job : jobs) {
String oldCargo = job.getCargoSpaceId();
//上报异常 - 向wms请求重分接口
// TaskExceptionRequest taskExceptionRequest = new TaskExceptionRequest();
// taskExceptionRequest.setTaskClass(job.getInOrOut().substring(0, 1));
// taskExceptionRequest.setType(String.valueOf(TASK_EXCEPTION_STOCKIN_OCCUPIED));
// taskExceptionRequest.setTaskCode(job.getWmsTaskNo());
// taskExceptionRequest.setTaskTypeCode(WMS_TASK_TYPE_EXCEPTION);//wms自定义文本
// taskExceptionRequest.setReqCode(UUID.randomUUID().toString().replace("-", ""));
// taskExceptionRequest.setAdverseCauses("当前位置已有货物,盘点后重新分配货位");
JobParam param = new JobParam();
param.setJobId(job.getJobId());
param.setTaskNo(job.getTaskNo());
param.setTrayCode(job.getTrayCode());
param.setCargoSpaceId(job.getCargoSpaceId());
AjaxResult ajaxResult = apiService.reAssign(param);
if (ajaxResult.isSuccess()){
//获取返回的任务号和新分配的货位
JobParam jobParam = BeanUtil.toBean(ajaxResult.get("data"), JobParam.class);
if (ObjUtil.isNull(jobParam)){
log.warn("【响应异常】入库重分请求异常,无响应数据,任务号:{}", jobParam.getTaskNo());
return;
}
MydoJob wmsJob = new MydoJob();
wmsJob.setTaskNo(jobParam.getTaskNo());
if (ObjUtil.isNull(wmsJob)) {
log.warn("【响应异常】该任务不存在,任务号:{}", jobParam.getTaskNo());
return;
}
//更新任务参数
job = mydoJobService.selectMydoJobByTaskNo(Long.valueOf(job.getTaskNo()));
job.setCargoSpaceId(jobParam.getCargoSpaceId());
job.setExecutionPhase(TASK_EXCEPTION_PUT_REASSIGN);
job.setFaultFlag("2");
mydoJobService.updateMydoJob(job);
log.info("【入库异常】请求wms重分货位成功,异常货位:{},新货位:{},任务号:{}", oldCargo, jobParam.getCargoSpaceId(), job.getTaskNo());
}else{
log.info("【入库异常】请求wms重分货位异常,异常上报请求失败,请咨询操作管理员,异常货位:{},当前任务号:{}", oldCargo, job.getTaskNo());
}
}
}
}
/**
* 【入库异常-重分完成】 - 堆垛机重新下发
*/
@Scheduled(fixedDelay = DEFAULTTIMEINTERVAL)
@Scheduled(fixedDelay = TIMEINTERVAL_DEFAULT)
public void sendTaskForStacker(){
List<MydoJob> jobs = mydoJobService.selectInOrOutMydoJobList(
List<MydoJob> jobs = mydoJobService.selectMydoJobList(
new MydoJob().builder().executionPhase(TASK_EXCEPTION_PUT_REASSIGN).build()
);
@@ -222,4 +288,295 @@ public class TaskHandler {
}
/**
* 【更新作业状态】 - 巷道口到位生成堆垛机【取货】作业
*/
// @Scheduled(fixedDelay = TIMEINTERVAL_DEFAULT)
public void updateStackerPickStatus() {
List<MydoJob> jobs = mydoJobService.selectMydoJobList(
new MydoJob().builder().status(TASK_STATUS_RUNNING).executionPhase(TASK_EP_ROADWAY_SSJ).build()
);
if (jobs.isEmpty()) return;
for (MydoJob job : jobs) {
// 生成堆垛机取货队列
if (Convert.toInt(job.getInOrOut()) >= 20) continue;
//弯轨堆垛机设备编号使用货位区域编号对应
int devId = 2;
if (job.getRoadwayId().equals("1")) {
devId = 1;
}
//检查堆垛机是否在正在执行中/已经有执行队列
List<DdjDeviceExecutionQueue> ddjDeviceExecutionQueues = ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueList(
new DdjDeviceExecutionQueue().builder().devId(devId).build()
);
//取货位置
BasCargoSpace basCargoSpace = basCargoSpaceService.selectBasCargoSpaceByCargoSpaceId(
ConvType.CONV_ROAD_CARGO.get(job.getEntranceId())
);
MsgDdj msgDdj = ddjService.selectMsgDdjById(Long.valueOf(devId));
//生成堆垛机执行队列
//生成取货作业时货叉必须有货 - 即【货叉状态】不为0
if (CollUtil.isEmpty(ddjDeviceExecutionQueues) && msgDdj.getHczt() == 0) {
DdjDeviceExecutionQueue ddjDeviceExecutionQueue = new DdjDeviceExecutionQueue();
ddjDeviceExecutionQueue.setUuid(IdUtil.simpleUUID());
ddjDeviceExecutionQueue.setRwh(Convert.toLong(job.getTaskNo()));
ddjDeviceExecutionQueue.setDevName(job.getRoadwayId());
ddjDeviceExecutionQueue.setDevId(devId);
ddjDeviceExecutionQueue.setRwzt(0);
ddjDeviceExecutionQueue.setYph(Convert.toInt(basCargoSpace.getThePlatoon()));
ddjDeviceExecutionQueue.setYlh(Convert.toInt(basCargoSpace.getTheColumn()));
ddjDeviceExecutionQueue.setYch(Convert.toInt(basCargoSpace.getTheFloor()));
ddjDeviceExecutionQueue.setMbph(Convert.toInt(basCargoSpace.getThePlatoon()));
ddjDeviceExecutionQueue.setMblh(1);
ddjDeviceExecutionQueue.setMbch(1);
ddjDeviceExecutionQueue.setDdjxf("0");
ddjDeviceExecutionQueue.setMlfs(3);//3-取货
// ddjDeviceExecutionQueue.setSpare1(job.getTraySize().toString());//货物高度
ddjDeviceExecutionQueue.setScsj(DateUtil.formatDateTime(DateUtil.date()));
// ddjDeviceExecutionQueue.setRwlx(DDJ_RWLX_3);
ddjDeviceExecutionQueueService.insertDdjDeviceExecutionQueue(ddjDeviceExecutionQueue);
log.info("【堆垛机执行】{}#堆垛机生成入库<取货>队列,任务号:{}", devId, job.getTaskNo());
}
}
}
/**
* 【更新作业状态】 - 取货完成--→请求wms并生成堆垛机放货任务
*/
// @Scheduled(fixedDelay = TIMEINTERVAL_DEFAULT)
public void updateStackerPutStatus(){
List<MydoJob> jobs = mydoJobService.selectMydoJobList(
new MydoJob().builder().status(TASK_STATUS_RUNNING).executionPhase(TASK_EP_DDJ_PICK).build()
);
if (jobs.isEmpty()) return;
for (MydoJob job : jobs) {
DdjDeviceExecutionQueue queue = ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueByTaskNo(job.getTaskNo());
DdjDeviceExecutionQueueFinish queueFinish = new DdjDeviceExecutionQueueFinish();
if (ObjUtil.isNotNull(queue)){
BeanUtils.copyProperties(queue, queueFinish);
//插入历史
ddjDeviceExecutionQueueFinishService.insertDdjDeviceExecutionQueueFinish(queueFinish);
//移除队列
ddjDeviceExecutionQueueService.deleteDdjDeviceExecutionQueueByTaskNo(job.getTaskNo());
log.info("【堆垛机执行】移除堆垛机入库取货队列,任务号:{}", job.getTaskNo());
}
Long ddjId = Convert.toInt(job.getRoadwayId()) == 1 ? 1L : 2L;
MsgDdj msgDdj = ddjService.selectMsgDdjById(ddjId);
if (msgDdj.getYxxf() != 1) continue;
if (msgDdj.getSbzt() != 0) continue;
if (msgDdj.getCzfs() != 5) continue;
if (msgDdj.getHeight() == 0) continue;
if (msgDdj.getHczt() == 0) continue;//货叉有货才能继续请求货位
//请求wms获取作业号和货位
//初始化请求wms参数
HashMap<String, Object> paramMap = new HashMap<>();
paramMap.put("reqCode", UUID.randomUUID().toString());//请求码
paramMap.put("trayCode", job.getTrayCode().trim());//容器编号
paramMap.put("entranceId", job.getEntranceId());//入口输送机编号
paramMap.put("roadwayId", job.getRoadwayId());//入口输送机编号对应巷道/区域
paramMap.put("cargoAreaId", ConvType.CONV_ROAD_AREA.get(job.getEntranceId()));//入口输送机编号对应巷道/区域
paramMap.put("height", msgDdj.getHeight());//高度
// paramMap.put("remark", errorMessage);
AjaxResult ajaxResult;
String errorMessage = "";
/*-----------------请求生成wcs任务----------------- */
ajaxResult = apiService.createMydoJobForStockin(paramMap);
if (ajaxResult.isSuccess()) {
if (job.getExecutionPhase().equals(TASK_EP_DDJ_PICK)){
job.setExecutionPhase(TASK_EP_DDJ);
mydoJobService.updateMydoJob(job);
}
//解析wms下发的响应参数(任务号和货位)
ResponseBase res = JSON.parseObject(ajaxResult.get("msg").toString(), ResponseBase.class);
StockinReceive result = BeanUtil.toBean(res.getData(), StockinReceive.class);
//校验:wms分配的货位(排列层)是否合法
if (ObjUtil.isNull(basCargoSpaceService.selectBasCargoSpaceByCargoSpaceId(result.getCargoSpaceId()))) {
errorMessage = "wms下发货位错误,任务生成失败!";
paramMap.put("remark", errorMessage);
// apiService.createInMydoJobException(paramMap);
log.info("【响应参数异常】异常货位:{},无法生成作业,托盘条码:{}", result.getCargoSpaceId(), job.getTrayCode());
return;
}
job.setJobId(result.getJobId());
job.setInOrOut(result.getInOrOut());
job.setCargoSpaceId(result.getCargoSpaceId());
mydoJobService.updateMydoJob(job);
log.info(
"【堆垛机入库请求】请求wms分配货位成功,wms作业号:{}, wcs任务号:{},分配货位:{}", job.getJobId(), job.getTaskNo(), job.getCargoSpaceId()
);
//生成堆垛机<放货>队列
// 检查任务属性:【任务已存在】、执行阶段-【巷道口输送机到位】、任务类型-【入库】 → 下发堆垛机执行队列
if (Convert.toInt(job.getInOrOut()) < 20) {
//弯轨堆垛机设备编号使用货位区域编号对应
int devId = 2;
if (basCargoSpaceService.selectBasCargoSpaceByCargoSpaceId(job.getCargoSpaceId()).getCargoAreaId().equals("01")){
devId = 1;
}
//检查堆垛机是否在正在执行中/已经有执行队列
List<DdjDeviceExecutionQueue> ddjDeviceExecutionQueues = ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueList(
new DdjDeviceExecutionQueue().builder().devId(devId).build()
);
//目标位置
BasCargoSpace basCargoSpacePut = basCargoSpaceService.selectBasCargoSpaceByWmsCargoSpaceId(job.getCargoSpaceId());
//取货位置
BasCargoSpace basCargoSpacePick = basCargoSpaceService.selectBasCargoSpaceByCargoSpaceId(
ConvType.CONV_ROAD_CARGO.get(job.getEntranceId())
);
//生成堆垛机执行队列
if (CollUtil.isEmpty(ddjDeviceExecutionQueues) && ObjUtil.isNotNull(basCargoSpacePut) && msgDdj.getHczt() != 0) {
DdjDeviceExecutionQueue ddjDeviceExecutionQueue = new DdjDeviceExecutionQueue();
ddjDeviceExecutionQueue.setUuid(IdUtil.simpleUUID());
ddjDeviceExecutionQueue.setRwh(Convert.toLong(job.getTaskNo()));
ddjDeviceExecutionQueue.setDevName("ddj" + devId);
ddjDeviceExecutionQueue.setDevId(devId);
ddjDeviceExecutionQueue.setRwzt(0);
ddjDeviceExecutionQueue.setYph(basCargoSpacePick.getThePlatoon());
ddjDeviceExecutionQueue.setYlh(basCargoSpacePick.getTheColumn());
ddjDeviceExecutionQueue.setYch(basCargoSpacePick.getTheFloor());
ddjDeviceExecutionQueue.setMbph(Convert.toInt(basCargoSpacePut.getThePlatoon()));
ddjDeviceExecutionQueue.setMblh(Convert.toInt(basCargoSpacePut.getTheColumn()));
ddjDeviceExecutionQueue.setMbch(Convert.toInt(basCargoSpacePut.getTheFloor()));
ddjDeviceExecutionQueue.setDdjxf("0");
ddjDeviceExecutionQueue.setMlfs(4);//4-放货
// ddjDeviceExecutionQueue.setSpare1(job.getTraySize().toString());//货物高度
ddjDeviceExecutionQueue.setScsj(DateUtil.formatDateTime(DateUtil.date()));
// ddjDeviceExecutionQueue.setRwlx(DDJ_RWLX_3);
ddjDeviceExecutionQueueService.insertDdjDeviceExecutionQueue(ddjDeviceExecutionQueue);
log.info("【堆垛机执行】{}#堆垛机生成入库放货作业,wcs任务号:{}", Long.valueOf(job.getRoadwayId()), job.getTaskNo());
}
}
}else{
// 接口调用失败处理
log.info("【入库请求】请求分配货位失败,请检查网络或请求参数,请求内容:{}", JSON.toJSONString(paramMap));
log.info("【错误信息】{}", requestLogService.selectRequestLogByLatestTask().getErrorDetails());
// 请求生成wcs任务失败
//todo 向堆垛机下发退回
}
}
}
/**
* 【移库作业】 - 取放
*/
@Scheduled(fixedDelay = TIMEINTERVAL_DEFAULT)
public void sendStackerMoveJob() {
List<MydoJob> jobs = mydoJobService.selectMydoJobList(
new MydoJob().builder().status(TASK_STATUS_CREATED).executionPhase(TASK_EP_CREATED).inOrOut(TaskType.TASKTYPE_MOVE_STR).build()
);
if (jobs.isEmpty()) return;
for (MydoJob job : jobs) {
//弯轨堆垛机设备编号使用货位区域编号对应
int devId = 2;
if (job.getRoadwayId().equals("1")) {
devId = 1;
}
//检查堆垛机是否在正在执行中/已经有执行队列
List<DdjDeviceExecutionQueue> ddjDeviceExecutionQueues = ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueList(
new DdjDeviceExecutionQueue().builder().devId(devId).build()
);
//取货位置
BasCargoSpace basCargoSpacePick = basCargoSpaceService.selectBasCargoSpaceByCargoSpaceId(
job.getCargoSpaceId()
);
//放货位置
BasCargoSpace basCargoSpacePut = basCargoSpaceService.selectBasCargoSpaceByCargoSpaceId(
job.getTargetCargoSpaceId()
);
MsgDdj msgDdj = ddjService.selectMsgDdjById(Long.valueOf(devId));
//生成堆垛机执行队列
//生成取货作业时货叉必须有货 - 即【货叉状态】不为0
if (CollUtil.isEmpty(ddjDeviceExecutionQueues) && msgDdj.getHczt() == 0) {
DdjDeviceExecutionQueue ddjDeviceExecutionQueue = new DdjDeviceExecutionQueue();
ddjDeviceExecutionQueue.setUuid(IdUtil.simpleUUID());
ddjDeviceExecutionQueue.setRwh(Convert.toLong(job.getTaskNo()));
ddjDeviceExecutionQueue.setDevName(job.getRoadwayId());
ddjDeviceExecutionQueue.setDevId(devId);
ddjDeviceExecutionQueue.setRwzt(0);
ddjDeviceExecutionQueue.setYph(Convert.toInt(basCargoSpacePick.getThePlatoon()));
ddjDeviceExecutionQueue.setYlh(Convert.toInt(basCargoSpacePick.getTheColumn()));
ddjDeviceExecutionQueue.setYch(Convert.toInt(basCargoSpacePick.getTheFloor()));
ddjDeviceExecutionQueue.setMbph(Convert.toInt(basCargoSpacePut.getThePlatoon()));
ddjDeviceExecutionQueue.setMblh(Convert.toInt(basCargoSpacePut.getTheColumn()));
ddjDeviceExecutionQueue.setMbch(Convert.toInt(basCargoSpacePut.getTheFloor()));
ddjDeviceExecutionQueue.setDdjxf("0");
ddjDeviceExecutionQueue.setMlfs(5);//
// ddjDeviceExecutionQueue.setSpare1(job.getTraySize().toString());//货物高度
ddjDeviceExecutionQueue.setScsj(DateUtil.formatDateTime(DateUtil.date()));
// ddjDeviceExecutionQueue.setRwlx(DDJ_RWLX_3);
ddjDeviceExecutionQueueService.insertDdjDeviceExecutionQueue(ddjDeviceExecutionQueue);
if (job.getExecutionPhase().equals(TASK_EP_CREATED) && job.getStatus().equals(TASK_STATUS_CREATED)){
job.setExecutionPhase(TASK_EP_DDJ);
job.setExecutionPhase(TASK_STATUS_RUNNING);
mydoJobService.updateMydoJob(job);
}
log.info("【堆垛机执行】{}#堆垛机生成移库<取放>队列,任务号:{}", devId, job.getTaskNo());
}
}
}
}

View File

@@ -68,33 +68,33 @@ public class DdjThread implements Runnable {
@Override
public void run() {
init();
while (isRun) {
for (String type : ddjCodeList.keySet()) {
if ("ddj".equals(type)) {
for (String ddjCode : ddjCodeList.get(type)) {
try {
if ("ddj1".equals(ddjCode)) {
ddjTask(PlcDdj1Read.deviceDdjMap.get(ddjCode));
}
//PlcDdj2Read.deviceDdjMap.containsKey(ddjCode)
// if ("ddj2".equals(ddjCode)) {
// ddjTask(PlcDdj2Read.deviceDdjMap.get(ddjCode));
// init();
// while (isRun) {
// for (String type : ddjCodeList.keySet()) {
//
// if ("ddj".equals(type)) {
// for (String ddjCode : ddjCodeList.get(type)) {
// try {
// if ("ddj1".equals(ddjCode)) {
//// ddjTask(PlcDdj1Read.deviceDdjMap.get(ddjCode));
// }
} catch (RuntimeException e) {
log.error(e.getMessage(), e);
}
}
}
}
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
// //PlcDdj2Read.deviceDdjMap.containsKey(ddjCode)
//// if ("ddj2".equals(ddjCode)) {
//// ddjTask(PlcDdj2Read.deviceDdjMap.get(ddjCode));
//// }
// } catch (RuntimeException e) {
// log.error(e.getMessage(), e);
// }
//
// }
// }
// }
// try {
// Thread.sleep(3000);
// } catch (InterruptedException e) {
// throw new RuntimeException(e);
// }
// }
}
@@ -145,11 +145,6 @@ public class DdjThread implements Runnable {
}
/* -------------------------------------- 【3 放货有货,重新分配货位】-------------------------------------- */
// ddj.setCzfs(5);
// ddj.setSbzt(1052);
// ddj.setYxxf(1);
// ddj.setJdbz(4);
// ddj.setRwh(85015L);
// 1.联机自动【5】 2.设备状态-放货有货【1052】 3.执行阶段【0】【5】(无执行中的任务)
if (ddj.getSbzt() == 1052 && ddj.getJdbz() < 5 && ddj.getYxxf() == 1) {
@@ -211,14 +206,6 @@ public class DdjThread implements Runnable {
// -------------------------------------- 4 取货无货,作废当前任务,重新分配单据 --------------------------------------
//测试数据
// ddj.setCzfs(5);
// ddj.setSbzt(1053);
// ddj.setYxxf(1);
// ddj.setJdbz(3);
// ddj.setRwh(20021L);
// ddj.setId(1);
// 1.联机自动【5】 2.设备状态-取货无货【1053】 3.执行阶段【<5】(任务执行中)
if (ddj.getSbzt() == 1053 && ddj.getJdbz() < 5) {
Long rwh = ddj.getRwh();
@@ -292,7 +279,7 @@ public class DdjThread implements Runnable {
}
//正常下发
if (ddj.getYxxf() == 1 && ddj.getSbzt() == 0 ) {
if (ddj.getYxxf() == 1 && ddj.getSbzt() == 0) {
//检查是否有正在执行的堆垛机队列
Long rwh = ddj.getRwh();
DdjDeviceExecutionQueue ddjDeviceExecutionQueueRunningParam = new DdjDeviceExecutionQueue();

View File

@@ -0,0 +1,330 @@
package com.ruoyi.schedule.scheduleTask.ddj;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjUtil;
import com.ruoyi.api.service.IApiService;
import com.ruoyi.bas.cargospace.service.IBasCargoSpaceService;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.device.ddj.domain.MsgDdj;
import com.ruoyi.job.domain.MydoJob;
import com.ruoyi.job.service.IMydoJobService;
import com.ruoyi.queue.ddj.domain.DdjDeviceExecutionQueue;
import com.ruoyi.queue.ddj.service.IDdjDeviceExecutionQueueFinishService;
import com.ruoyi.queue.ddj.service.IDdjDeviceExecutionQueueService;
import com.ruoyi.schedule.plcRead.ddj.PlcDdj1Read;
import com.ruoyi.schedule.plcRead.ddj.PlcDdj2Read;
import com.ruoyi.schedule.plcRead.util.Tools;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import static com.ruoyi.common.TaskStatusCode.*;
@Slf4j
public class DdjThread_1 implements Runnable {
public HashMap<String, List<String>> ddjCodeList;
private IApiService apiService;
private IDdjDeviceExecutionQueueService ddjDeviceExecutionQueueService;
private IDdjDeviceExecutionQueueFinishService ddjDeviceExecutionQueueFinishService;
private IMydoJobService mydoJobService;
private IBasCargoSpaceService basCargoSpaceService;
public boolean isRun = true;
public void init() {
//todo 获取设备编码列表
ddjCodeList = new HashMap<>();
ArrayList<String> ddjCodes = new ArrayList<>();
ddjCodes.add("ddj1");
// ddjCodes.add("ddj2");
ddjCodeList.put("ddj", ddjCodes);
apiService = SpringUtils.getBean(IApiService.class);
ddjDeviceExecutionQueueService = SpringUtils.getBean(IDdjDeviceExecutionQueueService.class);
ddjDeviceExecutionQueueFinishService = SpringUtils.getBean(IDdjDeviceExecutionQueueFinishService.class);
basCargoSpaceService = SpringUtils.getBean(IBasCargoSpaceService.class);
mydoJobService = SpringUtils.getBean(IMydoJobService.class);
log.info("初始化服务 {},{},{},{}", apiService, ddjDeviceExecutionQueueService, ddjDeviceExecutionQueueFinishService,mydoJobService);
}
@Override
public void run() {
init();
while (isRun) {
for (String type : ddjCodeList.keySet()) {
if ("ddj".equals(type)) {
for (String ddjCode : ddjCodeList.get(type)) {
try {
if ("ddj1".equals(ddjCode)) {
ddjTask(PlcDdj1Read.deviceDdjMap.get(ddjCode));
}
} catch (RuntimeException e) {
log.error(e.getMessage(), e);
}
}
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
private void ddjTask(MsgDdj ddj) {
/* --------------------------------------【1 处理已经完成的作业】--------------------------------------
堆垛机线程进来后第一件事先进行堆垛机正执行任务的账务处理
以防存在漏处理,没处理的情况发生
*/
//非【联机自动】状态
if (ddj.getCzfs() != 5) return;
// 检查当前堆垛机参数 - 是否有执行中的作业
// 1.联机自动【5】 2.设备状态【0】 3.执行阶段【0】【5】(无执行中的任务)
if (ddj.getSbzt() == 0 && (ddj.getJdbz() == 5 || ddj.getJdbz() == 0)) {
Long rwh = ddj.getRwh();
//完成作业
MydoJob mydoJob = mydoJobService.selectMydoJobByTaskNo(rwh);
if (ddj.getHczt() == 0){
DdjDeviceExecutionQueue ddjDeviceExecutionQueue = ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueByRwh(rwh,ddj.getId());
//满足上述条件(【有实时任务】且【存在堆垛机执行队列】),表示该任务已完成-标记为已完成状态
if (mydoJob != null && ddjDeviceExecutionQueue != null) {
//标记为堆垛机执行完成
mydoJob.setExecutionPhase(TASK_EP_DDJ_FINISH);
mydoJobService.updateMydoJob(mydoJob);
log.info("【堆垛机执行】设备编号:" + ddj.getId() + " 执行完成,任务结束,任务号:"+ddj.getRwh());
}
}else{
if (mydoJob.getExecutionPhase().equals(TASK_EP_ROADWAY_SSJ)){
mydoJob.setExecutionPhase(TASK_EP_DDJ_PICK);
mydoJobService.updateMydoJob(mydoJob);
log.info("【更新状态】{}#堆垛机巷道口取货完成,等待下发放货任务,wcs任务号:{}", Long.valueOf(mydoJob.getRoadwayId()), mydoJob.getTaskNo());
}
}
}
//-------------------------------------- 【2 更新执行阶段】 --------------------------------------
// 设备状态 - 运行中【1】 执行阶段【2】
if (ddj.getSbzt() == 1 && ddj.getJdbz() == 2) {
//根据堆垛机上任务号,修改任务执行阶段
Long rwh = ddj.getRwh();
DdjDeviceExecutionQueue ddjDeviceExecutionQueue = ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueByRwh(rwh, ddj.getId());
if (ddjDeviceExecutionQueue != null && !"1".equals(ddjDeviceExecutionQueue.getSpare1())) {
//修改队列执行阶段
ddjDeviceExecutionQueue.setRwzt(ddj.getJdbz());
// ddjDeviceExecutionQueue.setSpare1("1");
ddjDeviceExecutionQueueService.updateDdjDeviceExecutionQueue(ddjDeviceExecutionQueue);
}
}
/* -------------------------------------- 【3 放货有货,重新分配货位】-------------------------------------- */
// 1.联机自动【5】 2.设备状态-放货有货【1052】 3.执行阶段【0】【5】(无执行中的任务)
if (ddj.getSbzt() == 1052 && ddj.getJdbz() < 5 && ddj.getYxxf() == 1) {
// 判断堆垛机上任务是否已重分,若未重分,则调用接口,请求重分货位
Long rwh = ddj.getRwh();
//查询正在执行中的【任务号】获取堆垛机队列
MydoJob mydoJob = mydoJobService.selectMydoJobByTaskNo(rwh);
if (mydoJob != null && mydoJob.getExecutionPhase() != TASK_EXCEPTION_PUT) {
DdjDeviceExecutionQueue ddjDeviceExecutionQueue = ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueByRwh(rwh, ddj.getId());
//更新异常类型【FaultFlag】-1
if ("0".equals(mydoJob.getFaultFlag()) && "1".equals(ddjDeviceExecutionQueue.getSpare1())) {
mydoJob.setStatus("1");
//把执行阶段标记为【入库放货有货】的异常
mydoJob.setExecutionPhase(TASK_EXCEPTION_PUT);
mydoJobService.updateMydoJob(mydoJob);
log.info("【入库异常】堆垛机放货时目标位置有货,异常货位:{},任务号:{}", mydoJob.getCargoSpaceId(), rwh);
}
}
}
// -------------------------------------- 【4 取货无货,作废当前任务,重新分配单据】 --------------------------------------
// 1.联机自动【5】 2.设备状态-取货无货【1053】 3.执行阶段【<5】(任务执行中)
if (ddj.getSbzt() == 1053 && ddj.getJdbz() < 5) {
Long rwh = ddj.getRwh();
MydoJob mydoJob = mydoJobService.selectMydoJobByTaskNo(rwh);
if (mydoJob != null && mydoJob.getExecutionPhase() != TASK_EXCEPTION_PICK) {
//把执行阶段标记为【出库取货无货】的异常
mydoJob.setExecutionPhase(TASK_EXCEPTION_PICK);
mydoJobService.updateMydoJob(mydoJob);
log.info("【出库异常】堆垛机取货时目标位置无货,异常货位:{},任务号:{}", mydoJob.getCargoSpaceId(), rwh);
}
// //无货异常处理
// DdjDeviceExecutionQueue ddjDeviceExecutionQueue = ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueByRwh(rwh,ddj.getId());
//
// //找到对应任务 调用api接口 取货无货,重新分配单据
// if (ObjUtil.isNotNull(ddjDeviceExecutionQueue)) {
//
// //向wms返回异常信息
// TaskExceptionRequest taskExceptionRequest = new TaskExceptionRequest();
// taskExceptionRequest.setTaskClass(mydoJob.getInOrOut().substring(0, 1));
// taskExceptionRequest.setType(String.valueOf(TASK_EXCEPTION_STOCKIN_OCCUPIED));
// taskExceptionRequest.setTaskCode(String.valueOf(mydoJob));
// taskExceptionRequest.setTaskTypeCode(WMS_TASK_TYPE_EXCEPTION);//todo 不知道填什么
// taskExceptionRequest.setReqCode(UUID.randomUUID().toString().replace("-", ""));
// taskExceptionRequest.setAdverseCauses("取货位置空,盘点后作废该任务");
//
// AjaxResult ajaxResult = apiService.reMaterial(taskExceptionRequest);
// if (ajaxResult.isSuccess()) {
// //作废作业
// InvalidMydoJob(rwh, ddj.getId());
//
// //清空/重置【取货无货】的出库异常货位库存信息
// basCargoSpaceService.resetCargoSpaceByStockoutException(mydoJob.getCargoSpaceId());
// }
// }
}
// -------------------------------------- 【5 下发堆垛机任务】 --------------------------------------
//重分货位后重下
if (ddj.getYxxf() == 1 && ddj.getSbzt() == 1052) {
Long rwh = ddj.getRwh();
//查询执行中的作业
MydoJob mydoJob = mydoJobService.selectMydoJobByTaskNo(rwh);
//该任务存在且【FaultFlag】为 2-已重分完成
if (ObjUtil.isNotNull(mydoJob) && "2".equals(mydoJob.getFaultFlag())) {
//判断任务是否重分完成
DdjDeviceExecutionQueue ddjDeviceExecutionQueue = ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueByRwh(rwh,ddj.getId());
if (ObjUtil.isNotNull(ddjDeviceExecutionQueue) && "0".equals(ddjDeviceExecutionQueue.getDdjxf())) {
//重新下发堆垛机任务
int i = issuedDDJTask(ddj.getId(), ddjDeviceExecutionQueue);
if (i == 1) {
//更新开始时间,修改ddjxf为已下发1
ddjDeviceExecutionQueue.setXfsj(DateUtil.formatDateTime(DateUtil.date()));
ddjDeviceExecutionQueue.setDdjxf("1");
ddjDeviceExecutionQueueService.updateDdjDeviceExecutionQueue(ddjDeviceExecutionQueue);
mydoJob.setFaultFlag("0");
mydoJobService.updateMydoJob(mydoJob);
log.info("【入库异常】重分货位下发堆垛机任务成功,当前任务号:{}", rwh);
} else {
log.error("【入库异常】重分货位 - 下发堆垛机任务失败!!!!!!!");
}
}
}
}
//正常下发
if (ddj.getYxxf() == 1 && ddj.getSbzt() == 0 ) {
//检查是否有正在执行的堆垛机队列
Long rwh = ddj.getRwh();
DdjDeviceExecutionQueue ddjDeviceExecutionQueueRunningParam = new DdjDeviceExecutionQueue();
ddjDeviceExecutionQueueRunningParam.setDdjxf("1");
//ddjDeviceExecutionQueueRunningParam.setSpare1("1");
ddjDeviceExecutionQueueRunningParam.setDevId(ddj.getId());
List<DdjDeviceExecutionQueue> ddjDeviceExecutionRunningQueues = ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueList(ddjDeviceExecutionQueueRunningParam);
if (CollUtil.isNotEmpty(ddjDeviceExecutionRunningQueues)) {
log.error("【提示】堆垛机有正在执行的队列,任务号: {},请检查该任务号的wcs作业是否已经手动处理" , ddjDeviceExecutionRunningQueues.get(0).getRwh());
return;
}
//对堆垛机执行队列中无已下发队列
DdjDeviceExecutionQueue ddjDeviceExecutionQueueParam = new DdjDeviceExecutionQueue();
ddjDeviceExecutionQueueParam.setDdjxf("0");
ddjDeviceExecutionQueueParam.setDevId(ddj.getId());
List<DdjDeviceExecutionQueue> ddjDeviceExecutionQueues = ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueList(ddjDeviceExecutionQueueParam);
//取堆垛机队列中,生成时间最早的执行队列下发
if (CollUtil.isNotEmpty(ddjDeviceExecutionQueues)) {
DdjDeviceExecutionQueue ddjDeviceExecutionQueue = ddjDeviceExecutionQueues.get(0);
int i = issuedDDJTask(ddj.getId(), ddjDeviceExecutionQueue);
if (i == 1) {
//更新开始时间,修改ddjxf为已下发1
ddjDeviceExecutionQueue.setXfsj(DateUtil.formatDateTime(DateUtil.date()));
ddjDeviceExecutionQueue.setDdjxf("1");
ddjDeviceExecutionQueueService.updateDdjDeviceExecutionQueue(ddjDeviceExecutionQueue);
log.info("【堆垛机作业】下发任务成功,任务执行中, 任务号:{}", ddjDeviceExecutionQueue.getRwh());
} else {
log.error("【堆垛机作业】堆垛机下发任务失败,任务号:{},等待重新下发...", ddjDeviceExecutionQueue.getRwh());
}
}
}
}
/**
* 作废作业
*
* @param rwh 作业单号
* @param id 作业单id
*/
private void InvalidMydoJob(Long rwh, Integer id) {
mydoJobService.InvalidMydoJob(rwh, id);
}
/**
* 堆垛机任务完成
*
* @param rwh 作业单号
* @param id 作业单id
*/
private void ddjTaskFinish(Long rwh, Integer id) {
mydoJobService.ddjTaskFinish(rwh, id);
}
/**
* 给堆垛机下发任务
*
* @param queue 堆垛机执行的队列
*/
private int issuedDDJTask(Integer devId, DdjDeviceExecutionQueue queue) {
int taskNo = Convert.toInt(queue.getRwh());
int yph = Convert.toInt(queue.getYph());
int ylh = Convert.toInt(queue.getYlh());
int ych = Convert.toInt(queue.getYch());
int mbph = Convert.toInt(queue.getMbph());
int mblh = Convert.toInt(queue.getMblh());
int mbch = Convert.toInt(queue.getMbch());
int mlfs = queue.getMlfs();
int xfwc = 1;
// int hwlx = Convert.toInt(queue.getSpare1());
int hwlx = 0;//默认值
int jym = Tools.getJYM(taskNo, yph, ylh, ych, mbph, mblh, mbch, mlfs);
byte[] sendData = Tools.sendDataToDevice(taskNo, null, yph, ylh, ych, mbph, mblh, mbch, mlfs, xfwc, jym);
if (devId==1){
return PlcDdj1Read.WriteToDDJ("DB61.0", sendData);
}else {
return PlcDdj2Read.WriteToDDJ("DB61.0", sendData);
}
}
}

View File

@@ -0,0 +1,343 @@
package com.ruoyi.schedule.scheduleTask.ddj;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjUtil;
import com.ruoyi.api.service.IApiService;
import com.ruoyi.bas.cargospace.service.IBasCargoSpaceService;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.device.ddj.domain.MsgDdj;
import com.ruoyi.job.domain.MydoJob;
import com.ruoyi.job.service.IMydoJobService;
import com.ruoyi.queue.ddj.domain.DdjDeviceExecutionQueue;
import com.ruoyi.queue.ddj.service.IDdjDeviceExecutionQueueFinishService;
import com.ruoyi.queue.ddj.service.IDdjDeviceExecutionQueueService;
import com.ruoyi.schedule.plcRead.ddj.PlcDdj1Read;
import com.ruoyi.schedule.plcRead.ddj.PlcDdj2Read;
import com.ruoyi.schedule.plcRead.util.Tools;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import static com.ruoyi.common.TaskStatusCode.*;
@Slf4j
public class DdjThread_2 implements Runnable {
public HashMap<String, List<String>> ddjCodeList;
private IApiService apiService;
private IDdjDeviceExecutionQueueService ddjDeviceExecutionQueueService;
private IDdjDeviceExecutionQueueFinishService ddjDeviceExecutionQueueFinishService;
private IMydoJobService mydoJobService;
private IBasCargoSpaceService basCargoSpaceService;
public boolean isRun = true;
public void init() {
//todo 获取设备编码列表
ddjCodeList = new HashMap<>();
ArrayList<String> ddjCodes = new ArrayList<>();
ddjCodes.add("ddj2");
// ddjCodes.add("ddj2");
ddjCodeList.put("ddj", ddjCodes);
apiService = SpringUtils.getBean(IApiService.class);
ddjDeviceExecutionQueueService = SpringUtils.getBean(IDdjDeviceExecutionQueueService.class);
ddjDeviceExecutionQueueFinishService = SpringUtils.getBean(IDdjDeviceExecutionQueueFinishService.class);
basCargoSpaceService = SpringUtils.getBean(IBasCargoSpaceService.class);
mydoJobService = SpringUtils.getBean(IMydoJobService.class);
log.info("初始化服务 {},{},{},{}", apiService, ddjDeviceExecutionQueueService, ddjDeviceExecutionQueueFinishService,mydoJobService);
}
@Override
public void run() {
init();
while (isRun) {
for (String type : ddjCodeList.keySet()) {
if ("ddj".equals(type)) {
for (String ddjCode : ddjCodeList.get(type)) {
try {
if ("ddj2".equals(ddjCode)) {
ddjTask(PlcDdj2Read.deviceDdjMap.get(ddjCode));
}
} catch (RuntimeException e) {
log.error(e.getMessage(), e);
}
}
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
private void ddjTask(MsgDdj ddj) {
/* --------------------------------------【1 处理已经完成的作业】--------------------------------------
堆垛机线程进来后第一件事先进行堆垛机正执行任务的账务处理
以防存在漏处理,没处理的情况发生
*/
//非【联机自动】状态
if (ddj.getCzfs() != 5) return;
// 检查当前堆垛机参数 - 是否有执行中的作业
// 1.联机自动【5】 2.设备状态【0】 3.执行阶段【0】【5】(无执行中的任务)
if (ddj.getSbzt() == 0 && (ddj.getJdbz() == 5 || ddj.getJdbz() == 0)) {
Long rwh = ddj.getRwh();
//完成作业
MydoJob mydoJob = mydoJobService.selectMydoJobByTaskNo(rwh);
if (ddj.getHczt() == 0){
DdjDeviceExecutionQueue ddjDeviceExecutionQueue = ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueByRwh(rwh,ddj.getId());
//满足上述条件(【有实时任务】且【存在堆垛机执行队列】),表示该任务已完成-标记为已完成状态
if (mydoJob != null && ddjDeviceExecutionQueue != null) {
//标记为堆垛机执行完成
mydoJob.setExecutionPhase(TASK_EP_DDJ_FINISH);
mydoJobService.updateMydoJob(mydoJob);
log.info("【堆垛机执行】设备编号:" + ddj.getId() + " 执行完成,任务结束,任务号:"+ddj.getRwh());
}
}else{
if (mydoJob.getExecutionPhase().equals(TASK_EP_ROADWAY_SSJ)){
mydoJob.setExecutionPhase(TASK_EP_DDJ_PICK);
mydoJobService.updateMydoJob(mydoJob);
log.info("【更新状态】{}#堆垛机巷道口取货完成,等待下发放货任务,wcs任务号:{}", Long.valueOf(mydoJob.getRoadwayId()), mydoJob.getTaskNo());
}
}
}
//-------------------------------------- 【2 更新执行阶段】 --------------------------------------
// 1.联机自动【5】 2.设备状态 - 运行中【1】 3.执行阶段【2】
if (ddj.getSbzt() == 1 && ddj.getJdbz() == 2) {
//根据堆垛机上任务号,修改任务执行阶段
Long rwh = ddj.getRwh();
DdjDeviceExecutionQueue ddjDeviceExecutionQueue = ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueByRwh(rwh, ddj.getId());
if (ddjDeviceExecutionQueue != null && !"1".equals(ddjDeviceExecutionQueue.getSpare1())) {
//修改队列执行阶段
ddjDeviceExecutionQueue.setRwzt(ddj.getJdbz());
// ddjDeviceExecutionQueue.setSpare1("1");
ddjDeviceExecutionQueueService.updateDdjDeviceExecutionQueue(ddjDeviceExecutionQueue);
}
}
/* -------------------------------------- 【3 放货有货,重新分配货位】-------------------------------------- */
// ddj.setCzfs(5);
// ddj.setSbzt(1052);
// ddj.setYxxf(1);
// ddj.setJdbz(4);
// ddj.setRwh(85015L);
// 1.联机自动【5】 2.设备状态-放货有货【1052】 3.执行阶段【0】【5】(无执行中的任务)
if (ddj.getSbzt() == 1052 && ddj.getJdbz() < 5 && ddj.getYxxf() == 1) {
// 判断堆垛机上任务是否已重分,若未重分,则调用接口,请求重分货位
Long rwh = ddj.getRwh();
//查询正在执行中的【任务号】获取堆垛机队列
MydoJob mydoJob = mydoJobService.selectMydoJobByTaskNo(rwh);
if (mydoJob != null && mydoJob.getExecutionPhase() != TASK_EXCEPTION_PUT) {
// DdjDeviceExecutionQueue ddjDeviceExecutionQueue = ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueByRwh(rwh, ddj.getId());
//更新异常类型【FaultFlag】-1
if ("0".equals(mydoJob.getFaultFlag())) {
mydoJob.setStatus("1");
//把执行阶段标记为【入库放货有货】的异常
mydoJob.setExecutionPhase(TASK_EXCEPTION_PUT);
mydoJobService.updateMydoJob(mydoJob);
log.info("【入库异常】堆垛机放货时目标位置有货,异常货位:{},任务号:{}", mydoJob.getCargoSpaceId(), rwh);
}
}
}
// -------------------------------------- 4 取货无货,作废当前任务,重新分配单据 --------------------------------------
//测试数据
// ddj.setCzfs(5);
// ddj.setSbzt(1053);
// ddj.setYxxf(1);
// ddj.setJdbz(3);
// ddj.setRwh(20021L);
// ddj.setId(1);
// 1.联机自动【5】 2.设备状态-取货无货【1053】 3.执行阶段【<5】(任务执行中)
if (ddj.getSbzt() == 1053 && ddj.getJdbz() < 5) {
Long rwh = ddj.getRwh();
MydoJob mydoJob = mydoJobService.selectMydoJobByTaskNo(rwh);
if (mydoJob != null && mydoJob.getExecutionPhase() != TASK_EXCEPTION_PICK) {
//把执行阶段标记为【出库取货无货】的异常
mydoJob.setExecutionPhase(TASK_EXCEPTION_PICK);
mydoJobService.updateMydoJob(mydoJob);
log.info("【出库异常】堆垛机取货时目标位置无货,异常货位:{},任务号:{}", mydoJob.getCargoSpaceId(), rwh);
}
// //无货异常处理
// DdjDeviceExecutionQueue ddjDeviceExecutionQueue = ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueByRwh(rwh,ddj.getId());
//
// //找到对应任务 调用api接口 取货无货,重新分配单据
// if (ObjUtil.isNotNull(ddjDeviceExecutionQueue)) {
//
// //向wms返回异常信息
// TaskExceptionRequest taskExceptionRequest = new TaskExceptionRequest();
// taskExceptionRequest.setTaskClass(mydoJob.getInOrOut().substring(0, 1));
// taskExceptionRequest.setType(String.valueOf(TASK_EXCEPTION_STOCKIN_OCCUPIED));
// taskExceptionRequest.setTaskCode(String.valueOf(mydoJob));
// taskExceptionRequest.setTaskTypeCode(WMS_TASK_TYPE_EXCEPTION);//todo 不知道填什么
// taskExceptionRequest.setReqCode(UUID.randomUUID().toString().replace("-", ""));
// taskExceptionRequest.setAdverseCauses("取货位置空,盘点后作废该任务");
//
// AjaxResult ajaxResult = apiService.reMaterial(taskExceptionRequest);
// if (ajaxResult.isSuccess()) {
// //作废作业
// InvalidMydoJob(rwh, ddj.getId());
//
// //清空/重置【取货无货】的出库异常货位库存信息
// basCargoSpaceService.resetCargoSpaceByStockoutException(mydoJob.getCargoSpaceId());
// }
// }
}
// -------------------------------------- 5 下发堆垛机任务 --------------------------------------
//重分货位后重下
if (ddj.getYxxf() == 1 && ddj.getSbzt() == 1052) {
Long rwh = ddj.getRwh();
//查询执行中的作业
MydoJob mydoJob = mydoJobService.selectMydoJobByTaskNo(rwh);
//该任务存在且【FaultFlag】为 2-已重分完成
if (ObjUtil.isNotNull(mydoJob) && "2".equals(mydoJob.getFaultFlag())) {
//判断任务是否重分完成
DdjDeviceExecutionQueue ddjDeviceExecutionQueue = ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueByRwh(rwh,ddj.getId());
if (ObjUtil.isNotNull(ddjDeviceExecutionQueue) && "0".equals(ddjDeviceExecutionQueue.getDdjxf())) {
//重新下发堆垛机任务
int i = issuedDDJTask(ddj.getId(), ddjDeviceExecutionQueue);
if (i == 1) {
//更新开始时间,修改ddjxf为已下发1
ddjDeviceExecutionQueue.setXfsj(DateUtil.formatDateTime(DateUtil.date()));
ddjDeviceExecutionQueue.setDdjxf("1");
ddjDeviceExecutionQueueService.updateDdjDeviceExecutionQueue(ddjDeviceExecutionQueue);
mydoJob.setFaultFlag("0");
mydoJobService.updateMydoJob(mydoJob);
log.info("【入库异常】重分货位下发堆垛机任务成功,当前任务号:{}", rwh);
} else {
log.error("【入库异常】重分货位 - 下发堆垛机任务失败!!!!!!!");
}
}
}
}
//正常下发
if (ddj.getYxxf() == 1 && ddj.getSbzt() == 0 ) {
//检查是否有正在执行的堆垛机队列
Long rwh = ddj.getRwh();
DdjDeviceExecutionQueue ddjDeviceExecutionQueueRunningParam = new DdjDeviceExecutionQueue();
ddjDeviceExecutionQueueRunningParam.setDdjxf("1");
//ddjDeviceExecutionQueueRunningParam.setSpare1("1");
ddjDeviceExecutionQueueRunningParam.setDevId(ddj.getId());
List<DdjDeviceExecutionQueue> ddjDeviceExecutionRunningQueues = ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueList(ddjDeviceExecutionQueueRunningParam);
if (CollUtil.isNotEmpty(ddjDeviceExecutionRunningQueues)) {
log.error("【提示】堆垛机有正在执行的队列,任务号: {},请检查该任务号的wcs作业是否已经手动处理" , ddjDeviceExecutionRunningQueues.get(0).getRwh());
return;
}
//对堆垛机执行队列中无已下发队列
DdjDeviceExecutionQueue ddjDeviceExecutionQueueParam = new DdjDeviceExecutionQueue();
ddjDeviceExecutionQueueParam.setDdjxf("0");
ddjDeviceExecutionQueueParam.setDevId(ddj.getId());
List<DdjDeviceExecutionQueue> ddjDeviceExecutionQueues = ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueList(ddjDeviceExecutionQueueParam);
//取堆垛机队列中,生成时间最早的执行队列下发
if (CollUtil.isNotEmpty(ddjDeviceExecutionQueues)) {
DdjDeviceExecutionQueue ddjDeviceExecutionQueue = ddjDeviceExecutionQueues.get(0);
int i = issuedDDJTask(ddj.getId(), ddjDeviceExecutionQueue);
if (i == 1) {
//更新开始时间,修改ddjxf为已下发1
ddjDeviceExecutionQueue.setXfsj(DateUtil.formatDateTime(DateUtil.date()));
ddjDeviceExecutionQueue.setDdjxf("1");
ddjDeviceExecutionQueueService.updateDdjDeviceExecutionQueue(ddjDeviceExecutionQueue);
log.info("【堆垛机入库】下发任务成功,任务执行中, 任务号:{}", ddjDeviceExecutionQueue.getRwh());
} else {
log.error("【堆垛机入库】堆垛机下发任务失败,任务号:{},等待重新下发...", ddjDeviceExecutionQueue.getRwh());
}
}
}
}
/**
* 作废作业
*
* @param rwh 作业单号
* @param id 作业单id
*/
private void InvalidMydoJob(Long rwh, Integer id) {
mydoJobService.InvalidMydoJob(rwh, id);
}
/**
* 堆垛机任务完成
*
* @param rwh 作业单号
* @param id 作业单id
*/
private void ddjTaskFinish(Long rwh, Integer id) {
mydoJobService.ddjTaskFinish(rwh, id);
}
/**
* 给堆垛机下发任务
*
* @param queue 堆垛机执行的队列
*/
private int issuedDDJTask(Integer devId, DdjDeviceExecutionQueue queue) {
int taskNo = Convert.toInt(queue.getRwh());
int yph = Convert.toInt(queue.getYph());
int ylh = Convert.toInt(queue.getYlh());
int ych = Convert.toInt(queue.getYch());
int mbph = Convert.toInt(queue.getMbph());
int mblh = Convert.toInt(queue.getMblh());
int mbch = Convert.toInt(queue.getMbch());
int mlfs = queue.getMlfs();
int xfwc = 1;
// int hwlx = Convert.toInt(queue.getSpare1());
int hwlx = 0;//默认值
int jym = Tools.getJYM(taskNo, yph, ylh, ych, mbph, mblh, mbch, mlfs);
byte[] sendData = Tools.sendDataToDevice(taskNo, null, yph, ylh, ych, mbph, mblh, mbch, mlfs, xfwc, jym);
if (devId==1){
return PlcDdj1Read.WriteToDDJ("DB61.0", sendData);
}else {
return PlcDdj2Read.WriteToDDJ("DB61.0", sendData);
}
}
}

View File

@@ -87,46 +87,46 @@ public class MonitoringThread implements Runnable {
}
}
}
// for (String ddjCode : PlcDdj2Read.deviceDdjMap.keySet()) {
// MsgDdj msgDdj = PlcDdj2Read.deviceDdjMap.get(ddjCode);
// msgDdjService.updateMsgDdj(msgDdj);
//
// if (msgDdj.getSbzt() > 1000) {
// BasFaultRecord param = new BasFaultRecord();
// param.setTaskNo(msgDdj.getRwh() + "");
// param.setDeviceId(String.valueOf(msgDdj.getId()));
// param.setDeviceType("DDJ");
// param.setFault(msgDdj.getSbzt() + "");
// param.setJobId("0");
// List<BasFaultRecord> basFaultRecords = basFaultRecordService.selectBasFaultRecordList(param);
// if (CollUtil.isEmpty(basFaultRecords)) {
// BasFaultRecord faultRecord = new BasFaultRecord();
// faultRecord.setId(IdUtil.fastSimpleUUID());
// faultRecord.setDeviceId(String.valueOf(msgDdj.getId()));
// faultRecord.setDeviceName(msgDdj.getName());
// faultRecord.setDeviceType("DDJ");
// faultRecord.setJobId("0");
// faultRecord.setTaskNo(msgDdj.getRwh() + "");
// faultRecord.setFault(msgDdj.getSbzt() + "");
// faultRecord.setStartTime(DateUtil.formatDateTime(DateUtil.date()));
// //faultRecord.setWarehouseId(mydoJob.getWarehouseId());
// basFaultRecordService.insertBasFaultRecord(faultRecord);
// }
// }
// if (msgDdj.getSbzt() < 1000 && msgDdj.getCzfs() == 5){
// BasFaultRecord param = new BasFaultRecord();
// param.setDeviceId(String.valueOf(msgDdj.getId()));
// param.setDeviceType("DDJ");
// param.setJobId("0");
// List<BasFaultRecord> basFaultRecords = basFaultRecordService.selectBasFaultRecordList(param);
// if (CollUtil.isNotEmpty(basFaultRecords)) {
// BasFaultRecord faultRecord = basFaultRecords.get(0);
// faultRecord.setJobId("1");
// faultRecord.setFinishTime(DateUtil.formatDateTime(DateUtil.date()));
// basFaultRecordService.updateBasFaultRecord(faultRecord);
// }
// }
// }
for (String ddjCode : PlcDdj2Read.deviceDdjMap.keySet()) {
MsgDdj msgDdj = PlcDdj2Read.deviceDdjMap.get(ddjCode);
msgDdjService.updateMsgDdj(msgDdj);
if (msgDdj.getSbzt() > 1000) {
BasFaultRecord param = new BasFaultRecord();
param.setTaskNo(msgDdj.getRwh() + "");
param.setDeviceId(String.valueOf(msgDdj.getId()));
param.setDeviceType("DDJ");
param.setFault(msgDdj.getSbzt() + "");
param.setJobId("0");
List<BasFaultRecord> basFaultRecords = basFaultRecordService.selectBasFaultRecordList(param);
if (CollUtil.isEmpty(basFaultRecords)) {
BasFaultRecord faultRecord = new BasFaultRecord();
faultRecord.setId(IdUtil.fastSimpleUUID());
faultRecord.setDeviceId(String.valueOf(msgDdj.getId()));
faultRecord.setDeviceName(msgDdj.getName());
faultRecord.setDeviceType("DDJ");
faultRecord.setJobId("0");
faultRecord.setTaskNo(msgDdj.getRwh() + "");
faultRecord.setFault(msgDdj.getSbzt() + "");
faultRecord.setStartTime(DateUtil.formatDateTime(DateUtil.date()));
//faultRecord.setWarehouseId(mydoJob.getWarehouseId());
basFaultRecordService.insertBasFaultRecord(faultRecord);
}
}
if (msgDdj.getSbzt() < 1000 && msgDdj.getCzfs() == 5){
BasFaultRecord param = new BasFaultRecord();
param.setDeviceId(String.valueOf(msgDdj.getId()));
param.setDeviceType("DDJ");
param.setJobId("0");
List<BasFaultRecord> basFaultRecords = basFaultRecordService.selectBasFaultRecordList(param);
if (CollUtil.isNotEmpty(basFaultRecords)) {
BasFaultRecord faultRecord = basFaultRecords.get(0);
faultRecord.setJobId("1");
faultRecord.setFinishTime(DateUtil.formatDateTime(DateUtil.date()));
basFaultRecordService.updateBasFaultRecord(faultRecord);
}
}
}
try {
Thread.sleep(1500);
} catch (InterruptedException e) {

View File

@@ -2,6 +2,7 @@ package com.ruoyi.schedule.scheduleTask.ssj;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
@@ -11,6 +12,7 @@ import com.ruoyi.api.service.IApiService;
import com.ruoyi.api.service.IRequestLogService;
import com.ruoyi.bas.cargospace.domain.BasCargoSpace;
import com.ruoyi.bas.cargospace.service.IBasCargoSpaceService;
import com.ruoyi.common.ConvType;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.device.ssj.domain.DeviceSsj;
@@ -31,7 +33,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static com.ruoyi.common.TaskStatusCode.*;
import static com.ruoyi.common.WmsTaskTypeCode.WMS_TASK_TYPE_STOCKIN;
import static com.ruoyi.common.TaskType.*;
import static com.ruoyi.schedule.plcRead.ssj.PlcSsjRead.writeToSsj;
/**
@@ -57,8 +59,12 @@ public class PortConvThread implements Runnable {
public void init() {
ssjCodeList = new HashMap<>();
ArrayList<String> ssjCodes = new ArrayList<>();
ssjCodes.add("G1004");
ssjCodes.add("TD1001");
ssjCodes.add("L1001");
ssjCodes.add("L1004");
ssjCodes.add("L1006");
ssjCodes.add("L1008");
ssjCodes.add("L1002");
ssjCodes.add("L1009");
ssjCodeList.put("portConv", ssjCodes);
apiService = SpringUtils.getBean(IApiService.class);
// agvQueueService = SpringUtils.getBean(IAgvQueueService.class);
@@ -80,13 +86,7 @@ public class PortConvThread implements Runnable {
for (String ssjCode : ssjCodeList.get(type)) {
try {
if (PlcSsjRead.deviceSsjMap.containsKey(ssjCode)) {
if (ssjCode == "G1004"){
inDispatch(PlcSsjRead.deviceSsjMap.get(ssjCode));
}
if (ssjCode == "TD1001"){
outDispatch(PlcSsjRead.deviceSsjMap.get(ssjCode));
}
Schedule(PlcSsjRead.deviceSsjMap.get(ssjCode));
} else {
log.error("设备不存在 ssjCode:{}", ssjCode);
}
@@ -99,7 +99,7 @@ public class PortConvThread implements Runnable {
}
}
try {
Thread.sleep(3000);
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
@@ -107,90 +107,104 @@ public class PortConvThread implements Runnable {
}
public void Schedule(DeviceSsj deviceSsj){
public void inDispatch(DeviceSsj inSsjDevice) {
// 测试数据
// inSsjDevice.setInOrOut(1);
// inSsjDevice.setTrayCode("T000004503");
// inSsjDevice.setTaskNo(777778);
// inSsjDevice.setKx(0);
// inSsjDevice.setDw(1);
// inSsjDevice.setHeight(1);
// inSsjDevice.setWeight("100");
// inSsjDevice.setException(0);
// inSsjDevice.setRkqq(1);
switch (deviceSsj.getDeviceCode()){
//输送机状态
if (!convChecked(inSsjDevice)) return;
//更新入库任务阶段
updateMydoJob(inSsjDevice);
//请求wms获取入库任务
requestMydoJob(inSsjDevice);
//1#巷道出库口(单向)
case "L1008":
//3#巷道出库口(单向)
case "L1001":
//出库完成
// finishStockoutMydoJob(deviceSsj);
//盘点出库
finishInventoryStockoutMydoJob(deviceSsj);
break;
//1#巷道/区域01出库口(双向)
case "L1002":
//3#巷道/区域03出库口(双向)
case "L1009":
//2#巷道/区域02出库口(双向)
case "L1004":
//2#巷道/区域03出库口(双向)
case "L1006":
//更新入库任务阶段
// updateMydoJob(deviceSsj);
//出库完成
finishStockoutMydoJob(deviceSsj);
//盘点出库
// finishInventoryStockoutMydoJob(deviceSsj);
break;
}
}
/**
* 输送机到位判断校验
* @param inSsjDevice
* @return
*/
private boolean convChecked(DeviceSsj inSsjDevice){
private boolean portConvChecked(DeviceSsj inSsjDevice){
boolean flag = false;
//---------------------------入口取输送机(叉车取放货位置)---------------------------
//输送机【条码】空
if (inSsjDevice.getTrayCode() == "" || inSsjDevice.getTrayCode() == null) return flag;
if (inSsjDevice.getTrayCode() == "" || inSsjDevice.getTrayCode() == null)
return flag;
//不存在扫描【条码】的作业
if (mydoJobService.selectMydoJobList(
new MydoJob().builder().trayCode(inSsjDevice.getTrayCode()).build()
).size() == 1)
return flag;
//【入库请求】,表示输送到位和空闲
if (inSsjDevice.getRkqq() != 1) return flag;
if (inSsjDevice.getRkqq() != 1)
return flag;
//【输送高度】
if (inSsjDevice.getHeight() == 0) return flag;
if (inSsjDevice.getHeight() == 0)
return flag;
return true;
}
/**
* 请求wms获取wcs任务参数
* @param inSsjDevice
*/
private void requestMydoJob(DeviceSsj inSsjDevice){
//请求成功已经生成该任务则不继续执行
//如果已经生成wcs任务则不继续执行后续请求操作
//包括请求成功生成作业和wms推送成功的情况
int count = mydoJobService.selectInOrOutMydoJobList(
new MydoJob().builder().trayCode(inSsjDevice.getTrayCode()).build()
).size();
if (count > 0) {
//如果查到输送机有已经该条码的入库作业 - 把该作业更新为初始状态(未向入库输送机下发任务号的阶段)
// 省去入库输送机口的手动作废操作,自动更新任务至初始阶段
// mydoJobService.updateMydoJob(
// new MydoJob().builder()
// .status("1")
// .executionPhase("0")
// .build()
// );
return;
}
String errorMessage = "";
AjaxResult ajaxResult;
//初始化请求wms参数
HashMap<String, Object> paramMap = new HashMap<>();
paramMap.put("taskTypeCode", WMS_TASK_TYPE_STOCKIN);//wms自定义的任务类型编号
paramMap.put("reqCode", UUID.randomUUID().toString());//请求码
paramMap.put("cntCode", inSsjDevice.getTrayCode().trim());//容器编号
paramMap.put("trayCode", inSsjDevice.getTrayCode().trim());//容器编号
// paramMap.put("entranceId", inSsjDevice.getDeviceCode());//入口输送机编号
paramMap.put("cargoAreaId", ConvType.CONV_ROAD_AREA.get(inSsjDevice.getDeviceCode()));//入口输送机编号对应巷道/区域
int height = inSsjDevice.getHeight();
// String weight = inSsjDevice.getWeight();//不需要直读重量或从plc读值,wms不需要该参数
// paramMap.put("weight", getWeightByMoxa(MOXA_IP, MOXA_PORT, SO_TIMEOUT_MS));//重量
paramMap.put("altimetry", height);//高度
paramMap.put("adverseCauses", errorMessage);
paramMap.put("height", height);//高度
// paramMap.put("remark", errorMessage);
//-----------------警告校验:条码已有库存-----------------
@@ -209,9 +223,9 @@ public class PortConvThread implements Runnable {
StockinReceive result = BeanUtil.toBean(ajaxResult.get("data"), StockinReceive.class);
//校验:wms分配的货位(排列层)是否合法
if (ObjUtil.isNull(basCargoSpaceService.selectBasCargoSpaceByCargoSpaceId(result.getSiteCode()))) {
if (ObjUtil.isNull(basCargoSpaceService.selectBasCargoSpaceByCargoSpaceId(result.getCargoSpaceId()))) {
errorMessage = "wms下发货位错误,任务生成失败!";
paramMap.put("adverseCauses", errorMessage);
paramMap.put("remark", errorMessage);
apiService.createInMydoJobException(paramMap);
log.info("【响应参数异常】分配货位:null,无法生成作业,托盘条码:{}",inSsjDevice.getTrayCode());
writeToSsj(inSsjDevice.getPlcDbWriteAddress(), "99", 2, 1);
@@ -220,27 +234,26 @@ public class PortConvThread implements Runnable {
//初始化要生成的任务
MydoJob mydoJob = new MydoJob().builder()
// mydoJob.setTaskNo(result.getTaskCode());//如果需要用wms下发的任务号作为wcs的任务号使用
.trayCode(result.getCntCode())
.cargoSpaceId(result.getSiteCode())
.wmsTaskNo(result.getTaskCode())
.jobId(mydoJobService.getJobId("RK"))
.taskNo(mydoJobService.getTaskNo("1"))
.traySize(String.valueOf(inSsjDevice.getHeight()))
.status(TASK_STATUS_CREATED)
.jobId(result.getJobId())
.taskNo(mydoJobService.getTaskNo("2"))//如果需要用wms下发的任务号作为wcs的任务号使用
.status(TASK_STATUS_CREATED)
.trayCode(result.getTrayCode())
.cargoSpaceId(result.getCargoSpaceId())
// .wmsTaskNo(mydoJobService.getTaskNo("1"))
.traySize(inSsjDevice.getHeight())
.inOrOut("1")
.roadwayId(basCargoSpaceService.selectBasCargoSpaceByWmsCargoSpaceId(result.getSiteCode()).getRoadwayId())//获取货位表货位对应的巷道号
.entranceId("G1004")
.roadwayId(basCargoSpaceService.selectBasCargoSpaceByWmsCargoSpaceId(result.getCargoSpaceId()).getRoadwayId())//获取货位表货位对应的巷道号
.entranceId(inSsjDevice.getDeviceCode())
.executionPhase(TASK_EP_CREATED)
.faultFlag("0")
.priority(10L)
.priority(10)
.build();
//如果还没有wcs任务 - 生成一条任务
if (mydoJobService.selectInOrOutMydoJobList(mydoJob).isEmpty()) {
mydoJobService.insertMydoJob(mydoJob);
log.info("【入库请求】请求生成wcs作业成功,wms下发任务单号:{}, 任务号:{},托盘条码:{},分配货位:{}", mydoJob.getJobId(), mydoJob.getTaskNo(), mydoJob.getTrayCode(), mydoJob.getCargoSpaceId());
log.info("【入库请求】请求生成wcs作业成功,wms任务号:{}, wcs任务号:{},托盘条码:{},分配货位:{}", mydoJob.getWmsTaskNo(), mydoJob.getTaskNo(), mydoJob.getTrayCode(), mydoJob.getCargoSpaceId());
}
}else{
@@ -256,36 +269,113 @@ public class PortConvThread implements Runnable {
}
}
/**
* 入口到位生成wcs本地作业
* @param inSsjDevice
*/
private void generateWcsMydoJob(DeviceSsj inSsjDevice){
//如果已经生成wcs任务则不继续执行后续请求操作
//包括请求成功生成作业和wms推送成功的情况
int count = mydoJobService.selectInOrOutMydoJobList(
new MydoJob().builder().trayCode(inSsjDevice.getTrayCode()).build()
).size();
if (count > 0) return;
//-----------------警告校验:条码已有库存-----------------
BasCargoSpace cargoSpace = new BasCargoSpace();
cargoSpace.setTrayCode(inSsjDevice.getTrayCode());
if (!basCargoSpaceService.selectBasCargoSpaceList(cargoSpace).isEmpty()) {
log.warn("【警告】该托盘号已有库存,托盘条码:{}",inSsjDevice.getTrayCode());
}
int trayType = mydoJobService.getTraytypeByTrayCode(inSsjDevice.getTrayCode());
//生成的任务初始化
MydoJob mydoJob = new MydoJob().builder()
// .jobId(result.getJobId())
.taskNo(mydoJobService.getTaskNo("2"))//如果需要用wms下发的任务号作为wcs的任务号使用
.status(TASK_STATUS_CREATED)
.trayCode(inSsjDevice.getTrayCode())
// .cargoSpaceId(result.getCargoSpaceId())
// .wmsTaskNo(mydoJobService.getTaskNo("1"))
.traySize(inSsjDevice.getHeight())
.inOrOut("1")
.roadwayId(String.valueOf(ConvType.CONV_ROAD_ROADWAY.get(inSsjDevice.getDeviceCode())))//获取货位表货位对应的巷道号
.entranceId(inSsjDevice.getDeviceCode())
.executionPhase(TASK_EP_CREATED)
.faultFlag("0")
.traySize(trayType)
.priority(10)
.build();
//如果还没有wcs任务 - 生成一条任务
if (mydoJobService.selectInOrOutMydoJobList(mydoJob).isEmpty()) {
mydoJobService.insertMydoJob(mydoJob);
log.info("【生成入库】本地生成wcs作业成功,wcs任务号:{},托盘条码:{}", mydoJob.getTaskNo(), mydoJob.getTrayCode());
}
}
/**
* 更新入库任务阶段
* @param inSsjDevice
*/
private void updateMydoJob(DeviceSsj inSsjDevice){
//-------------------------------------------常规入库-------------------------------------------
//检查是否有已经创建成功的任务(请求成功的入库任务) - 更新到下一个执行阶段
MydoJob mydoJobStockin = new MydoJob().builder()
.trayCode(inSsjDevice.getTrayCode())
.status(TASK_STATUS_CREATED)
.executionPhase(TASK_EP_CREATED)
.build();
if(!mydoJobService.selectMydoJobList(mydoJobStockin).isEmpty()){
mydoJobStockin = mydoJobService.selectMydoJobList(mydoJobStockin).get(0);
//如果已经生成入库任务 - 向输送机下发任务号
//输送去向值【1】
mydoJobStockin = mydoJobService.selectMydoJobList(mydoJobStockin).get(0);
//输送机去向值【1】
int i = writeToSsj(inSsjDevice.getPlcDbWriteAddress(), mydoJobStockin.getTaskNo(), 1, 1);
// int i = 1;
if (i == 1) {
//写入成功则更新执行阶段
mydoJobStockin.setStatus(TASK_STATUS_RUNNING);
mydoJobStockin.setExecutionPhase(TASK_EP_SSJ);
// mydoJobStockin.setEntranceId(inSsjDevice.getDeviceCode());
mydoJobStockin.setStartTime(DateUtil.formatDateTime(DateUtil.date()));
mydoJobService.updateMydoJob(mydoJobStockin);
log.info("【更新状态】G1004入口输送机下发成功,任务号:{},入库执行中", mydoJobStockin.getTaskNo());
log.info("【更新状态】入口输送机{}下发成功,任务号:{},入库执行中", inSsjDevice.getDeviceCode(), mydoJobStockin.getTaskNo());
}
}
//-------------------------------------------盘点回库-------------------------------------------
//检查是否有已经创建成功的任务(请求成功的入库任务) - 更新到下一个执行阶段
mydoJobStockin = new MydoJob().builder()
.trayCode(inSsjDevice.getTrayCode())
.status(TASK_STATUS_RUNNING)
.executionPhase(TASK_EP_SSJ_INVENTORY_STOCKOUT_FINISH)
.build();
if(!mydoJobService.selectMydoJobList(mydoJobStockin).isEmpty()){
//如果已经生成入库任务 - 向输送机下发任务号
mydoJobStockin = mydoJobService.selectMydoJobList(mydoJobStockin).get(0);
//输送机去向值【1】
int i = writeToSsj(inSsjDevice.getPlcDbWriteAddress(), mydoJobStockin.getTaskNo(), 1, 1);
// int i = 1;
if (i == 1) {
//写入成功则更新执行阶段
mydoJobStockin.setExecutionPhase(TASK_EP_SSJ);
mydoJobStockin.setStartTime(DateUtil.formatDateTime(DateUtil.date()));
mydoJobService.updateMydoJob(mydoJobStockin);
log.info("【更新状态】入口输送机{}下发成功,任务号:{},盘点回库执行中", inSsjDevice.getDeviceCode(), mydoJobStockin.getTaskNo());
}
}
}
/**
* 输送机出库到位 - 任务出库完成
* 出库完成在升降位置,即【TD1001】判断完成
@@ -296,88 +386,44 @@ public class PortConvThread implements Runnable {
if (outSsjDevice.getDw() == 1 && outSsjDevice.getTaskNo() > 0) {
//查询该出库任务
MydoJob mydoJob = mydoJobService.selectMydoJobByTaskNo(Convert.toLong(outSsjDevice.getTaskNo()));
if (mydoJob != null && Integer.parseInt(mydoJob.getInOrOut()) > 20) {
log.info("【出库完成】去向:{},出库货位:{},任务号:{},出库到位", "任务结束", outSsjDevice.getDeviceCode(),mydoJob.getCargoSpaceId() , mydoJob.getTaskNo());
if (ObjUtil.isNull(mydoJob)) return;
if (Integer.parseInt(mydoJob.getInOrOut()) >= 20 && Integer.parseInt(mydoJob.getInOrOut()) == TASKTYPE_INVENTORY) {
log.info("【出库到位】去向:{},出库货位:{},任务号:{},出库完成,等待确认执行回流操作, 任务结束", outSsjDevice.getDeviceCode(),mydoJob.getCargoSpaceId() , mydoJob.getTaskNo());
mydoJob.setExecutionPhase(TASK_EP_SSJ_STOCKOUT_FINISH);
mydoJobService.updateMydoJob(mydoJob);
mydoJobService.taskFinish(Long.valueOf(mydoJob.getTaskNo()));
}
}
}
// ====== 【请按实际修改】======
private static final String MOXA_IP = "192.168.1.200"; // NPort 5110 的 IP
private static final int MOXA_PORT = 4001; // NPort 配置的 Local Port
private static final int RECONNECT_DELAY_SEC = 3; // 断线后重试间隔(秒)
private static final int SO_TIMEOUT_MS = 5000; // Socket 读超时(防卡死)
private static final Pattern WEIGHT_PATTERN = Pattern.compile(
"[+-]?\\d+\\.\\d{1,3}(?=[\\s\\r\\n]|kg|g|lb|$)"); // 匹配如 +12.34、-5.678、345.0kg
/**
* 从 MOXA NPort 5110(TCP Server 模式)读取单次称重值
* ************测试方法************
* ************测试方法************
* ************测试方法************
*
* @param moxaIp MOXA 设备 IP(如 "192.168.1.200")
* @param moxaPort MOXA 配置的 TCP 端口(如 4001)
* @param timeout 最大等待时间(单位:毫秒),建议 2000~5000
* @return 重量(kg),成功时为非 NaN 的 Double;失败(超时/断连/解析失败)返回 null
* 输送机出库到位 - 盘点任务出库阶段完成
* 出库完成在升降位置,即【TD1001】判断完成
* @param outSsjDevice
*/
public static Double getWeightByMoxa(String moxaIp, int moxaPort, long timeout) {
Socket socket = null;
try {
// 1️⃣ - 建立连接(带连接超时)
socket = new Socket();
socket.connect(new InetSocketAddress(moxaIp, moxaPort), 3000); // 连接超时 3s
socket.setSoTimeout((int) Math.min(timeout, Integer.MAX_VALUE)); // 读超时
private void finishInventoryStockoutMydoJob(DeviceSsj outSsjDevice){
//出库到位
if (outSsjDevice.getDw() == 1 && outSsjDevice.getTaskNo() > 0) {
//查询该出库任务
MydoJob mydoJob = mydoJobService.selectMydoJobByTaskNo(Convert.toLong(outSsjDevice.getTaskNo()));
// 2 - 发送请求指令(可选:仅当秤需指令才启用)
// OutputStream out = socket.getOutputStream();
// out.write("\r\n".getBytes(StandardCharsets.US_ASCII)); // 或 "\r", "W\r\n"
// out.flush();
if (ObjUtil.isNull(mydoJob)) return;
// 3 - 读响应(使用 BufferedInputStream + 手动读字节,更健壮于无换行场景)
InputStream in = socket.getInputStream();
byte[] buffer = new byte[128];
int len = in.read(buffer);
if (len <= 0) return null;
String response = new String(buffer, 0, len, StandardCharsets.US_ASCII).trim();
if (response.isEmpty()) return null;
// 4 - 解析重量(兼容常见格式:+12.34、-5.678、00012.34kg、123.45\r\n)
Pattern p = Pattern.compile("[+-]?\\d*\\.?\\d+(?=[\\s\\r\\n]|kg|g|lb|$)");
java.util.regex.Matcher m = p.matcher(response);
if (m.find()) {
try {
double w = Double.parseDouble(m.group());
// 过滤明显异常值(可选)
if (Double.isFinite(w) && Math.abs(w) < 1e6) {
return w;
}
} catch (NumberFormatException ignored) {}
//盘点任务出库到位不结束任务
if (Integer.parseInt(mydoJob.getInOrOut()) == TASKTYPE_INVENTORY) {
log.info("【盘点出库完成】去向:{},出库货位:{},任务号:{},出库到位", "盘点出库完成,等待执行回流", outSsjDevice.getDeviceCode(),mydoJob.getCargoSpaceId() , mydoJob.getTaskNo());
mydoJob.setExecutionPhase(TASK_EP_SSJ_INVENTORY_STOCKOUT_FINISH);
mydoJobService.updateMydoJob(mydoJob);
// mydoJobService.taskFinish(Long.valueOf(mydoJob.getTaskNo()));
}
return null;
} catch (IOException e) {
return null; // 连接失败、读超时、解析异常等均返回 null
} finally {
if (socket != null && !socket.isClosed()) {
try { socket.close(); } catch (IOException ignored) {}
}
}
}
public void inDispatch1(DeviceSsj ssjDevice) {
//有入库请求就肯定是电气的任务号的作业
@@ -427,7 +473,7 @@ public class PortConvThread implements Runnable {
mydoJob2.setExecutionPhase(TASK_EP_CREATED);
mydoJob2.setCreateTime(new Date());
mydoJob2.setFaultFlag("0");
mydoJob2.setPriority(10L);
mydoJob2.setPriority(10);
mydoJobService.insertMydoJob(mydoJob2);
int i = writeToSsj(ssjDevice.getPlcDbWriteAddress(),mydoJob2.getTaskNo(),1,1);
if (i == 1) {
@@ -448,16 +494,6 @@ public class PortConvThread implements Runnable {
}
public void outDispatch(DeviceSsj ssjDevice) {
//出库完成
finishStockoutMydoJob(ssjDevice);
}

View File

@@ -1,17 +1,32 @@
package com.ruoyi.schedule.scheduleTask.ssj;
import HslCommunication.Core.Types.OperateResult;
import HslCommunication.Core.Types.OperateResultExOne;
import HslCommunication.Profinet.Siemens.SiemensPLCS;
import HslCommunication.Profinet.Siemens.SiemensS7Net;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSON;
import com.ruoyi.api.domain.agv.ResponseBase;
import com.ruoyi.api.domain.wcs2wms.stockin.StockinReceive;
import com.ruoyi.api.service.IApiService;
import com.ruoyi.api.service.IRequestLogService;
import com.ruoyi.bas.cargospace.domain.BasCargoSpace;
import com.ruoyi.bas.cargospace.service.IBasCargoSpaceService;
import com.ruoyi.common.ConvType;
import com.ruoyi.common.TaskStatusCode;
import com.ruoyi.common.TaskType;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.device.ssj.domain.DeviceSsj;
import com.ruoyi.device.ssj.service.IDeviceSsjService;
import com.ruoyi.job.domain.MydoJob;
import com.ruoyi.job.service.IMydoJobService;
import com.ruoyi.queue.agv.service.IAgvQueueService;
@@ -22,10 +37,9 @@ import lombok.extern.slf4j.Slf4j;
import java.util.*;
import static com.ruoyi.common.ConvType.CONV_ROAD_1;
import static com.ruoyi.common.ConvType.CONV_STOCKOUT;
import static com.ruoyi.common.ConvType.CONV_ROAD_ROADWAY;
import static com.ruoyi.common.TaskStatusCode.*;
import static com.ruoyi.common.TaskType.*;
import static com.ruoyi.schedule.plcRead.ssj.PlcSsjRead.writeToSsj;
/**
* 巷道口输送机(堆垛机取放位)线程 检测当前巷道有没有入库作业,没有作业,生成堆垛机出库队列
@@ -40,24 +54,38 @@ public class RoadConvThread implements Runnable {
private IMydoJobService mydoJobService;
private IBasCargoSpaceService basCargoSpaceService;
private IDdjDeviceExecutionQueueService ddjDeviceExecutionQueueService;
private IRequestLogService requestLogService;
private IDeviceSsjService deviceSsjService;
public boolean isRun = true;
private static SiemensS7Net plcConv = new SiemensS7Net(SiemensPLCS.S1500, "172.16.30.140");
public void init() {
ssjCodeList = new HashMap<>();
ArrayList<String> ssjCodes = new ArrayList<>();
// ssjCodes.add("L1002");
ssjCodes.add("L1001");
ssjCodes.add("L1003");
ssjCodes.add("L1005");
ssjCodes.add("L1007");
ssjCodes.add("L1010");
ssjCodes.add("L1008");
ssjCodeList.put("roadConv", ssjCodes);
apiService = SpringUtils.getBean(IApiService.class);
agvQueueService = SpringUtils.getBean(IAgvQueueService.class);
mydoJobService = SpringUtils.getBean(IMydoJobService.class);
basCargoSpaceService = SpringUtils.getBean(IBasCargoSpaceService.class);
ddjDeviceExecutionQueueService = SpringUtils.getBean(IDdjDeviceExecutionQueueService.class);
deviceSsjService = SpringUtils.getBean(IDeviceSsjService.class);
requestLogService = SpringUtils.getBean(IRequestLogService.class);
//初始化巷道口 排 列 层
//todo 核对堆垛机取放位置的货位编码
roadwayMap.put("L1001", Arrays.asList(2, 1, 1));
// roadwayMap.put("L1004", Arrays.asList(4, 0, 1));
roadwayMap.put("L1001", Arrays.asList(2, 0, 1));
roadwayMap.put("L1003", Arrays.asList(3, 0, 1));
roadwayMap.put("L1005", Arrays.asList(5, 1, 1));
roadwayMap.put("L1007", Arrays.asList(7, 1, 1));
roadwayMap.put("L1010", Arrays.asList(10, 0, 1));
roadwayMap.put("L1008", Arrays.asList(11, 0, 1));
log.info("初始化服务 {},{}", apiService, agvQueueService);
}
@@ -72,9 +100,9 @@ public class RoadConvThread implements Runnable {
for (String ssjCode : ssjCodeList.get(type)) {
try {
if (PlcSsjRead.deviceSsjMap.containsKey(ssjCode)) {
inDispatch(PlcSsjRead.deviceSsjMap.get(ssjCode));
schedule(PlcSsjRead.deviceSsjMap.get(ssjCode));
} else {
log.error("设备不存在 ssjCode{}", ssjCode);
log.error("设备不存在:ssjCode{}", ssjCode);
}
} catch (RuntimeException e) {
log.error(e.getMessage(),e);
@@ -84,7 +112,7 @@ public class RoadConvThread implements Runnable {
}
}
try {
Thread.sleep(1500);
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
@@ -93,12 +121,477 @@ public class RoadConvThread implements Runnable {
}
public void inDispatch(DeviceSsj roadSsjDevice) {
public void schedule(DeviceSsj roadSsjDevice) {
sendStackerIn(roadSsjDevice);
sendStackerMove();
sendStackerOut(roadSsjDevice);
switch (roadSsjDevice.getDeviceCode()){
//1#巷道入库(双向)
case "L1003":
//3#巷道入库(双向)
case "L1010":
//到位校验
if (roadConvCheckedForStockin(roadSsjDevice)) {
//生成堆垛机取货队列
sendStackerIn(roadSsjDevice);
//更新入库任务阶段
updateMydoJob(roadSsjDevice);
//生成wcs本地作业
// generateWcsMydoJob(roadSsjDevice);
//巷道口到位请求
requestMydoJob(roadSsjDevice);
};
if (roadConvCheckedForStackerin(roadSsjDevice)) {
//生成堆垛机取货队列
sendStackerIn(roadSsjDevice);
};
if (roadConvCheckedForStockout(roadSsjDevice)) {
sendStackerOut(roadSsjDevice);
}
break;
//1#巷道出库口(单向)
// -- FT577项目巷道1和巷道3出库位置为单输送机,故此处【出库完成】的方法移至端口输送机线程【PortConvThread】中执行
//1001和1008作为盘点和手动出库口使用
case "L1001":
//3#巷道出库口(单向)
case "L1008":
// if (roadConvCheckedForStockout(roadSsjDevice)) {
// sendStackerOut(roadSsjDevice);
// }
break;
//2#巷道/区域02出库口(双向)
case "L1005":
//3#巷道/区域03出库口(双向)
case "L1007":
//到位校验
if (roadConvCheckedForStockin(roadSsjDevice)) {
//更新入库任务阶段
updateMydoJob(roadSsjDevice);
//生成wcs本地作业
// generateWcsMydoJob(roadSsjDevice);
//巷道口到位请求
requestMydoJob(roadSsjDevice);
}
if (roadConvCheckedForStackerin(roadSsjDevice)) {
//生成堆垛机取货队列
sendStackerIn(roadSsjDevice);
};
if (roadConvCheckedForStockout(roadSsjDevice)) {
sendStackerOut(roadSsjDevice);
}
break;
}
}
/**
* 输送机到位判断校验 - 入库
* @param inSsjDevice
* @return
*/
private boolean roadConvCheckedForStockin(DeviceSsj inSsjDevice){
boolean flag = false;
//---------------------------巷道口取放货输送机---------------------------
//输送机【任务号】和【到位】校验
// if (inSsjDevice.getTaskNo() == 0 || inSsjDevice.getDw() == 0) return flag;
if (inSsjDevice.getRkqq() == 0) return flag;
//输送机条码不能为空
if (StrUtil.isBlank(inSsjDevice.getTrayCode())) return flag;
String cargoAreaId = String.valueOf(ConvType.CONV_ROAD_AREA.get(inSsjDevice.getDeviceCode()));
int trayType = mydoJobService.getTraytypeByTrayCode(inSsjDevice.getTrayCode());
if (cargoAreaId.equals("02")){
if (trayType != 3){
log.warn("【入库异常】托盘类型与货区{}不匹配,请检查条码格式,输送机:{},托盘码:{}", cargoAreaId, inSsjDevice.getDeviceCode(), inSsjDevice.getTrayCode());
writeToSsj(inSsjDevice.getPlcDbWriteAddress(), "99", 6, 2);
return false;
}
}else{
if (trayType == 3){
log.warn("【入库异常】托盘类型与货区{}不匹配,请检查条码格式,输送机:{},托盘码:{}", cargoAreaId, inSsjDevice.getDeviceCode(), inSsjDevice.getTrayCode());
writeToSsj(inSsjDevice.getPlcDbWriteAddress(), "99", 6, 2);
return false;
}
}
return true;
}
/**
* 输送机到位判断校验 - 堆垛机入库
* @param inSsjDevice
* @return
*/
private boolean roadConvCheckedForStackerin(DeviceSsj inSsjDevice){
boolean flag = false;
//---------------------------巷道口取放货输送机---------------------------
//输送机【任务号】和【到位】校验
if (inSsjDevice.getTaskNo() == 0 || inSsjDevice.getDw() == 0) return flag;
//输送机条码不能为空
if (StrUtil.isBlank(inSsjDevice.getTrayCode())) return flag;
return true;
}
/**
* 输送机到位判断校验 - 出库
* @param outSsjDevice
* @return
*/
private boolean roadConvCheckedForStockout(DeviceSsj outSsjDevice){
//---------------------------巷道口取放货输送机---------------------------
//输送机【任务号】和【到位】校验
if (outSsjDevice.getTaskNo() != 0 || outSsjDevice.getDw() != 0) return false;
String roadwayId = CONV_ROAD_ROADWAY.get(outSsjDevice.getDeviceCode()).toString();
//当前巷道无入库作业
List<MydoJob> jobs = mydoJobService.selectMydoJobList(new MydoJob().builder().roadwayId(roadwayId).build());
if (jobs.isEmpty() || jobs.stream().anyMatch(s -> Convert.toInt(s.getInOrOut()) < 20)){
return false;
}
//入口输送机无空闲和任务号
DeviceSsj ssj;
if (outSsjDevice.getDeviceCode().equals("L1003")){
ssj = deviceSsjService.selectDeviceSsjByDeviceCode("L1002");
if (ObjUtil.isNotNull(ssj)){
if (ssj.getKx() != 1 || ssj.getTaskNo() != 0) {
// log.info("L1002");
return false;
}
}
}
if (outSsjDevice.getDeviceCode().equals("L1005")){
ssj = deviceSsjService.selectDeviceSsjByDeviceCode("L1004");
if (ObjUtil.isNotNull(ssj)){
if (ssj.getKx() != 1 || ssj.getTaskNo() != 0){
// log.info("L1004");
return false;
}
}
}
if (outSsjDevice.getDeviceCode().equals("L1007")){
ssj = deviceSsjService.selectDeviceSsjByDeviceCode("L1006");
if (ObjUtil.isNotNull(ssj)){
if (ssj.getKx() != 1 || ssj.getTaskNo() != 0) {
// log.info("L1006");
return false;
}
}
}
if (outSsjDevice.getDeviceCode().equals("L1010")){
ssj = deviceSsjService.selectDeviceSsjByDeviceCode("L1009");
if (ObjUtil.isNotNull(ssj)){
if (ssj.getKx() != 1 || ssj.getTaskNo() != 0) {
// log.info("L1009");
return false;
}
}
}
return true;
}
/**
* 入口到位生成wcs本地作业
* @param inSsjDevice
*/
private void generateWcsMydoJob(DeviceSsj inSsjDevice){
//如果已经生成wcs任务则不继续执行后续请求操作
//包括请求成功生成作业和wms推送成功的情况
int count = mydoJobService.selectInOrOutMydoJobList(
new MydoJob().builder().trayCode(inSsjDevice.getTrayCode()).build()
).size();
if (count > 0) return;
//-----------------警告校验:条码已有库存-----------------
BasCargoSpace cargoSpace = new BasCargoSpace();
cargoSpace.setTrayCode(inSsjDevice.getTrayCode());
if (!basCargoSpaceService.selectBasCargoSpaceList(cargoSpace).isEmpty()) {
log.warn("【警告】该托盘号已有库存,托盘条码:{}",inSsjDevice.getTrayCode());
}
int trayType = mydoJobService.getTraytypeByTrayCode(inSsjDevice.getTrayCode());
//生成的任务初始化
MydoJob mydoJob = new MydoJob().builder()
// .jobId(result.getJobId())
.taskNo(mydoJobService.getTaskNo("2"))//如果需要用wms下发的任务号作为wcs的任务号使用
.status(TASK_STATUS_CREATED)
.trayCode(inSsjDevice.getTrayCode())
// .cargoSpaceId(result.getCargoSpaceId())
// .wmsTaskNo(mydoJobService.getTaskNo("1"))
.traySize(inSsjDevice.getHeight())
.inOrOut("1")
.roadwayId(String.valueOf(CONV_ROAD_ROADWAY.get(inSsjDevice.getDeviceCode())))//获取货位表货位对应的巷道号
.entranceId(inSsjDevice.getDeviceCode())
.executionPhase(TASK_EP_CREATED)
.faultFlag("0")
.traySize(trayType)
.priority(10)
.build();
//如果还没有这个条码的wcs任务 - 生成一条任务
List<MydoJob> jobs = mydoJobService.selectMydoJobList(
new MydoJob().builder().trayCode(inSsjDevice.getTrayCode()).build()
);
if (jobs.isEmpty()) {
mydoJobService.insertMydoJob(mydoJob);
log.info("【生成入库】本地生成wcs作业成功,wcs任务号:{},托盘条码:{}", mydoJob.getTaskNo(), mydoJob.getTrayCode());
}
}
/**
* 请求wms获取wcs任务参数
* @param inSsjDevice
*/
private void requestMydoJob(DeviceSsj inSsjDevice){
//如果已经生成wcs任务则不继续执行后续请求操作
//包括请求成功生成作业和wms推送成功的情况
int count = mydoJobService.selectInOrOutMydoJobList(
new MydoJob().builder().trayCode(inSsjDevice.getTrayCode()).build()
).size();
if (count > 0) {
return;
}
String errorMessage = "";
AjaxResult ajaxResult;
//初始化请求wms参数
HashMap<String, Object> paramMap = new HashMap<>();
paramMap.put("reqCode", UUID.randomUUID().toString());//请求码
paramMap.put("trayCode", inSsjDevice.getTrayCode().trim());//容器编号
paramMap.put("entranceId", inSsjDevice.getDeviceCode());//入口输送机编号
paramMap.put("cargoAreaId", ConvType.CONV_ROAD_AREA.get(inSsjDevice.getDeviceCode()));//入口输送机编号对应巷道/区域
int height = mydoJobService.getTraytypeByTrayCode(inSsjDevice.getTrayCode());
if (height == 0){
log.warn("【请求入库】参数异常,高度不符合入库条件,可能是条码格式错误,条码:{},高度:{}", inSsjDevice.getTrayCode(), height);
return;
}
paramMap.put("height", height);//高度
// paramMap.put("remark", errorMessage);
//-----------------警告校验:条码已有库存-----------------
BasCargoSpace cargoSpace = new BasCargoSpace();
cargoSpace.setTrayCode(inSsjDevice.getTrayCode());
if (!basCargoSpaceService.selectBasCargoSpaceList(cargoSpace).isEmpty()) {
log.warn("【警告】该托盘号已有库存,托盘条码:{}",inSsjDevice.getTrayCode());
}
/*-----------------请求生成wcs任务----------------- */
ajaxResult = apiService.createMydoJobForStockin(paramMap);
if (ajaxResult.isSuccess()) {
//解析wms下发的响应参数(任务号和货位)
ResponseBase res = JSON.parseObject(ajaxResult.get("msg").toString(), ResponseBase.class);
StockinReceive result = BeanUtil.toBean(res.getData(), StockinReceive.class);
//校验:wms分配的货位(排列层)是否合法
if (ObjUtil.isNull(basCargoSpaceService.selectBasCargoSpaceByCargoSpaceId(result.getCargoSpaceId()))) {
errorMessage = "wms下发货位错误,任务生成失败!";
paramMap.put("remark", errorMessage);
apiService.createInMydoJobException(paramMap);
log.info("【响应参数异常】分配货位:null,无法生成作业,托盘条码:{}",inSsjDevice.getTrayCode());
writeToSsj(inSsjDevice.getPlcDbWriteAddress(), "99", 2, 1);
return;
}
int priority = result.getInOrOut() == TaskType.TASKTYPE_MOVE_STR ? 0 : 10;
//初始化要生成的任务
MydoJob mydoJob = new MydoJob().builder()
.jobId(result.getJobId())
.taskNo(mydoJobService.getTaskNo("2"))//如果需要用wms下发的任务号作为wcs的任务号使用
.status(TASK_STATUS_CREATED)
.trayCode(result.getTrayCode())
.cargoSpaceId(result.getCargoSpaceId())
// .wmsTaskNo(mydoJobService.getTaskNo("1"))
.traySize(height)
.inOrOut(result.getInOrOut())
.roadwayId(basCargoSpaceService.selectBasCargoSpaceByWmsCargoSpaceId(result.getCargoSpaceId()).getRoadwayId())//获取货位表货位对应的巷道号
.entranceId(inSsjDevice.getDeviceCode())
.executionPhase(TASK_EP_CREATED)
.faultFlag("0")
.priority(priority)
.build();
//如果还没有wcs任务 - 生成一条任务
if (mydoJobService.selectInOrOutMydoJobList(mydoJob).isEmpty()) {
mydoJobService.insertMydoJob(mydoJob);
log.info("【入库请求】请求生成wcs作业成功,wms任务号:{}, wcs任务号:{},托盘条码:{},分配货位:{}", mydoJob.getJobId(), mydoJob.getTaskNo(), mydoJob.getTrayCode(), mydoJob.getCargoSpaceId());
}
}else{
// 请求生成wcs任务失败
// 向输送机下发退回
int i = writeToSsj(inSsjDevice.getPlcDbWriteAddress(), "99", 6, 2);
if(i == 1){
// 接口调用失败处理
log.info("【入库请求】请求生成wcs作业失败退回,请检查网络或请求参数,请求内容:{}", JSON.toJSONString(paramMap));
log.info("【错误信息】{}", requestLogService.selectRequestLogByLatestTask().getErrorDetails());
}
}
}
/**
* 更新入库任务阶段
* @param inSsjDevice
*/
private void updateMydoJob(DeviceSsj inSsjDevice) {
//-------------------------------------------常规入库-------------------------------------------
//检查是否有已经创建成功的任务(请求成功的入库任务) - 更新到下一个执行阶段
MydoJob mydoJobStockin = new MydoJob().builder()
.trayCode(inSsjDevice.getTrayCode())
.status(TASK_STATUS_CREATED)
.build();
if (mydoJobService.selectMydoJobList(mydoJobStockin).isEmpty()) return;
//如果已经生成入库任务 - 向输送机下发任务号
mydoJobStockin = mydoJobService.selectMydoJobList(mydoJobStockin).get(0);
//输送机去向值【1】
int i = writeToSsj(inSsjDevice.getPlcDbWriteAddress(), mydoJobStockin.getTaskNo(), 1, 1);
if (i == 1) {
//执行下发后再次读输送机任务号检查是否写入成功
boolean sendConvIsSuccess = Convert.toInt(mydoJobStockin.getTaskNo()) == getRoadConvTaskNo(inSsjDevice.getDeviceCode());
if (!sendConvIsSuccess){
log.info("【更新状态】巷道口输送机{}未获取到下发任务号:{},等待重试中...", inSsjDevice.getDeviceCode(), mydoJobStockin.getTaskNo());
return;
}
//写入成功则更新执行阶段
mydoJobStockin.setStatus(TASK_STATUS_RUNNING);
mydoJobStockin.setExecutionPhase(TASK_EP_ROADWAY_SSJ);
// mydoJobStockin.setEntranceId(inSsjDevice.getDeviceCode());
mydoJobStockin.setStartTime(DateUtil.formatDateTime(DateUtil.date()));
mydoJobService.updateMydoJob(mydoJobStockin);
log.info("【更新状态】巷道输送机{}入库到位,下发成功,任务号:{},等待堆垛机取货", inSsjDevice.getDeviceCode(), mydoJobStockin.getTaskNo());
}else{
log.info("【更新状态】巷道输送机{}入库到位,下发失败,任务号:{},等待重试中...", inSsjDevice.getDeviceCode(), mydoJobStockin.getTaskNo());
}
}
/**
* 向堆垛机发送【出库】任务
* @param roadSsjDevice
*/
private void sendStackerOut(DeviceSsj roadSsjDevice){
//---------------------------出库任务---------------------------
//检查巷道口输送机是否空闲
if(roadSsjDevice.getKx() == 1 && roadSsjDevice.getTaskNo() == 0){
//检查是否有当前巷道的出库任务
String exitId = roadSsjDevice.getDeviceCode();
//检查是否有出库任务
MydoJob mydoJob = mydoJobService.selectMydoJobByExitId(exitId);
List<MydoJob> mydoJobs = mydoJobService.selectMydoJobList(
new MydoJob().builder().exitId(exitId).build()
);
//有正在执行的作业
if ( mydoJobs.stream().anyMatch(s -> Convert.toInt(s.getStatus()) > 1)) return;
if (!mydoJobs.isEmpty()){
//如果有出库任务 - 检查货位编码是否合法
BasCargoSpace basCargoSpace = basCargoSpaceService.selectBasCargoSpaceByWmsCargoSpaceId(mydoJob.getCargoSpaceId());
int devId = 1;
if (!basCargoSpace.getRoadwayId().equals("1")){
devId = 2;
}
if (ObjUtil.isNull(basCargoSpace)) {
log.error("【任务异常】货位不存在 cargoSpaceId{}", mydoJob.getCargoSpaceId());
} else {
//生成队列
List<DdjDeviceExecutionQueue> list = ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueList(
new DdjDeviceExecutionQueue().builder().devId(Convert.toInt(mydoJob.getRoadwayId())).build()
);
List<Integer> pclList = roadwayMap.get(roadSsjDevice.getDeviceCode());
if (CollUtil.isEmpty(list) && CollUtil.isNotEmpty(pclList)) {
DdjDeviceExecutionQueue ddjDeviceExecutionQueue = new DdjDeviceExecutionQueue();
ddjDeviceExecutionQueue.setUuid(IdUtil.simpleUUID());
ddjDeviceExecutionQueue.setRwh(Convert.toLong(mydoJob.getTaskNo()));
ddjDeviceExecutionQueue.setDevName(String.valueOf("ddj" + devId));
ddjDeviceExecutionQueue.setDevId(devId);
ddjDeviceExecutionQueue.setRwzt(0);
ddjDeviceExecutionQueue.setYph(Convert.toInt(basCargoSpace.getThePlatoon()));
ddjDeviceExecutionQueue.setYlh(Convert.toInt(basCargoSpace.getTheColumn()));
ddjDeviceExecutionQueue.setYch(Convert.toInt(basCargoSpace.getTheFloor()));
ddjDeviceExecutionQueue.setMbph(pclList.get(0));
ddjDeviceExecutionQueue.setMblh(pclList.get(1));
ddjDeviceExecutionQueue.setMbch(pclList.get(2));
ddjDeviceExecutionQueue.setDdjxf("0");
ddjDeviceExecutionQueue.setMlfs(5);
// ddjDeviceExecutionQueue.setSpare1(mydoJob.getTraySize().toString());//货物高度
ddjDeviceExecutionQueue.setScsj(DateUtil.formatDateTime(DateUtil.date()));
// ddjDeviceExecutionQueue.setRwlx(DDJ_RWLX_2);
ddjDeviceExecutionQueueService.insertDdjDeviceExecutionQueue(ddjDeviceExecutionQueue);
//修改作业状态
mydoJob.setStatus(TASK_STATUS_RUNNING);
mydoJob.setExecutionPhase(TASK_EP_DDJ);
mydoJob.setStartTime(DateUtil.formatDateTime(DateUtil.date()));
mydoJobService.updateMydoJob(mydoJob);
log.info("【堆垛机出库】输送机:{}空闲,等待堆垛机执行,更新任务状态,任务号:{}", roadSsjDevice.getDeviceCode(), mydoJob.getTaskNo());
}
}
}else{
// log.info("【出库警告】当前出口"+ exitId +"存在入库任务,无法出库!");
}
}
}
@@ -107,40 +600,37 @@ public class RoadConvThread implements Runnable {
* @param roadSsjDevice
*/
private void sendStackerIn(DeviceSsj roadSsjDevice){
//模拟数据
// roadSsjDevice.setDw(1);
// roadSsjDevice.setTaskNo(85012);
//---------------------------出库任务---------------------------
//---------------------------入库任务---------------------------
//巷道口输送机到位,且任务号大于1000
if (roadSsjDevice.getDw()==1 && roadSsjDevice.getTaskNo()>1000) {
//检查是否有入库任务
MydoJob mydoJob = mydoJobService.selectMydoJobByTaskNo(Long.valueOf(roadSsjDevice.getTaskNo()));
if (ObjUtil.isNotNull(mydoJob)) {
//根据输送机【任务号】查找当前执行的入库任务
MydoJob mydoJob = mydoJobService.selectMydoJobByTaskNo(Convert.toLong(roadSsjDevice.getTaskNo()));
if(ObjUtil.isNotNull(mydoJob)){
//检查执行阶段
if (!mydoJob.getExecutionPhase().equals(TASK_EP_ROADWAY_SSJ)) return;
//如果任务存在 - 表示该任务已经巷道口输送到位
//更新任务阶段【巷道口入库到位】
if(mydoJob.getExecutionPhase().equals(TASK_EP_SSJ)){
mydoJob.setExecutionPhase(TASK_EP_ROADWAY_SSJ);
mydoJobService.updateMydoJob(mydoJob);
//如果有入库任务 - 检查货位编码是否合法
BasCargoSpace basCargoSpace = basCargoSpaceService.selectBasCargoSpaceByWmsCargoSpaceId(mydoJob.getCargoSpaceId());
int devId = 1;
if (!basCargoSpace.getRoadwayId().equals("1")){
devId = 2;
}
// 检查任务属性:【任务已存在】、执行阶段-【巷道口输送机到位】、任务类型-【入库】 → 下发堆垛机执行队列
if (mydoJob.getExecutionPhase().equals(TASK_EP_ROADWAY_SSJ) && Convert.toInt(mydoJob.getInOrOut()) < 20) {
//检查堆垛机是否在正在执行中/已经有执行队列
List<DdjDeviceExecutionQueue> ddjDeviceExecutionQueues = ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueListByRwlx(DDJ_RWLX_3, Convert.toInt(mydoJob.getRoadwayId()));
BasCargoSpace basCargoSpace = basCargoSpaceService.selectBasCargoSpaceByWmsCargoSpaceId(mydoJob.getCargoSpaceId());
if (ObjUtil.isNull(basCargoSpace)) {
log.error("【任务异常】货位不存在 cargoSpaceId{}", mydoJob.getCargoSpaceId());
} else {
//生成队列
List<DdjDeviceExecutionQueue> list = ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueList(
new DdjDeviceExecutionQueue().builder().devId(Convert.toInt(mydoJob.getRoadwayId())).build()
);
List<Integer> pclList = roadwayMap.get(roadSsjDevice.getDeviceCode());
//生成堆垛机执行队列
if (CollUtil.isEmpty(ddjDeviceExecutionQueues) && ObjUtil.isNotNull(basCargoSpace) && CollUtil.isNotEmpty(pclList)) {
if (CollUtil.isEmpty(list) && CollUtil.isNotEmpty(pclList)) {
DdjDeviceExecutionQueue ddjDeviceExecutionQueue = new DdjDeviceExecutionQueue();
ddjDeviceExecutionQueue.setUuid(IdUtil.simpleUUID());
ddjDeviceExecutionQueue.setRwh(Convert.toLong(mydoJob.getTaskNo()));
ddjDeviceExecutionQueue.setDevName(mydoJob.getRoadwayId());
ddjDeviceExecutionQueue.setDevId(Convert.toInt(mydoJob.getRoadwayId()));
ddjDeviceExecutionQueue.setDevName("ddj" + devId);
ddjDeviceExecutionQueue.setDevId(devId);
ddjDeviceExecutionQueue.setRwzt(0);
ddjDeviceExecutionQueue.setYph(pclList.get(0));
ddjDeviceExecutionQueue.setYlh(pclList.get(1));
@@ -150,83 +640,124 @@ public class RoadConvThread implements Runnable {
ddjDeviceExecutionQueue.setMbch(Convert.toInt(basCargoSpace.getTheFloor()));
ddjDeviceExecutionQueue.setDdjxf("0");
ddjDeviceExecutionQueue.setMlfs(5);
ddjDeviceExecutionQueue.setSpare1(mydoJob.getTraySize());//货物高度
// ddjDeviceExecutionQueue.setSpare1(mydoJob.getTraySize().toString());//货物高度
ddjDeviceExecutionQueue.setScsj(DateUtil.formatDateTime(DateUtil.date()));
ddjDeviceExecutionQueue.setRwlx(DDJ_RWLX_3);
// ddjDeviceExecutionQueue.setRwlx(DDJ_RWLX_2);
ddjDeviceExecutionQueueService.insertDdjDeviceExecutionQueue(ddjDeviceExecutionQueue);
//修改作业状态
mydoJob.setStatus(TASK_STATUS_RUNNING);
mydoJob.setExecutionPhase(TASK_EP_DDJ);
mydoJob.setStartTime(DateUtil.formatDateTime(DateUtil.date()));
mydoJobService.updateMydoJob(mydoJob);
if (ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueList(ddjDeviceExecutionQueue).size() > 0){
//下发后更新任务阶段
mydoJob.setExecutionPhase(TASK_EP_DDJ);
mydoJobService.updateMydoJob(mydoJob);
}
}
}
}
}
}
/**
* 向堆垛机发送【出库】任务
* @param roadSsjDevice
*/
private void sendStackerOut(DeviceSsj roadSsjDevice){
//---------------------------出库任务---------------------------
//检查巷道口输送机是否空闲
if(roadSsjDevice.getKx()==1 && roadSsjDevice.getTaskNo() == 0){
//检查是否有入口是【G1004】的入库任务
String exitId = CONV_STOCKOUT;
List<MydoJob> inList = mydoJobService.getInJobByEntranceId(exitId);
if(inList.size() == 0){
//检查是否有出库任务
MydoJob mydoJob = mydoJobService.selectMydoJobByExitId(exitId);
if (ObjUtil.isNotNull(mydoJob)) {
//如果有出库任务 - 检查货位编码是否合法
BasCargoSpace basCargoSpace = basCargoSpaceService.selectBasCargoSpaceByWmsCargoSpaceId(mydoJob.getCargoSpaceId());
if (ObjUtil.isNull(basCargoSpace)) {
log.error("【任务异常】货位不存在 cargoSpaceId{}", mydoJob.getCargoSpaceId());
} else {
//生成队列
List<DdjDeviceExecutionQueue> list = ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueListByRwlx(DDJ_RWLX_2, Convert.toInt(mydoJob.getRoadwayId()));
List<Integer> pclList = roadwayMap.get(roadSsjDevice.getDeviceCode());
if (CollUtil.isEmpty(list) && CollUtil.isNotEmpty(pclList)) {
DdjDeviceExecutionQueue ddjDeviceExecutionQueue = new DdjDeviceExecutionQueue();
ddjDeviceExecutionQueue.setUuid(IdUtil.simpleUUID());
ddjDeviceExecutionQueue.setRwh(Convert.toLong(mydoJob.getTaskNo()));
ddjDeviceExecutionQueue.setDevName(mydoJob.getRoadwayId());
ddjDeviceExecutionQueue.setDevId(Convert.toInt(mydoJob.getRoadwayId()));
ddjDeviceExecutionQueue.setRwzt(0);
ddjDeviceExecutionQueue.setYph(Convert.toInt(basCargoSpace.getThePlatoon()));
ddjDeviceExecutionQueue.setYlh(Convert.toInt(basCargoSpace.getTheColumn()));
ddjDeviceExecutionQueue.setYch(Convert.toInt(basCargoSpace.getTheFloor()));
ddjDeviceExecutionQueue.setMbph(pclList.get(0));
ddjDeviceExecutionQueue.setMblh(pclList.get(1));
ddjDeviceExecutionQueue.setMbch(pclList.get(2));
ddjDeviceExecutionQueue.setDdjxf("0");
ddjDeviceExecutionQueue.setMlfs(5);
ddjDeviceExecutionQueue.setSpare1(mydoJob.getTraySize());//货物高度
ddjDeviceExecutionQueue.setScsj(DateUtil.formatDateTime(DateUtil.date()));
ddjDeviceExecutionQueue.setRwlx(DDJ_RWLX_2);
ddjDeviceExecutionQueueService.insertDdjDeviceExecutionQueue(ddjDeviceExecutionQueue);
//修改作业状态
mydoJob.setStatus(TASK_STATUS_RUNNING);
mydoJob.setExecutionPhase(TASK_EP_DDJ);
mydoJob.setStartTime(DateUtil.formatDateTime(DateUtil.date()));
mydoJobService.updateMydoJob(mydoJob);
}
log.info("【巷道口入库】输送机:{}入库到位,更新任务状态,等待堆垛机执行,任务号:{}", roadSsjDevice.getDeviceCode(), mydoJob.getTaskNo());
}
}
}else{
log.info("【出库警告】当前出口"+ exitId +"存在入库任务,无法出库!");
// log.info("【出库警告】当前出口"+ exitId +"存在入库任务,无法出库!");
}
}
}
/**
* 向堆垛机发送【移库】任务
*/
private void sendStackerMove(){
//---------------------------移库任务---------------------------
//检查是否有入库任务
// MydoJob mydoJob = mydoJobService.selectMydoJobByTaskNo(Long.valueOf(roadSsjDevice.getTaskNo()));
List<MydoJob> mydoJobs = mydoJobService.selectMydoJobList(
new MydoJob().builder().inOrOut(TaskType.TASKTYPE_MOVE_STR).build()
);
if (mydoJobs.isEmpty()) return;
for (MydoJob moveJob : mydoJobs) {
//检查执行阶段
if (!moveJob.getExecutionPhase().equals(TASK_EP_CREATED) || !moveJob.getStatus().equals(TASK_EP_CREATED)) return;
//如果有入库任务 - 检查货位编码是否合法
BasCargoSpace basCargoSpace = basCargoSpaceService.selectBasCargoSpaceByWmsCargoSpaceId(moveJob.getCargoSpaceId());
int devId = 1;
if (!basCargoSpace.getRoadwayId().equals("1")){
devId = 2;
}
if (ObjUtil.isNull(basCargoSpace)) {
log.error("【任务异常】货位不存在 cargoSpaceId{}", moveJob.getCargoSpaceId());
} else {
//生成队列
List<DdjDeviceExecutionQueue> list = ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueList(
new DdjDeviceExecutionQueue().builder().devId(Convert.toInt(moveJob.getRoadwayId())).build()
);
// List<Integer> pclList = roadwayMap.get(roadSsjDevice.getDeviceCode());
BasCargoSpace cargo = basCargoSpaceService.selectBasCargoSpaceByCargoSpaceId(moveJob.getCargoSpaceId());
BasCargoSpace cargoTarget = basCargoSpaceService.selectBasCargoSpaceByCargoSpaceId(moveJob.getTargetCargoSpaceId());
if (CollUtil.isEmpty(list)) {
DdjDeviceExecutionQueue ddjDeviceExecutionQueue = new DdjDeviceExecutionQueue();
ddjDeviceExecutionQueue.setUuid(IdUtil.simpleUUID());
ddjDeviceExecutionQueue.setRwh(Convert.toLong(moveJob.getTaskNo()));
ddjDeviceExecutionQueue.setDevName("ddj" + devId);
ddjDeviceExecutionQueue.setDevId(devId);
ddjDeviceExecutionQueue.setRwzt(0);
ddjDeviceExecutionQueue.setYph(Convert.toInt(cargo.getThePlatoon()));
ddjDeviceExecutionQueue.setYlh(Convert.toInt(cargo.getTheColumn()));
ddjDeviceExecutionQueue.setYch(Convert.toInt(cargo.getTheFloor()));
ddjDeviceExecutionQueue.setMbph(Convert.toInt(cargoTarget.getThePlatoon()));
ddjDeviceExecutionQueue.setMblh(Convert.toInt(cargoTarget.getTheColumn()));
ddjDeviceExecutionQueue.setMbch(Convert.toInt(cargoTarget.getTheFloor()));
ddjDeviceExecutionQueue.setDdjxf("0");
ddjDeviceExecutionQueue.setMlfs(5);
// ddjDeviceExecutionQueue.setSpare1(mydoJob.getTraySize().toString());//货物高度
ddjDeviceExecutionQueue.setScsj(DateUtil.formatDateTime(DateUtil.date()));
// ddjDeviceExecutionQueue.setRwlx(DDJ_RWLX_2);
ddjDeviceExecutionQueueService.insertDdjDeviceExecutionQueue(ddjDeviceExecutionQueue);
//修改作业状态
moveJob.setStatus(TASK_STATUS_RUNNING);
moveJob.setExecutionPhase(TASK_EP_DDJ);
moveJob.setStartTime(DateUtil.formatDateTime(DateUtil.date()));
mydoJobService.updateMydoJob(moveJob);
log.info("【堆垛机移库】生成移库队列,更新任务状态,等待堆垛机执行,任务号:{},源位置:{},目标位置:{}", moveJob.getTaskNo(), moveJob.getCargoSpaceId(), moveJob.getTargetCargoSpaceId());
}
}
}
}
int getRoadConvTaskNo(String deviceCode){
String readAddr = "";
switch (deviceCode){
case "1003":
readAddr = "DB501.88";
break;
case "1005":
readAddr = "DB501.116";
break;
case "1007":
readAddr = "DB501.146";
break;
case "1010":
readAddr = "DB501.172";
break;
}
OperateResultExOne<Integer> res = plcConv.ReadInt32(readAddr);
if (res.IsSuccess){
return res.Content;
}
return 0;
}
}

View File

@@ -12,7 +12,7 @@ spring:
# password: Flrd0914.
# 本机
url: jdbc:sqlserver://127.0.0.1:1433;databaseName=FT568-wcs;encrypt=true;trustServerCertificate=true;
url: jdbc:sqlserver://127.0.0.1:1433;databaseName=FT577-wcs;encrypt=true;trustServerCertificate=true;
username: sa
password: 123456

View File

@@ -16,7 +16,7 @@ ruoyi:
# 开发环境配置
server:
# 服务器的HTTP端口,默认为8080
port: 8084
port: 8081
servlet:
# 应用的访问路径
context-path: /
@@ -60,22 +60,26 @@ spring:
max-file-size: 10MB
# 设置总上传的文件大小
max-request-size: 20MB
encoding:
charset: UTF-8
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss
# 服务模块
devtools:
restart:
# 热部署开关
enabled: true
# redis 配置
spring.redis:
redis:
# 地址
host: 127.0.0.1
# host: 172.16.4.12
host: 172.16.30.100
# 端口,默认为6379
port: 6379
# 数据库索引
database: 2
database: 0
# 密码
password: 123456
password:
# 连接超时时间
timeout: 10s
lettuce:
@@ -113,6 +117,7 @@ mybatis:
# mapper-locations: classpath*:mapper/**/*Mapper.xml
# # 实体类别名包(让 XML 中能用 User 而非全限定名)
# type-aliases-package: com.ruoyi.**.domain
# config-location: classpath:mybatis/mybatis-config.xml
# configuration:
# map-underscore-to-camel-case: true
# cache-enabled: false

View File

@@ -5,9 +5,6 @@
<!-- 日志输出格式 -->
<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
<!-- 输出编码格式 -->
<property name="log.charset" value="UTF-8" />
<!-- 控制台输出 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
@@ -27,7 +24,6 @@
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
<charset>${log.charset}</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
@@ -50,7 +46,6 @@
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
<charset>${log.charset}</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->

View File

@@ -28,10 +28,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="port" column="port" />
<result property="plcDbReadAddress" column="plc_db_read_address" />
<result property="plcDbWriteAddress" column="plc_db_write_address" />
<result property="height" column="height" />
</resultMap>
<sql id="selectMsgDdjVo">
select id, name, rwh, jdbz, sbzt, czfs, yxxf, yph, ylh, ych, mbph, mblh, mbch, xtxh, dqxd, hczt, current_row, current_column, current_floor,ip,port,plc_db_read_address,plc_db_write_address from msg_ddj
select id, name, rwh, jdbz, sbzt, czfs, yxxf, yph, ylh, ych, mbph, mblh, mbch, xtxh, dqxd, hczt, current_row, current_column, current_floor,ip,port,plc_db_read_address,plc_db_write_address,height from msg_ddj
</sql>
<select id="selectMsgDdjList" parameterType="MsgDdj" resultMap="MsgDdjResult">
@@ -55,6 +56,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="currentRow != null "> and current_row = #{currentRow}</if>
<if test="currentColumn != null "> and current_column = #{currentColumn}</if>
<if test="currentFloor != null "> and current_floor = #{currentFloor}</if>
<if test="height != null "> and height = #{height}</if>
</where>
</select>
@@ -85,6 +87,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="currentRow != null">current_row,</if>
<if test="currentColumn != null">current_column,</if>
<if test="currentFloor != null">current_floor,</if>
<if test="height != null">height,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">#{id},</if>
@@ -106,6 +109,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="currentRow != null">#{currentRow},</if>
<if test="currentColumn != null">#{currentColumn},</if>
<if test="currentFloor != null">#{currentFloor},</if>
<if test="height != null">#{height},</if>
</trim>
</insert>
@@ -130,6 +134,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="currentRow != null">current_row = #{currentRow},</if>
<if test="currentColumn != null">current_column = #{currentColumn},</if>
<if test="currentFloor != null">current_floor = #{currentFloor},</if>
<if test="height != null">height = #{height},</if>
</trim>
where id = #{id}
</update>

View File

@@ -26,6 +26,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
select request_id, request_time, source_system, target_system, endpoint, request_url, request_method, request_headers, request_body, response_time, response_body, response_status, error_details, duration, Is_successful from request_log
</sql>
<sql id="selectTop1RequestLogVo">
select top 1 request_id, request_time, source_system, target_system, endpoint, request_url, request_method, request_headers, request_body, response_time, response_body, response_status, error_details, duration, Is_successful from request_log
</sql>
<select id="selectRequestLogList" parameterType="RequestLog" resultMap="RequestLogResult">
<include refid="selectRequestLogVo"/>
<where>
@@ -50,7 +54,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</select>
<select id="selectRequestLogByLatestTask" resultMap="RequestLogResult">
select top 1 request_id, request_time, source_system, target_system, endpoint, request_url, request_method, request_headers, request_body, response_time, response_body, response_status, error_details, duration, Is_successful from request_log
<include refid="selectTop1RequestLogVo"/>
order by request_time desc
</select>

View File

@@ -187,6 +187,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<trim prefix="SET" suffixOverrides=",">
<if test="status != null and status != ''">status = #{status},</if>
<if test="taskNo != null and taskNo != ''">task_no = #{taskNo},</if>
<if test="jobId != null and jobId != ''">job_id = #{jobId},</if>
<if test="roadwayId != null">roadway_id = #{roadwayId},</if>
<if test="cargoSpaceId != null">cargo_space_id = #{cargoSpaceId},</if>
<if test="targetRoadwayId != null">target_roadway_id = #{targetRoadwayId},</if>
@@ -206,7 +207,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="traySize != null">tray_size = #{traySize},</if>
<if test="wmsTaskNo != null">wms_task_no = #{wmsTaskNo},</if>
</trim>
where job_id = #{jobId}
where task_no = #{taskNo}
</update>
<delete id="deleteMydoJobByJobId" parameterType="String">
@@ -278,7 +279,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<select id="selectMydoJobByExitId" parameterType="java.lang.String" resultMap="MydoJobResult">
select TOP 1 job_id, status, task_no, roadway_id, cargo_space_id, target_roadway_id, target_cargo_space_id, priority, execution_phase, in_or_out, create_time, start_time, finish_time, entrance_id, exit_id, warehouse_id, fault_flag, wms_task_no, tray_code, tray_size, flag from mydo_job_wcs
where exit_id = #{exitId}
and in_or_out = 2
and in_or_out &gt;= 20
and status = 1 and execution_phase= 0
order by priority asc,create_time asc
</select>
@@ -297,7 +298,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="cargoSpaceId != null and cargoSpaceId != ''"> and cargo_space_id = #{cargoSpaceId}</if>
<if test="targetRoadwayId != null and targetRoadwayId != ''"> and target_roadway_id = #{targetRoadwayId}</if>
<if test="targetCargoSpaceId != null and targetCargoSpaceId != ''"> and target_cargo_space_id = #{targetCargoSpaceId}</if>
<if test="priority != null "> and priority = #{priority}</if>
<if test="priority != null and priority != '' "> and priority = #{priority}</if>
<if test="executionPhase != null and executionPhase != ''"> and execution_phase = #{executionPhase}</if>
<if test="inOrOut != null and inOrOut != ''"> and in_or_out = #{inOrOut}</if>
<if test="startTime != null and startTime != ''"> and start_time = #{startTime}</if>
@@ -311,6 +312,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="traySize != null and traySize != ''"> and tray_size = #{traySize}</if>
<if test="wmsTaskNo != null and wmsTaskNo != ''">and wms_task_no = #{wmsTaskNo}</if>
</where>
order by create_time desc
</select>
<select id="selectRunningMydoJobByExitList" resultMap="MydoJobResult">
select TOP 1 job_id, status, task_no, roadway_id, cargo_space_id, target_roadway_id, target_cargo_space_id, priority, execution_phase, in_or_out, create_time, start_time, finish_time, entrance_id, exit_id, warehouse_id, fault_flag,flag,tray_size,tray_code from mydo_job_wcs

View File

@@ -67,14 +67,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
where rwh = #{taskNo}
</select>
<select id="selectDdjDeviceExecutionQueueListByRwlx"
resultMap="DdjDeviceExecutionQueueResult">
<select id="selectDdjDeviceExecutionQueueListByRwlx" resultMap="DdjDeviceExecutionQueueResult">
<include refid="selectDdjDeviceExecutionQueueVo"/>
where rwlx = #{rwlx} and dev_id = #{devId}
</select>
<select id="selectDdjDeviceExecutionQueueByRwhAndXd"
resultMap="DdjDeviceExecutionQueueResult">
<select id="selectDdjDeviceExecutionQueueByRwhAndXd" resultMap="DdjDeviceExecutionQueueResult">
<include refid="selectDdjDeviceExecutionQueueVo"/>
where rwh = #{rwh} and dev_id = #{devId}
</select>