package com.zy.asrs.task;
|
|
import com.alibaba.fastjson.JSON;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.zy.asrs.domain.enums.NotifyMsgType;
|
import com.zy.asrs.entity.BasStation;
|
import com.zy.asrs.entity.LocMast;
|
import com.zy.asrs.entity.WrkMast;
|
import com.zy.asrs.entity.WrkMastLog;
|
import com.zy.asrs.service.BasStationService;
|
import com.zy.asrs.service.LocMastService;
|
import com.zy.asrs.service.WrkAnalysisService;
|
import com.zy.asrs.service.WrkMastLogService;
|
import com.zy.asrs.service.WrkMastService;
|
import com.zy.asrs.utils.NotifyUtils;
|
import com.zy.common.utils.RedisUtil;
|
import com.zy.core.cache.SlaveConnection;
|
import com.zy.core.enums.LocStsType;
|
import com.zy.core.enums.RedisKeyType;
|
import com.zy.core.enums.SlaveType;
|
import com.zy.core.enums.WrkIoType;
|
import com.zy.core.enums.WrkStsType;
|
import com.zy.core.thread.StationThread;
|
import com.zy.core.utils.StationOperateProcessUtils;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.stereotype.Component;
|
import org.springframework.transaction.annotation.Transactional;
|
|
import java.util.Arrays;
|
import java.util.Date;
|
import java.util.List;
|
import java.util.Objects;
|
import java.util.UUID;
|
|
@Component
|
@Slf4j
|
public class WrkMastFinalizeProcessor {
|
|
private static final int WRK_LOCK_SECONDS = 30;
|
private static final List<String> CANCEL_MKS = Arrays.asList("taskCancel", "taskForceCancel");
|
|
private final WrkMastService wrkMastService;
|
private final WrkMastLogService wrkMastLogService;
|
private final WrkAnalysisService wrkAnalysisService;
|
private final LocMastService locMastService;
|
private final NotifyUtils notifyUtils;
|
private final StationOperateProcessUtils stationOperateProcessUtils;
|
private final BasStationService basStationService;
|
private final RedisUtil redisUtil;
|
|
public WrkMastFinalizeProcessor(WrkMastService wrkMastService,
|
WrkMastLogService wrkMastLogService,
|
WrkAnalysisService wrkAnalysisService,
|
LocMastService locMastService,
|
NotifyUtils notifyUtils,
|
StationOperateProcessUtils stationOperateProcessUtils,
|
BasStationService basStationService,
|
RedisUtil redisUtil) {
|
this.wrkMastService = wrkMastService;
|
this.wrkMastLogService = wrkMastLogService;
|
this.wrkAnalysisService = wrkAnalysisService;
|
this.locMastService = locMastService;
|
this.notifyUtils = notifyUtils;
|
this.stationOperateProcessUtils = stationOperateProcessUtils;
|
this.basStationService = basStationService;
|
this.redisUtil = redisUtil;
|
}
|
|
@Transactional(rollbackFor = Exception.class)
|
public void processCompleteInbound(Integer wrkNo) {
|
processWithLock(wrkNo, () -> {
|
WrkMast wrkMast = wrkMastService.selectByWorkNo(wrkNo);
|
if (wrkMast == null) {
|
log.error("入库完成清理跳过,未找到工作档。wrkNo={}", wrkNo);
|
return;
|
}
|
if (!Objects.equals(wrkMast.getWrkSts(), WrkStsType.COMPLETE_INBOUND.sts)) {
|
log.error("入库完成清理跳过,工作状态不匹配。wrkNo={}, wrkSts={}", wrkNo, wrkMast.getWrkSts());
|
return;
|
}
|
|
Integer taskNo = wrkMast.getWrkNo();
|
Integer sourceStaNo = wrkMast.getSourceStaNo();
|
Integer staNo = wrkMast.getStaNo();
|
LocMast locMast = locMastService.queryByLoc(wrkMast.getLocNo());
|
if (locMast == null) {
|
log.error("入库完成清理跳过,目标库位不存在。wrkNo={}, locNo={}", wrkNo, wrkMast.getLocNo());
|
return;
|
}
|
if (!"S".equals(locMast.getLocSts())) {
|
log.error("入库完成清理跳过,目标库位状态不为S。wrkNo={}, locNo={}, locSts={}", wrkNo, wrkMast.getLocNo(), locMast.getLocSts());
|
return;
|
}
|
|
locMast.setLocSts("F");
|
locMast.setBarcode(wrkMast.getBarcode());
|
locMast.setModiTime(new Date());
|
if (!locMastService.updateById(locMast)) {
|
log.error("入库完成清理失败,目标库位更新失败。wrkNo={}, locNo={}", wrkNo, wrkMast.getLocNo());
|
throw new IllegalStateException("入库完成清理更新目标库位失败,事务回滚。wrkNo=" + wrkNo + ", locNo=" + wrkMast.getLocNo());
|
}
|
|
archiveAndFinish(wrkMast);
|
if (wrkMastService.deleteByWrkNoAndCurrentWrkSts(wrkMast.getWrkNo(), WrkStsType.COMPLETE_INBOUND.sts) <= 0) {
|
log.error("入库完成清理失败,删除工作档失败或状态已变化。wrkNo={}", wrkNo);
|
throw new IllegalStateException("入库完成清理删除工作档失败,事务回滚。wrkNo=" + wrkNo);
|
}
|
|
notifyUtils.notify("task", 1, String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.TASK_COMPLETE, JSON.toJSONString(wrkMast));
|
clearTaskPath(taskNo, sourceStaNo, staNo);
|
});
|
}
|
|
@Transactional(rollbackFor = Exception.class)
|
public void processCompleteOutbound(Integer wrkNo) {
|
processWithLock(wrkNo, () -> {
|
WrkMast wrkMast = wrkMastService.selectByWorkNo(wrkNo);
|
if (wrkMast == null) {
|
log.error("出库完成清理跳过,未找到工作档。wrkNo={}", wrkNo);
|
return;
|
}
|
if (!Objects.equals(wrkMast.getWrkSts(), WrkStsType.COMPLETE_OUTBOUND.sts)) {
|
log.error("出库完成清理跳过,工作状态不匹配。wrkNo={}, wrkSts={}", wrkNo, wrkMast.getWrkSts());
|
return;
|
}
|
|
Integer taskNo = wrkMast.getWrkNo();
|
Integer sourceStaNo = wrkMast.getSourceStaNo();
|
Integer staNo = wrkMast.getStaNo();
|
LocMast locMast = locMastService.queryByLoc(wrkMast.getSourceLocNo());
|
if (locMast == null) {
|
log.error("出库完成清理跳过,源库位不存在。wrkNo={}, sourceLocNo={}", wrkNo, wrkMast.getSourceLocNo());
|
return;
|
}
|
if (!("R".equals(locMast.getLocSts()) || "O".equals(locMast.getLocSts()))) {
|
log.error("出库完成清理跳过,源库位状态异常。wrkNo={}, sourceLocNo={}, locSts={}", wrkNo, wrkMast.getSourceLocNo(), locMast.getLocSts());
|
return;
|
}
|
|
locMast.setLocSts("O");
|
locMast.setBarcode("");
|
locMast.setModiTime(new Date());
|
if (!locMastService.updateById(locMast)) {
|
log.error("出库完成清理失败,源库位更新失败。wrkNo={}, sourceLocNo={}", wrkNo, wrkMast.getSourceLocNo());
|
throw new IllegalStateException("出库完成清理更新源库位失败,事务回滚。wrkNo=" + wrkNo + ", sourceLocNo=" + wrkMast.getSourceLocNo());
|
}
|
|
archiveAndFinish(wrkMast);
|
if (wrkMastService.deleteByWrkNoAndCurrentWrkSts(wrkMast.getWrkNo(), WrkStsType.COMPLETE_OUTBOUND.sts) <= 0) {
|
log.error("出库完成清理失败,删除工作档失败或状态已变化。wrkNo={}", wrkNo);
|
throw new IllegalStateException("出库完成清理删除工作档失败,事务回滚。wrkNo=" + wrkNo);
|
}
|
|
notifyUtils.notify("task", 1, String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.TASK_COMPLETE, JSON.toJSONString(wrkMast));
|
clearTaskPath(taskNo, sourceStaNo, staNo);
|
});
|
}
|
|
@Transactional(rollbackFor = Exception.class)
|
public void processCompleteLocMove(Integer wrkNo) {
|
processWithLock(wrkNo, () -> {
|
WrkMast wrkMast = wrkMastService.selectByWorkNo(wrkNo);
|
if (wrkMast == null) {
|
log.error("移库完成清理跳过,未找到工作档。wrkNo={}", wrkNo);
|
return;
|
}
|
if (!Objects.equals(wrkMast.getWrkSts(), WrkStsType.COMPLETE_LOC_MOVE.sts)) {
|
log.error("移库完成清理跳过,工作状态不匹配。wrkNo={}, wrkSts={}", wrkNo, wrkMast.getWrkSts());
|
return;
|
}
|
|
LocMast locMast = locMastService.queryByLoc(wrkMast.getLocNo());
|
LocMast sourceLocMast = locMastService.queryByLoc(wrkMast.getSourceLocNo());
|
if (locMast == null || sourceLocMast == null) {
|
log.error("移库完成清理跳过,源库位或目标库位不存在。wrkNo={}, sourceLocNo={}, locNo={}", wrkNo, wrkMast.getSourceLocNo(), wrkMast.getLocNo());
|
return;
|
}
|
if (!"S".equals(locMast.getLocSts()) || !"R".equals(sourceLocMast.getLocSts())) {
|
log.error("移库完成清理跳过,库位状态异常。wrkNo={}, sourceLocNo={}, sourceLocSts={}, locNo={}, locSts={}",
|
wrkNo, wrkMast.getSourceLocNo(), sourceLocMast.getLocSts(), wrkMast.getLocNo(), locMast.getLocSts());
|
return;
|
}
|
|
locMast.setLocSts("F");
|
locMast.setBarcode(wrkMast.getBarcode());
|
locMast.setModiTime(new Date());
|
if (!locMastService.updateById(locMast)) {
|
log.error("移库完成清理失败,目标库位更新失败。wrkNo={}, locNo={}", wrkNo, wrkMast.getLocNo());
|
throw new IllegalStateException("移库完成清理更新目标库位失败,事务回滚。wrkNo=" + wrkNo + ", locNo=" + wrkMast.getLocNo());
|
}
|
|
sourceLocMast.setLocSts("O");
|
sourceLocMast.setBarcode("");
|
sourceLocMast.setModiTime(new Date());
|
if (!locMastService.updateById(sourceLocMast)) {
|
log.error("移库完成清理失败,源库位更新失败。wrkNo={}, sourceLocNo={}", wrkNo, wrkMast.getSourceLocNo());
|
throw new IllegalStateException("移库完成清理更新源库位失败,事务回滚。wrkNo=" + wrkNo + ", sourceLocNo=" + wrkMast.getSourceLocNo());
|
}
|
|
archiveAndFinish(wrkMast);
|
if (wrkMastService.deleteByWrkNoAndCurrentWrkSts(wrkMast.getWrkNo(), WrkStsType.COMPLETE_LOC_MOVE.sts) <= 0) {
|
log.error("移库完成清理失败,删除工作档失败或状态已变化。wrkNo={}", wrkNo);
|
throw new IllegalStateException("移库完成清理删除工作档失败,事务回滚。wrkNo=" + wrkNo);
|
}
|
|
notifyUtils.notify("task", 1, String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.TASK_COMPLETE, JSON.toJSONString(wrkMast));
|
});
|
}
|
|
@Transactional(rollbackFor = Exception.class)
|
public void processCompleteCrnMove(Integer wrkNo) {
|
processWithLock(wrkNo, () -> {
|
WrkMast wrkMast = wrkMastService.selectByWorkNo(wrkNo);
|
if (wrkMast == null) {
|
log.error("堆垛机移位完成清理跳过,未找到工作档。wrkNo={}", wrkNo);
|
return;
|
}
|
if (!Objects.equals(wrkMast.getWrkSts(), WrkStsType.COMPLETE_CRN_MOVE.sts)) {
|
log.error("堆垛机移位完成清理跳过,工作状态不匹配。wrkNo={}, wrkSts={}", wrkNo, wrkMast.getWrkSts());
|
return;
|
}
|
archiveAndFinish(wrkMast);
|
if (wrkMastService.deleteByWrkNoAndCurrentWrkSts(wrkMast.getWrkNo(), WrkStsType.COMPLETE_CRN_MOVE.sts) <= 0) {
|
log.error("堆垛机移位完成清理失败,删除工作档失败或状态已变化。wrkNo={}", wrkNo);
|
throw new IllegalStateException("堆垛机移位完成清理删除工作档失败,事务回滚。wrkNo=" + wrkNo);
|
}
|
});
|
}
|
|
@Transactional(rollbackFor = Exception.class)
|
public void processCancelTask(Integer wrkNo) {
|
processWithLock(wrkNo, () -> {
|
WrkMast wrkMast = wrkMastService.selectByWorkNo(wrkNo);
|
if (wrkMast == null) {
|
log.error("取消任务清理跳过,未找到工作档。wrkNo={}", wrkNo);
|
return;
|
}
|
if (wrkMast.getMk() == null || !CANCEL_MKS.contains(wrkMast.getMk())) {
|
log.error("取消任务清理跳过,取消标记不匹配。wrkNo={}, mk={}", wrkNo, wrkMast.getMk());
|
return;
|
}
|
|
archiveAndFinish(wrkMast);
|
if (wrkMastService.deleteByWrkNoAndMkIn(wrkMast.getWrkNo(), CANCEL_MKS) <= 0) {
|
log.error("取消任务清理失败,删除工作档失败或标记已变化。wrkNo={}, mk={}", wrkNo, wrkMast.getMk());
|
throw new IllegalStateException("取消任务清理删除工作档失败,事务回滚。wrkNo=" + wrkNo + ", mk=" + wrkMast.getMk());
|
}
|
|
if (Objects.equals(wrkMast.getIoType(), WrkIoType.IN.id)) {
|
LocMast locMast = locMastService.queryByLoc(wrkMast.getLocNo());
|
if (locMast != null) {
|
locMast.setLocSts(String.valueOf(LocStsType.O));
|
locMast.setModiTime(new Date());
|
if (!locMastService.updateById(locMast)) {
|
throw new IllegalStateException("取消任务清理恢复入库目标库位失败,事务回滚。wrkNo=" + wrkNo + ", locNo=" + wrkMast.getLocNo());
|
}
|
}
|
} else if (Objects.equals(wrkMast.getIoType(), WrkIoType.OUT.id)) {
|
LocMast locMast = locMastService.queryByLoc(wrkMast.getSourceLocNo());
|
if (locMast != null) {
|
locMast.setLocSts(String.valueOf(LocStsType.F));
|
locMast.setModiTime(new Date());
|
if (!locMastService.updateById(locMast)) {
|
throw new IllegalStateException("取消任务清理恢复出库源库位失败,事务回滚。wrkNo=" + wrkNo + ", sourceLocNo=" + wrkMast.getSourceLocNo());
|
}
|
}
|
} else if (Objects.equals(wrkMast.getIoType(), WrkIoType.LOC_MOVE.id)) {
|
LocMast sourceLocMast = locMastService.queryByLoc(wrkMast.getSourceLocNo());
|
LocMast locMast = locMastService.queryByLoc(wrkMast.getLocNo());
|
if (sourceLocMast != null && String.valueOf(LocStsType.R).equals(sourceLocMast.getLocSts())) {
|
sourceLocMast.setLocSts(String.valueOf(LocStsType.F));
|
sourceLocMast.setModiTime(new Date());
|
if (!locMastService.updateById(sourceLocMast)) {
|
throw new IllegalStateException("取消任务清理恢复移库源库位失败,事务回滚。wrkNo=" + wrkNo + ", sourceLocNo=" + wrkMast.getSourceLocNo());
|
}
|
}
|
if (locMast != null && String.valueOf(LocStsType.S).equals(locMast.getLocSts())) {
|
locMast.setLocSts(String.valueOf(LocStsType.O));
|
locMast.setModiTime(new Date());
|
if (!locMastService.updateById(locMast)) {
|
throw new IllegalStateException("取消任务清理恢复移库目标库位失败,事务回滚。wrkNo=" + wrkNo + ", locNo=" + wrkMast.getLocNo());
|
}
|
}
|
}
|
|
notifyUtils.notify("task", 1, String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.TASK_CANCEL, JSON.toJSONString(wrkMast));
|
});
|
}
|
|
private void processWithLock(Integer wrkNo, Runnable action) {
|
if (wrkNo == null || wrkNo <= 0 || action == null) {
|
log.error("WrkMastFinalizeProcessor处理跳过,参数非法。wrkNo={}, actionNull={}", wrkNo, action == null);
|
return;
|
}
|
String lockKey = RedisKeyType.WRK_MAST_SCHEDULER_LOCK.key + wrkNo;
|
String lockValue = UUID.randomUUID().toString();
|
if (!redisUtil.trySetStringIfAbsent(lockKey, lockValue, WRK_LOCK_SECONDS)) {
|
log.error("WrkMastFinalizeProcessor获取工作档处理锁失败。wrkNo={}, lockKey={}", wrkNo, lockKey);
|
return;
|
}
|
try {
|
action.run();
|
} catch (Exception e) {
|
log.error("WrkMastFinalizeProcessor处理工作档异常。wrkNo={}", wrkNo, e);
|
throw e;
|
} finally {
|
if (!redisUtil.compareAndDelete(lockKey, lockValue)) {
|
log.error("WrkMastFinalizeProcessor释放工作档处理锁失败。wrkNo={}, lockKey={}", wrkNo, lockKey);
|
}
|
}
|
}
|
|
private void archiveAndFinish(WrkMast wrkMast) {
|
WrkMastLog wrkMastLog = wrkMastLogService.saveRecord(wrkMast.getWrkNo());
|
if (wrkMastLog != null) {
|
wrkAnalysisService.finishTask(wrkMast, resolveFinishTime(wrkMast), wrkMastLog.getId());
|
}
|
}
|
|
private void clearTaskPath(Integer taskNo, Integer sourceStaNo, Integer staNo) {
|
List<BasStation> basStations = basStationService.list(new QueryWrapper<BasStation>().in("station_id", sourceStaNo, staNo));
|
for (BasStation basStation : basStations) {
|
StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, basStation.getDeviceNo());
|
if (stationThread != null) {
|
stationOperateProcessUtils.attemptClearTaskPath(stationThread, taskNo);
|
}
|
}
|
}
|
|
private Date resolveFinishTime(WrkMast wrkMast) {
|
if (wrkMast == null) {
|
return new Date();
|
}
|
if (wrkMast.getModiTime() != null) {
|
return wrkMast.getModiTime();
|
}
|
if (wrkMast.getIoTime() != null) {
|
return wrkMast.getIoTime();
|
}
|
return new Date();
|
}
|
}
|