排序推单

uat-temp-wj-shenshanorder
王杰 3 months ago
parent 14dba4b720
commit cae8f9af41

@ -2,6 +2,7 @@ package cn.estsh.i3plus.ext.mes.pcn.api.busi;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.*;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.MesWorkOrderCutDetailModel;
import cn.estsh.i3plus.pojo.mes.bean.MesQueueOrderPush;
import cn.estsh.i3plus.pojo.mes.bean.MesRawPartCharging;
import cn.estsh.i3plus.pojo.mes.bean.shipping.MesShippingQueue;
import cn.estsh.i3plus.pojo.mes.model.StationKvBean;
@ -243,4 +244,10 @@ public interface IMesProductionDispatchContextStepService {
@ApiOperation(value = "保存上下文发运队列信息")
Boolean dispatchShippingQueueContext(StationRequestBean reqBean, MesShippingQueue shippingQueue);
@ApiOperation(value = "获取上下文推单队列信息")
List<MesQueueOrderPush> getSortQueuePushContext(StationRequestBean reqBean);
@ApiOperation(value = "保存上下文推单队列信息")
Boolean dispatchSortQueuePushContext(StationRequestBean reqBean, List<MesQueueOrderPush> queueOrderPushList);
}

@ -17,7 +17,10 @@ import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.TreeSet;
import java.util.stream.Collectors;
@Service
@ -99,7 +102,11 @@ public class MesQueueOrderPushService implements IMesQueueOrderPushService {
if (pushSourceCodeList.size() == 1) DdlPreparedPack.getStringEqualPack(pushSourceCodeList.get(0), MesPcnExtConstWords.PUSH_SOURCE_CODE, packBean);
else DdlPreparedPack.getInPackList(pushSourceCodeList, MesPcnExtConstWords.PUSH_SOURCE_CODE, packBean);
DdlPreparedPack.getOrderByPack(new Object[]{CommonEnumUtil.ASC_OR_DESC.ASC.getValue()}, new String[]{MesPcnExtConstWords.CREATE_DATE_TIME}, packBean);
return queueOrderPushRepository.findByHqlWhere(packBean);
List<MesQueueOrderPush> queueOrderPushList = queueOrderPushRepository.findByHqlWhere(packBean);
//条码去重
return CollectionUtils.isEmpty(queueOrderPushList) ? null :
queueOrderPushList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getProductSn()))).distinct()
.collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(MesQueueOrderPush::getProductSn))), ArrayList::new));
}
}

@ -5,10 +5,13 @@ import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionDispatchContextStepSer
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionProcessContextStepService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesQueueOrderPushService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesCellEquipContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesEquipVariableCollectContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionProcessContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.mes.pcn.actor.shipping.dispatch.IFsmCommonService;
import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseStepService;
import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.IStepService;
import cn.estsh.i3plus.mes.pcn.util.StringUtil;
import cn.estsh.i3plus.platform.common.tool.TimeTool;
import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil;
import cn.estsh.i3plus.pojo.mes.bean.MesQueueOrderPush;
@ -17,6 +20,8 @@ import cn.estsh.i3plus.pojo.mes.model.StationRequestBean;
import cn.estsh.i3plus.pojo.mes.model.StationResultBean;
import cn.estsh.i3plus.pojo.mes.model.StepResult;
import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil;
import cn.estsh.impp.framework.boot.util.SpringContextsUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -110,51 +115,76 @@ public class MesWorkOrderQueueAcceptStepService extends BaseStepService {
//搜集需要考虑加锁的推送来源代码
List<String> pushSourceCodeList = queueOrderPushCellCfgList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getIsNeedLock()))).map(MesQueueOrderPushCellCfg::getPushSourceCode).collect(Collectors.toList());
//验证是否执行加锁
//当前即将执行的接收队列
List<MesQueueOrderPush> curPushList = null;
for (MesQueueOrderPush queueOrderPush : queueOrderPushList) {
if (null == queueOrderPush) continue;
//当前遍历中的代码不考虑加锁
if (CollectionUtils.isEmpty(pushSourceCodeList) || !pushSourceCodeList.contains(queueOrderPush.getPushSourceCode())) {
if (CollectionUtils.isEmpty(curPushList)) curPushList = new ArrayList<>();
curPushList.add(queueOrderPush);
//满足腔数的情况下退出循环
if (curPushList.size() >= cellEquipContext.getCavity()) break;
} else {
//当前遍历中的代码考虑加锁; 获取不到锁的情况下退出循环
if (!tryLock(reqBean.getWorkCenterCode(), queueOrderPush.getPushSourceCode())) break;
List<String> queuePushIdList = productionCustomContextStepService.getSortQueuePushLockContext(reqBean.getOrganizeCode(), reqBean.getWorkCenterCode());
if (!CollectionUtils.isEmpty(queuePushIdList) && queuePushIdList.contains(queueOrderPush.getId().toString())) continue;
}
}
try {
//验证是否执行加锁
for (MesQueueOrderPush queueOrderPush : queueOrderPushList) {
if (null == queueOrderPush || StringUtils.isEmpty(queueOrderPush.getWorkOrderNo())) continue;
//当前遍历中的代码不考虑加锁
if (CollectionUtils.isEmpty(pushSourceCodeList) || !pushSourceCodeList.contains(queueOrderPush.getPushSourceCode())) {
if (CollectionUtils.isEmpty(curPushList)) curPushList = new ArrayList<>();
curPushList.add(queueOrderPush);
//满足腔数的情况下退出循环
if (curPushList.size() >= cellEquipContext.getCavity()) break;
} else {
//当前遍历中的代码考虑加锁; 获取不到锁的情况下退出循环
if (!tryLock(reqBean.getWorkCenterCode(), queueOrderPush.getPushSourceCode())) break;
List<String> queuePushIdList = productionCustomContextStepService.getSortQueuePushLockContext(reqBean.getOrganizeCode(), reqBean.getWorkCenterCode());
if (!CollectionUtils.isEmpty(queuePushIdList) && queuePushIdList.contains(queueOrderPush.getId().toString())) continue;
}
//验证是否执行解锁
if (!CollectionUtils.isEmpty(curPushList)) {
for (MesQueueOrderPush queueOrderPush : curPushList) {
if (null == queueOrderPush) continue;
if (CollectionUtils.isEmpty(pushSourceCodeList) || !pushSourceCodeList.contains(queueOrderPush.getPushSourceCode())) continue;
//当需要考虑加锁且满足腔数的情况下, 保存排序线工单队列推送锁数据
if (curPushList.size() >= cellEquipContext.getCavity()) productionCustomContextStepService.dispatchSortQueuePushLockContext(reqBean.getOrganizeCode(), reqBean.getWorkCenterCode(), queueOrderPush.getId().toString());
//解锁
unLock(reqBean.getWorkCenterCode(), queueOrderPush.getPushSourceCode());
}
}
//验证是否满足腔数
if (CollectionUtils.isEmpty(curPushList) || curPushList.size() < cellEquipContext.getCavity()) {
return stepDynamicsCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog().checkRepeat(), stepResult,
false, MesPcnEnumUtil.STATION_BUSI_TYPE.GUIDE, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT,
CollectionUtils.isEmpty(queueOrderPushList) ? "当前未接收到工位工单队列,持续监听中..." : String.format("当前接收到到工位工单队列个数[%s]不满足腔数[%s],持续监听中...", queueOrderPushList.size(), cellEquipContext.getCavity()),
getStepParams(reqBean), MesPcnExtConstWords.READ_FAILURE_SLEEP, MesPcnExtConstWords.READ_FAILURE_SLEEP_DEFAULT_TIME);
}
//验证是否满足腔数
if (CollectionUtils.isEmpty(curPushList) || curPushList.size() < cellEquipContext.getCavity()) {
return stepDynamicsCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog().checkRepeat(), stepResult,
false, MesPcnEnumUtil.STATION_BUSI_TYPE.GUIDE, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT,
CollectionUtils.isEmpty(curPushList) ? "当前未接收到工位工单队列,持续监听中..." : String.format("当前接收到到工位工单队列个数[%s]不满足腔数[%s],持续监听中...", curPushList.size(), cellEquipContext.getCavity()),
getStepParams(reqBean), MesPcnExtConstWords.READ_FAILURE_SLEEP, MesPcnExtConstWords.READ_FAILURE_SLEEP_DEFAULT_TIME);
}
//搜集工单号
List<String> workOrderNoList = curPushList.stream().filter(o -> null != o).map(MesQueueOrderPush::getWorkOrderNo).collect(Collectors.toList());
//发送工步内容
productionCustomContextStepService.sendStepContextMessage(reqBean, workOrderNoList.toString(), MesExtEnumUtil.CELL_MESSAGE_SOURCE.READ);
List<MesEquipVariableCollectContext> equipVariableCollectContextList = new ArrayList<>();
workOrderNoList.stream().filter(o -> !StringUtils.isEmpty(o)).forEach(o ->
equipVariableCollectContextList.add(new MesEquipVariableCollectContext(reqBean.getOrganizeCode(), o, MesExtEnumUtil.CELL_MESSAGE_SOURCE.READ.getValue())));
//保存上下文扫/读信息:加工单
productionDispatchContextStepService.dispatchScanWorkOrderNoContext(reqBean, equipVariableCollectContextList);
this.sendMessage(reqBean, new StationResultBean().writeDbLog(), String.format("获取到工位工单推送队列%s!", workOrderNoList.toString()), MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT);
log.info("工厂{}生产线{}工位{}:FSM STATE DISPATCHER --- DO STEP --- {} EXEC --- QUEUE_ORDER_PUSH:{}",
reqBean.getOrganizeCode(), reqBean.getWorkCenterCode(), reqBean.getWorkCellCode(), StringUtil.toLowerCaseFirst(this.getClass().getSimpleName()), JSONObject.toJSONString(curPushList));
//加工单验证工步 【排序】
stepResult = ((IStepService) SpringContextsUtil.getBean("mesWorkOrderCheckSortStepService")).executeInState(reqBean);
//保存上下文推单信息
if (stepResult.isCompleted()) productionDispatchContextStepService.dispatchSortQueuePushContext(reqBean, curPushList);
return stepResult;
return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.PROCESS.getValue()), stepResult, "工位工单接收成功!");
} finally {
//验证是否执行解锁
if (!CollectionUtils.isEmpty(curPushList)) {
for (MesQueueOrderPush queueOrderPush : curPushList) {
if (null == queueOrderPush) continue;
if (CollectionUtils.isEmpty(pushSourceCodeList) || !pushSourceCodeList.contains(queueOrderPush.getPushSourceCode())) continue;
//当需要考虑加锁且满足腔数的情况下, 保存排序线工单队列推送锁数据
if (curPushList.size() >= cellEquipContext.getCavity()) productionCustomContextStepService.dispatchSortQueuePushLockContext(reqBean.getOrganizeCode(), reqBean.getWorkCenterCode(), queueOrderPush.getId().toString());
//解锁
unLock(reqBean.getWorkCenterCode(), queueOrderPush.getPushSourceCode());
}
}
}
}
@ -163,8 +193,8 @@ public class MesWorkOrderQueueAcceptStepService extends BaseStepService {
try {
String key = new StringJoiner(MesPcnExtConstWords.AND).add(workCenterCode).add(pushSourceCode).toString();
ReentrantLock lock = lockMap.computeIfAbsent(key, item -> new ReentrantLock(true));
//拿不到锁的情况下监控锁是否已经超时
if (!lock.tryLock(MesPcnExtConstWords.ONE_HUNDRED, TimeUnit.MILLISECONDS) && checkTimeOut(key, lock)) return false;
//500ms内拿不到锁的情况下监控锁是否已经超时
if (!lock.tryLock(MesPcnExtConstWords.FIVE_HUNDRED, TimeUnit.MILLISECONDS) && checkTimeOut(key, lock)) return false;
lockTimeMap.put(key, TimeTool.getNowTime(true));
return true;
} catch (InterruptedException e) {

@ -6,6 +6,7 @@ import cn.estsh.i3plus.ext.mes.pcn.pojo.model.MesWorkOrderCutDetailModel;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseStepService;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.mes.bean.MesQueueOrderPush;
import cn.estsh.i3plus.pojo.mes.bean.MesRawPartCharging;
import cn.estsh.i3plus.pojo.mes.bean.shipping.MesShippingQueue;
import cn.estsh.i3plus.pojo.mes.model.StationKvBean;
@ -550,4 +551,18 @@ public class MesProductionDispatchContextStepService extends BaseStepService imp
return dispatchFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.SHIPPING_QUEUE_CONTEXT, JSONObject.toJSONString(shippingQueue));
}
//获取上下文推单队列信息
@Override
public List<MesQueueOrderPush> getSortQueuePushContext(StationRequestBean reqBean) {
String sortQueuePushJson = getFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.QUEUE_PUSH_CONTEXT);
return !StringUtils.isEmpty(sortQueuePushJson) ? JSONObject.parseArray(sortQueuePushJson, MesQueueOrderPush.class) : null;
}
//保存上下文推单队列信息
@Override
public Boolean dispatchSortQueuePushContext(StationRequestBean reqBean, List<MesQueueOrderPush> queueOrderPushList) {
if (CollectionUtils.isEmpty(queueOrderPushList)) return false;
return dispatchFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.QUEUE_PUSH_CONTEXT, JSONObject.toJSONString(queueOrderPushList));
}
}

@ -629,10 +629,12 @@ public class MesPcnExtConstWords {
public static final String EQUIP_SPOT_CHECK_CONTEXT = "EQUIP_SPOT_CHECK_CONTEXT";
// 加工不可用规则上下文
public static final String PROD_RULE_IGNORE_CFG_CONTEXT = "PROD_RULE_IGNORE_CFG_CONTEXT";
// 队列推送配置上下文
// 推送队列配置上下文
public static final String QUEUE_PUSH_CFG_CONTEXT = "QUEUE_PUSH_CFG_CONTEXT";
// 队列推送锁上下文
// 推送队列锁上下文
public static final String QUEUE_PUSH_LOCK_CONTEXT = "QUEUE_PUSH_LOCK_CONTEXT";
// 推送队列上下文
public static final String QUEUE_PUSH_CONTEXT = "QUEUE_PUSH_CONTEXT";
// 上下文: 展示组件数据
public static final String MODULE_CONTENT_CONTEXT = "MODULE_CONTENT_CONTEXT";

Loading…
Cancel
Save