| | |
| | | import com.core.common.Cools; |
| | | import com.zy.asrs.domain.param.CreateInTaskParam; |
| | | import com.zy.asrs.entity.BasDevp; |
| | | import com.zy.asrs.entity.WrkLastno; |
| | | import com.zy.asrs.entity.WrkMast; |
| | | import com.zy.asrs.service.WrkLastnoService; |
| | | import com.zy.asrs.service.WrkMastService; |
| | | import com.zy.common.model.StartupDto; |
| | | import com.zy.common.service.CommonService; |
| | | import com.zy.common.utils.RedisUtil; |
| | | import com.zy.core.News; |
| | | import com.zy.core.cache.SlaveConnection; |
| | | import com.zy.core.dispatch.StationCommandDispatchResult; |
| | | import com.zy.core.dispatch.StationCommandDispatcher; |
| | | import com.zy.core.enums.RedisKeyType; |
| | | import com.zy.core.enums.SlaveType; |
| | | import com.zy.core.enums.StationCommandType; |
| | | import com.zy.core.enums.WrkIoType; |
| | | import com.zy.core.model.StationObjModel; |
| | | import com.zy.core.model.command.StationCommand; |
| | | import com.zy.core.model.protocol.StationProtocol; |
| | | import com.zy.core.task.MainProcessLane; |
| | | import com.zy.core.task.MainProcessTaskSubmitter; |
| | |
| | | @Service |
| | | public class StoreInTaskGenerationService { |
| | | private static final int APPLY_IN_TASK_TIMEOUT_SECONDS = 5; |
| | | private static final int APPLY_FAIL_STATION_BACK_LOCK_SECONDS = 30; |
| | | |
| | | @Autowired |
| | | private WrkMastService wrkMastService; |
| | |
| | | private CommonService commonService; |
| | | @Autowired |
| | | private MainProcessTaskSubmitter mainProcessTaskSubmitter; |
| | | @Autowired |
| | | private StationCommandDispatcher stationCommandDispatcher; |
| | | @Autowired |
| | | private WrkLastnoService wrkLastnoService; |
| | | |
| | | /** |
| | | * 保留当前按站点 lane 并发的能力,同时用一个简单计数避免并发生成把站点任务数顶穿上限。 |
| | |
| | | public void generate(StoreInTaskPolicy policy, BasDevp basDevp, StationObjModel stationObjModel) { |
| | | try { |
| | | if (!policy.isEnabled()) { |
| | | return; |
| | | } |
| | | |
| | | StoreInTaskContext earlyContext = buildContext(basDevp, stationObjModel); |
| | | if (earlyContext == null || !handleErrorStationBack(earlyContext)) { |
| | | return; |
| | | } |
| | | |
| | |
| | | return; |
| | | } |
| | | |
| | | long count = wrkMastService.count(new QueryWrapper<WrkMast>().eq("barcode", context.getStationProtocol().getBarcode())); |
| | | if (!stationProtocol.getIoMode().equals(1)) { |
| | | policy.setSystemWarning(context, "当前站点不处于入库模式"); |
| | | return; |
| | | } |
| | | |
| | | String barcode = context.getStationProtocol().getBarcode(); |
| | | long count = wrkMastService.count(new QueryWrapper<WrkMast>().eq("barcode", barcode)); |
| | | if (count > 0) { |
| | | policy.setSystemWarning(context, "系统任务已存在"); |
| | | Object tipsLimit = redisUtil.get(RedisKeyType.GENERATE_IN_TASK_SUCCESS_REPEAT_WARNING_TIPS_LIMIT.key + barcode); |
| | | if (tipsLimit == null) { |
| | | policy.setSystemWarning(context, "系统任务已存在"); |
| | | } |
| | | return; |
| | | } |
| | | |
| | |
| | | } finally { |
| | | releaseGenerateCapacity(); |
| | | } |
| | | } |
| | | |
| | | private boolean handleErrorStationBack(StoreInTaskContext context) { |
| | | StationProtocol stationProtocol = context.getStationProtocol(); |
| | | if (stationProtocol == null) { |
| | | return false; |
| | | } |
| | | |
| | | if (!stationProtocol.isAutoing()) { |
| | | return false; |
| | | } |
| | | |
| | | if (!stationProtocol.isLoading()) { |
| | | return false; |
| | | } |
| | | |
| | | if (stationProtocol.getError() <= 0) { |
| | | return true; |
| | | } |
| | | |
| | | if (!stationProtocol.isInBarcodeError()) { |
| | | return true; |
| | | } |
| | | |
| | | WrkLastno stationBackTaskRange = wrkLastnoService.getById(WrkIoType.STATION_BACK.id); |
| | | Integer currentTaskNo = stationProtocol.getTaskNo(); |
| | | if (currentTaskNo != null |
| | | && currentTaskNo > 0 |
| | | && stationBackTaskRange != null |
| | | && stationBackTaskRange.getsNo() != null |
| | | && stationBackTaskRange.geteNo() != null |
| | | && currentTaskNo >= stationBackTaskRange.getsNo() |
| | | && currentTaskNo <= stationBackTaskRange.geteNo()) { |
| | | News.info("条码站已处于退回工作号范围,跳过重复生成退回命令。stationId={},taskNo={},range=[{}, {}]", |
| | | stationProtocol.getStationId(), |
| | | currentTaskNo, |
| | | stationBackTaskRange.getsNo(), |
| | | stationBackTaskRange.geteNo()); |
| | | return false; |
| | | } |
| | | |
| | | StationObjModel backStation = context.getStationObjModel().getBackStation(); |
| | | if (backStation == null || backStation.getStationId() == null) { |
| | | News.warn("条码站退回失败,退回站未配置。deviceNo={},stationId={}", |
| | | context.getBasDevp() == null ? null : context.getBasDevp().getDevpNo(), |
| | | stationProtocol.getStationId()); |
| | | return false; |
| | | } |
| | | |
| | | if (stationProtocol.getTaskNo() != null |
| | | && stationProtocol.getTaskNo() > 0 |
| | | && backStation.getStationId().equals(stationProtocol.getTargetStaNo())) { |
| | | return false; |
| | | } |
| | | |
| | | Object lock = redisUtil.get(RedisKeyType.GENERATE_STATION_BACK_LIMIT.key + stationProtocol.getStationId()); |
| | | if (lock != null) { |
| | | return false; |
| | | } |
| | | |
| | | StationCommand command = context.getStationThread().getCommand(StationCommandType.MOVE, |
| | | commonService.getWorkNo(WrkIoType.STATION_BACK.id), |
| | | context.getStationObjModel().getStationId(), |
| | | backStation.getStationId(), 0); |
| | | if (command == null) { |
| | | News.taskInfo(stationProtocol.getTaskNo(), "{}工作,获取输送线命令失败", stationProtocol.getTaskNo()); |
| | | return false; |
| | | } |
| | | stationCommandDispatcher.dispatch(context.getBasDevp().getDevpNo(), command, "store-in-task", "station-back"); |
| | | News.info("{}扫码站异常,已退回至{},条码站状态:{}", stationProtocol.getTaskNo(), |
| | | backStation.getStationId(), JSON.toJSONString(stationProtocol)); |
| | | redisUtil.set(RedisKeyType.GENERATE_STATION_BACK_LIMIT.key + stationProtocol.getStationId(), |
| | | "lock", 60 * 60); |
| | | return false; |
| | | } |
| | | |
| | | private StoreInTaskContext buildContext(BasDevp basDevp, StationObjModel stationObjModel) { |
| | |
| | | WrkMast wrkMast = commonService.createInTask(taskParam); |
| | | policy.afterTaskCreated(context, wrkMast); |
| | | policy.clearSystemWarning(context); |
| | | redisUtil.set(RedisKeyType.GENERATE_IN_TASK_SUCCESS_REPEAT_WARNING_TIPS_LIMIT.key + wrkMast.getBarcode(), "lock", 30); |
| | | } catch (Exception e) { |
| | | News.error("处理WMS入库响应异常,barcode={},stationId={}", request.getBarcode(), |
| | | request.getSourceStaNo(), e); |
| | |
| | | result.setResponse(response); |
| | | result.setMessage(message); |
| | | |
| | | News.error("WMS入库请求失败,barcode={},stationId={},response={}", |
| | | request.getBarcode(), request.getSourceStaNo(), policy.buildFailureMessage(result)); |
| | | News.error("WMS入库请求失败,barcode={},stationId={},response={},WCS响应={}", |
| | | request.getBarcode(), request.getSourceStaNo(), result.getResponse(), result.getMessage()); |
| | | redisUtil.set(policy.getGenerateLockKey(context), "lock", policy.getRetryLockSeconds(context)); |
| | | policy.onApplyFailed(context, result); |
| | | triggerStationBackOnApplyFailed(context, request, result); |
| | | } |
| | | |
| | | /** |
| | | * WMS 申请入库失败后,货物仍停留在扫码站,此时补发退回到入库站的输送命令,避免货物长期滞留。 |
| | | */ |
| | | private void triggerStationBackOnApplyFailed(StoreInTaskContext context, |
| | | InTaskApplyRequest request, |
| | | InTaskApplyResult result) { |
| | | if (context == null || context.getStationThread() == null || context.getStationObjModel() == null) { |
| | | return; |
| | | } |
| | | |
| | | StationProtocol stationProtocol = context.getStationProtocol(); |
| | | if (stationProtocol == null || stationProtocol.getStationId() == null) { |
| | | return; |
| | | } |
| | | |
| | | StationObjModel backStation = context.getStationObjModel().getBackStation(); |
| | | if (backStation == null || backStation.getStationId() == null) { |
| | | News.warn("WMS入库失败后无法退回入库站,退回站未配置。barcode={},stationId={}", |
| | | request == null ? null : request.getBarcode(), stationProtocol.getStationId()); |
| | | return; |
| | | } |
| | | |
| | | Integer currentStationId = stationProtocol.getStationId(); |
| | | Integer backStationId = backStation.getStationId(); |
| | | if (backStationId.equals(currentStationId)) { |
| | | return; |
| | | } |
| | | |
| | | if (stationProtocol.getTaskNo() != null |
| | | && stationProtocol.getTaskNo() > 0 |
| | | && backStationId.equals(stationProtocol.getTargetStaNo())) { |
| | | return; |
| | | } |
| | | |
| | | String lockKey = RedisKeyType.GENERATE_STATION_BACK_LIMIT.key |
| | | + currentStationId + "_" + stationProtocol.getTaskNo(); |
| | | if (redisUtil.get(lockKey) != null) { |
| | | return; |
| | | } |
| | | |
| | | Integer stationBackTaskNo = commonService.getWorkNo(WrkIoType.STATION_BACK.id); |
| | | StationCommand command = context.getStationThread().getCommand( |
| | | StationCommandType.MOVE, |
| | | stationBackTaskNo, |
| | | currentStationId, |
| | | backStationId, |
| | | 0 |
| | | ); |
| | | if (command == null) { |
| | | News.warn("WMS入库失败后生成退回入库站命令失败。barcode={},stationId={},backStationId={},warning={}", |
| | | request == null ? null : request.getBarcode(), |
| | | currentStationId, |
| | | backStationId, |
| | | result == null ? null : result.getMessage()); |
| | | return; |
| | | } |
| | | |
| | | StationCommandDispatchResult dispatchResult = stationCommandDispatcher.dispatch( |
| | | context.getBasDevp().getDevpNo(), |
| | | command, |
| | | "store-in-task-generation", |
| | | "apply-failed-station-back" |
| | | ); |
| | | if (!dispatchResult.isAccepted()) { |
| | | News.warn("WMS入库失败后退回入库站命令入队失败。barcode={},stationId={},backStationId={},reason={},warning={}", |
| | | request == null ? null : request.getBarcode(), |
| | | currentStationId, |
| | | backStationId, |
| | | dispatchResult.getReason(), |
| | | result == null ? null : result.getMessage()); |
| | | return; |
| | | } |
| | | |
| | | redisUtil.set(lockKey, "lock", APPLY_FAIL_STATION_BACK_LOCK_SECONDS); |
| | | News.warn("WMS入库失败,已触发货物退回入库站。barcode={},stationId={},backStationId={},warning={}", |
| | | request == null ? null : request.getBarcode(), |
| | | currentStationId, |
| | | backStationId, |
| | | result == null ? null : result.getMessage()); |
| | | } |
| | | |
| | | private HashMap<String, String> getSystemConfigMap() { |