1. 小幅更新托盘库的入库流程,与上层商量后改为先调用query接口查询是否可上料,可上料才能调用orderIn接口,之后轮询agvDone接口,直到返回0,即入库订单状态更新完成,将入库任务推送wcs入库
2. 删除托盘库和料箱库的资源锁插件
This commit is contained in:
parent
c81c639a19
commit
0e5b01739c
|
|
@ -1,14 +1,14 @@
|
||||||
### MyWMS接口测试
|
### MyWMS接口测试
|
||||||
### 基础配置
|
### 基础配置
|
||||||
@baseUrl = http://localhost:12315
|
@baseUrl = http://localhost:12325
|
||||||
|
|
||||||
### 1. 入库订单接口
|
### 1. 入库订单接口
|
||||||
POST {{baseUrl}}/mywms/orderIn
|
POST {{baseUrl}}/mywms/orderIn
|
||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
|
|
||||||
{
|
{
|
||||||
"taskId": "testOrderId9",
|
"taskId": "testId1",
|
||||||
"vehicleNo": "1002"
|
"vehicleNo": "1001"
|
||||||
}
|
}
|
||||||
|
|
||||||
### 2. 出库订单接口
|
### 2. 出库订单接口
|
||||||
|
|
@ -16,54 +16,18 @@ POST {{baseUrl}}/mywms/orderOut
|
||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
|
|
||||||
{
|
{
|
||||||
"taskId": "testOrderId1",
|
"taskId": "testId1",
|
||||||
"vehicleNo": "1002"
|
"vehicleNo": "1002"
|
||||||
}
|
}
|
||||||
|
|
||||||
### 3. 库存查询接口 - 仅按载具查询
|
### 3. 发送任务结果 - 任务完成
|
||||||
POST {{baseUrl}}/mywms/stock
|
POST {{baseUrl}}/wms/task/sendTaskResult
|
||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
|
|
||||||
{
|
{
|
||||||
"requestId": "testOrderId1",
|
"taskId": "1758635063394010001",
|
||||||
"details": [
|
"taskStatus": 100,
|
||||||
{
|
"vehicleNo": "1009",
|
||||||
"vehicleNo": "1002"
|
"destination": "CR",
|
||||||
}
|
"message": "任务执行成功"
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
### 4. 库存查询接口 - 仅按库位查询
|
|
||||||
POST {{baseUrl}}/mywms/stock
|
|
||||||
Content-Type: application/json
|
|
||||||
|
|
||||||
{
|
|
||||||
"requestId": "testOrderId2",
|
|
||||||
"details": [
|
|
||||||
{
|
|
||||||
"locationId": "A02-01-02-02"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
### 5. 检查是否允许投料
|
|
||||||
GET {{baseUrl}}/mywms/allowFeed
|
|
||||||
|
|
||||||
### 6. 允许出库
|
|
||||||
GET {{baseUrl}}/mywms/allowOut
|
|
||||||
|
|
||||||
### 测试数据说明
|
|
||||||
# 1. orderIn: 入库订单接口,需要taskId和vehicleNo
|
|
||||||
# 2. orderOut: 出库订单接口,需要taskId和vehicleNo
|
|
||||||
# 3. stock: 库存查询接口,需要requestId和details数组
|
|
||||||
# - details中可以包含vehicleNo和/或locationId
|
|
||||||
# 4. allowFeed: 查询当前系统是否允许投料操作(GET请求)
|
|
||||||
|
|
||||||
### 响应格式说明
|
|
||||||
# 所有接口都返回MyWmsResponse格式:
|
|
||||||
# {
|
|
||||||
# "code": 200, // 响应码
|
|
||||||
# "message": "操作成功", // 响应消息
|
|
||||||
# "data": {}, // 具体数据
|
|
||||||
# "success": true // 是否成功
|
|
||||||
# }
|
|
||||||
|
|
@ -1,60 +0,0 @@
|
||||||
### TaskController接口测试 - WMS任务控制接口
|
|
||||||
### 基础配置
|
|
||||||
@baseUrl = http://localhost:12315
|
|
||||||
|
|
||||||
### 1. WCS请求载具入库
|
|
||||||
POST {{baseUrl}}/wms/task/wcsRequestVehicleIn
|
|
||||||
Content-Type: application/json
|
|
||||||
|
|
||||||
{
|
|
||||||
"origin": "CR",
|
|
||||||
"vehicleNo": "1002",
|
|
||||||
"codeMessage": "test",
|
|
||||||
"remark": "载具入库测试"
|
|
||||||
}
|
|
||||||
|
|
||||||
### 2. 发送任务结果 - 任务完成
|
|
||||||
POST {{baseUrl}}/wms/task/sendTaskResult
|
|
||||||
Content-Type: application/json
|
|
||||||
|
|
||||||
{
|
|
||||||
"taskId": "1756881794848010000",
|
|
||||||
"taskStatus": 100,
|
|
||||||
"vehicleNo": "1009",
|
|
||||||
"destination": "CR",
|
|
||||||
"message": "任务执行成功"
|
|
||||||
}
|
|
||||||
|
|
||||||
### 测试数据说明
|
|
||||||
# 1. wcsRequestVehicleIn: WCS请求载具入库
|
|
||||||
# - origin: 点位(必填)
|
|
||||||
# - vehicleNo: 载具信息(必填)
|
|
||||||
# - codeMessage: 条码信息(可选)
|
|
||||||
# - remark: 备注(可选)
|
|
||||||
|
|
||||||
# 2. sendTaskResult: WCS反馈任务执行结果
|
|
||||||
# - taskId: 任务ID(必填)
|
|
||||||
# - taskStatus: 任务状态(必填)
|
|
||||||
# * 0: 等待执行
|
|
||||||
# * 1: 执行中
|
|
||||||
# * 2: 执行完成
|
|
||||||
# * 3: 执行失败
|
|
||||||
# - vehicleNo: 载具号(必填)
|
|
||||||
# - destination: 终点(可选)
|
|
||||||
# - message: 信息(可选)
|
|
||||||
|
|
||||||
### 响应格式说明
|
|
||||||
# wcsRequestVehicleIn返回WcsVehicleInResponse:
|
|
||||||
# {
|
|
||||||
# "success": true,
|
|
||||||
# "code": "SUCCESS",
|
|
||||||
# "message": "请求成功",
|
|
||||||
# "data": {}
|
|
||||||
# }
|
|
||||||
|
|
||||||
# sendTaskResult返回BaseWcsApiResponse:
|
|
||||||
# {
|
|
||||||
# "success": true,
|
|
||||||
# "code": "SUCCESS",
|
|
||||||
# "message": "任务结果接收成功"
|
|
||||||
# }
|
|
||||||
|
|
@ -90,6 +90,7 @@ public class HttpClient {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发送一个 Post 请求
|
* 发送一个 Post 请求
|
||||||
|
*
|
||||||
* @param request 请求数据
|
* @param request 请求数据
|
||||||
* @return 响应数据
|
* @return 响应数据
|
||||||
*/
|
*/
|
||||||
|
|
@ -97,14 +98,14 @@ public class HttpClient {
|
||||||
log.info("请求信息{}", StringUtils.objectToString(request));
|
log.info("请求信息{}", StringUtils.objectToString(request));
|
||||||
HttpResponse response = new HttpResponse();
|
HttpResponse response = new HttpResponse();
|
||||||
String url = request.getUrl();
|
String url = request.getUrl();
|
||||||
if(StringUtils.isEmpty(url)) {
|
if (StringUtils.isEmpty(url)) {
|
||||||
// 请求地址没传
|
// 请求地址没传
|
||||||
response.setSuccess(false);
|
response.setSuccess(false);
|
||||||
response.setResponseCode(999);
|
response.setResponseCode(999);
|
||||||
response.setException(new Exception("请求地址为空"));
|
response.setException(new Exception("请求地址为空"));
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
if(StringUtils.isEmpty(request.getData())) {
|
if (StringUtils.isEmpty(request.getData())) {
|
||||||
request.setData("{}");
|
request.setData("{}");
|
||||||
}
|
}
|
||||||
response.setRequestUrl(url);
|
response.setRequestUrl(url);
|
||||||
|
|
@ -113,11 +114,12 @@ public class HttpClient {
|
||||||
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
|
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
|
||||||
HttpPost postRequest = new HttpPost(url);
|
HttpPost postRequest = new HttpPost(url);
|
||||||
postRequest.setHeader("Content-Type", request.getContentType());
|
postRequest.setHeader("Content-Type", request.getContentType());
|
||||||
postRequest.setHeader("Authorization", request.getToken());
|
postRequest.setHeader("Expect", "100-continue");
|
||||||
|
// postRequest.setHeader("Authorization", request.getToken());
|
||||||
// 设置请求头
|
// 设置请求头
|
||||||
for(Map.Entry<String, String> entry : request.getHeader().entrySet()){
|
// for(Map.Entry<String, String> entry : request.getHeader().entrySet()){
|
||||||
postRequest.setHeader(entry.getKey(), entry.getValue());
|
// postRequest.setHeader(entry.getKey(), entry.getValue());
|
||||||
}
|
// }
|
||||||
postRequest.setEntity(new StringEntity(request.getData()));
|
postRequest.setEntity(new StringEntity(request.getData()));
|
||||||
RequestConfig requestConfig = RequestConfig.custom()
|
RequestConfig requestConfig = RequestConfig.custom()
|
||||||
.setConnectTimeout(request.getTimeout())
|
.setConnectTimeout(request.getTimeout())
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,6 @@ public class WcsApiServiceImpl implements IWcsApiService {
|
||||||
// response = httpResponse.getData(response.getClass().asSubclass(WcsApiResponse.class));
|
// response = httpResponse.getData(response.getClass().asSubclass(WcsApiResponse.class));
|
||||||
// return response;
|
// return response;
|
||||||
// }
|
// }
|
||||||
// TODO success -> error
|
|
||||||
return WcsApiResponse.success("请求未获得响应信息。", null);
|
return WcsApiResponse.success("请求未获得响应信息。", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -116,7 +115,6 @@ public class WcsApiServiceImpl implements IWcsApiService {
|
||||||
// response = httpResponse.getData(response.getClass().asSubclass(WcsApiResponse.class));
|
// response = httpResponse.getData(response.getClass().asSubclass(WcsApiResponse.class));
|
||||||
// return response;
|
// return response;
|
||||||
// }
|
// }
|
||||||
// TODO error -> success
|
|
||||||
// return WcsApiResponse.error("请求未获得响应信息。", null);
|
// return WcsApiResponse.error("请求未获得响应信息。", null);
|
||||||
WcsCanFeedResponse wcsCanFeedResponse = new WcsCanFeedResponse();
|
WcsCanFeedResponse wcsCanFeedResponse = new WcsCanFeedResponse();
|
||||||
wcsCanFeedResponse.setResponseTime(LocalDateTime.now());
|
wcsCanFeedResponse.setResponseTime(LocalDateTime.now());
|
||||||
|
|
|
||||||
|
|
@ -1,52 +0,0 @@
|
||||||
package com.wms_main.service.business;
|
|
||||||
|
|
||||||
import com.wms_main.model.po.TAppAgvLock;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 入库口互锁服务接口
|
|
||||||
* 管理单一入库口的AGV上料互锁机制
|
|
||||||
*/
|
|
||||||
public interface IAgvLockService {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* AGV就位并放货后,锁定入库口
|
|
||||||
* @param agvId AGV设备ID
|
|
||||||
* @param inboundPort 入库口编号
|
|
||||||
* @return 锁定结果:成功返回锁定记录,失败返回null
|
|
||||||
*/
|
|
||||||
TAppAgvLock lockInboundPort(String agvId, String inboundPort);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 检查入库口是否可以上料(MES系统调用)
|
|
||||||
* @param inboundPort 入库口编号
|
|
||||||
* @return 是否可以上料
|
|
||||||
*/
|
|
||||||
boolean canFeedToInboundPort(String inboundPort);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取当前入库口处理中的任务数量
|
|
||||||
* @param inboundPort 入库口编号
|
|
||||||
* @return 处理中的任务数量
|
|
||||||
*/
|
|
||||||
int getProcessingTaskCount(String inboundPort);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取入库口状态描述
|
|
||||||
* @param inboundPort 入库口编号
|
|
||||||
* @return 状态描述(空闲/占用)
|
|
||||||
*/
|
|
||||||
String getInboundPortStatus(String inboundPort);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 清理超时锁定
|
|
||||||
* @return 清理的记录数
|
|
||||||
*/
|
|
||||||
int cleanTimeoutLocks();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 释放指定入库口的所有活动锁定
|
|
||||||
* @param inboundPort 入库口编号
|
|
||||||
* @return 释放的锁定数量
|
|
||||||
*/
|
|
||||||
int releaseAllInboundPortLocks(String inboundPort);
|
|
||||||
}
|
|
||||||
|
|
@ -1,232 +0,0 @@
|
||||||
package com.wms_main.service.business.serviceImpl;
|
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|
||||||
import com.wms_main.constant.enums.wms.WmsAgvLockEnums;
|
|
||||||
import com.wms_main.dao.ITAppAgvLockService;
|
|
||||||
import com.wms_main.dao.ITAppTaskService;
|
|
||||||
import com.wms_main.model.po.TAppAgvLock;
|
|
||||||
import com.wms_main.model.po.TAppTask;
|
|
||||||
import com.wms_main.constant.enums.wms.WmsTaskTypeEnums;
|
|
||||||
import com.wms_main.constant.enums.wms.WmsStackerTaskStatusEnums;
|
|
||||||
import com.wms_main.repository.utils.StringUtils;
|
|
||||||
import com.wms_main.repository.utils.UUIDUtils;
|
|
||||||
import com.wms_main.service.business.IAgvLockService;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 入库口互锁服务实现
|
|
||||||
* 管理单一入库口的AGV上料互锁机制
|
|
||||||
*/
|
|
||||||
@Service
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
@Slf4j
|
|
||||||
public class AgvLockServiceImpl implements IAgvLockService {
|
|
||||||
|
|
||||||
private final ITAppAgvLockService agvLockService;
|
|
||||||
private final ITAppTaskService appTaskService;
|
|
||||||
|
|
||||||
private static final String DEFAULT_INBOUND_PORT = "R1"; // 默认入库口
|
|
||||||
private static final int DEFAULT_TIMEOUT_SECONDS = 600; // 默认超时时间10分钟
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional
|
|
||||||
public TAppAgvLock lockInboundPort(String agvId, String inboundPort) {
|
|
||||||
if (StringUtils.isEmpty(agvId)) {
|
|
||||||
log.warn("AGV ID为空");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 使用默认入库口如果未指定
|
|
||||||
if (StringUtils.isEmpty(inboundPort)) {
|
|
||||||
inboundPort = DEFAULT_INBOUND_PORT;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 清理超时锁定
|
|
||||||
cleanTimeoutLocks();
|
|
||||||
|
|
||||||
// 检查入库口是否已被占用
|
|
||||||
List<TAppAgvLock> existingLocks = agvLockService.list(new LambdaQueryWrapper<TAppAgvLock>().eq(TAppAgvLock::getFeedStation, inboundPort));
|
|
||||||
if (existingLocks == null || existingLocks.isEmpty()) {
|
|
||||||
return createInboundPortLock(agvId, inboundPort);
|
|
||||||
} else {
|
|
||||||
agvLockService.update(
|
|
||||||
new LambdaUpdateWrapper<TAppAgvLock>()
|
|
||||||
.eq(TAppAgvLock::getFeedStation, inboundPort)
|
|
||||||
.eq(TAppAgvLock::getLockStatus, WmsAgvLockEnums.AVAILABLE.getCode())
|
|
||||||
.set(TAppAgvLock::getLockStatus, WmsAgvLockEnums.LOCK.getCode())
|
|
||||||
.set(TAppAgvLock::getLockTime, LocalDateTime.now())
|
|
||||||
.set(TAppAgvLock::getRemark, "AGV就位并放货,锁定入库口")
|
|
||||||
);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canFeedToInboundPort(String inboundPort) {
|
|
||||||
// 使用默认入库口如果未指定
|
|
||||||
if (StringUtils.isEmpty(inboundPort)) {
|
|
||||||
inboundPort = DEFAULT_INBOUND_PORT;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 清理超时锁定
|
|
||||||
cleanTimeoutLocks();
|
|
||||||
|
|
||||||
// 检查入库口是否有活动的锁定
|
|
||||||
List<TAppAgvLock> activeLocks = agvLockService.getByStation(inboundPort);
|
|
||||||
boolean hasActiveLock = activeLocks.stream()
|
|
||||||
.anyMatch(lock -> lock.getLockStatus() == 1);
|
|
||||||
|
|
||||||
if (hasActiveLock) {
|
|
||||||
log.debug("入库口 {} 当前被占用,无法上料", inboundPort);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查是否有正在处理的入库任务
|
|
||||||
int processingTasks = getProcessingTaskCount(inboundPort);
|
|
||||||
boolean canFeed = processingTasks == 0;
|
|
||||||
|
|
||||||
log.debug("入库口 {} 可上料状态: {}, 处理中任务数: {}", inboundPort, canFeed, processingTasks);
|
|
||||||
return canFeed;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getProcessingTaskCount(String inboundPort) {
|
|
||||||
// 使用默认入库口如果未指定
|
|
||||||
if (StringUtils.isEmpty(inboundPort)) {
|
|
||||||
inboundPort = DEFAULT_INBOUND_PORT;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 统计正在处理的入库任务数量(包括等待、运行状态的任务)
|
|
||||||
List<TAppTask> processingTasks = appTaskService.list(
|
|
||||||
new LambdaQueryWrapper<TAppTask>()
|
|
||||||
.eq(TAppTask::getTaskType, WmsTaskTypeEnums.IN.getCode())
|
|
||||||
.in(TAppTask::getTaskStatus,
|
|
||||||
WmsStackerTaskStatusEnums.WAIT.getCode(),
|
|
||||||
WmsStackerTaskStatusEnums.RUN.getCode())
|
|
||||||
.like(TAppTask::getOrigin, inboundPort) // 假设任务来源包含入库口信息
|
|
||||||
);
|
|
||||||
|
|
||||||
return processingTasks.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getInboundPortStatus(String inboundPort) {
|
|
||||||
// 使用默认入库口如果未指定
|
|
||||||
if (StringUtils.isEmpty(inboundPort)) {
|
|
||||||
inboundPort = DEFAULT_INBOUND_PORT;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查是否有活动锁定
|
|
||||||
List<TAppAgvLock> activeLocks = agvLockService.getByStation(inboundPort);
|
|
||||||
boolean hasActiveLock = activeLocks.stream()
|
|
||||||
.anyMatch(lock -> lock.getLockStatus() == 1);
|
|
||||||
|
|
||||||
if (hasActiveLock) {
|
|
||||||
return "占用";
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查是否有处理中的任务
|
|
||||||
int processingTasks = getProcessingTaskCount(inboundPort);
|
|
||||||
if (processingTasks > 0) {
|
|
||||||
return "占用";
|
|
||||||
}
|
|
||||||
|
|
||||||
return "空闲";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional
|
|
||||||
public int cleanTimeoutLocks() {
|
|
||||||
List<TAppAgvLock> timeoutLocks = agvLockService.getTimeoutLocks();
|
|
||||||
if (timeoutLocks.isEmpty()) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
for (TAppAgvLock lock : timeoutLocks) {
|
|
||||||
agvLockService.update(
|
|
||||||
new LambdaUpdateWrapper<TAppAgvLock>()
|
|
||||||
.eq(TAppAgvLock::getLockId, lock.getLockId())
|
|
||||||
.set(TAppAgvLock::getLockStatus, 0)
|
|
||||||
.set(TAppAgvLock::getUnlockTime, LocalDateTime.now())
|
|
||||||
.set(TAppAgvLock::getRemark, "超时自动释放")
|
|
||||||
);
|
|
||||||
|
|
||||||
log.info("释放超时锁定: AGV {} 在入库口 {}", lock.getAgvId(), lock.getFeedStation());
|
|
||||||
}
|
|
||||||
|
|
||||||
log.info("清理了 {} 个超时锁定", timeoutLocks.size());
|
|
||||||
return timeoutLocks.size();
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("清理超时锁定失败", e);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional
|
|
||||||
public int releaseAllInboundPortLocks(String inboundPort) {
|
|
||||||
// 使用默认入库口如果未指定
|
|
||||||
if (StringUtils.isEmpty(inboundPort)) {
|
|
||||||
inboundPort = DEFAULT_INBOUND_PORT;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
// 释放指定入库口的所有活动锁定
|
|
||||||
agvLockService.update(
|
|
||||||
new LambdaUpdateWrapper<TAppAgvLock>()
|
|
||||||
.eq(TAppAgvLock::getFeedStation, inboundPort)
|
|
||||||
.eq(TAppAgvLock::getLockStatus, WmsAgvLockEnums.LOCK.getCode())
|
|
||||||
.set(TAppAgvLock::getLockStatus, WmsAgvLockEnums.AVAILABLE.getCode())
|
|
||||||
.set(TAppAgvLock::getUnlockTime, LocalDateTime.now())
|
|
||||||
.set(TAppAgvLock::getRemark, "入库任务完成,批量释放锁定")
|
|
||||||
);
|
|
||||||
|
|
||||||
// 查询实际释放的锁定数量
|
|
||||||
List<TAppAgvLock> activeLocks = agvLockService.getByStation(inboundPort);
|
|
||||||
int releasedCount = (int) activeLocks.stream()
|
|
||||||
.filter(lock -> lock.getLockStatus() == 0)
|
|
||||||
.count();
|
|
||||||
|
|
||||||
log.info("释放入库口 {} 的所有锁定,共释放 {} 个锁定", inboundPort, releasedCount);
|
|
||||||
return releasedCount;
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("释放入库口 {} 的所有锁定失败", inboundPort, e);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建入库口锁定记录
|
|
||||||
*/
|
|
||||||
private TAppAgvLock createInboundPortLock(String agvId, String inboundPort) {
|
|
||||||
TAppAgvLock lock = new TAppAgvLock();
|
|
||||||
lock.setLockId(UUIDUtils.getNewUUID());
|
|
||||||
lock.setAgvId(agvId);
|
|
||||||
lock.setFeedStation(inboundPort);
|
|
||||||
lock.setLockStatus(1);
|
|
||||||
lock.setLockType("INBOUND_PORT_LOCK");
|
|
||||||
lock.setPriority(1);
|
|
||||||
lock.setQueuePosition(1);
|
|
||||||
lock.setLockTime(LocalDateTime.now());
|
|
||||||
lock.setTimeoutSeconds(DEFAULT_TIMEOUT_SECONDS);
|
|
||||||
lock.setCreateTime(LocalDateTime.now());
|
|
||||||
lock.setUpdateTime(LocalDateTime.now());
|
|
||||||
lock.setRemark("AGV就位并放货,锁定入库口");
|
|
||||||
|
|
||||||
if (agvLockService.save(lock)) {
|
|
||||||
log.info("AGV {} 成功锁定入库口 {}", agvId, inboundPort);
|
|
||||||
return lock;
|
|
||||||
}
|
|
||||||
|
|
||||||
log.error("AGV {} 锁定入库口 {} 失败", agvId, inboundPort);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -9,12 +9,12 @@ import com.wms_main.constant.enums.wms.*;
|
||||||
import com.wms_main.dao.*;
|
import com.wms_main.dao.*;
|
||||||
import com.wms_main.model.dto.request.mywms.OrderInCBReq;
|
import com.wms_main.model.dto.request.mywms.OrderInCBReq;
|
||||||
import com.wms_main.model.dto.request.mywms.OrderOutCBReq;
|
import com.wms_main.model.dto.request.mywms.OrderOutCBReq;
|
||||||
|
import com.wms_main.model.dto.response.mes.MesApiResponse;
|
||||||
import com.wms_main.model.po.*;
|
import com.wms_main.model.po.*;
|
||||||
import com.wms_main.repository.utils.ConvertUtils;
|
import com.wms_main.repository.utils.ConvertUtils;
|
||||||
import com.wms_main.repository.utils.StringUtils;
|
import com.wms_main.repository.utils.StringUtils;
|
||||||
import com.wms_main.repository.utils.UUIDUtils;
|
import com.wms_main.repository.utils.UUIDUtils;
|
||||||
import com.wms_main.service.api.IExternalApiService;
|
import com.wms_main.service.api.IExternalApiService;
|
||||||
import com.wms_main.service.business.IAgvLockService;
|
|
||||||
import com.wms_main.service.business.IStackerTaskService;
|
import com.wms_main.service.business.IStackerTaskService;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
@ -25,7 +25,6 @@ import java.time.LocalDateTime;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 服务实现
|
* 服务实现
|
||||||
*/
|
*/
|
||||||
|
|
@ -73,8 +72,6 @@ public class StackerTaskServiceImpl implements IStackerTaskService {
|
||||||
*/
|
*/
|
||||||
private final AppCommon appCommon;
|
private final AppCommon appCommon;
|
||||||
|
|
||||||
private final IAgvLockService agvLockService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 存WcsTask表
|
* 存WcsTask表
|
||||||
* 更新WmsTask表
|
* 更新WmsTask表
|
||||||
|
|
@ -92,9 +89,9 @@ public class StackerTaskServiceImpl implements IStackerTaskService {
|
||||||
.set(TAppTask::getWcsTaskId, wcsTask.getWcsTaskId())
|
.set(TAppTask::getWcsTaskId, wcsTask.getWcsTaskId())
|
||||||
.set(TAppTask::getTaskStatus, WmsStackerTaskStatusEnums.EXECUTED.getCode())
|
.set(TAppTask::getTaskStatus, WmsStackerTaskStatusEnums.EXECUTED.getCode())
|
||||||
.eq(TAppTask::getVehicleId, wcsTask.getVehicleId())
|
.eq(TAppTask::getVehicleId, wcsTask.getVehicleId())
|
||||||
.eq(TAppTask::getTaskType, ConvertUtils.convertStackerTaskTypeFromWcsToWms(wcsTask.getWcsTaskType()))
|
.eq(TAppTask::getTaskType,
|
||||||
.eq(TAppTask::getTaskStatus, WmsStackerTaskStatusEnums.WAIT.getCode())
|
ConvertUtils.convertStackerTaskTypeFromWcsToWms(wcsTask.getWcsTaskType()))
|
||||||
);
|
.eq(TAppTask::getTaskStatus, WmsStackerTaskStatusEnums.WAIT.getCode()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -131,33 +128,36 @@ public class StackerTaskServiceImpl implements IStackerTaskService {
|
||||||
// 查询库位
|
// 查询库位
|
||||||
List<TAppLocation> locationList = appLocationService.list(queryWrapper);
|
List<TAppLocation> locationList = appLocationService.list(queryWrapper);
|
||||||
List<TAppLocation> candidateLocationList = locationList.stream().filter(item -> {
|
List<TAppLocation> candidateLocationList = locationList.stream().filter(item -> {
|
||||||
boolean filterResult = item.getIsWorking() == 0 && item.getIsLock() == 0 && item.getIsOccupy() == 0;
|
boolean filterResult = item.getIsWorking() == 0 && item.getIsLock() == 0 && item.getIsOccupy() == 0;
|
||||||
if (locationFilter != null) {
|
if (locationFilter != null) {
|
||||||
if (locationFilter.getLRow() != null) {
|
if (locationFilter.getLRow() != null) {
|
||||||
filterResult = filterResult && Objects.equals(item.getLRow(), locationFilter.getLRow());
|
filterResult = filterResult && Objects.equals(item.getLRow(), locationFilter.getLRow());
|
||||||
}
|
}
|
||||||
if (locationFilter.getLCol() != null) {
|
if (locationFilter.getLCol() != null) {
|
||||||
filterResult = filterResult && Objects.equals(item.getLCol(), locationFilter.getLCol());
|
filterResult = filterResult && Objects.equals(item.getLCol(), locationFilter.getLCol());
|
||||||
}
|
}
|
||||||
if (locationFilter.getLLayer() != null) {
|
if (locationFilter.getLLayer() != null) {
|
||||||
filterResult = filterResult && Objects.equals(item.getLLayer(), locationFilter.getLLayer());
|
filterResult = filterResult && Objects.equals(item.getLLayer(), locationFilter.getLLayer());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return filterResult;
|
return filterResult;
|
||||||
}).sorted(Comparator.comparingInt(TAppLocation::getLDepth).reversed())
|
}).sorted(Comparator.comparingInt(TAppLocation::getLDepth).reversed())
|
||||||
.sorted(Comparator.comparingInt(location -> location.getLCol() + location.getLLayer()))
|
.sorted(Comparator.comparingInt(location -> location.getLCol() + location.getLLayer()))
|
||||||
.toList();
|
.toList();
|
||||||
// 判断是否输入了subArea
|
// 判断是否输入了subArea
|
||||||
if (locationFilter != null && StringUtils.isNotEmpty(locationFilter.getSubArea())) {
|
if (locationFilter != null && StringUtils.isNotEmpty(locationFilter.getSubArea())) {
|
||||||
// 对candidateLocationList进行排序
|
// 对candidateLocationList进行排序
|
||||||
List<TAppLocation> firstList = candidateLocationList.stream().filter(item -> item.getSubArea().equals(locationFilter.getSubArea())).toList();
|
List<TAppLocation> firstList = candidateLocationList.stream()
|
||||||
List<TAppLocation> lastList = candidateLocationList.stream().filter(item -> !item.getSubArea().equals(locationFilter.getSubArea())).toList();
|
.filter(item -> item.getSubArea().equals(locationFilter.getSubArea())).toList();
|
||||||
|
List<TAppLocation> lastList = candidateLocationList.stream()
|
||||||
|
.filter(item -> !item.getSubArea().equals(locationFilter.getSubArea())).toList();
|
||||||
candidateLocationList = new ArrayList<>(firstList);// 先添加符合subArea的库位
|
candidateLocationList = new ArrayList<>(firstList);// 先添加符合subArea的库位
|
||||||
candidateLocationList.addAll(lastList);// 再添加不符合subArea的库位
|
candidateLocationList.addAll(lastList);// 再添加不符合subArea的库位
|
||||||
}
|
}
|
||||||
// 找一个空闲的库位
|
// 找一个空闲的库位
|
||||||
for (TAppLocation candidateLocation : candidateLocationList) {
|
for (TAppLocation candidateLocation : candidateLocationList) {
|
||||||
if (candidateLocation.getIsWorking() == 1 || candidateLocation.getIsLock() == 1 || candidateLocation.getIsOccupy() == 1) {
|
if (candidateLocation.getIsWorking() == 1 || candidateLocation.getIsLock() == 1
|
||||||
|
|| candidateLocation.getIsOccupy() == 1) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (isMaxDepthAvailable(locationList, candidateLocation)) {
|
if (isMaxDepthAvailable(locationList, candidateLocation)) {
|
||||||
|
|
@ -167,8 +167,7 @@ public class StackerTaskServiceImpl implements IStackerTaskService {
|
||||||
.set(TAppLocation::getIsOccupy, 1)
|
.set(TAppLocation::getIsOccupy, 1)
|
||||||
.set(TAppLocation::getVehicleId, requestVehicleId)
|
.set(TAppLocation::getVehicleId, requestVehicleId)
|
||||||
.eq(TAppLocation::getLocationId, candidateLocation.getLocationId())
|
.eq(TAppLocation::getLocationId, candidateLocation.getLocationId())
|
||||||
.eq(TAppLocation::getIsOccupy, 0)
|
.eq(TAppLocation::getIsOccupy, 0))) {
|
||||||
)) {
|
|
||||||
// 当前库位可用
|
// 当前库位可用
|
||||||
targetLocation = candidateLocation;
|
targetLocation = candidateLocation;
|
||||||
break;
|
break;
|
||||||
|
|
@ -193,31 +192,37 @@ public class StackerTaskServiceImpl implements IStackerTaskService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取一个堆垛机库的空库位
|
* 获取一个堆垛机库的空库位
|
||||||
|
*
|
||||||
* @param equipmentId 设备号
|
* @param equipmentId 设备号
|
||||||
* @return 返回的库位信息
|
* @return 返回的库位信息
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public TAppLocation getEmptyLocation(Integer equipmentId, WmsLocationTypeEnums type) {
|
public TAppLocation getEmptyLocation(Integer equipmentId, WmsLocationTypeEnums type) {
|
||||||
if(equipmentId == null) return null;
|
if (equipmentId == null)
|
||||||
|
return null;
|
||||||
List<TAppLocation> allLocations = appLocationService.getAllLocation(equipmentId);
|
List<TAppLocation> allLocations = appLocationService.getAllLocation(equipmentId);
|
||||||
if(allLocations == null || allLocations.isEmpty()) return null;
|
if (allLocations == null || allLocations.isEmpty())
|
||||||
|
return null;
|
||||||
for (TAppLocation location : allLocations) {
|
for (TAppLocation location : allLocations) {
|
||||||
if(location.getIsOccupy() != 0 || location.getIsLock() != 0 || location.getIsWorking() != 0){
|
if (location.getIsOccupy() != 0 || location.getIsLock() != 0 || location.getIsWorking() != 0) {
|
||||||
continue; // 不可用货位
|
continue; // 不可用货位
|
||||||
}
|
}
|
||||||
if(type != null && !type.getCode().equals(location.getLocationType())) {
|
if (type != null && !type.getCode().equals(location.getLocationType())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// 检查内侧深度是否可用
|
// 检查内侧深度是否可用
|
||||||
Integer lDepth = location.getLDepth();
|
Integer lDepth = location.getLDepth();
|
||||||
if(lDepth != null && lDepth.compareTo(1) > 0) {
|
if (lDepth != null && lDepth.compareTo(1) > 0) {
|
||||||
boolean canUse = true;
|
boolean canUse = true;
|
||||||
for(int i = lDepth - 1; i > 0; i--) {
|
for (int i = lDepth - 1; i > 0; i--) {
|
||||||
int checkDepth = i;
|
int checkDepth = i;
|
||||||
List<TAppLocation> sameColLocations = allLocations.stream().filter(item ->
|
List<TAppLocation> sameColLocations = allLocations.stream()
|
||||||
item.getLRow().equals(location.getLRow()) && item.getLCol().equals(location.getLCol())
|
.filter(item -> item.getLRow().equals(location.getLRow())
|
||||||
&& item.getLLayer().equals(location.getLLayer()) && item.getLDepth().equals(checkDepth)).toList();
|
&& item.getLCol().equals(location.getLCol())
|
||||||
if(sameColLocations.isEmpty()) {
|
&& item.getLLayer().equals(location.getLLayer())
|
||||||
|
&& item.getLDepth().equals(checkDepth))
|
||||||
|
.toList();
|
||||||
|
if (sameColLocations.isEmpty()) {
|
||||||
continue; // 库位不存在可能
|
continue; // 库位不存在可能
|
||||||
}
|
}
|
||||||
TAppLocation sameColLocationsFirst = sameColLocations.getFirst();
|
TAppLocation sameColLocationsFirst = sameColLocations.getFirst();
|
||||||
|
|
@ -225,26 +230,26 @@ public class StackerTaskServiceImpl implements IStackerTaskService {
|
||||||
TAppStock checkIsHaveStock = new TAppStock();
|
TAppStock checkIsHaveStock = new TAppStock();
|
||||||
checkIsHaveStock.setLocationId(sameColLocationsFirst.getLocationId());
|
checkIsHaveStock.setLocationId(sameColLocationsFirst.getLocationId());
|
||||||
List<TAppStock> checkStockIsHaveStockResult = appStockService.getWithEntity(checkIsHaveStock);
|
List<TAppStock> checkStockIsHaveStockResult = appStockService.getWithEntity(checkIsHaveStock);
|
||||||
if(checkStockIsHaveStockResult == null) {
|
if (checkStockIsHaveStockResult == null) {
|
||||||
canUse = false; // 数据库查询失败,库位直接不可用
|
canUse = false; // 数据库查询失败,库位直接不可用
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(!checkStockIsHaveStockResult.isEmpty()) {
|
if (!checkStockIsHaveStockResult.isEmpty()) {
|
||||||
canUse = false; // 库位有库存,不可用
|
canUse = false; // 库位有库存,不可用
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// 校验是否存在出入库任务
|
// 校验是否存在出入库任务
|
||||||
Boolean existsTaskWithLocation = appWcsTaskService.existsTaskWithLocation(location.getLocationId());
|
Boolean existsTaskWithLocation = appWcsTaskService.existsTaskWithLocation(location.getLocationId());
|
||||||
if(existsTaskWithLocation == null) {
|
if (existsTaskWithLocation == null) {
|
||||||
canUse = false;
|
canUse = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(existsTaskWithLocation) {
|
if (existsTaskWithLocation) {
|
||||||
canUse = false; // 库位有任务,不可用
|
canUse = false; // 库位有任务,不可用
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!canUse) {
|
if (!canUse) {
|
||||||
continue; // 不可用
|
continue; // 不可用
|
||||||
}
|
}
|
||||||
return location;
|
return location;
|
||||||
|
|
@ -273,11 +278,12 @@ public class StackerTaskServiceImpl implements IStackerTaskService {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// 查询到排列层对应的库位列表
|
// 查询到排列层对应的库位列表
|
||||||
List<TAppLocation> diffDepthLocationList = appLocationList.stream().filter(item ->
|
List<TAppLocation> diffDepthLocationList = appLocationList.stream()
|
||||||
Objects.equals(item.getLRow(), appLocation.getLRow()) &&
|
.filter(item -> Objects.equals(item.getLRow(), appLocation.getLRow()) &&
|
||||||
Objects.equals(item.getLCol(), appLocation.getLCol()) &&
|
Objects.equals(item.getLCol(), appLocation.getLCol()) &&
|
||||||
Objects.equals(item.getLLayer(), appLocation.getLLayer()) &&
|
Objects.equals(item.getLLayer(), appLocation.getLLayer()) &&
|
||||||
!Objects.equals(item.getLDepth(), appLocation.getLDepth())).toList();
|
!Objects.equals(item.getLDepth(), appLocation.getLDepth()))
|
||||||
|
.toList();
|
||||||
// 结果
|
// 结果
|
||||||
boolean result = true;
|
boolean result = true;
|
||||||
for (TAppLocation diffDepthLocation : diffDepthLocationList) {
|
for (TAppLocation diffDepthLocation : diffDepthLocationList) {
|
||||||
|
|
@ -324,20 +330,24 @@ public class StackerTaskServiceImpl implements IStackerTaskService {
|
||||||
// 查找到所有的入库任务列表---非暂存和完成状态。
|
// 查找到所有的入库任务列表---非暂存和完成状态。
|
||||||
List<TAppTask> inTasks = appTaskService.list(new LambdaQueryWrapper<TAppTask>()
|
List<TAppTask> inTasks = appTaskService.list(new LambdaQueryWrapper<TAppTask>()
|
||||||
.eq(TAppTask::getTaskType, WmsTaskTypeEnums.IN.getCode())
|
.eq(TAppTask::getTaskType, WmsTaskTypeEnums.IN.getCode())
|
||||||
.notIn(TAppTask::getTaskStatus, WmsStackerTaskStatusEnums.FINISH.getCode(), WmsStackerTaskStatusEnums.TEMP.getCode()));
|
.notIn(TAppTask::getTaskStatus, WmsStackerTaskStatusEnums.FINISH.getCode(),
|
||||||
|
WmsStackerTaskStatusEnums.TEMP.getCode()));
|
||||||
if (inTasks == null || inTasks.isEmpty()) {
|
if (inTasks == null || inTasks.isEmpty()) {
|
||||||
for (TAppLocation appLocation : emptyLocationList) {
|
for (TAppLocation appLocation : emptyLocationList) {
|
||||||
if (equipCountMap.containsKey(appLocation.getEquipmentId())) {
|
if (equipCountMap.containsKey(appLocation.getEquipmentId())) {
|
||||||
equipCountMap.replace(appLocation.getEquipmentId(), equipCountMap.get(appLocation.getEquipmentId()) + 1);
|
equipCountMap.replace(appLocation.getEquipmentId(),
|
||||||
|
equipCountMap.get(appLocation.getEquipmentId()) + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (TAppTask inTask : inTasks) {
|
for (TAppTask inTask : inTasks) {
|
||||||
if (StringUtils.isNotEmpty(inTask.getDestination())) {
|
if (StringUtils.isNotEmpty(inTask.getDestination())) {
|
||||||
// 当前目标库位的设备号
|
// 当前目标库位的设备号
|
||||||
TAppLocation destinationEquipmentId = appCommon.getInstantLocationByLocationId(inTask.getDestination());
|
TAppLocation destinationEquipmentId = appCommon
|
||||||
|
.getInstantLocationByLocationId(inTask.getDestination());
|
||||||
if (equipCountMap.containsKey(destinationEquipmentId.getEquipmentId())) {
|
if (equipCountMap.containsKey(destinationEquipmentId.getEquipmentId())) {
|
||||||
equipCountMap.replace(destinationEquipmentId.getEquipmentId(), equipCountMap.get(destinationEquipmentId.getEquipmentId()) + 1);
|
equipCountMap.replace(destinationEquipmentId.getEquipmentId(),
|
||||||
|
equipCountMap.get(destinationEquipmentId.getEquipmentId()) + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -352,7 +362,6 @@ public class StackerTaskServiceImpl implements IStackerTaskService {
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 实现
|
* 实现
|
||||||
*
|
*
|
||||||
|
|
@ -393,25 +402,6 @@ public class StackerTaskServiceImpl implements IStackerTaskService {
|
||||||
.eq(TAppStock::getVehicleId, orderIn.getVehicleNo()));
|
.eq(TAppStock::getVehicleId, orderIn.getVehicleNo()));
|
||||||
}
|
}
|
||||||
|
|
||||||
OrderInCBReq orderInCBReq = new OrderInCBReq();
|
|
||||||
orderInCBReq.setTaskId(orderIn.getOrderId());
|
|
||||||
orderInCBReq.setVehicleNo(wmsTask.getVehicleId());
|
|
||||||
orderInCBReq.setLocationId(wmsTask.getDestination());
|
|
||||||
orderInCBReq.setResult(OrderInCBEnums.COMPLETE.getCode());
|
|
||||||
orderInCBReq.setResultMessage("入库完成");
|
|
||||||
|
|
||||||
// int times = 0;
|
|
||||||
// MesApiResponse response = null;
|
|
||||||
// do {
|
|
||||||
// Thread.sleep(15000L * times);
|
|
||||||
// response = externalApiService.invokeOrderInCB(orderInCBReq);
|
|
||||||
// times++;
|
|
||||||
// } while (response.getCode() != 0 && times <= 10);
|
|
||||||
// if (response.getCode() != 0) {
|
|
||||||
// log.error("[wms]上报失败");
|
|
||||||
// } else {
|
|
||||||
// log.info("[wms]上报成功");
|
|
||||||
// }
|
|
||||||
if (!appOrderInService.removeById(orderIn.getRecordId())) {
|
if (!appOrderInService.removeById(orderIn.getRecordId())) {
|
||||||
log.info("整箱入库完成删除入库单失败,任务:{},原因:删除入库单失败", wmsTask.getTaskId());
|
log.info("整箱入库完成删除入库单失败,任务:{},原因:删除入库单失败", wmsTask.getTaskId());
|
||||||
}
|
}
|
||||||
|
|
@ -424,7 +414,6 @@ public class StackerTaskServiceImpl implements IStackerTaskService {
|
||||||
appVehicleService.saveOrUpdate(vehicle);
|
appVehicleService.saveOrUpdate(vehicle);
|
||||||
|
|
||||||
appCommon.updateWorkingLocations(wmsTask.getDestination(), 0);
|
appCommon.updateWorkingLocations(wmsTask.getDestination(), 0);
|
||||||
agvLockService.releaseAllInboundPortLocks("CR");
|
|
||||||
// 备份并删除任务
|
// 备份并删除任务
|
||||||
if (!appTaskService.removeById(wmsTask.getTaskId())) {
|
if (!appTaskService.removeById(wmsTask.getTaskId())) {
|
||||||
log.info("删除入库任务失败,任务:{}", wmsTask.getTaskId());
|
log.info("删除入库任务失败,任务:{}", wmsTask.getTaskId());
|
||||||
|
|
@ -432,6 +421,24 @@ public class StackerTaskServiceImpl implements IStackerTaskService {
|
||||||
if (!appTaskBakService.save(wmsTask.of())) {
|
if (!appTaskBakService.save(wmsTask.of())) {
|
||||||
log.info("备份入库任务失败,任务:{}", wmsTask.getTaskId());
|
log.info("备份入库任务失败,任务:{}", wmsTask.getTaskId());
|
||||||
}
|
}
|
||||||
|
// OrderInCBReq orderInCBReq = new OrderInCBReq();
|
||||||
|
// orderInCBReq.setTaskId(orderIn.getOrderId());
|
||||||
|
// orderInCBReq.setVehicleNo(wmsTask.getVehicleId());
|
||||||
|
// orderInCBReq.setLocationId(wmsTask.getDestination());
|
||||||
|
// orderInCBReq.setResult(OrderInCBEnums.COMPLETE.getCode());
|
||||||
|
// orderInCBReq.setResultMessage("入库完成");
|
||||||
|
// int times = 0;
|
||||||
|
// MesApiResponse response = null;
|
||||||
|
// do {
|
||||||
|
// Thread.sleep(15000L * times);
|
||||||
|
// response = externalApiService.invokeOrderInCB(orderInCBReq);
|
||||||
|
// times++;
|
||||||
|
// } while (response.getCode() != 0 && times <= 10);
|
||||||
|
// if (response.getCode() != 0) {
|
||||||
|
// log.error("[wms]上报失败");
|
||||||
|
// } else {
|
||||||
|
// log.info("[wms]上报成功");
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -449,16 +456,14 @@ public class StackerTaskServiceImpl implements IStackerTaskService {
|
||||||
appStockService.update(new LambdaUpdateWrapper<TAppStock>()
|
appStockService.update(new LambdaUpdateWrapper<TAppStock>()
|
||||||
.in(TAppStock::getStockId, thisVehicleStocks.stream().map(TAppStock::getStockId).toList())
|
.in(TAppStock::getStockId, thisVehicleStocks.stream().map(TAppStock::getStockId).toList())
|
||||||
.set(TAppStock::getLocationId, wmsTask.getDestination())
|
.set(TAppStock::getLocationId, wmsTask.getDestination())
|
||||||
.set(TAppStock::getStockStatus, WmsStockStatusEnums.OK.getCode())
|
.set(TAppStock::getStockStatus, WmsStockStatusEnums.OK.getCode()));
|
||||||
);
|
|
||||||
appLocationService.update(new LambdaUpdateWrapper<TAppLocation>()
|
appLocationService.update(new LambdaUpdateWrapper<TAppLocation>()
|
||||||
.eq(TAppLocation::getLocationId, wmsTask.getOrigin())
|
.eq(TAppLocation::getLocationId, wmsTask.getOrigin())
|
||||||
.set(TAppLocation::getIsOccupy, WmsLocationOccupyStatusEnums.EMPTY.getCode())
|
.set(TAppLocation::getIsOccupy, WmsLocationOccupyStatusEnums.EMPTY.getCode())
|
||||||
.set(TAppLocation::getVehicleId, ""));
|
.set(TAppLocation::getVehicleId, ""));
|
||||||
appVehicleService.update(new LambdaUpdateWrapper<TAppVehicle>()
|
appVehicleService.update(new LambdaUpdateWrapper<TAppVehicle>()
|
||||||
.eq(TAppVehicle::getVehicleId, wmsTask.getVehicleId())
|
.eq(TAppVehicle::getVehicleId, wmsTask.getVehicleId())
|
||||||
.set(TAppVehicle::getLocationId, wmsTask.getDestination())
|
.set(TAppVehicle::getLocationId, wmsTask.getDestination()));
|
||||||
);
|
|
||||||
appCommon.updateWorkingLocations(wmsTask.getDestination(), 0);
|
appCommon.updateWorkingLocations(wmsTask.getDestination(), 0);
|
||||||
appCommon.updateWorkingLocations(wmsTask.getOrigin(), 0);
|
appCommon.updateWorkingLocations(wmsTask.getOrigin(), 0);
|
||||||
appTaskService.removeById(wmsTask.getTaskId());
|
appTaskService.removeById(wmsTask.getTaskId());
|
||||||
|
|
@ -482,7 +487,8 @@ public class StackerTaskServiceImpl implements IStackerTaskService {
|
||||||
// 5. 添加出库记录
|
// 5. 添加出库记录
|
||||||
// 根据载具号map一下
|
// 根据载具号map一下
|
||||||
Map<String, List<TAppTask>> vehicleIdToTaskMap = stackerOutTasks.stream()
|
Map<String, List<TAppTask>> vehicleIdToTaskMap = stackerOutTasks.stream()
|
||||||
.filter(outTask -> Objects.equals(outTask.getTaskType(), WmsTaskTypeEnums.OUT.getCode()) && Objects.equals(outTask.getTaskStatus(), WmsStackerTaskStatusEnums.FINISH.getCode()))
|
.filter(outTask -> Objects.equals(outTask.getTaskType(), WmsTaskTypeEnums.OUT.getCode())
|
||||||
|
&& Objects.equals(outTask.getTaskStatus(), WmsStackerTaskStatusEnums.FINISH.getCode()))
|
||||||
.collect(Collectors.groupingBy(TAppTask::getVehicleId));
|
.collect(Collectors.groupingBy(TAppTask::getVehicleId));
|
||||||
for (String vehicleId : vehicleIdToTaskMap.keySet()) {
|
for (String vehicleId : vehicleIdToTaskMap.keySet()) {
|
||||||
// 查询当前载具的数据
|
// 查询当前载具的数据
|
||||||
|
|
@ -515,7 +521,6 @@ public class StackerTaskServiceImpl implements IStackerTaskService {
|
||||||
.set(TAppStock::getStockStatus, WmsStockStatusEnums.OUTED.getCode())
|
.set(TAppStock::getStockStatus, WmsStockStatusEnums.OUTED.getCode())
|
||||||
.set(TAppStock::getLocationId, "")
|
.set(TAppStock::getLocationId, "")
|
||||||
.eq(TAppStock::getVehicleId, vehicleId));
|
.eq(TAppStock::getVehicleId, vehicleId));
|
||||||
agvLockService.releaseAllInboundPortLocks("CR");
|
|
||||||
// 当前载具的任务列表
|
// 当前载具的任务列表
|
||||||
List<TAppTask> thisVehicleOutTasks = vehicleIdToTaskMap.get(vehicleId);
|
List<TAppTask> thisVehicleOutTasks = vehicleIdToTaskMap.get(vehicleId);
|
||||||
if (thisVehicleOutTasks.isEmpty()) {
|
if (thisVehicleOutTasks.isEmpty()) {
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ import com.wms_main.model.po.TAppStock;
|
||||||
import com.wms_main.repository.utils.StringUtils;
|
import com.wms_main.repository.utils.StringUtils;
|
||||||
import com.wms_main.repository.utils.UUIDUtils;
|
import com.wms_main.repository.utils.UUIDUtils;
|
||||||
import com.wms_main.service.api.IWcsApiService;
|
import com.wms_main.service.api.IWcsApiService;
|
||||||
import com.wms_main.service.business.IAgvLockService;
|
|
||||||
import com.wms_main.service.controller.IMyWmsControllerService;
|
import com.wms_main.service.controller.IMyWmsControllerService;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
@ -39,7 +38,6 @@ public class MyWmsControllerServiceImpl implements IMyWmsControllerService {
|
||||||
private final ITAppOrderOutService appOrderOutService;
|
private final ITAppOrderOutService appOrderOutService;
|
||||||
private final ITAppStockService appStockService;
|
private final ITAppStockService appStockService;
|
||||||
private final ITAppLocationService appLocationService;
|
private final ITAppLocationService appLocationService;
|
||||||
private final IAgvLockService agvLockService;
|
|
||||||
private final IWcsApiService wcsApiService;
|
private final IWcsApiService wcsApiService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -181,17 +179,6 @@ public class MyWmsControllerServiceImpl implements IMyWmsControllerService {
|
||||||
return MyWmsResponse.error("WCS系统查询失败", false);
|
return MyWmsResponse.error("WCS系统查询失败", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Boolean wcsAllow = wcsResponse.getData().isAllowAction();
|
|
||||||
if (!wcsAllow) {
|
|
||||||
return MyWmsResponse.error("WCS系统不允许入库", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. 检查agvLock服务获取wms状态
|
|
||||||
Boolean wmsAllow = agvLockService.canFeedToInboundPort("CR");
|
|
||||||
if (!wmsAllow) {
|
|
||||||
return MyWmsResponse.error("入库口锁定中", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
return MyWmsResponse.success(true);
|
return MyWmsResponse.success(true);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return MyWmsResponse.error("系统异常,请稍后重试", false);
|
return MyWmsResponse.error("系统异常,请稍后重试", false);
|
||||||
|
|
@ -207,17 +194,6 @@ public class MyWmsControllerServiceImpl implements IMyWmsControllerService {
|
||||||
return MyWmsResponse.error("WCS系统查询失败", false);
|
return MyWmsResponse.error("WCS系统查询失败", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Boolean wcsAllow = wcsResponse.getData().isAllowAction();
|
|
||||||
if (!wcsAllow) {
|
|
||||||
return MyWmsResponse.error("WCS系统不允许出库", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. 检查agvLock服务获取wms状态 (使用CR口)
|
|
||||||
Boolean wmsAllow = agvLockService.canFeedToInboundPort("CR");
|
|
||||||
if (!wmsAllow) {
|
|
||||||
return MyWmsResponse.error("出库口锁定中", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
return MyWmsResponse.success(true);
|
return MyWmsResponse.success(true);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return MyWmsResponse.error("系统异常,请稍后重试", false);
|
return MyWmsResponse.error("系统异常,请稍后重试", false);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,97 @@
|
||||||
|
package com.wms_main.service.quartz_job.job_executor;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||||
|
import com.wms_main.constant.enums.wms.OrderStatusEnum;
|
||||||
|
import com.wms_main.constant.enums.wms.WmsStackerTaskStatusEnums;
|
||||||
|
import com.wms_main.constant.enums.wms.WmsTaskTypeEnums;
|
||||||
|
import com.wms_main.dao.ITAppOrderInService;
|
||||||
|
import com.wms_main.dao.ITAppTaskService;
|
||||||
|
import com.wms_main.model.po.TAppLocation;
|
||||||
|
import com.wms_main.model.po.TAppOrderIn;
|
||||||
|
import com.wms_main.model.po.TAppTask;
|
||||||
|
import com.wms_main.repository.utils.UUIDUtils;
|
||||||
|
import com.wms_main.service.business.IStackerTaskService;
|
||||||
|
|
||||||
|
import org.quartz.DisallowConcurrentExecution;
|
||||||
|
import org.quartz.Job;
|
||||||
|
import org.quartz.JobExecutionContext;
|
||||||
|
import org.quartz.PersistJobDataAfterExecution;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@PersistJobDataAfterExecution
|
||||||
|
// 以下注解用于实现fixed_delay
|
||||||
|
@DisallowConcurrentExecution
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class MyInExecutor implements Job {
|
||||||
|
private final ITAppOrderInService appOrderInService;
|
||||||
|
private final IStackerTaskService stackerTaskService;
|
||||||
|
private final ITAppTaskService appWmsTaskService;
|
||||||
|
|
||||||
|
private static String ORIGIN = "CR";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(JobExecutionContext context) {
|
||||||
|
processInOrders();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processInOrders() {
|
||||||
|
List<TAppOrderIn> orders = appOrderInService.list(
|
||||||
|
new LambdaQueryWrapper<TAppOrderIn>()
|
||||||
|
.eq(TAppOrderIn::getOrderStatus, OrderStatusEnum.CREATE.getCode()));
|
||||||
|
orders.forEach(this::processSingleOrder);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processSingleOrder(TAppOrderIn orderIn) {
|
||||||
|
if (orderIn == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* 查找可用库位 */
|
||||||
|
TAppLocation useLocation = stackerTaskService.requestOneLocation(null, orderIn.getVehicleNo());
|
||||||
|
if (useLocation == null) {
|
||||||
|
log.error("暂没有可以直接使用的库位,因为存在互锁的库位,请等待当前任务都执行完成后再试");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
TAppTask newInTask = appWmsTaskService.getOne(new LambdaQueryWrapper<TAppTask>()
|
||||||
|
.eq(TAppTask::getVehicleId, orderIn.getVehicleNo())
|
||||||
|
.eq(TAppTask::getTaskType, WmsTaskTypeEnums.IN.getCode()));
|
||||||
|
if (newInTask != null) {
|
||||||
|
newInTask.setTaskStatus(WmsStackerTaskStatusEnums.WAIT.getCode());
|
||||||
|
newInTask.setDestination(useLocation.getLocationId());
|
||||||
|
newInTask.setTaskGroup(orderIn.getOrderId());
|
||||||
|
if (!appWmsTaskService.updateById(newInTask)) {
|
||||||
|
log.error("生成任务失败,无法插入新的入库任务");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
newInTask = new TAppTask();
|
||||||
|
newInTask.setTaskId(UUIDUtils.getNewUUID());
|
||||||
|
newInTask.setTaskGroup(orderIn.getOrderId());
|
||||||
|
newInTask.setTaskType(WmsTaskTypeEnums.IN.getCode());
|
||||||
|
newInTask.setTaskStatus(WmsStackerTaskStatusEnums.WAIT.getCode());
|
||||||
|
newInTask.setOrigin(ORIGIN);
|
||||||
|
newInTask.setDestination(useLocation.getLocationId());
|
||||||
|
newInTask.setCreateTime(LocalDateTime.now());
|
||||||
|
newInTask.setOpUser("wcs");
|
||||||
|
newInTask.setVehicleId(orderIn.getVehicleNo());
|
||||||
|
newInTask.setTaskPriority(1);
|
||||||
|
|
||||||
|
if (!appWmsTaskService.save(newInTask)) {
|
||||||
|
log.error("生成任务失败,无法插入新的入库任务");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
appOrderInService.update(
|
||||||
|
new LambdaUpdateWrapper<TAppOrderIn>()
|
||||||
|
.eq(TAppOrderIn::getRecordId, orderIn.getRecordId())
|
||||||
|
.set(TAppOrderIn::getOrderStatus, OrderStatusEnum.RUNNING.getCode())
|
||||||
|
.set(TAppOrderIn::getUpdateTime, LocalDateTime.now()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,7 +4,6 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||||
import com.wms_main.constant.enums.wcs.WcsApiResponseCodeEnums;
|
import com.wms_main.constant.enums.wcs.WcsApiResponseCodeEnums;
|
||||||
import com.wms_main.constant.enums.wcs.WcsStackerTaskStatusEnums;
|
import com.wms_main.constant.enums.wcs.WcsStackerTaskStatusEnums;
|
||||||
import com.wms_main.constant.enums.wcs.WcsStackerTaskTypeEnums;
|
|
||||||
import com.wms_main.constant.enums.wms.WmsStackerTaskStatusEnums;
|
import com.wms_main.constant.enums.wms.WmsStackerTaskStatusEnums;
|
||||||
import com.wms_main.dao.ITAppTaskService;
|
import com.wms_main.dao.ITAppTaskService;
|
||||||
import com.wms_main.dao.ITAppWcsTaskService;
|
import com.wms_main.dao.ITAppWcsTaskService;
|
||||||
|
|
@ -15,7 +14,6 @@ import com.wms_main.model.po.TAppTask;
|
||||||
import com.wms_main.model.po.TAppWcsTask;
|
import com.wms_main.model.po.TAppWcsTask;
|
||||||
import com.wms_main.repository.utils.StringUtils;
|
import com.wms_main.repository.utils.StringUtils;
|
||||||
import com.wms_main.service.api.IWcsApiService;
|
import com.wms_main.service.api.IWcsApiService;
|
||||||
import com.wms_main.service.business.IAgvLockService;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.quartz.*;
|
import org.quartz.*;
|
||||||
|
|
@ -43,11 +41,6 @@ public class WcsStackerTaskSender implements Job {
|
||||||
* Wcs接口服务
|
* Wcs接口服务
|
||||||
*/
|
*/
|
||||||
private final IWcsApiService wcsApiService;
|
private final IWcsApiService wcsApiService;
|
||||||
/**
|
|
||||||
* AGV锁定服务
|
|
||||||
*/
|
|
||||||
private final IAgvLockService agvLockService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 运行定时任务
|
* 运行定时任务
|
||||||
* 向Wcs发送堆垛机任务
|
* 向Wcs发送堆垛机任务
|
||||||
|
|
@ -56,10 +49,10 @@ public class WcsStackerTaskSender implements Job {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void execute(JobExecutionContext jobExecutionContext) {
|
public void execute(JobExecutionContext jobExecutionContext) {
|
||||||
if (appWcsTaskService.exists(new LambdaQueryWrapper<TAppWcsTask>().eq(TAppWcsTask::getWcsTaskStatus,
|
// if (appWcsTaskService.exists(new LambdaQueryWrapper<TAppWcsTask>().eq(TAppWcsTask::getWcsTaskStatus,
|
||||||
WcsStackerTaskStatusEnums.WAIT.getCode()))) {
|
// WcsStackerTaskStatusEnums.WAIT.getCode()))) {
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
// 查询到所有的待下发的wcsTask并按优先级排序
|
// 查询到所有的待下发的wcsTask并按优先级排序
|
||||||
List<TAppWcsTask> waitSendWcsTaskList = appWcsTaskService.list(
|
List<TAppWcsTask> waitSendWcsTaskList = appWcsTaskService.list(
|
||||||
new LambdaQueryWrapper<TAppWcsTask>()
|
new LambdaQueryWrapper<TAppWcsTask>()
|
||||||
|
|
@ -72,12 +65,6 @@ public class WcsStackerTaskSender implements Job {
|
||||||
waitSendWcsTaskList.sort((task1, task2) -> Integer.compare(task2.getTaskPriority(), task1.getTaskPriority()));
|
waitSendWcsTaskList.sort((task1, task2) -> Integer.compare(task2.getTaskPriority(), task1.getTaskPriority()));
|
||||||
// 发送任务
|
// 发送任务
|
||||||
TAppWcsTask wcsTask = waitSendWcsTaskList.getFirst();
|
TAppWcsTask wcsTask = waitSendWcsTaskList.getFirst();
|
||||||
if (wcsTask.getWcsTaskType().equals(WcsStackerTaskTypeEnums.OUT.getCode())) {
|
|
||||||
Boolean wmsAllow = agvLockService.canFeedToInboundPort(wcsTask.getDestination());
|
|
||||||
if (!wmsAllow) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 生成请求
|
// 生成请求
|
||||||
WcsStackerTaskRequest request = new WcsStackerTaskRequest(
|
WcsStackerTaskRequest request = new WcsStackerTaskRequest(
|
||||||
wcsTask.getWcsTaskId(),
|
wcsTask.getWcsTaskId(),
|
||||||
|
|
@ -101,19 +88,6 @@ public class WcsStackerTaskSender implements Job {
|
||||||
.set(TAppTask::getTaskStatus, WmsStackerTaskStatusEnums.SEND.getCode())
|
.set(TAppTask::getTaskStatus, WmsStackerTaskStatusEnums.SEND.getCode())
|
||||||
.eq(TAppTask::getWcsTaskId, wcsTask.getWcsTaskId()));
|
.eq(TAppTask::getWcsTaskId, wcsTask.getWcsTaskId()));
|
||||||
|
|
||||||
if (wcsTask.getWcsTaskType().equals(WcsStackerTaskTypeEnums.OUT.getCode())) {
|
|
||||||
try {
|
|
||||||
agvLockService.lockInboundPort("AGV", wcsTask.getDestination());
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("任务发送成功后锁定{}口失败,任务ID: {}", wcsTask.getDestination(), wcsTask.getWcsTaskId());
|
|
||||||
}
|
|
||||||
} else if (wcsTask.getWcsTaskType().equals(WcsStackerTaskTypeEnums.IN.getCode())) {
|
|
||||||
try {
|
|
||||||
agvLockService.lockInboundPort("AGV", wcsTask.getOrigin());
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("任务发送成功后锁定{}口失败,任务ID: {}", wcsTask.getOrigin(), wcsTask.getWcsTaskId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
log.error("堆垛机任务发送失败,请求{},响应信息{}。", StringUtils.objectToString(request),
|
log.error("堆垛机任务发送失败,请求{},响应信息{}。", StringUtils.objectToString(request),
|
||||||
StringUtils.objectToString(wcsResponse));
|
StringUtils.objectToString(wcsResponse));
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ spring:
|
||||||
|
|
||||||
# 服务配置
|
# 服务配置
|
||||||
server:
|
server:
|
||||||
port: 12315
|
port: 12325
|
||||||
servlet:
|
servlet:
|
||||||
context-path: /
|
context-path: /
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ Content-Type: application/json
|
||||||
|
|
||||||
{
|
{
|
||||||
"taskId": "testOrderId1",
|
"taskId": "testOrderId1",
|
||||||
"vehicleNo": "1003"
|
"vehicleNo": "1001"
|
||||||
}
|
}
|
||||||
|
|
||||||
### 2. 出库订单接口
|
### 2. 出库订单接口
|
||||||
|
|
@ -16,8 +16,8 @@ POST {{baseUrl}}/mywms/orderOut
|
||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
|
|
||||||
{
|
{
|
||||||
"taskId": "testOrderId3",
|
"taskId": "testOrderId2",
|
||||||
"vehicleNo": "1001"
|
"vehicleNo": "1002"
|
||||||
}
|
}
|
||||||
|
|
||||||
### 3. 发送任务结果 - 任务完成
|
### 3. 发送任务结果 - 任务完成
|
||||||
|
|
@ -25,7 +25,7 @@ POST {{baseUrl}}/wms/task/sendTaskResult
|
||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
|
|
||||||
{
|
{
|
||||||
"taskId": "1757666162511010000",
|
"taskId": "1758595357068010000",
|
||||||
"taskStatus": 100,
|
"taskStatus": 100,
|
||||||
"vehicleNo": "1007",
|
"vehicleNo": "1007",
|
||||||
"destination": "C1",
|
"destination": "C1",
|
||||||
|
|
@ -51,7 +51,15 @@ POST {{baseUrl}}/mywms/cancelOrderIn
|
||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
|
|
||||||
{
|
{
|
||||||
"vehicleNo": "1003"
|
"vehicleNo": "1005"
|
||||||
|
}
|
||||||
|
|
||||||
|
### 8. AGVDone
|
||||||
|
POST {{baseUrl}}/mywms/agvDone
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"taskId": "testOrderId1"
|
||||||
}
|
}
|
||||||
|
|
||||||
### 测试数据说明
|
### 测试数据说明
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import lombok.Getter;
|
||||||
@Getter
|
@Getter
|
||||||
public enum OrderStatusEnum {
|
public enum OrderStatusEnum {
|
||||||
|
|
||||||
|
TEMP(-1, "暂存"),
|
||||||
CREATE(0, "创建"),
|
CREATE(0, "创建"),
|
||||||
RUNNING(1, "运行中"),
|
RUNNING(1, "运行中"),
|
||||||
COMPLETE(2, "完成"),
|
COMPLETE(2, "完成"),
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package com.wms_main.controller.mywms;
|
package com.wms_main.controller.mywms;
|
||||||
|
|
||||||
|
import com.wms_main.model.dto.request.mywms.AGVDoneReq;
|
||||||
import com.wms_main.model.dto.request.mywms.OrderInCancel;
|
import com.wms_main.model.dto.request.mywms.OrderInCancel;
|
||||||
import com.wms_main.model.dto.request.mywms.OrderInReq;
|
import com.wms_main.model.dto.request.mywms.OrderInReq;
|
||||||
import com.wms_main.model.dto.request.mywms.OrderOutReq;
|
import com.wms_main.model.dto.request.mywms.OrderOutReq;
|
||||||
|
|
@ -49,8 +50,8 @@ public class MyWmsController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/agvDone")
|
@PostMapping("/agvDone")
|
||||||
public MyWmsResponse<Object> agvDone() {
|
public MyWmsResponse<Object> agvDone(@RequestBody AGVDoneReq request) {
|
||||||
return myWmsControllerService.agvDone();
|
return myWmsControllerService.agvDone(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/cancelOrderIn")
|
@PostMapping("/cancelOrderIn")
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
package com.wms_main.model.dto.request.mywms;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class AGVDoneReq {
|
||||||
|
@JsonProperty("taskId")
|
||||||
|
private String taskId;
|
||||||
|
}
|
||||||
|
|
@ -1,109 +0,0 @@
|
||||||
package com.wms_main.service.business;
|
|
||||||
|
|
||||||
import com.wms_main.model.po.TAppAgvLock;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* AGV资源锁定服务接口
|
|
||||||
* 管理入库口和出库口的AGV设备互锁机制
|
|
||||||
*/
|
|
||||||
public interface IAgvLockService {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* AGV就位并放货后,锁定入库口
|
|
||||||
* @param agvId AGV设备ID
|
|
||||||
* @param inboundPort 入库口编号
|
|
||||||
* @return 锁定结果:成功返回锁定记录,失败返回null
|
|
||||||
*/
|
|
||||||
TAppAgvLock lockInboundPort(String agvId, String inboundPort);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 检查入库口是否可以上料(MES系统调用)
|
|
||||||
* @param inboundPort 入库口编号
|
|
||||||
* @return 是否可以上料
|
|
||||||
*/
|
|
||||||
boolean canFeedToInboundPort(String inboundPort);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取当前入库口处理中的任务数量
|
|
||||||
* @param inboundPort 入库口编号
|
|
||||||
* @return 处理中的任务数量
|
|
||||||
*/
|
|
||||||
int getProcessingTaskCount(String inboundPort);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取入库口状态描述
|
|
||||||
* @param inboundPort 入库口编号
|
|
||||||
* @return 状态描述(空闲/占用)
|
|
||||||
*/
|
|
||||||
String getInboundPortStatus(String inboundPort);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 清理超时锁定
|
|
||||||
* @return 清理的记录数
|
|
||||||
*/
|
|
||||||
int cleanTimeoutLocks();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 释放指定入库口的所有活动锁定
|
|
||||||
* @param inboundPort 入库口编号
|
|
||||||
* @return 释放的锁定数量
|
|
||||||
*/
|
|
||||||
int releaseAllInboundPortLocks(String inboundPort);
|
|
||||||
|
|
||||||
// ========== 出库口锁定相关方法 ==========
|
|
||||||
|
|
||||||
/**
|
|
||||||
* AGV到达出库口后,锁定出库口
|
|
||||||
* @param agvId AGV设备ID
|
|
||||||
* @param outboundPort 出库口编号
|
|
||||||
* @return 锁定结果:成功返回锁定记录,失败返回null
|
|
||||||
*/
|
|
||||||
TAppAgvLock lockOutboundPort(String agvId, String outboundPort);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 检查出库口是否可以出料(MES系统调用)
|
|
||||||
* @param outboundPort 出库口编号
|
|
||||||
* @return 是否可以出料
|
|
||||||
*/
|
|
||||||
boolean canFeedToOutboundPort(String outboundPort);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取当前出库口处理中的任务数量
|
|
||||||
* @param outboundPort 出库口编号
|
|
||||||
* @return 处理中的任务数量
|
|
||||||
*/
|
|
||||||
int getProcessingOutTaskCount(String outboundPort);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取出库口状态描述
|
|
||||||
* @param outboundPort 出库口编号
|
|
||||||
* @return 状态描述(空闲/占用)
|
|
||||||
*/
|
|
||||||
String getOutboundPortStatus(String outboundPort);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 释放指定出库口的所有活动锁定
|
|
||||||
* @param outboundPort 出库口编号
|
|
||||||
* @return 释放的锁定数量
|
|
||||||
*/
|
|
||||||
int releaseAllOutboundPortLocks(String outboundPort);
|
|
||||||
|
|
||||||
// ========== 通用锁定方法 ==========
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 通用资源锁定方法
|
|
||||||
* @param agvId AGV设备ID
|
|
||||||
* @param stationCode 站台编号(R1=入库口,C1=出库口)
|
|
||||||
* @param taskType 任务类型(1=入库,2=出库)
|
|
||||||
* @return 锁定结果:成功返回锁定记录,失败返回null
|
|
||||||
*/
|
|
||||||
TAppAgvLock lockStation(String agvId, String stationCode, Integer taskType);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 通用资源解锁方法
|
|
||||||
* @param stationCode 站台编号(R1=入库口,C1=出库口)
|
|
||||||
* @param taskType 任务类型(1=入库,2=出库)
|
|
||||||
* @return 释放的锁定数量
|
|
||||||
*/
|
|
||||||
int releaseStationLocks(String stationCode, Integer taskType);
|
|
||||||
}
|
|
||||||
|
|
@ -1,442 +0,0 @@
|
||||||
package com.wms_main.service.business.serviceImpl;
|
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|
||||||
import com.wms_main.constant.enums.wms.WmsAgvLockEnums;
|
|
||||||
import com.wms_main.dao.ITAppAgvLockService;
|
|
||||||
import com.wms_main.dao.ITAppTaskService;
|
|
||||||
import com.wms_main.model.po.TAppAgvLock;
|
|
||||||
import com.wms_main.model.po.TAppTask;
|
|
||||||
import com.wms_main.constant.enums.wms.WmsTaskTypeEnums;
|
|
||||||
import com.wms_main.constant.enums.wms.WmsStackerTaskStatusEnums;
|
|
||||||
import com.wms_main.repository.utils.StringUtils;
|
|
||||||
import com.wms_main.repository.utils.UUIDUtils;
|
|
||||||
import com.wms_main.service.business.IAgvLockService;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* AGV资源锁定服务实现
|
|
||||||
* 管理入库口和出库口的AGV设备互锁机制
|
|
||||||
*/
|
|
||||||
@Service
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
@Slf4j
|
|
||||||
public class AgvLockServiceImpl implements IAgvLockService {
|
|
||||||
|
|
||||||
private final ITAppAgvLockService agvLockService;
|
|
||||||
private final ITAppTaskService appTaskService;
|
|
||||||
|
|
||||||
private static final String DEFAULT_INBOUND_PORT = "R1"; // 默认入库口
|
|
||||||
private static final String DEFAULT_OUTBOUND_PORT = "C1"; // 默认出库口
|
|
||||||
private static final int DEFAULT_TIMEOUT_SECONDS = 600; // 默认超时时间10分钟
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional
|
|
||||||
public TAppAgvLock lockInboundPort(String agvId, String inboundPort) {
|
|
||||||
if (StringUtils.isEmpty(agvId)) {
|
|
||||||
log.warn("AGV ID为空");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 使用默认入库口如果未指定
|
|
||||||
if (StringUtils.isEmpty(inboundPort)) {
|
|
||||||
inboundPort = DEFAULT_INBOUND_PORT;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 清理超时锁定
|
|
||||||
cleanTimeoutLocks();
|
|
||||||
|
|
||||||
// 检查入库口是否已被占用
|
|
||||||
List<TAppAgvLock> existingLocks = agvLockService.list(new LambdaQueryWrapper<TAppAgvLock>().eq(TAppAgvLock::getFeedStation, inboundPort));
|
|
||||||
if (existingLocks == null || existingLocks.isEmpty()) {
|
|
||||||
return createInboundPortLock(agvId, inboundPort);
|
|
||||||
} else {
|
|
||||||
agvLockService.update(
|
|
||||||
new LambdaUpdateWrapper<TAppAgvLock>()
|
|
||||||
.eq(TAppAgvLock::getFeedStation, inboundPort)
|
|
||||||
.eq(TAppAgvLock::getLockStatus, WmsAgvLockEnums.AVAILABLE.getCode())
|
|
||||||
.set(TAppAgvLock::getLockStatus, WmsAgvLockEnums.LOCK.getCode())
|
|
||||||
.set(TAppAgvLock::getLockTime, LocalDateTime.now())
|
|
||||||
.set(TAppAgvLock::getRemark, "AGV就位并放货,锁定入库口")
|
|
||||||
);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canFeedToInboundPort(String inboundPort) {
|
|
||||||
// 使用默认入库口如果未指定
|
|
||||||
if (StringUtils.isEmpty(inboundPort)) {
|
|
||||||
inboundPort = DEFAULT_INBOUND_PORT;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 清理超时锁定
|
|
||||||
cleanTimeoutLocks();
|
|
||||||
|
|
||||||
// 检查入库口是否有活动的锁定
|
|
||||||
List<TAppAgvLock> activeLocks = agvLockService.getByStation(inboundPort);
|
|
||||||
boolean hasActiveLock = activeLocks.stream()
|
|
||||||
.anyMatch(lock -> lock.getLockStatus() == 1);
|
|
||||||
|
|
||||||
if (hasActiveLock) {
|
|
||||||
log.debug("入库口 {} 当前被占用,无法上料", inboundPort);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查是否有正在处理的入库任务
|
|
||||||
int processingTasks = getProcessingTaskCount(inboundPort);
|
|
||||||
boolean canFeed = processingTasks == 0;
|
|
||||||
|
|
||||||
log.debug("入库口 {} 可上料状态: {}, 处理中任务数: {}", inboundPort, canFeed, processingTasks);
|
|
||||||
return canFeed;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getProcessingTaskCount(String inboundPort) {
|
|
||||||
// 使用默认入库口如果未指定
|
|
||||||
if (StringUtils.isEmpty(inboundPort)) {
|
|
||||||
inboundPort = DEFAULT_INBOUND_PORT;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 统计正在处理的入库任务数量(包括等待、运行状态的任务)
|
|
||||||
List<TAppTask> processingTasks = appTaskService.list(
|
|
||||||
new LambdaQueryWrapper<TAppTask>()
|
|
||||||
.eq(TAppTask::getTaskType, WmsTaskTypeEnums.IN.getCode())
|
|
||||||
.in(TAppTask::getTaskStatus,
|
|
||||||
WmsStackerTaskStatusEnums.WAIT.getCode(),
|
|
||||||
WmsStackerTaskStatusEnums.RUN.getCode())
|
|
||||||
.like(TAppTask::getOrigin, inboundPort) // 假设任务来源包含入库口信息
|
|
||||||
);
|
|
||||||
|
|
||||||
return processingTasks.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getInboundPortStatus(String inboundPort) {
|
|
||||||
// 使用默认入库口如果未指定
|
|
||||||
if (StringUtils.isEmpty(inboundPort)) {
|
|
||||||
inboundPort = DEFAULT_INBOUND_PORT;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查是否有活动锁定
|
|
||||||
List<TAppAgvLock> activeLocks = agvLockService.getByStation(inboundPort);
|
|
||||||
boolean hasActiveLock = activeLocks.stream()
|
|
||||||
.anyMatch(lock -> lock.getLockStatus() == 1);
|
|
||||||
|
|
||||||
if (hasActiveLock) {
|
|
||||||
return "占用";
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查是否有处理中的任务
|
|
||||||
int processingTasks = getProcessingTaskCount(inboundPort);
|
|
||||||
if (processingTasks > 0) {
|
|
||||||
return "占用";
|
|
||||||
}
|
|
||||||
|
|
||||||
return "空闲";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional
|
|
||||||
public int cleanTimeoutLocks() {
|
|
||||||
List<TAppAgvLock> timeoutLocks = agvLockService.getTimeoutLocks();
|
|
||||||
if (timeoutLocks.isEmpty()) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
for (TAppAgvLock lock : timeoutLocks) {
|
|
||||||
agvLockService.update(
|
|
||||||
new LambdaUpdateWrapper<TAppAgvLock>()
|
|
||||||
.eq(TAppAgvLock::getLockId, lock.getLockId())
|
|
||||||
.set(TAppAgvLock::getLockStatus, 0)
|
|
||||||
.set(TAppAgvLock::getUnlockTime, LocalDateTime.now())
|
|
||||||
.set(TAppAgvLock::getRemark, "超时自动释放")
|
|
||||||
);
|
|
||||||
|
|
||||||
log.info("释放超时锁定: AGV {} 在入库口 {}", lock.getAgvId(), lock.getFeedStation());
|
|
||||||
}
|
|
||||||
|
|
||||||
log.info("清理了 {} 个超时锁定", timeoutLocks.size());
|
|
||||||
return timeoutLocks.size();
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("清理超时锁定失败", e);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional
|
|
||||||
public int releaseAllInboundPortLocks(String inboundPort) {
|
|
||||||
// 使用默认入库口如果未指定
|
|
||||||
if (StringUtils.isEmpty(inboundPort)) {
|
|
||||||
inboundPort = DEFAULT_INBOUND_PORT;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
// 释放指定入库口的所有活动锁定
|
|
||||||
agvLockService.update(
|
|
||||||
new LambdaUpdateWrapper<TAppAgvLock>()
|
|
||||||
.eq(TAppAgvLock::getFeedStation, inboundPort)
|
|
||||||
.eq(TAppAgvLock::getLockStatus, WmsAgvLockEnums.LOCK.getCode())
|
|
||||||
.set(TAppAgvLock::getLockStatus, WmsAgvLockEnums.AVAILABLE.getCode())
|
|
||||||
.set(TAppAgvLock::getUnlockTime, LocalDateTime.now())
|
|
||||||
.set(TAppAgvLock::getRemark, "入库任务完成,批量释放锁定")
|
|
||||||
);
|
|
||||||
|
|
||||||
// 查询实际释放的锁定数量
|
|
||||||
List<TAppAgvLock> activeLocks = agvLockService.getByStation(inboundPort);
|
|
||||||
int releasedCount = (int) activeLocks.stream()
|
|
||||||
.filter(lock -> lock.getLockStatus() == 0)
|
|
||||||
.count();
|
|
||||||
|
|
||||||
log.info("释放入库口 {} 的所有锁定,共释放 {} 个锁定", inboundPort, releasedCount);
|
|
||||||
return releasedCount;
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("释放入库口 {} 的所有锁定失败", inboundPort, e);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ========== 出库口锁定相关方法实现 ==========
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional
|
|
||||||
public TAppAgvLock lockOutboundPort(String agvId, String outboundPort) {
|
|
||||||
if (StringUtils.isEmpty(agvId)) {
|
|
||||||
log.warn("AGV ID为空");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 使用默认出库口如果未指定
|
|
||||||
if (StringUtils.isEmpty(outboundPort)) {
|
|
||||||
outboundPort = DEFAULT_OUTBOUND_PORT;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 清理超时锁定
|
|
||||||
cleanTimeoutLocks();
|
|
||||||
|
|
||||||
// 检查出库口是否已被占用
|
|
||||||
List<TAppAgvLock> existingLocks = agvLockService.list(new LambdaQueryWrapper<TAppAgvLock>().eq(TAppAgvLock::getFeedStation, outboundPort));
|
|
||||||
if (existingLocks == null || existingLocks.isEmpty()) {
|
|
||||||
return createOutboundPortLock(agvId, outboundPort);
|
|
||||||
} else {
|
|
||||||
agvLockService.update(
|
|
||||||
new LambdaUpdateWrapper<TAppAgvLock>()
|
|
||||||
.eq(TAppAgvLock::getFeedStation, outboundPort)
|
|
||||||
.eq(TAppAgvLock::getLockStatus, WmsAgvLockEnums.AVAILABLE.getCode())
|
|
||||||
.set(TAppAgvLock::getLockStatus, WmsAgvLockEnums.LOCK.getCode())
|
|
||||||
.set(TAppAgvLock::getLockTime, LocalDateTime.now())
|
|
||||||
.set(TAppAgvLock::getRemark, "AGV就位并取货,锁定出库口")
|
|
||||||
);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canFeedToOutboundPort(String outboundPort) {
|
|
||||||
// 使用默认出库口如果未指定
|
|
||||||
if (StringUtils.isEmpty(outboundPort)) {
|
|
||||||
outboundPort = DEFAULT_OUTBOUND_PORT;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 清理超时锁定
|
|
||||||
cleanTimeoutLocks();
|
|
||||||
|
|
||||||
// 检查出库口是否有活动的锁定
|
|
||||||
List<TAppAgvLock> activeLocks = agvLockService.getByStation(outboundPort);
|
|
||||||
boolean hasActiveLock = activeLocks.stream()
|
|
||||||
.anyMatch(lock -> lock.getLockStatus() == 1);
|
|
||||||
|
|
||||||
if (hasActiveLock) {
|
|
||||||
log.debug("出库口 {} 当前被占用,无法出料", outboundPort);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查是否有正在处理的出库任务
|
|
||||||
int processingTasks = getProcessingOutTaskCount(outboundPort);
|
|
||||||
boolean canFeed = processingTasks == 0;
|
|
||||||
|
|
||||||
log.debug("出库口 {} 可出料状态: {}, 处理中任务数: {}", outboundPort, canFeed, processingTasks);
|
|
||||||
return canFeed;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getProcessingOutTaskCount(String outboundPort) {
|
|
||||||
// 使用默认出库口如果未指定
|
|
||||||
if (StringUtils.isEmpty(outboundPort)) {
|
|
||||||
outboundPort = DEFAULT_OUTBOUND_PORT;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 统计正在处理的出库任务数量(包括等待、运行状态的任务)
|
|
||||||
List<TAppTask> processingTasks = appTaskService.list(
|
|
||||||
new LambdaQueryWrapper<TAppTask>()
|
|
||||||
.eq(TAppTask::getTaskType, WmsTaskTypeEnums.OUT.getCode())
|
|
||||||
.in(TAppTask::getTaskStatus,
|
|
||||||
WmsStackerTaskStatusEnums.WAIT.getCode(),
|
|
||||||
WmsStackerTaskStatusEnums.RUN.getCode())
|
|
||||||
.like(TAppTask::getDestination, outboundPort) // 假设任务目标包含出库口信息
|
|
||||||
);
|
|
||||||
|
|
||||||
return processingTasks.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getOutboundPortStatus(String outboundPort) {
|
|
||||||
// 使用默认出库口如果未指定
|
|
||||||
if (StringUtils.isEmpty(outboundPort)) {
|
|
||||||
outboundPort = DEFAULT_OUTBOUND_PORT;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查是否有活动锁定
|
|
||||||
List<TAppAgvLock> activeLocks = agvLockService.getByStation(outboundPort);
|
|
||||||
boolean hasActiveLock = activeLocks.stream()
|
|
||||||
.anyMatch(lock -> lock.getLockStatus() == 1);
|
|
||||||
|
|
||||||
if (hasActiveLock) {
|
|
||||||
return "占用";
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查是否有处理中的任务
|
|
||||||
int processingTasks = getProcessingOutTaskCount(outboundPort);
|
|
||||||
if (processingTasks > 0) {
|
|
||||||
return "占用";
|
|
||||||
}
|
|
||||||
|
|
||||||
return "空闲";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional
|
|
||||||
public int releaseAllOutboundPortLocks(String outboundPort) {
|
|
||||||
// 使用默认出库口如果未指定
|
|
||||||
if (StringUtils.isEmpty(outboundPort)) {
|
|
||||||
outboundPort = DEFAULT_OUTBOUND_PORT;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
// 释放指定出库口的所有活动锁定
|
|
||||||
agvLockService.update(
|
|
||||||
new LambdaUpdateWrapper<TAppAgvLock>()
|
|
||||||
.eq(TAppAgvLock::getFeedStation, outboundPort)
|
|
||||||
.eq(TAppAgvLock::getLockStatus, WmsAgvLockEnums.LOCK.getCode())
|
|
||||||
.set(TAppAgvLock::getLockStatus, WmsAgvLockEnums.AVAILABLE.getCode())
|
|
||||||
.set(TAppAgvLock::getUnlockTime, LocalDateTime.now())
|
|
||||||
.set(TAppAgvLock::getRemark, "出库任务完成,批量释放锁定")
|
|
||||||
);
|
|
||||||
|
|
||||||
// 查询实际释放的锁定数量
|
|
||||||
List<TAppAgvLock> activeLocks = agvLockService.getByStation(outboundPort);
|
|
||||||
int releasedCount = (int) activeLocks.stream()
|
|
||||||
.filter(lock -> lock.getLockStatus() == 0)
|
|
||||||
.count();
|
|
||||||
|
|
||||||
log.info("释放出库口 {} 的所有锁定,共释放 {} 个锁定", outboundPort, releasedCount);
|
|
||||||
return releasedCount;
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("释放出库口 {} 的所有锁定失败", outboundPort, e);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ========== 通用锁定方法实现 ==========
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional
|
|
||||||
public TAppAgvLock lockStation(String agvId, String stationCode, Integer taskType) {
|
|
||||||
if (StringUtils.isEmpty(agvId) || StringUtils.isEmpty(stationCode) || Objects.isNull(taskType)) {
|
|
||||||
log.warn("锁定参数不完整: agvId={}, stationCode={}, taskType={}", agvId, stationCode, taskType);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (WmsTaskTypeEnums.IN.getCode().equals(taskType)) {
|
|
||||||
return lockInboundPort(agvId, stationCode);
|
|
||||||
} else if (WmsTaskTypeEnums.OUT.getCode().equals(taskType)) {
|
|
||||||
return lockOutboundPort(agvId, stationCode);
|
|
||||||
} else {
|
|
||||||
log.warn("不支持的任务类型: {}", taskType);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional
|
|
||||||
public int releaseStationLocks(String stationCode, Integer taskType) {
|
|
||||||
if (StringUtils.isEmpty(stationCode) || Objects.isNull(taskType)) {
|
|
||||||
log.warn("解锁参数不完整: stationCode={}, taskType={}", stationCode, taskType);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (WmsTaskTypeEnums.IN.getCode().equals(taskType)) {
|
|
||||||
return releaseAllInboundPortLocks(stationCode);
|
|
||||||
} else if (WmsTaskTypeEnums.OUT.getCode().equals(taskType)) {
|
|
||||||
return releaseAllOutboundPortLocks(stationCode);
|
|
||||||
} else {
|
|
||||||
log.warn("不支持的任务类型: {}", taskType);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ========== 私有方法 ==========
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建入库口锁定记录
|
|
||||||
*/
|
|
||||||
private TAppAgvLock createInboundPortLock(String agvId, String inboundPort) {
|
|
||||||
TAppAgvLock lock = new TAppAgvLock();
|
|
||||||
lock.setLockId(UUIDUtils.getNewUUID());
|
|
||||||
lock.setAgvId(agvId);
|
|
||||||
lock.setFeedStation(inboundPort);
|
|
||||||
lock.setLockStatus(1);
|
|
||||||
lock.setLockType("INBOUND_PORT_LOCK");
|
|
||||||
lock.setPriority(1);
|
|
||||||
lock.setQueuePosition(1);
|
|
||||||
lock.setLockTime(LocalDateTime.now());
|
|
||||||
lock.setTimeoutSeconds(DEFAULT_TIMEOUT_SECONDS);
|
|
||||||
lock.setCreateTime(LocalDateTime.now());
|
|
||||||
lock.setUpdateTime(LocalDateTime.now());
|
|
||||||
lock.setRemark("AGV就位并放货,锁定入库口");
|
|
||||||
|
|
||||||
if (agvLockService.save(lock)) {
|
|
||||||
log.info("AGV {} 成功锁定入库口 {}", agvId, inboundPort);
|
|
||||||
return lock;
|
|
||||||
}
|
|
||||||
|
|
||||||
log.error("AGV {} 锁定入库口 {} 失败", agvId, inboundPort);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建出库口锁定记录
|
|
||||||
*/
|
|
||||||
private TAppAgvLock createOutboundPortLock(String agvId, String outboundPort) {
|
|
||||||
TAppAgvLock lock = new TAppAgvLock();
|
|
||||||
lock.setLockId(UUIDUtils.getNewUUID());
|
|
||||||
lock.setAgvId(agvId);
|
|
||||||
lock.setFeedStation(outboundPort);
|
|
||||||
lock.setLockStatus(1);
|
|
||||||
lock.setLockType("OUTBOUND_PORT_LOCK");
|
|
||||||
lock.setPriority(1);
|
|
||||||
lock.setQueuePosition(1);
|
|
||||||
lock.setLockTime(LocalDateTime.now());
|
|
||||||
lock.setTimeoutSeconds(DEFAULT_TIMEOUT_SECONDS);
|
|
||||||
lock.setCreateTime(LocalDateTime.now());
|
|
||||||
lock.setUpdateTime(LocalDateTime.now());
|
|
||||||
lock.setRemark("AGV就位并取货,锁定出库口");
|
|
||||||
|
|
||||||
if (agvLockService.save(lock)) {
|
|
||||||
log.info("AGV {} 成功锁定出库口 {}", agvId, outboundPort);
|
|
||||||
return lock;
|
|
||||||
}
|
|
||||||
|
|
||||||
log.error("AGV {} 锁定出库口 {} 失败", agvId, outboundPort);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -15,7 +15,6 @@ import com.wms_main.repository.utils.ConvertUtils;
|
||||||
import com.wms_main.repository.utils.StringUtils;
|
import com.wms_main.repository.utils.StringUtils;
|
||||||
import com.wms_main.repository.utils.UUIDUtils;
|
import com.wms_main.repository.utils.UUIDUtils;
|
||||||
import com.wms_main.service.api.IExternalApiService;
|
import com.wms_main.service.api.IExternalApiService;
|
||||||
import com.wms_main.service.business.IAgvLockService;
|
|
||||||
import com.wms_main.service.business.IStackerTaskService;
|
import com.wms_main.service.business.IStackerTaskService;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
@ -68,8 +67,6 @@ public class StackerTaskServiceImpl implements IStackerTaskService {
|
||||||
private final ITAppOrderOutService appOrderOutService;
|
private final ITAppOrderOutService appOrderOutService;
|
||||||
|
|
||||||
private final IExternalApiService externalApiService;
|
private final IExternalApiService externalApiService;
|
||||||
|
|
||||||
private final IAgvLockService agvLockService;
|
|
||||||
/**
|
/**
|
||||||
* 业务通用
|
* 业务通用
|
||||||
*/
|
*/
|
||||||
|
|
@ -455,7 +452,6 @@ public class StackerTaskServiceImpl implements IStackerTaskService {
|
||||||
appVehicleService.saveOrUpdate(vehicle);
|
appVehicleService.saveOrUpdate(vehicle);
|
||||||
|
|
||||||
appCommon.updateWorkingLocations(wmsTask.getDestination(), 0);
|
appCommon.updateWorkingLocations(wmsTask.getDestination(), 0);
|
||||||
agvLockService.releaseStationLocks("R1", WmsTaskTypeEnums.IN.getCode());
|
|
||||||
// 备份并删除任务
|
// 备份并删除任务
|
||||||
if (!appTaskService.removeById(wmsTask.getTaskId())) {
|
if (!appTaskService.removeById(wmsTask.getTaskId())) {
|
||||||
log.info("删除入库任务失败,任务:{}", wmsTask.getTaskId());
|
log.info("删除入库任务失败,任务:{}", wmsTask.getTaskId());
|
||||||
|
|
@ -571,7 +567,6 @@ public class StackerTaskServiceImpl implements IStackerTaskService {
|
||||||
.set(TAppStock::getStockStatus, WmsStockStatusEnums.OUTED.getCode())
|
.set(TAppStock::getStockStatus, WmsStockStatusEnums.OUTED.getCode())
|
||||||
.set(TAppStock::getLocationId, "")
|
.set(TAppStock::getLocationId, "")
|
||||||
.eq(TAppStock::getVehicleId, vehicleId));
|
.eq(TAppStock::getVehicleId, vehicleId));
|
||||||
agvLockService.releaseStationLocks("C1", WmsTaskTypeEnums.OUT.getCode());
|
|
||||||
// 当前载具的任务列表
|
// 当前载具的任务列表
|
||||||
List<TAppTask> thisVehicleOutTasks = vehicleIdToTaskMap.get(vehicleId);
|
List<TAppTask> thisVehicleOutTasks = vehicleIdToTaskMap.get(vehicleId);
|
||||||
if (thisVehicleOutTasks.isEmpty()) {
|
if (thisVehicleOutTasks.isEmpty()) {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package com.wms_main.service.controller;
|
package com.wms_main.service.controller;
|
||||||
|
|
||||||
|
import com.wms_main.model.dto.request.mywms.AGVDoneReq;
|
||||||
import com.wms_main.model.dto.request.mywms.OrderInCancel;
|
import com.wms_main.model.dto.request.mywms.OrderInCancel;
|
||||||
import com.wms_main.model.dto.request.mywms.OrderInReq;
|
import com.wms_main.model.dto.request.mywms.OrderInReq;
|
||||||
import com.wms_main.model.dto.request.mywms.OrderOutReq;
|
import com.wms_main.model.dto.request.mywms.OrderOutReq;
|
||||||
|
|
@ -22,5 +23,5 @@ public interface IMyWmsControllerService {
|
||||||
|
|
||||||
String cancelOrderIn(OrderInCancel request);
|
String cancelOrderIn(OrderInCancel request);
|
||||||
|
|
||||||
MyWmsResponse<Object> agvDone();
|
MyWmsResponse<Object> agvDone(AGVDoneReq request);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,6 @@ import com.wms_main.model.po.TAppWcsTask;
|
||||||
import com.wms_main.repository.utils.StringUtils;
|
import com.wms_main.repository.utils.StringUtils;
|
||||||
import com.wms_main.repository.utils.UUIDUtils;
|
import com.wms_main.repository.utils.UUIDUtils;
|
||||||
import com.wms_main.service.api.IWcsApiService;
|
import com.wms_main.service.api.IWcsApiService;
|
||||||
import com.wms_main.service.business.IAgvLockService;
|
|
||||||
import com.wms_main.service.controller.IMyWmsControllerService;
|
import com.wms_main.service.controller.IMyWmsControllerService;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
@ -47,7 +46,6 @@ public class MyWmsControllerServiceImpl implements IMyWmsControllerService {
|
||||||
private final ITAppOrderInService appOrderInService;
|
private final ITAppOrderInService appOrderInService;
|
||||||
private final ITAppOrderOutService appOrderOutService;
|
private final ITAppOrderOutService appOrderOutService;
|
||||||
private final ITAppStockService appStockService;
|
private final ITAppStockService appStockService;
|
||||||
private final IAgvLockService agvLockService;
|
|
||||||
private final IWcsApiService wcsApiService;
|
private final IWcsApiService wcsApiService;
|
||||||
private final ITAppTaskService appTaskService;
|
private final ITAppTaskService appTaskService;
|
||||||
private final ITAppWcsTaskService appWcsTaskService;
|
private final ITAppWcsTaskService appWcsTaskService;
|
||||||
|
|
@ -63,14 +61,6 @@ public class MyWmsControllerServiceImpl implements IMyWmsControllerService {
|
||||||
return OrderResponse.error("参数错误");
|
return OrderResponse.error("参数错误");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查入库口是否可用
|
|
||||||
String inboundPort = "R1"; // 默认入库口
|
|
||||||
boolean canFeed = agvLockService.canFeedToInboundPort(inboundPort);
|
|
||||||
if (!canFeed) {
|
|
||||||
String portStatus = agvLockService.getInboundPortStatus(inboundPort);
|
|
||||||
return OrderResponse.error("入库口当前" + portStatus + ",无法生成入库订单,请稍后重试");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 校验是否存在相同的入库单
|
// 校验是否存在相同的入库单
|
||||||
List<TAppOrderIn> withTaskId = appOrderInService.getWithTaskId(request.getTaskId());
|
List<TAppOrderIn> withTaskId = appOrderInService.getWithTaskId(request.getTaskId());
|
||||||
if (withTaskId == null) {
|
if (withTaskId == null) {
|
||||||
|
|
@ -91,7 +81,7 @@ public class MyWmsControllerServiceImpl implements IMyWmsControllerService {
|
||||||
orderIn.setVehicleNo(request.getVehicleNo());
|
orderIn.setVehicleNo(request.getVehicleNo());
|
||||||
orderIn.setInStand("R1");
|
orderIn.setInStand("R1");
|
||||||
orderIn.setRequestUser("wms");
|
orderIn.setRequestUser("wms");
|
||||||
orderIn.setOrderStatus(OrderStatusEnum.CREATE.getCode());
|
orderIn.setOrderStatus(OrderStatusEnum.TEMP.getCode());
|
||||||
orderIn.setCreateTime(LocalDateTime.now());
|
orderIn.setCreateTime(LocalDateTime.now());
|
||||||
orderIn.setUpdateTime(LocalDateTime.now());
|
orderIn.setUpdateTime(LocalDateTime.now());
|
||||||
if (!appOrderInService.save(orderIn)) {
|
if (!appOrderInService.save(orderIn)) {
|
||||||
|
|
@ -209,11 +199,6 @@ public class MyWmsControllerServiceImpl implements IMyWmsControllerService {
|
||||||
if (!wcsAllow) {
|
if (!wcsAllow) {
|
||||||
return MyWmsResponse.error("WCS系统不允许AGV上料", false);
|
return MyWmsResponse.error("WCS系统不允许AGV上料", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Boolean wmsAllow = agvLockService.canFeedToInboundPort("R1");
|
|
||||||
if (!wmsAllow) {
|
|
||||||
return MyWmsResponse.error("入库口锁定中", false);
|
|
||||||
}
|
|
||||||
return MyWmsResponse.success(true);
|
return MyWmsResponse.success(true);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return MyWmsResponse.error("系统异常,请稍后重试", null);
|
return MyWmsResponse.error("系统异常,请稍后重试", null);
|
||||||
|
|
@ -222,7 +207,6 @@ public class MyWmsControllerServiceImpl implements IMyWmsControllerService {
|
||||||
|
|
||||||
private MyWmsResponse<Boolean> queryStandStatusOut(QueryStandStatusReq request) {
|
private MyWmsResponse<Boolean> queryStandStatusOut(QueryStandStatusReq request) {
|
||||||
try {
|
try {
|
||||||
// 1. 调用wcs.canFeed检查wcs状态 (使用R1口)
|
|
||||||
WcsApiResponse<WcsCanFeedResponse> wcsResponse = wcsApiService
|
WcsApiResponse<WcsCanFeedResponse> wcsResponse = wcsApiService
|
||||||
.queryStandStatus(new WcsQueryStandStatusRequest(request.getStandType()));
|
.queryStandStatus(new WcsQueryStandStatusRequest(request.getStandType()));
|
||||||
if (wcsResponse == null || wcsResponse.getData() == null) {
|
if (wcsResponse == null || wcsResponse.getData() == null) {
|
||||||
|
|
@ -234,12 +218,6 @@ public class MyWmsControllerServiceImpl implements IMyWmsControllerService {
|
||||||
return MyWmsResponse.error("WCS系统不允许AGV取货", false);
|
return MyWmsResponse.error("WCS系统不允许AGV取货", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 检查agvLock服务获取wms状态 (使用R1口)
|
|
||||||
Boolean wmsAllow = agvLockService.canFeedToInboundPort("C1");
|
|
||||||
if (!wmsAllow) {
|
|
||||||
return MyWmsResponse.error("出库口锁定中", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
return MyWmsResponse.success(true);
|
return MyWmsResponse.success(true);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return MyWmsResponse.error("系统异常,请稍后重试", false);
|
return MyWmsResponse.error("系统异常,请稍后重试", false);
|
||||||
|
|
@ -247,7 +225,27 @@ public class MyWmsControllerServiceImpl implements IMyWmsControllerService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MyWmsResponse<Object> agvDone() {
|
public MyWmsResponse<Object> agvDone(AGVDoneReq request) {
|
||||||
|
if (StringUtils.isEmpty(request.getTaskId())) {
|
||||||
|
return agvDoneOut();
|
||||||
|
} else {
|
||||||
|
return agvDoneIn(request);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private MyWmsResponse<Object> agvDoneIn(AGVDoneReq request) {
|
||||||
|
LambdaUpdateWrapper<TAppOrderIn> updateWrapper = new LambdaUpdateWrapper<TAppOrderIn>()
|
||||||
|
.eq(TAppOrderIn::getOrderId, request.getTaskId())
|
||||||
|
.eq(TAppOrderIn::getOrderStatus, OrderStatusEnum.TEMP.getCode())
|
||||||
|
.set(TAppOrderIn::getOrderStatus, OrderStatusEnum.CREATE.getCode());
|
||||||
|
if (appOrderInService.update(updateWrapper)) {
|
||||||
|
return MyWmsResponse.success();
|
||||||
|
} else {
|
||||||
|
return MyWmsResponse.error("更新订单状态失败", null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private MyWmsResponse<Object> agvDoneOut() {
|
||||||
try {
|
try {
|
||||||
BaseWcsApiResponse wcsResponse = wcsApiService.agvDone();
|
BaseWcsApiResponse wcsResponse = wcsApiService.agvDone();
|
||||||
if (wcsResponse == null) {
|
if (wcsResponse == null) {
|
||||||
|
|
@ -284,8 +282,10 @@ public class MyWmsControllerServiceImpl implements IMyWmsControllerService {
|
||||||
if (locationList != null && locationList.size() > 0) {
|
if (locationList != null && locationList.size() > 0) {
|
||||||
location = locationList.getFirst();
|
location = locationList.getFirst();
|
||||||
}
|
}
|
||||||
if (location != null && !appStockService.exists(new LambdaQueryWrapper<TAppStock>().eq(StringUtils.isNotEmpty(vehicleNo),
|
if (location != null && !appStockService.exists(new LambdaQueryWrapper<TAppStock>()
|
||||||
TAppStock::getVehicleId, vehicleNo).eq(TAppStock::getStockStatus, WmsStockStatusEnums.OK.getCode()))) {
|
.eq(StringUtils.isNotEmpty(vehicleNo),
|
||||||
|
TAppStock::getVehicleId, vehicleNo)
|
||||||
|
.eq(TAppStock::getStockStatus, WmsStockStatusEnums.OK.getCode()))) {
|
||||||
if (!appLocationService.update(
|
if (!appLocationService.update(
|
||||||
new LambdaUpdateWrapper<TAppLocation>().eq(TAppLocation::getLocationId, location.getLocationId())
|
new LambdaUpdateWrapper<TAppLocation>().eq(TAppLocation::getLocationId, location.getLocationId())
|
||||||
.set(TAppLocation::getIsOccupy, WmsLocationOccupyStatusEnums.EMPTY.getCode())
|
.set(TAppLocation::getIsOccupy, WmsLocationOccupyStatusEnums.EMPTY.getCode())
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||||
import com.wms_main.constant.enums.wcs.WcsApiResponseCodeEnums;
|
import com.wms_main.constant.enums.wcs.WcsApiResponseCodeEnums;
|
||||||
import com.wms_main.constant.enums.wcs.WcsStackerTaskStatusEnums;
|
import com.wms_main.constant.enums.wcs.WcsStackerTaskStatusEnums;
|
||||||
import com.wms_main.constant.enums.wcs.WcsStackerTaskTypeEnums;
|
|
||||||
import com.wms_main.constant.enums.wms.WmsStackerTaskStatusEnums;
|
import com.wms_main.constant.enums.wms.WmsStackerTaskStatusEnums;
|
||||||
import com.wms_main.dao.ITAppTaskService;
|
import com.wms_main.dao.ITAppTaskService;
|
||||||
import com.wms_main.dao.ITAppWcsTaskService;
|
import com.wms_main.dao.ITAppWcsTaskService;
|
||||||
|
|
@ -15,7 +14,6 @@ import com.wms_main.model.po.TAppTask;
|
||||||
import com.wms_main.model.po.TAppWcsTask;
|
import com.wms_main.model.po.TAppWcsTask;
|
||||||
import com.wms_main.repository.utils.StringUtils;
|
import com.wms_main.repository.utils.StringUtils;
|
||||||
import com.wms_main.service.api.IWcsApiService;
|
import com.wms_main.service.api.IWcsApiService;
|
||||||
import com.wms_main.service.business.IAgvLockService;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.quartz.*;
|
import org.quartz.*;
|
||||||
|
|
@ -44,11 +42,6 @@ public class WcsStackerTaskSender implements Job {
|
||||||
* Wcs接口服务
|
* Wcs接口服务
|
||||||
*/
|
*/
|
||||||
private final IWcsApiService wcsApiService;
|
private final IWcsApiService wcsApiService;
|
||||||
/**
|
|
||||||
* AGV锁定服务
|
|
||||||
*/
|
|
||||||
private final IAgvLockService agvLockService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 运行定时任务
|
* 运行定时任务
|
||||||
* 向Wcs发送堆垛机任务
|
* 向Wcs发送堆垛机任务
|
||||||
|
|
@ -73,18 +66,6 @@ public class WcsStackerTaskSender implements Job {
|
||||||
waitSendWcsTaskList.sort((task1, task2) -> Integer.compare(task2.getTaskPriority(), task1.getTaskPriority()));
|
waitSendWcsTaskList.sort((task1, task2) -> Integer.compare(task2.getTaskPriority(), task1.getTaskPriority()));
|
||||||
// 发送任务
|
// 发送任务
|
||||||
TAppWcsTask wcsTask = waitSendWcsTaskList.getFirst();
|
TAppWcsTask wcsTask = waitSendWcsTaskList.getFirst();
|
||||||
Boolean wmsAllow = false;
|
|
||||||
if (wcsTask.getWcsTaskType().equals(WcsStackerTaskTypeEnums.OUT.getCode())) {
|
|
||||||
wmsAllow = agvLockService.canFeedToOutboundPort(wcsTask.getDestination());
|
|
||||||
} else if (wcsTask.getWcsTaskType().equals(WcsStackerTaskTypeEnums.IN.getCode())) {
|
|
||||||
wmsAllow = agvLockService.canFeedToInboundPort(wcsTask.getOrigin());
|
|
||||||
}
|
|
||||||
if (wcsTask.getWcsTaskType().equals(WcsStackerTaskTypeEnums.OUT.getCode())
|
|
||||||
|| wcsTask.getWcsTaskType().equals(WcsStackerTaskTypeEnums.IN.getCode())) {
|
|
||||||
if (!wmsAllow) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 生成请求
|
// 生成请求
|
||||||
WcsStackerTaskRequest request = new WcsStackerTaskRequest(
|
WcsStackerTaskRequest request = new WcsStackerTaskRequest(
|
||||||
wcsTask.getWcsTaskId(),
|
wcsTask.getWcsTaskId(),
|
||||||
|
|
@ -107,20 +88,6 @@ public class WcsStackerTaskSender implements Job {
|
||||||
new LambdaUpdateWrapper<TAppTask>()
|
new LambdaUpdateWrapper<TAppTask>()
|
||||||
.set(TAppTask::getTaskStatus, WmsStackerTaskStatusEnums.SEND.getCode())
|
.set(TAppTask::getTaskStatus, WmsStackerTaskStatusEnums.SEND.getCode())
|
||||||
.eq(TAppTask::getWcsTaskId, wcsTask.getWcsTaskId()));
|
.eq(TAppTask::getWcsTaskId, wcsTask.getWcsTaskId()));
|
||||||
|
|
||||||
if (wcsTask.getWcsTaskType().equals(WcsStackerTaskTypeEnums.OUT.getCode())) {
|
|
||||||
try {
|
|
||||||
agvLockService.lockOutboundPort("AGV", wcsTask.getDestination());
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("任务发送成功后锁定{}口失败,任务ID: {}", wcsTask.getDestination(), wcsTask.getWcsTaskId());
|
|
||||||
}
|
|
||||||
} else if (wcsTask.getWcsTaskType().equals(WcsStackerTaskTypeEnums.IN.getCode())) {
|
|
||||||
try {
|
|
||||||
agvLockService.lockInboundPort("AGV", wcsTask.getOrigin());
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("任务发送成功后锁定{}口失败,任务ID: {}", wcsTask.getOrigin(), wcsTask.getWcsTaskId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
log.error("堆垛机任务发送失败,请求{},响应信息{}。", StringUtils.objectToString(request),
|
log.error("堆垛机任务发送失败,请求{},响应信息{}。", StringUtils.objectToString(request),
|
||||||
StringUtils.objectToString(wcsResponse));
|
StringUtils.objectToString(wcsResponse));
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,13 @@ spring:
|
||||||
datasource:
|
datasource:
|
||||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||||
# 本地
|
# 本地
|
||||||
# url: jdbc:mysql://localhost:3306/wms_mengyang_tp?characterEncoding=utf8&serverTimezone=Asia/Shanghai&allowMultiQueries=true&rewriteBatchedStatements=true
|
|
||||||
# username: root
|
|
||||||
# password: root
|
|
||||||
# 服务器
|
|
||||||
url: jdbc:mysql://localhost:3306/wms_mengyang_tp?characterEncoding=utf8&serverTimezone=Asia/Shanghai&allowMultiQueries=true&rewriteBatchedStatements=true
|
url: jdbc:mysql://localhost:3306/wms_mengyang_tp?characterEncoding=utf8&serverTimezone=Asia/Shanghai&allowMultiQueries=true&rewriteBatchedStatements=true
|
||||||
username: user
|
username: root
|
||||||
password: user
|
password: root
|
||||||
|
# 服务器
|
||||||
|
# url: jdbc:mysql://localhost:3306/wms_mengyang_tp?characterEncoding=utf8&serverTimezone=Asia/Shanghai&allowMultiQueries=true&rewriteBatchedStatements=true
|
||||||
|
# username: user
|
||||||
|
# password: user
|
||||||
|
|
||||||
profiles:
|
profiles:
|
||||||
active: online
|
active: online
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user