@@ -1,7 +1,16 @@
package org.nl.extInterface.wms.service.impl ;
import lombok.RequiredArgsConstructor ;
import cn.hutool.core.collection.CollUtil ;
import cn.hutool.core.util.IdUtil ;
import cn.hutool.core.util.ObjectUtil ;
import cn.hutool.core.util.StrUtil ;
import com.alibaba.fastjson.JSONObject ;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper ;
import lombok.extern.slf4j.Slf4j ;
import org.nl.acs.device.storageMgt.service.entity.StorageCell ;
import org.nl.acs.device.storageMgt.service.mapper.StorageCellMapper ;
import org.nl.acs.task.task.service.TaskService ;
import org.nl.acs.task.task.service.dto.TaskDto ;
import org.nl.extInterface.wms.data.req.OperateCheckReqVO ;
import org.nl.extInterface.wms.data.req.TaskIssueReqVO ;
import org.nl.extInterface.wms.data.resp.OperateCheckRespVO ;
@@ -9,21 +18,218 @@ import org.nl.extInterface.wms.data.resp.TaskIssueResultRespVO;
import org.nl.extInterface.wms.service.WmsToAcsService ;
import org.springframework.stereotype.Service ;
import javax.annotation.Resource ;
import java.util.ArrayList ;
import java.util.LinkedHashMap ;
import java.util.List ;
import java.util.Map ;
@Service
@RequiredArgsConstructor
@Slf4j
public class WmsToAcsServiceImpl implements WmsToAcsService {
private static final String DEFAULT_TASK_TYPE = " 1 " ;
private static final String DEFAULT_ROUTE_PLAN_CODE = " normal " ;
@Resource
private TaskService taskService ;
@Resource
private StorageCellMapper storageCellMapper ;
@Override
public TaskIssueResultRespVO issueTask ( List < TaskIssueReqVO > tasks ) {
// todo
log . info ( " 接受WMS下发的任务: {} " , JSONObject . toJSONString ( tasks ) ) ;
TaskIssueResultRespVO response = new TaskIssueResultRespVO ( ) ;
List < TaskIssueResultRespVO . FailedTask > failedTasks = new ArrayList < > ( ) ;
if ( CollUtil . isEmpty ( tasks ) ) {
response . setFailedTasks ( failedTasks ) ;
return response ;
}
for ( TaskIssueReqVO task : tasks ) {
TaskIssueResultRespVO . FailedTask failedTask = issueSingleTask ( task ) ;
if ( failedTask ! = null ) {
failedTasks . add ( failedTask ) ;
}
}
response . setFailedTasks ( failedTasks ) ;
return response ;
}
private TaskIssueResultRespVO . FailedTask issueSingleTask ( TaskIssueReqVO task ) {
try {
validateRequired ( task ) ;
ensureTaskNotExists ( task ) ;
TaskLocation startLocation = resolveLocation ( task . getStartDeviceCode ( ) ) ;
TaskLocation nextLocation = resolveLocation ( task . getNextDeviceCode ( ) ) ;
TaskLocation startLocation2 = resolveOptionalLocation ( task . getStartDeviceCode2 ( ) ) ;
TaskLocation nextLocation2 = resolveOptionalLocation ( task . getNextDeviceCode2 ( ) ) ;
TaskDto taskDto = buildTaskDto ( task , startLocation , nextLocation , startLocation2 , nextLocation2 ) ;
extendBeforeCreate ( task , taskDto ) ;
taskService . create ( taskDto ) ;
return null ;
} catch ( Exception e ) {
log . warn ( " WMS任务下发失败, taskId={}, taskCode={} " , getTaskId ( task ) , getTaskCode ( task ) , e ) ;
return failedTask ( getTaskId ( task ) , e . getMessage ( ) ) ;
}
}
private void validateRequired ( TaskIssueReqVO task ) {
if ( task = = null ) {
throw new IllegalArgumentException ( " 任务不能为空 " ) ;
}
if ( StrUtil . isBlank ( task . getTaskCode ( ) ) ) {
throw new IllegalArgumentException ( " 任务编码不能为空 " ) ;
}
if ( StrUtil . isBlank ( task . getStartDeviceCode ( ) ) ) {
throw new IllegalArgumentException ( " 起点不能为空 " ) ;
}
if ( StrUtil . isBlank ( task . getNextDeviceCode ( ) ) ) {
throw new IllegalArgumentException ( " 终点不能为空 " ) ;
}
}
private void ensureTaskNotExists ( TaskIssueReqVO task ) {
TaskDto cachedTask = taskService . findByCodeFromCache ( task . getTaskCode ( ) ) ;
if ( cachedTask ! = null ) {
throw new IllegalArgumentException ( " 存在相同的任务编码: " + task . getTaskCode ( ) ) ;
}
TaskDto dbTask = taskService . findByCode ( task . getTaskCode ( ) ) ;
if ( dbTask ! = null ) {
throw new IllegalArgumentException ( " 存在相同的任务编码: " + task . getTaskCode ( ) ) ;
}
if ( StrUtil . isNotBlank ( task . getVehicleCode ( ) ) ) {
TaskDto vehicleTask = taskService . findByContainer ( task . getVehicleCode ( ) ) ;
if ( vehicleTask ! = null ) {
throw new IllegalArgumentException ( " 载具 " + task . getVehicleCode ( ) + " 已存在任务: " + vehicleTask . getTask_code ( ) ) ;
}
}
}
private TaskLocation resolveLocation ( String storageCode ) {
TaskLocation location = resolveOptionalLocation ( storageCode ) ;
if ( StrUtil . isBlank ( location . getPointCode ( ) ) ) {
throw new IllegalArgumentException ( storageCode + " 未找到对应点位 " ) ;
}
return location ;
}
private TaskLocation resolveOptionalLocation ( String storageCode ) {
if ( StrUtil . isBlank ( storageCode ) ) {
return TaskLocation . empty ( ) ;
}
StorageCell storageCell = new LambdaQueryChainWrapper < > ( storageCellMapper )
. eq ( StorageCell : : getStorage_code , storageCode )
. one ( ) ;
if ( storageCell = = null ) {
return TaskLocation . empty ( ) ;
}
String pointCode = StrUtil . isBlank ( storageCell . getParent_storage_code ( ) )
? storageCode
: storageCell . getStorage_code ( ) ;
return new TaskLocation ( pointCode , getDeviceCode ( pointCode ) ) ;
}
private TaskDto buildTaskDto ( TaskIssueReqVO task ,
TaskLocation startLocation ,
TaskLocation nextLocation ,
TaskLocation startLocation2 ,
TaskLocation nextLocation2 ) {
TaskDto taskDto = new TaskDto ( ) ;
taskDto . setTask_id ( IdUtil . simpleUUID ( ) ) ;
taskDto . setExt_task_id ( task . getTaskId ( ) = = null ? null : String . valueOf ( task . getTaskId ( ) ) ) ;
taskDto . setTask_code ( task . getTaskCode ( ) ) ;
taskDto . setStart_point_code ( startLocation . getPointCode ( ) ) ;
taskDto . setStart_device_code ( startLocation . getDeviceCode ( ) ) ;
taskDto . setNext_point_code ( nextLocation . getPointCode ( ) ) ;
taskDto . setNext_device_code ( nextLocation . getDeviceCode ( ) ) ;
taskDto . setStart_point_code2 ( startLocation2 . getPointCode ( ) ) ;
taskDto . setStart_device_code2 ( startLocation2 . getDeviceCode ( ) ) ;
taskDto . setNext_point_code2 ( nextLocation2 . getPointCode ( ) ) ;
taskDto . setNext_device_code2 ( nextLocation2 . getDeviceCode ( ) ) ;
taskDto . setPriority ( task . getPriority ( ) ) ;
taskDto . setVehicle_code ( task . getVehicleCode ( ) ) ;
taskDto . setVehicle_code2 ( task . getVehicleCode2 ( ) ) ;
taskDto . setTask_type ( StrUtil . blankToDefault ( task . getTaskType ( ) , DEFAULT_TASK_TYPE ) ) ;
taskDto . setRoute_plan_code ( DEFAULT_ROUTE_PLAN_CODE ) ;
taskDto . setRemark ( task . getRemark ( ) ) ;
taskDto . setParamJson ( new JSONObject ( buildTaskParam ( task ) ) ) ;
return taskDto ;
}
private Map < String , Object > buildTaskParam ( TaskIssueReqVO task ) {
Map < String , Object > param = new LinkedHashMap < > ( ) ;
if ( ObjectUtil . isNotEmpty ( task . getPayload ( ) ) ) {
param . putAll ( task . getPayload ( ) ) ;
}
putIfNotBlank ( param , " agvSystemType " , task . getAgvSystemType ( ) ) ;
putIfNotBlank ( param , " productArea " , task . getProductArea ( ) ) ;
putIfNotBlank ( param , " traceId " , task . getTraceId ( ) ) ;
if ( task . getTimestamp ( ) ! = null ) {
param . put ( " timestamp " , task . getTimestamp ( ) ) ;
}
return param ;
}
private void extendBeforeCreate ( TaskIssueReqVO task , TaskDto taskDto ) {
// todo Extend project-specific validation or conversion by taskType/agvSystemType/payload.
}
private void putIfNotBlank ( Map < String , Object > param , String key , String value ) {
if ( StrUtil . isNotBlank ( value ) ) {
param . put ( key , value ) ;
}
}
private String getDeviceCode ( String pointCode ) {
if ( StrUtil . isBlank ( pointCode ) ) {
return pointCode ;
}
return pointCode . contains ( " - " ) ? StrUtil . subBefore ( pointCode , " - " , false ) : pointCode ;
}
private TaskIssueResultRespVO . FailedTask failedTask ( Long taskId , String errorMessage ) {
TaskIssueResultRespVO . FailedTask failedTask = new TaskIssueResultRespVO . FailedTask ( ) ;
failedTask . setTaskId ( taskId ) ;
failedTask . setErrorMessage ( StrUtil . blankToDefault ( errorMessage , " 任务下发失败 " ) ) ;
return failedTask ;
}
private Long getTaskId ( TaskIssueReqVO task ) {
return task = = null ? null : task . getTaskId ( ) ;
}
private String getTaskCode ( TaskIssueReqVO task ) {
return task = = null ? null : task . getTaskCode ( ) ;
}
private static class TaskLocation {
private final String pointCode ;
private final String deviceCode ;
private TaskLocation ( String pointCode , String deviceCode ) {
this . pointCode = pointCode ;
this . deviceCode = deviceCode ;
}
private static TaskLocation empty ( ) {
return new TaskLocation ( null , null ) ;
}
private String getPointCode ( ) {
return pointCode ;
}
private String getDeviceCode ( ) {
return deviceCode ;
}
}
@Override
public OperateCheckRespVO checkEnableOperate ( OperateCheckReqVO task ) {
// todo 检测任务能否取消或者完成,取消和完成判断逻辑一样,不需要管他,先判断指令是否存在,存在则显示不允许操作,