匹配原料站点工步

mes-uat-changshu0609^2
王杰 2 weeks ago
parent fbea1bb2f3
commit 07ff755b9c

@ -143,4 +143,13 @@ public interface IMesProductionCustomContextStepService {
@ApiOperation(value = "重置原料条码的缓存库存")
void dispatchContainerPackageDetailContext(String organizeCode, Map<String, MesContainerPackageDetailContext> remainQtyMap2Cache);
@ApiOperation(value = "验证主条码或容器条码是否被占用的key")
String getContainerPackageDetailPsKey(String organizeCode, String suffix, String psOrContainerSnAppendId);
@ApiOperation(value = "验证主条码或容器条码是否被占用")
Boolean checkContainerPackageDetailPsIsUsed(StationRequestBean reqBean, String suffix, String psOrContainerSnAppendId);
@ApiOperation(value = "锁定主条码或容器条码")
void dispatchContainerPackageDetailPs(StationRequestBean reqBean, String suffix, String psOrContainerSnAppendId);
}

@ -260,10 +260,19 @@ public interface IMesProductionDispatchContextStepService {
Boolean dispatchSortQueuePushContext(StationRequestBean reqBean, List<MesQueueOrderPush> queueOrderPushList);
@ApiOperation(value = "获取站点用于缺料时进行上料绑定")
List<MesStation> getMatchStationContext(StationRequestBean reqBean);
List<MesStation> getMatchStationContext(StationRequestBean reqBean, String item);
@ApiOperation(value = "保存站点用于缺料时进行上料绑定")
void dispatchMatchStationContext(StationRequestBean reqBean, List<MesStation> stationList);
@ApiOperation(value = "获取装配件站点用于缺料时进行上料绑定")
List<MesStation> getMatchStationAssemblyContext(StationRequestBean reqBean);
@ApiOperation(value = "保存装配件站点用于缺料时进行上料绑定")
void dispatchMatchStationAssemblyContext(StationRequestBean reqBean, List<MesStation> stationList);
@ApiOperation(value = "获取站点用于进料时进行上料绑定")
List<MesStation> getMatchStationProductSnContext(StationRequestBean reqBean);
@ApiOperation(value = "保存站点用于进料时进行上料绑定")
void dispatchMatchStationProductSnContext(StationRequestBean reqBean, List<MesStation> stationList);
@ApiOperation(value = "获取站点用于扣料业务中进行LOCK")
Map<String, MesStation> getLockStationContext(StationRequestBean reqBean);
@ -277,10 +286,4 @@ public interface IMesProductionDispatchContextStepService {
@ApiOperation(value = "保存站点用于缺料时进行上料绑定的容器条码")
void dispatchMatchStationFeedContainerSnContext(StationRequestBean reqBean, String sn);
@ApiOperation(value = "获取站点用于进料时进行上料绑定")
List<MesStation> getPsMatchStationContext(StationRequestBean reqBean);
@ApiOperation(value = "保存站点用于进料时进行上料绑定")
void dispatchPsMatchStationContext(StationRequestBean reqBean, List<MesStation> stationList);
}

@ -21,6 +21,9 @@ public interface IMesStationContainerSnExtService {
Map<String, List<MesContainerSnStation>> getContainerSnStationMap(String organizeCode, List<MesStation> stationList);
@ApiOperation(value = "获取站点关联的容器条码")
Map<String, List<MesContainerSnStation>> getContainerSnStationTopMap(String organizeCode, List<MesStation> stationList);
@ApiOperation(value = "获取站点关联的容器条码")
List<MesContainerSnStation> getContainerSnStationList(String organizeCode, List<MesStation> stationList);
@ApiOperation(value = "获取站点关联的容器条码")
@ -35,6 +38,9 @@ public interface IMesStationContainerSnExtService {
@ApiOperation(value = "获取容器条码上料主表信息")
List<MesContainerPackage> getContainerPackageListByContainerSn(String organizeCode, List<String> containerSnList, Integer packageStatus);
@ApiOperation(value = "获取容器条码上料主表信息【进料】的一条数据")
MesContainerPackage getContainerPackageByContainerSn(String organizeCode, List<String> containerSnList, Integer packageStatus);
@ApiOperation(value = "获取容器条码上料明细表信息【可扣减】")
List<MesContainerPackageDetail> getContainerPackageDetailList(String organizeCode, List<MesContainerPackage> containerPackageList);

@ -63,7 +63,16 @@ public class MesStationContainerSnExtService implements IMesStationContainerSnEx
if (StringUtils.isEmpty(organizeCode) || CollectionUtils.isEmpty(stationList)) return null;
List<MesContainerSnStation> containerSnStationList = getContainerSnStationList(organizeCode, stationList);
return CollectionUtils.isEmpty(containerSnStationList) ? null :
containerSnStationList.stream().filter(o -> null != o).collect(Collectors.groupingBy(MesContainerSnStation::getContainerSn));
containerSnStationList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getContainerSn()))).collect(Collectors.groupingBy(MesContainerSnStation::getContainerSn));
}
//获取站点关联的容器条码
@Override
public Map<String, List<MesContainerSnStation>> getContainerSnStationTopMap(String organizeCode, List<MesStation> stationList) {
if (StringUtils.isEmpty(organizeCode) || CollectionUtils.isEmpty(stationList)) return null;
List<MesContainerSnStation> containerSnStationList = getContainerSnStationList(organizeCode, stationList);
return CollectionUtils.isEmpty(containerSnStationList) ? null :
containerSnStationList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getTopContainerSn()))).collect(Collectors.groupingBy(MesContainerSnStation::getTopContainerSn));
}
//获取站点关联的容器条码
@ -76,6 +85,7 @@ public class MesStationContainerSnExtService implements IMesStationContainerSnEx
//获取站点关联的容器条码
@Override
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public List<MesContainerSnStation> getContainerSnStationListByStation(String organizeCode, List<String> stationList) {
if (StringUtils.isEmpty(organizeCode) || CollectionUtils.isEmpty(stationList)) return null;
DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
@ -123,6 +133,7 @@ public class MesStationContainerSnExtService implements IMesStationContainerSnEx
//获取容器条码上料主表信息
@Override
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public List<MesContainerPackage> getContainerPackageListByContainerSn(String organizeCode, List<String> containerSnList, Integer packageStatus) {
if (StringUtils.isEmpty(organizeCode) || CollectionUtils.isEmpty(containerSnList)) return null;
DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
@ -132,6 +143,18 @@ public class MesStationContainerSnExtService implements IMesStationContainerSnEx
return containerPackageRepository.findByHqlWhere(packBean);
}
//获取容器条码上料主表信息【进料】的一条数据
@Override
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public MesContainerPackage getContainerPackageByContainerSn(String organizeCode, List<String> containerSnList, Integer packageStatus) {
if (StringUtils.isEmpty(organizeCode) || CollectionUtils.isEmpty(containerSnList)) return null;
DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
if (containerSnList.size() == 1) DdlPreparedPack.getStringEqualPack(containerSnList.get(0), MesPcnExtConstWords.CONTAINER_SN, packBean);
else DdlPreparedPack.getInPackList(containerSnList, MesPcnExtConstWords.CONTAINER_SN, packBean);
DdlPreparedPack.getNumEqualPack(packageStatus, MesPcnExtConstWords.PACKAGE_STATUS, packBean);
return containerPackageRepository.getByProperty(packBean);
}
//获取容器条码上料明细表信息【可扣减】
@Override
public List<MesContainerPackageDetail> getContainerPackageDetailList(String organizeCode, List<MesContainerPackage> containerPackageList) {
@ -142,6 +165,7 @@ public class MesStationContainerSnExtService implements IMesStationContainerSnEx
//获取容器条码上料明细表信息【可扣减】
@Override
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public List<MesContainerPackageDetail> getContainerPackageDetailListById(String organizeCode, List<Long> idList) {
if (StringUtils.isEmpty(organizeCode) || CollectionUtils.isEmpty(idList)) return null;
DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
@ -153,6 +177,7 @@ public class MesStationContainerSnExtService implements IMesStationContainerSnEx
//获取容器条码的一条上料明细表信息【可扣减】
@Override
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public Boolean checkIsExistContainerPackageDetail(String organizeCode, Long id) {
if (StringUtils.isEmpty(organizeCode) || StringUtils.isEmpty(id)) return null;
DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);

@ -229,7 +229,7 @@ public class MesTimeEfficientCfgMatchService implements IMesTimeEfficientCfgMatc
if (null == timeliness || StringUtils.isEmpty(timeliness.getPartNo()) || !timeliness.getPartNo().equals(containerPackageDetailContext.getPartNo())) continue;
Date productDateTime = sdf.parse(containerPackageDetailContext.getCreateDatetime());
Date productDateTime = sdf.parse(containerPackageDetailContext.getLoadPartTime());
//时差
int minDiff = (int) ((now.getTime() - productDateTime.getTime())/(60 * 1000));
if (!checkTimeliness(timeliness, minDiff)) return backResultMap(resultMap, String.format("原材料条码[%s]时效性零件号[%s]验证失败!", containerPackageDetailContext.getBarCode(), timeliness.getPartNo()));

@ -6,7 +6,6 @@ import cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step.method.MesWorkOrd
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProdRuleContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionPartContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionProcessContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionPsOutContext;
import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseSwsService;
import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.IShippingDispatchService;
import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.function.IFsmModuleFunctionService;
@ -19,7 +18,6 @@ import cn.estsh.i3plus.pojo.mes.model.StepResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/**
@ -53,17 +51,13 @@ public class MesFunctionDialogInputOrderQtyService extends BaseSwsService implem
//获取上下文产出零件信息
List<MesProductionPartContext> productionPartContextList = productionDispatchContextStepService.getProductionPartContext(reqBean);
//用弹框输入的工单数量 虚拟产出零件信息
List<MesProductionPsOutContext> productionPsOutContextList = new ArrayList<>();
productionPartContextList.forEach(o -> {
MesProductionPsOutContext productionPsOutContext = new MesProductionPsOutContext().foreignKey(o.getForeignKey());
productionPsOutContext.setQty(new Double(buttonDynamicModel.getFunctionValue()));
productionPsOutContextList.add(productionPsOutContext);
});
//获取上下文产品加工规则数据信息集合
List<MesProdRuleContext> prodRuleContextList = productionDispatchContextStepService.getProdRuleDataContext(reqBean);
prodRuleContextList.stream().forEach(o -> o.eachCavityQty(buttonDynamicModel.getFunctionValue()));
StepResult stepResult = StepResult.getSuccessComplete();
//验证加工单完成数量
workOrderCheckCompleteQtyStepService.dispatchWorkOrderCompleteQtyContext(reqBean, resultBean, stepResult, productionProcessContext, productionPartContextList, null, productionPsOutContextList);
workOrderCheckCompleteQtyStepService.dispatchWorkOrderCompleteQtyContext(reqBean, resultBean, stepResult, productionProcessContext, productionPartContextList, null, prodRuleContextList);
reqBean.setClientInfo(shippingDispatchService.getActorClientInfo(reqBean));
reqBean.setInterfaceType(MesPcnConstWords.SHIPPING);
@ -72,10 +66,6 @@ public class MesFunctionDialogInputOrderQtyService extends BaseSwsService implem
if (!stepResult.isCompleted()) reqBean.setTriggerAutoFsm(true);
else {
//获取上下文产品加工规则数据信息集合
List<MesProdRuleContext> prodRuleContextList = productionDispatchContextStepService.getProdRuleDataContext(reqBean);
prodRuleContextList.stream().forEach(o -> o.eachCavityQty(buttonDynamicModel.getFunctionValue()));
productionDispatchContextStepService.dispatchProdRuleDataContext(reqBean, prodRuleContextList);
reqBean.setButtonCode(buttonDynamicModel.getButtonCode());

@ -84,9 +84,6 @@ public class MesAssemblyShowNosortStepService extends BaseStepService {
//从上下文中取出生产线对象
MesCellEquipContext cellEquipContext = productionProcessContext.getCurCellEquip();
//获取上下文加工规则数据信息集合
List<MesProdRuleContext> prodRuleContextList = productionDispatchContextStepService.getProdRuleDataContext(reqBean);
//获取上下文产出零件数据信息集合
List<MesProductionPartContext> productionPartContextList = productionDispatchContextStepService.getProductionPartContext(reqBean);
@ -97,8 +94,34 @@ public class MesAssemblyShowNosortStepService extends BaseStepService {
if (CollectionUtils.isEmpty(productionPartContextList) && CollectionUtils.isEmpty(productionPsInContextList))
stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), String.format("生产线[%s]工位[%s]当前已不存在产成零件或进料条码数据信息,请重置工序!", reqBean.getWorkCenterCode(), reqBean.getWorkCellCode()));
//根据现有数据【产出零件数据】【进料零件条码信息】比对上下文中已经存在的加工规则数据信息集合, 没有加工规则的数据进行查询
//获取上下文加工规则数据信息集合
List<MesProdRuleContext> prodRuleContextList = productionDispatchContextStepService.getProdRuleDataContext(reqBean);
if (CollectionUtils.isEmpty(prodRuleContextList)) prodRuleContextList = new ArrayList<>();
//业务处理后显示装配件扫描项
return doHandleAssemblyShowNosort(reqBean, resultBean, stepResult, workCenter, productionProcessContext, cellEquipContext, prodRuleContextList, productionPartContextList, productionPsInContextList);
}
//业务处理后显示装配件扫描项
private StepResult doHandleAssemblyShowNosort(StationRequestBean reqBean, StationResultBean resultBean, StepResult stepResult, MesWorkCenter workCenter, MesProductionProcessContext productionProcessContext, MesCellEquipContext cellEquipContext,
List<MesProdRuleContext> prodRuleContextList, List<MesProductionPartContext> productionPartContextList, List<MesProductionPsInContext> productionPsInContextList) {
//业务处理
doHandleProdRuleContext(reqBean, resultBean, stepResult, workCenter, productionProcessContext, cellEquipContext, prodRuleContextList, productionPartContextList, productionPsInContextList);
//显示装配件信息
Boolean isShow = showProductionAssembly(reqBean, resultBean, workCenter, prodRuleContextList);
return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.PROCESS.getValue()), stepResult,
isShow ? "已显示装配件清单,请查看!" : "当前腔匹配的加工规则无装配件清单!",
MesPcnEnumUtil.PROMPT_SOUND.SUCCESS.getValue());
}
//业务处理
public StepResult doHandleProdRuleContext(StationRequestBean reqBean, StationResultBean resultBean, StepResult stepResult, MesWorkCenter workCenter, MesProductionProcessContext productionProcessContext, MesCellEquipContext cellEquipContext,
List<MesProdRuleContext> prodRuleContextList, List<MesProductionPartContext> productionPartContextList, List<MesProductionPsInContext> productionPsInContextList) {
//根据现有数据【产出零件数据】【进料零件条码信息】比对上下文中已经存在的加工规则数据信息集合, 没有加工规则的数据进行查询
Integer initSize = prodRuleContextList.size();
//封装非排序加工规则
@ -106,7 +129,7 @@ public class MesAssemblyShowNosortStepService extends BaseStepService {
//验证加工单完成数量, 验证的前提条件: 每腔均已匹配到加工规则
workOrderCheckCompleteQtyStepService.dispatchWorkOrderCompleteQtyContext(
reqBean, resultBean, stepResult, productionProcessContext, productionPartContextList, productionPsInContextList);
reqBean, resultBean, stepResult, productionProcessContext, productionPartContextList, productionPsInContextList, prodRuleContextList);
//匹配失败需要清除本次扫描/读取信息
if (!stepResult.isCompleted() && workOrderCheckCompleteQtyStepService.doBusiCheckToDelete(reqBean, stepResult, productionPartContextList, productionPsInContextList))
@ -121,12 +144,7 @@ public class MesAssemblyShowNosortStepService extends BaseStepService {
if (!CollectionUtils.isEmpty(productionPsInContextList)) productionDispatchContextStepService.dispatchProductionPsInContext(reqBean, productionPsInContextList);
}
//显示装配件信息
Boolean isShow = showProductionAssembly(reqBean, resultBean, workCenter, prodRuleContextList);
return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.PROCESS.getValue()), stepResult,
isShow ? "已显示装配件清单,请查看!" : "当前腔匹配的加工规则无装配件清单!",
MesPcnEnumUtil.PROMPT_SOUND.SUCCESS.getValue());
return stepResult;
}
//封装非排序加工规则
@ -250,7 +268,7 @@ public class MesAssemblyShowNosortStepService extends BaseStepService {
//【非排序线】获取产品加工规则对应的装配件信息 -同时- 关联不可用规则
MesProdRuleContext prodRuleContext = new MesProdRuleContext(
reqBean.getOrganizeCode(), reqBean.getWorkCenterCode(), reqBean.getWorkCellCode(), reqBean.getProcessCode(), productionProcessContext.getCraftCode())
.copy(filterList.get(0)).productSn(productionPsInContext.getProductSn()).foreignKey(productionPsInContext.foreignKey(foreignKey += 1).getForeignKey());
.copy(filterList.get(0)).productSn(productionPsInContext.getProductSn()).eachCavityQty(productionPsInContext.getQty()).foreignKey(productionPsInContext.foreignKey(foreignKey += 1).getForeignKey());
prodRuleContext = prodRuleCfgExtService.getProdRuleNosortContext(prodRuleContext, prodRuleIgnoreCfgMap);
prodRuleContextList.add(prodRuleContext);
@ -365,7 +383,7 @@ public class MesAssemblyShowNosortStepService extends BaseStepService {
//【非排序线】获取产品加工规则对应的装配件信息 -同时- 关联不可用规则
MesProdRuleContext prodRuleContext = prodRuleCfgExtService.getProdRuleNosortContext(
new MesProdRuleContext(reqBean.getOrganizeCode(), reqBean.getWorkCenterCode(), reqBean.getWorkCellCode(), reqBean.getProcessCode(), productionProcessContext.getCraftCode())
.copy(innerfilterList.get(0)).productSn(productSn.getProductSn()),
.copy(innerfilterList.get(0)).productSn(productSn.getProductSn()).eachCavityQty(productSn.getQty()),
prodRuleIgnoreCfgMap);
prodRuleContext.foreignKey(productionPartContext.getForeignKey());

@ -126,8 +126,11 @@ public class MesPackageNoGenerateStepService extends BaseStepService implements
/**Map<String, List<String>> productSnMap2Part = productionPsOutContextList.stream()
.filter(o -> (null != o && o.getQcStatus().compareTo(MesExtEnumUtil.PRODUCE_QC_STATUS.QUALIFIED.getValue()) == 0 && foreignKeyList.contains(o.getForeignKey())))
.collect(Collectors.groupingBy(MesProductionPsOutContext::getPartNo, Collectors.mapping(MesProductionPsOutContext::getProductSn, Collectors.toList())));**/
//适配单个产品条码QTY大于1
Map<String, LinkedList<String>> productSnMap2Part = new HashMap<>();
productionPsOutContextList.forEach(o -> productSnMap2Part.computeIfAbsent(o.getPartNo(), k -> new LinkedList<>()).addAll(generateVirtualPs(o.getQty(), o.getProductSn())));
productionPsOutContextList.stream()
.filter(o -> (null != o && o.getQcStatus().compareTo(MesExtEnumUtil.PRODUCE_QC_STATUS.QUALIFIED.getValue()) == 0 && foreignKeyList.contains(o.getForeignKey())))
.forEach(o -> productSnMap2Part.computeIfAbsent(o.getPartNo(), k -> new LinkedList<>()).addAll(generateVirtualPs(o.getQty(), o.getProductSn())));
//获取包装规则信息
Map<String, MesPackageRuleContext> packageRuleContextMap = productionProcessContextStepService.getPackageRuleContext(reqBean);

@ -9,7 +9,6 @@ import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionPsInContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.mes.pcn.api.iservice.base.IConfigService;
import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseStepService;
import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.IStepService;
import cn.estsh.i3plus.pojo.mes.bean.MesConfig;
import cn.estsh.i3plus.pojo.mes.bean.MesProduceSn;
import cn.estsh.i3plus.pojo.mes.bean.MesWorkCell;
@ -18,7 +17,6 @@ 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 lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -82,6 +80,19 @@ public class MesProductSnCheckStepService extends BaseStepService {
//清除本次已获取得到的主条码信息
productionDispatchContextStepService.removeScanProductSnContext(reqBean);
//获取进料主条码数据信息
List<MesProductionPsInContext> productionPsInContextList = productionDispatchContextStepService.getProductionPsInContext(reqBean);
//处理条码验证逻辑
checkProduceSnValid(reqBean, resultBean, stepResult, productionProcessContext, equipVariableCollectContextList, productionPsInContextList);
return stepResult;
}
//处理条码验证逻辑
public List<MesProductionPsInContext> checkProduceSnValid(StationRequestBean reqBean, StationResultBean resultBean, StepResult stepResult, MesProductionProcessContext productionProcessContext,
List<MesEquipVariableCollectContext> equipVariableCollectContextList, List<MesProductionPsInContext> productionPsInContextList) {
//搜集主条码值
List<String> productSnList = equipVariableCollectContextList.stream().filter(o -> null != o).map(MesEquipVariableCollectContext::getEquipVariableValue).collect(Collectors.toList());
@ -89,19 +100,20 @@ public class MesProductSnCheckStepService extends BaseStepService {
MesWorkCell workCell = productionProcessContext.getWorkCell();
//验证上下文中主条码的有效性 封装 读/扫主条件信息到进料主条码数据信息中
List<MesProductionPsInContext> productionPsInContextList = new ArrayList<>();
if (!checkProduceSnValid(reqBean, resultBean, stepResult, productionProcessContext, workCell, productSnList, equipVariableCollectContextList, productionPsInContextList).isCompleted())
return stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, String.format("验证失败!原因:%s!", stepResult.getMsg()));
List<MesProductionPsInContext> productionPsInContextList2Cur = new ArrayList<>();
if (!checkProduceSnValid(reqBean, resultBean, stepResult, productionProcessContext, workCell, productSnList, equipVariableCollectContextList, productionPsInContextList).isCompleted()) {
stepNonCompleteAndSendMsg(reqBean, resultBean.writeDbLog(), stepResult, String.format("验证失败!原因:%s!", stepResult.getMsg()));
return productionPsInContextList;
}
//获取进料主条码数据信息
List<MesProductionPsInContext> productionPsInContext = productionDispatchContextStepService.getProductionPsInContext(reqBean);
if (!CollectionUtils.isEmpty(productionPsInContext)) productionPsInContextList.addAll(productionPsInContext);
if (!CollectionUtils.isEmpty(productionPsInContextList)) productionPsInContextList2Cur.addAll(productionPsInContextList);
//保存进料主条码数据
productionDispatchContextStepService.dispatchProductionPsInContext(reqBean, productionPsInContextList);
productionDispatchContextStepService.dispatchProductionPsInContext(reqBean, productionPsInContextList2Cur);
return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog().scanInfo(productSnList.toString()), stepResult, String.format("主条码%s验证条码状态成功!", productSnList.toString()));
stepSuccessCompleteAndSendMsg(reqBean, resultBean.writeDbLog().scanInfo(productSnList.toString()), stepResult, String.format("主条码%s验证条码状态成功!", productSnList.toString()));
return productionPsInContextList2Cur;
}
private List<String> filterEquipVariableCollectContextList(MesProductionProcessContext productionProcessContext, List<MesEquipVariableCollectContext> equipVariableCollectContextList) {
@ -115,9 +127,14 @@ public class MesProductSnCheckStepService extends BaseStepService {
Map<String, List<MesProduceSn>> produceSnMap = produceSnExtService.getProduceSnMap(reqBean.getOrganizeCode(), productSnList);
for (MesEquipVariableCollectContext equipVariableCollectContext : equipVariableCollectContextList) {
if (null == equipVariableCollectContext || StringUtils.isEmpty(equipVariableCollectContext.getEquipVariableValue())) continue;
if (CollectionUtils.isEmpty(produceSnMap) || !produceSnMap.containsKey(equipVariableCollectContext.getEquipVariableValue()))
productionPsInContextList.add(new MesProductionPsInContext(reqBean.getOrganizeCode(), equipVariableCollectContext.getEquipVariableValue()).messageSource(equipVariableCollectContext.getMessageSource()));
else createProductionPsInContext(reqBean, stepResult, workCell, equipVariableCollectContext, produceSnMap.get(equipVariableCollectContext.getEquipVariableValue()), productionPsInContextList);
if (CollectionUtils.isEmpty(produceSnMap) || !produceSnMap.containsKey(equipVariableCollectContext.getEquipVariableValue())) {
MesProductionPsInContext productionPsInContext = new MesProductionPsInContext(reqBean.getOrganizeCode(), equipVariableCollectContext.getEquipVariableValue()).messageSource(equipVariableCollectContext.getMessageSource());
//适配智慧内饰容器进料的qty
if (!StringUtils.isEmpty(equipVariableCollectContext.getQty())) productionPsInContext.qty(equipVariableCollectContext.getQty());
productionPsInContextList.add(productionPsInContext);
} else {
createProductionPsInContext(reqBean, stepResult, workCell, equipVariableCollectContext, produceSnMap.get(equipVariableCollectContext.getEquipVariableValue()), productionPsInContextList);
}
}
return stepResult;
}

@ -131,6 +131,15 @@ public class MesProductSnGenerateStepService extends BaseStepService {
//获取上下文进料零件条码信息集合
List<MesProductionPsInContext> productionPsInContextList = productionDispatchContextStepService.getProductionPsInContext(reqBean);
//生产零件条码业务处理
doHandleProductSnGenerate(reqBean, resultBean, stepResult, productionProcessContext, productionPartContextList, productionPsInContextList, prodRuleContextList, prodShiftContext);
return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.PROCESS.getValue()), stepResult, "生成零件条码成功!");
}
//生产零件条码业务处理
public void doHandleProductSnGenerate(StationRequestBean reqBean, StationResultBean resultBean, StepResult stepResult, MesProductionProcessContext productionProcessContext, List<MesProductionPartContext> productionPartContextList, List<MesProductionPsInContext> productionPsInContextList, List<MesProdRuleContext> prodRuleContextList, MesProdShiftContext prodShiftContext) {
//获取上下文零件数据信息
List<String> partNoList = (prodRuleContextList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getOutPartNo()))).map(MesProdRuleContext::getOutPartNo).collect(Collectors.toList())).stream().filter(o -> !StringUtils.isEmpty(o)).distinct().collect(Collectors.toList());
partDataMapSaveStepService.savePartDataMap(reqBean, resultBean, stepResult, partNoList, false, true, false);
@ -153,9 +162,6 @@ public class MesProductSnGenerateStepService extends BaseStepService {
//保存上下文产出条码数据信息集合
productionDispatchContextStepService.dispatchProductionPsOutContext(reqBean, productionPsOutContextList);
return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.PROCESS.getValue()), stepResult, "生成零件条码成功!");
}
//生成零件条码

@ -3,6 +3,7 @@ package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionDispatchContextStepService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionProcessContextStepService;
import cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step.method.MesWorkOrderCheckCompleteQtyStepService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProdRuleContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionPartContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionProcessContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionPsInContext;
@ -60,11 +61,14 @@ public class MesProductionDataSaveBeforeLockOrderStepService extends BaseStepSer
//获取上下文进料零件条码信息集合
List<MesProductionPsInContext> productionPsInContextList = productionDispatchContextStepService.getProductionPsInContext(reqBean);
//获取上下文加工规则信息集合
List<MesProdRuleContext> prodRuleContextList = productionDispatchContextStepService.getProdRuleDataContext(reqBean);
synchronized (new StringJoiner(MesPcnExtConstWords.COLON).add(reqBean.getOrganizeCode()).add(reqBean.getWorkCenterCode()).add(MesPcnExtConstWords.WORK_ORDER_COMPLETE_CONTEXT).toString().intern()) {
//验证加工单完成数量
workOrderCheckCompleteQtyStepService.dispatchWorkOrderCompleteQtyContext(
reqBean, resultBean, stepResult, productionProcessContext, productionPartContextList, productionPsInContextList);
reqBean, resultBean, stepResult, productionProcessContext, productionPartContextList, productionPsInContextList, prodRuleContextList);
//匹配失败需要清除本次扫描/读取信息
if (!stepResult.isCompleted() && workOrderCheckCompleteQtyStepService.doBusiCheckToDelete(reqBean, stepResult, productionPartContextList, productionPsInContextList))

@ -3,6 +3,7 @@ package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionCustomContextStepService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionDispatchContextStepService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionProcessContextStepService;
import cn.estsh.i3plus.ext.mes.pcn.apiservice.util.MesReentrantLockUtil;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesContainerPackageDetailContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProdRuleContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionAssemblyContext;
@ -27,13 +28,11 @@ import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;
/**
* @Description :
* @Description :
* @Author : wangjie
**/
@Slf4j
@ -52,8 +51,6 @@ public class MesStationDeductionAssemblyStepService extends BaseStepService {
@Autowired
private IFsmCommonService fsmCommonService;
private final static Map<String, ReentrantLock> lockMap = new ConcurrentHashMap<>();
@Override
public StepResult init(StationRequestBean reqBean) {
@ -63,13 +60,10 @@ public class MesStationDeductionAssemblyStepService extends BaseStepService {
if (StringUtils.isEmpty(endlessLoopReadTimes)) endlessLoopReadTimes = MesPcnExtConstWords.ENDLESS_LOOP_READ_TIMES_DEFAULT;
if (productionDispatchContextStepService.dispatchOverEndlessLoopReadTimes(reqBean, endlessLoopReadTimes)) {
stepThreadSleepAndSendTaskCompleteAndThrowEx(reqBean, new StationResultBean().isWs(false).writeDbLog().checkRepeat(),
stepResult.isCompleted(false).msg(String.format("当前未能执行完成站点扣减装配件超过[%s]次!", endlessLoopReadTimes)),
stepResult.isCompleted(false).msg(String.format("当前未能执行完成装配件站点扣减超过[%s]次!", endlessLoopReadTimes)),
MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT, getStepParams(reqBean), MesPcnExtConstWords.READ_FAILURE_SLEEP, MesPcnExtConstWords.READ_FAILURE_SLEEP_DEFAULT_TIME);
}
//发送工步内容
productionCustomContextStepService.sendStepContextMessage(reqBean);
return stepResult;
}
@ -95,7 +89,7 @@ public class MesStationDeductionAssemblyStepService extends BaseStepService {
Optional<MesProdRuleContext> optional = prodRuleContextList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getIsMatchContainer()))).findFirst();
if (null == optional || !optional.isPresent()) {
return stepDynamicsCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, true,
MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT, "验证每腔不存在容器匹配的装配件,默认跳过站点扣减装配件!");
MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT, "验证每腔不存在容器匹配的装配件,默认跳过装配件站点扣减!");
}
//获取站点用于扣料业务中进行LOCK
@ -107,9 +101,9 @@ public class MesStationDeductionAssemblyStepService extends BaseStepService {
List<ReentrantLock> acquiredLocks = new ArrayList<>();
try {
if (!tryLock(acquiredLocks, stationNameList)) {
if (!MesReentrantLockUtil.tryLock(acquiredLocks, stationNameList, MesPcnExtConstWords.MATCH_STATION_ASSEMBLY_CONTEXT + MesPcnExtConstWords.COLON, 3000L)) {
return stepDynamicsCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog().checkRepeat(), stepResult, false,
MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT, "站点扣减装配件扣减失败,即将重试!");
MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT, "装配件站点扣减LOCK失败,即将重试!");
}
//用于重置原料条码的缓存库存
@ -136,12 +130,12 @@ public class MesStationDeductionAssemblyStepService extends BaseStepService {
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return stepDynamicsCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog().checkRepeat(), stepResult, false,
MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT, "站点扣减装配件扣减异常,即将重试!");
MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT, "装配件站点扣减异常,即将重试!");
} finally {
unLockAll(acquiredLocks);
MesReentrantLockUtil.unLockAll(acquiredLocks);
}
return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, "站点扣减装配件验证成功!");
return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, "装配件站点扣减验证成功!");
}
@ -156,7 +150,7 @@ public class MesStationDeductionAssemblyStepService extends BaseStepService {
}
if (!CollectionUtils.isEmpty(needFeedPartNoList)) {
stepResult.isCompleted(false)
.msg(String.format("站点匹配装配件时验证零件号%s当前缺料,请扫描上料条码!",
.msg(String.format("装配件站点扣减时验证零件号%s当前缺料,请扫描上料条码!",
(needFeedPartNoList.stream().filter(o -> !StringUtils.isEmpty(o)).distinct().collect(Collectors.toList())).toString()));
}
return isNeedSavePrc;
@ -244,33 +238,4 @@ public class MesStationDeductionAssemblyStepService extends BaseStepService {
return isNeedSavePrc;
}
private Boolean tryLock(List<ReentrantLock> acquiredLocks, List<String> stationNameList) throws InterruptedException {
Collections.sort(stationNameList);
long remaining = TimeUnit.MILLISECONDS.toNanos(3000);
long endTime = System.nanoTime() + remaining;
for (String stationName : stationNameList) {
if (StringUtils.isEmpty(stationName)) continue;
ReentrantLock lock = lockMap.computeIfAbsent(stationName, o -> new ReentrantLock());
if (!lock.tryLock(remaining, TimeUnit.NANOSECONDS)) return false;
acquiredLocks.add(lock);
remaining = endTime - System.nanoTime();
}
return true;
}
private void unLockAll(List<ReentrantLock> acquiredLocks) {
for (int i = acquiredLocks.size() - 1; i >= 0; i --) acquiredLocks.get(i).unlock();
}
}

@ -84,7 +84,7 @@ public class MesStationFeedContainerPackageDetailStepService extends BaseStepSer
}
//获取站点用于缺料时进行上料绑定
List<MesStation> stationList = productionDispatchContextStepService.getMatchStationContext(reqBean);
List<MesStation> stationList = productionDispatchContextStepService.getMatchStationAssemblyContext(reqBean);
if (CollectionUtils.isEmpty(stationList)) {
return stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult.nextTriggerEvent(MesPcnExtConstWords.NEXT_TRIGGER_EVENT_FEEDING), "容器条码扣减装配件时验证设备未关联支持上料的站点");
}

@ -0,0 +1,46 @@
package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionCustomContextStepService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseStepService;
import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.IStepService;
import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil;
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.impp.framework.boot.util.SpringContextsUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @Description :
* @Author : wangjie
**/
@Slf4j
@Service("mesStationFeedContainerSnByAssemblyStepService")
public class MesStationFeedContainerSnByAssemblyStepService extends BaseStepService {
@Autowired
private IMesProductionCustomContextStepService productionCustomContextStepService;
@Override
public StepResult guide(StationRequestBean reqBean) {
//发送工步内容
productionCustomContextStepService.sendStepContextMessage(reqBean);
return stepSuccessCompleteAndSendGuideReturn(reqBean, new StationResultBean().writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.PROCESS.getValue()), "请扫描容器条码!");
}
@Override
public StepResult execute(StationRequestBean reqBean) {
reqBean.getDataMap().put(MesPcnExtConstWords.MATCH_STATION_CONTEXT_FLAG, MesPcnExtConstWords.MATCH_STATION_ASSEMBLY_CONTEXT);
return ((IStepService) SpringContextsUtil.getBean("mesStationFeedContainerSnByFlagStepService")).executeInState(reqBean);
}
}

@ -0,0 +1,73 @@
package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionCustomContextStepService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionDispatchContextStepService;
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.MesPcnEnumUtil;
import cn.estsh.i3plus.pojo.mes.bean.MesStation;
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 lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.util.List;
/**
* @Description :
* @Author : wangjie
**/
@Slf4j
@Service("mesStationFeedContainerSnByFlagStepService")
public class MesStationFeedContainerSnByFlagStepService extends BaseStepService {
@Autowired
private IMesProductionDispatchContextStepService productionDispatchContextStepService;
@Autowired
private IMesProductionCustomContextStepService productionCustomContextStepService;
@Override
public StepResult guide(StationRequestBean reqBean) {
//发送工步内容
productionCustomContextStepService.sendStepContextMessage(reqBean);
return stepSuccessCompleteAndSendGuideReturn(reqBean, new StationResultBean().writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.PROCESS.getValue()), "请扫描容器条码!");
}
// @Override
// public StepResult execute(StationRequestBean reqBean) {
//
// StationResultBean resultBean = new StationResultBean();
//
// StepResult stepResult = StepResult.getSuccessComplete();
//
// //投料站点标识
// String flag = (String) reqBean.getDataMap().get(MesPcnExtConstWords.MATCH_STATION_CONTEXT_FLAG);
//
// if (StringUtils.isEmpty(flag)) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), "站点上料扫描容器条码时验证缺失必要flag参数!");
//
// if (StringUtils.isEmpty(reqBean.getScanInfo())) stepSendGuideAndThrowEx(reqBean, resultBean.writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.PROCESS.getValue()), "请扫描容器条码!");
//
// //获取站点用于缺料时进行上料绑定
// List<MesStation> stationList = productionDispatchContextStepService.getMatchStationContext(reqBean, flag);
// if (CollectionUtils.isEmpty(stationList)) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), "站点上料扫描容器条码时验证缺失站点信息!");
//
// //删除源工步传过来的参数标识
// reqBean.getDataMap().remove(MesPcnExtConstWords.MATCH_STATION_CONTEXT_FLAG);
//
// MesStation station = stationList.get(0);
//
// Integer packageStatus = flag.equals(MesPcnExtConstWords.MATCH_STATION_ASSEMBLY_CONTEXT) ? MesExtEnumUtil.CONTAINER_PACKAGE_STATUS.STATUS_20.getValue() :
// station
//
// }
}

@ -0,0 +1,46 @@
package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionCustomContextStepService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseStepService;
import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.IStepService;
import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil;
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.impp.framework.boot.util.SpringContextsUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @Description :
* @Author : wangjie
**/
@Slf4j
@Service("mesStationFeedContainerSnByPsInStepService")
public class MesStationFeedContainerSnByPsInStepService extends BaseStepService {
@Autowired
private IMesProductionCustomContextStepService productionCustomContextStepService;
@Override
public StepResult guide(StationRequestBean reqBean) {
//发送工步内容
productionCustomContextStepService.sendStepContextMessage(reqBean);
return stepSuccessCompleteAndSendGuideReturn(reqBean, new StationResultBean().writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.PROCESS.getValue()), "请扫描容器条码!");
}
@Override
public StepResult execute(StationRequestBean reqBean) {
reqBean.getDataMap().put(MesPcnExtConstWords.MATCH_STATION_CONTEXT_FLAG, MesPcnExtConstWords.MATCH_STATION_PRODUCT_SN_CONTEXT);
return ((IStepService) SpringContextsUtil.getBean("mesStationFeedContainerSnByFlagStepService")).executeInState(reqBean);
}
}

@ -76,7 +76,7 @@ public class MesStationFeedContainerSnStepService extends BaseStepService {
}
//获取站点用于缺料时进行上料绑定
List<MesStation> stationList = productionDispatchContextStepService.getMatchStationContext(reqBean);
List<MesStation> stationList = productionDispatchContextStepService.getMatchStationAssemblyContext(reqBean);
if (CollectionUtils.isEmpty(stationList)) {
stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), "容器条码扣减装配件时验证设备未关联支持上料的站点");
}

@ -29,7 +29,7 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @Description :
* @Description :
* @Author : wangjie
**/
@Slf4j
@ -72,23 +72,23 @@ public class MesStationMatchAssemblyStepService extends BaseStepService {
Optional<MesProdRuleContext> optional = prodRuleContextList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getIsMatchContainer()))).findFirst();
if (null == optional || !optional.isPresent()) {
return stepDynamicsCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, true,
MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT, "验证每腔不存在容器匹配的装配件,默认跳过站点匹配装配件!");
MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT, "验证每腔不存在容器匹配的装配件,默认跳过匹配装配件站点!");
}
//处理设备站点【装配件站点&&混料站点】
List<MesStation> stationList = productionProcessContextStepService.dispatchEquipmentStationContext(reqBean, productionProcessContext.getCurCellEquip().getEquipmentCode(),
Stream.of(MesExtEnumUtil.STATION_TYPE.STATION_TYPE_20.getValue(), MesExtEnumUtil.STATION_TYPE.STATION_TYPE_40.getValue()).collect(Collectors.toList()));
if (CollectionUtils.isEmpty(stationList)) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), "站点匹配装配件时验证设备未关联支持扣减的站点!");
List<Integer> stationTypeList = Stream.of(MesExtEnumUtil.STATION_TYPE.STATION_TYPE_20.getValue(), MesExtEnumUtil.STATION_TYPE.STATION_TYPE_40.getValue()).collect(Collectors.toList());
List<MesStation> stationList = productionProcessContextStepService.dispatchEquipmentStationContext(reqBean, productionProcessContext.getCurCellEquip().getEquipmentCode(), stationTypeList);
if (CollectionUtils.isEmpty(stationList)) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(),
String.format("匹配装配件站点时时验证设备未关联[%s]站点!", MesExtEnumUtil.STATION_TYPE.valueOfDescription(stationTypeList, MesPcnExtConstWords.SLANT_R)));
//保存站点用于缺料时进行上料绑定
productionDispatchContextStepService.dispatchMatchStationContext(reqBean, stationList);
productionDispatchContextStepService.dispatchMatchStationAssemblyContext(reqBean, stationList);
//获取容器条码上料明细表信息【可扣减】【根据 主表seq,主表createDatetime,明细表createDatetime 正序】
List<MesContainerPackageDetailContext> containerPackageDetailContextList = stationContainerSnExtService.getContainerPackageDetailContext(reqBean.getOrganizeCode(), stationList);
if (CollectionUtils.isEmpty(containerPackageDetailContextList)) return stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(),
stepResult.nextTriggerEvent(MesPcnExtConstWords.NEXT_TRIGGER_EVENT_FEEDING), "站点匹配装配件时验证当前无可扣减的原材料信息!");
stepResult.nextTriggerEvent(MesPcnExtConstWords.NEXT_TRIGGER_EVENT_FEEDING), "匹配装配件站点时验证当前无可扣减的原材料信息!");
//将可扣减的条码进行原子性缓存, 并获取最新的实际库存
productionCustomContextStepService.dispatchContainerPackageDetailAtomicity(reqBean.getOrganizeCode(), containerPackageDetailContextList);
@ -115,7 +115,7 @@ public class MesStationMatchAssemblyStepService extends BaseStepService {
//保存站点用于后面扣料业务中进行LOCK
productionDispatchContextStepService.dispatchLockStationContext(reqBean, stationMap2Lock);
return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, "站点匹配装配件验证成功!");
return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, "匹配装配件站点验证成功!");
}
//匹配装配件的工序用量【遍历加工规则】
@ -130,7 +130,7 @@ public class MesStationMatchAssemblyStepService extends BaseStepService {
}
if (!CollectionUtils.isEmpty(needFeedPartNoList)) {
stepResult.isCompleted(false)
.msg(String.format("站点匹配装配件时验证零件号%s当前缺料,请扫描上料条码!",
.msg(String.format("匹配装配件站点时验证零件号%s当前缺料,请扫描上料条码!",
(needFeedPartNoList.stream().filter(o -> !StringUtils.isEmpty(o)).distinct().collect(Collectors.toList())).toString()));
}
return isNeedSavePrc;

@ -1,123 +0,0 @@
package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.*;
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.serviceimpl.fsm.BaseStepService;
import cn.estsh.i3plus.pojo.mes.bean.MesContainerPackage;
import cn.estsh.i3plus.pojo.mes.bean.MesContainerSnStation;
import cn.estsh.i3plus.pojo.mes.bean.MesStation;
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 lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.StringJoiner;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @Description :
* @Author : wangjie
**/
@Slf4j
@Service("mesStationMatchProductSnInStepService")
public class MesStationMatchProductSnInStepService extends BaseStepService {
@Autowired
private IMesProductionProcessContextStepService productionProcessContextStepService;
@Autowired
private IMesProductionDispatchContextStepService productionDispatchContextStepService;
@Autowired
private IMesProductionCustomContextStepService productionCustomContextStepService;
@Autowired
private IMesStationContainerSnExtService stationContainerSnExtService;
@Autowired
private IMesTimeEfficientCfgMatchService timeEfficientCfgMatchService;
@Override
public StepResult execute(StationRequestBean reqBean) {
StationResultBean resultBean = new StationResultBean();
StepResult stepResult = StepResult.getSuccessComplete();
//获取工位当前设备信息
MesProductionProcessContext productionProcessContext = productionProcessContextStepService.dispatchCurCellEquipment(reqBean);
//配置错误 抛出异常
if (!productionProcessContext.getSuccess()) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), productionProcessContext.getMessage());
//处理设备站点【原料站点&&混料站点&&成品站点&&可疑站点】
List<MesStation> stationList = productionProcessContextStepService.dispatchEquipmentStationContext(reqBean, productionProcessContext.getCurCellEquip().getEquipmentCode(),
Stream.of(MesExtEnumUtil.STATION_TYPE.STATION_TYPE_10.getValue(), MesExtEnumUtil.STATION_TYPE.STATION_TYPE_40.getValue(),
MesExtEnumUtil.STATION_TYPE.STATION_TYPE_30.getValue(), MesExtEnumUtil.STATION_TYPE.STATION_TYPE_50.getValue()).collect(Collectors.toList()));
//搜集设备站点 【进料】【原料站点&&混料站点】
String suffix = new StringJoiner(MesPcnExtConstWords.SLANT_R).add(MesExtEnumUtil.STATION_TYPE.STATION_TYPE_10.getDescription()).add(MesExtEnumUtil.STATION_TYPE.STATION_TYPE_40.getDescription()).toString();
List<MesStation> stationList2PsIn = productionProcessContextStepService.dispatchEquipmentStationContext(stationList,
Stream.of(MesExtEnumUtil.STATION_TYPE.STATION_TYPE_10.getValue(), MesExtEnumUtil.STATION_TYPE.STATION_TYPE_40.getValue()).collect(Collectors.toList()));
if (CollectionUtils.isEmpty(stationList2PsIn)) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), String.format("站点匹配进料时验证设备未关联[%s]站点!", suffix));
//验证【原料站点&&混料站点】是否存在【已关箱】的容器条码
if (!checkIsFeedContainerSn(reqBean, resultBean, stepResult, stationList2PsIn, suffix, MesExtEnumUtil.CONTAINER_PACKAGE_STATUS.STATUS_20).isCompleted()) return stepResult;
//验证【成品站点】是否存在【未关箱】的容器条码
if (!checkIsFeedContainerSn(reqBean, resultBean, stepResult,
productionProcessContextStepService.dispatchEquipmentStationContext(stationList, Stream.of(MesExtEnumUtil.STATION_TYPE.STATION_TYPE_30.getValue()).collect(Collectors.toList())),
MesExtEnumUtil.STATION_TYPE.STATION_TYPE_30.getDescription(), MesExtEnumUtil.CONTAINER_PACKAGE_STATUS.STATUS_10).isCompleted()) return stepResult;
//验证【可疑站点】是否存在【未关箱】的容器条码
if (!checkIsFeedContainerSn(reqBean, resultBean, stepResult,
productionProcessContextStepService.dispatchEquipmentStationContext(stationList, Stream.of(MesExtEnumUtil.STATION_TYPE.STATION_TYPE_50.getValue()).collect(Collectors.toList())),
MesExtEnumUtil.STATION_TYPE.STATION_TYPE_50.getDescription(), MesExtEnumUtil.CONTAINER_PACKAGE_STATUS.STATUS_10).isCompleted()) return stepResult;
//验证【混料站点】是否存在容器条码
if (!checkIsFeedContainerSn(reqBean, resultBean, stepResult,
productionProcessContextStepService.dispatchEquipmentStationContext(stationList, Stream.of(MesExtEnumUtil.STATION_TYPE.STATION_TYPE_40.getValue()).collect(Collectors.toList())),
MesExtEnumUtil.STATION_TYPE.STATION_TYPE_40.getDescription(), null).isCompleted()) return stepResult;
return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, "站点匹配进料验证成功!");
}
private StepResult checkIsFeedContainerSn(StationRequestBean reqBean, StationResultBean resultBean, StepResult stepResult,
List<MesStation> stationList, String suffix, MesExtEnumUtil.CONTAINER_PACKAGE_STATUS containerPackageStatus) {
//获取站点关联的容器条码【进料】
Map<String, List<MesContainerSnStation>> containerSnStationMap = stationContainerSnExtService.getContainerSnStationMap(reqBean.getOrganizeCode(), stationList);
//获取容器条码上料主表信息【进料】 除了混料不带状态查询, 其他均查询【已关箱】的数据
List<MesContainerPackage> containerPackageList = stationContainerSnExtService.getContainerPackageListByContainerSn(reqBean.getOrganizeCode(),
CollectionUtils.isEmpty(containerSnStationMap) ? null : new ArrayList<>(containerSnStationMap.keySet()),
null != containerPackageStatus ? MesExtEnumUtil.CONTAINER_PACKAGE_STATUS.STATUS_20.getValue() : null);
if (CollectionUtils.isEmpty(stationList)) return stepResult;
//混料站点 或 判断已关箱的情况下 , containerPackageList 存在数据则通过
if ((null == containerPackageStatus || MesExtEnumUtil.CONTAINER_PACKAGE_STATUS.STATUS_20.getValue() == containerPackageStatus.getValue())
&& !CollectionUtils.isEmpty(containerPackageList)) return stepResult;
//判断未关箱的情况下,需要看当前的容器条码是否全部是已关箱的,如果是则验证不通过 【不存在已关箱状态的数据就默认是未关箱的, 及不存在数据也默认是未关箱的】
if (null != containerPackageStatus && MesExtEnumUtil.CONTAINER_PACKAGE_STATUS.STATUS_10.getValue() == containerPackageStatus.getValue()) {
List<String> containerSnList = CollectionUtils.isEmpty(containerPackageList) ? null :
(containerPackageList.stream().filter(o -> null != o).map(MesContainerPackage::getContainerSn).collect(Collectors.toList()))
.stream().filter(o -> !StringUtils.isEmpty(o)).distinct().collect(Collectors.toList());
if (CollectionUtils.isEmpty(containerSnList) || containerSnList.size() != containerSnStationMap.keySet().size()) return stepResult;
}
//保存站点用于绑定进料容器条码
productionDispatchContextStepService.dispatchPsMatchStationContext(reqBean, stationList);
return stepNonCompleteAndSendMsgReturn(reqBean, resultBean, stepResult.nextTriggerEvent(MesPcnExtConstWords.NEXT_TRIGGER_EVENT_FEEDING),
String.format("站点匹配进料时验证[%s]站点未绑定[%s]的容器条码!", suffix, containerPackageStatus.getDescription()));
}
}

@ -0,0 +1,303 @@
package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step;
import cn.estsh.i3plus.ext.mes.pcn.api.base.IMesProdShiftRecordService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionDispatchContextStepService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionProcessContextStepService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesStationContainerSnExtService;
import cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step.method.stationpm.IMesStationMatchPsProcessMethodStrategyStepService;
import cn.estsh.i3plus.ext.mes.pcn.apiservice.util.MesReentrantLockUtil;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.*;
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.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil;
import cn.estsh.i3plus.pojo.mes.bean.*;
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 lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.util.*;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @Description :
* @Author : wangjie
**/
@Slf4j
@Service("mesStationMatchProductSnStepService")
public class MesStationMatchProductSnStepService extends BaseStepService {
@Autowired
private IMesProductionProcessContextStepService productionProcessContextStepService;
@Autowired
private IMesProductionDispatchContextStepService productionDispatchContextStepService;
@Autowired
private MesProductSnCheckStepService productSnCheckStepService;
@Autowired
private MesAssemblyShowNosortStepService assemblyShowNosortStepService;
@Autowired
private MesProductSnGenerateStepService productSnGenerateStepService;
@Autowired
private IMesStationContainerSnExtService stationContainerSnExtService;
@Autowired
private IMesProdShiftRecordService prodShiftRecordService;
@Autowired
private IFsmCommonService fsmCommonService;
@Override
public StepResult init(StationRequestBean reqBean) {
StepResult stepResult = StepResult.getSuccessComplete();
String endlessLoopReadTimes = fsmCommonService.handleFsmWcpcMapDataForDoScanThenBackValue(reqBean, MesPcnExtConstWords.ENDLESS_LOOP_READ_TIMES);
if (StringUtils.isEmpty(endlessLoopReadTimes)) endlessLoopReadTimes = MesPcnExtConstWords.ENDLESS_LOOP_READ_TIMES_DEFAULT;
if (productionDispatchContextStepService.dispatchOverEndlessLoopReadTimes(reqBean, endlessLoopReadTimes)) {
stepThreadSleepAndSendTaskCompleteAndThrowEx(reqBean, new StationResultBean().isWs(false).writeDbLog().checkRepeat(),
stepResult.isCompleted(false).msg(String.format("当前未能执行完成匹配原料站点超过[%s]次!", endlessLoopReadTimes)),
MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT, getStepParams(reqBean), MesPcnExtConstWords.READ_FAILURE_SLEEP, MesPcnExtConstWords.READ_FAILURE_SLEEP_DEFAULT_TIME);
}
return stepResult;
}
@Override
public StepResult execute(StationRequestBean reqBean) {
StationResultBean resultBean = new StationResultBean();
StepResult stepResult = StepResult.getSuccessComplete();
//获取工位当前设备信息
MesProductionProcessContext productionProcessContext = productionProcessContextStepService.dispatchCurCellEquipment(reqBean);
//配置错误 抛出异常
if (!productionProcessContext.getSuccess()) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), productionProcessContext.getMessage());
//获取生产线的当前班组班次信息
MesProdShiftContext prodShiftContext = prodShiftRecordService.getMesProdShiftKvBean(reqBean.getOrganizeCode(), reqBean.getWorkCenterCode());
if (null == prodShiftContext) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), "当前不存在生产开班记录,请重新开班!");
//处理设备站点【原料站点&&混料站点&&成品站点&&可疑站点】
List<MesStation> stationList = productionProcessContextStepService.dispatchEquipmentStationContext(reqBean, productionProcessContext.getCurCellEquip().getEquipmentCode(),
Stream.of(MesExtEnumUtil.STATION_TYPE.STATION_TYPE_10.getValue(), MesExtEnumUtil.STATION_TYPE.STATION_TYPE_40.getValue(),
MesExtEnumUtil.STATION_TYPE.STATION_TYPE_30.getValue(), MesExtEnumUtil.STATION_TYPE.STATION_TYPE_50.getValue()).collect(Collectors.toList()));
//搜集设备站点 【进料】【原料站点&&混料站点】
List<MesStation> stationList2Ps = filterStationList2Ps(reqBean, resultBean, stationList);
//验证【成品站点】是否存在【未关箱】的容器条码
if (!beforeCheckIsExistContainerSn(reqBean, resultBean, stepResult,
productionProcessContextStepService.dispatchEquipmentStationContext(stationList, Stream.of(MesExtEnumUtil.STATION_TYPE.STATION_TYPE_30.getValue()).collect(Collectors.toList())),
MesExtEnumUtil.STATION_TYPE.STATION_TYPE_30.getDescription(), MesExtEnumUtil.CONTAINER_PACKAGE_STATUS.STATUS_10).isCompleted()) return stepResult;
//验证【可疑站点】是否存在【未关箱】的容器条码
if (!beforeCheckIsExistContainerSn(reqBean, resultBean, stepResult,
productionProcessContextStepService.dispatchEquipmentStationContext(stationList, Stream.of(MesExtEnumUtil.STATION_TYPE.STATION_TYPE_50.getValue()).collect(Collectors.toList())),
MesExtEnumUtil.STATION_TYPE.STATION_TYPE_50.getDescription(), MesExtEnumUtil.CONTAINER_PACKAGE_STATUS.STATUS_10).isCompleted()) return stepResult;
//验证【混料站点】是否存在容器条码
if (!beforeCheckIsExistContainerSn(reqBean, resultBean, stepResult,
productionProcessContextStepService.dispatchEquipmentStationContext(stationList, Stream.of(MesExtEnumUtil.STATION_TYPE.STATION_TYPE_40.getValue()).collect(Collectors.toList())),
MesExtEnumUtil.STATION_TYPE.STATION_TYPE_40.getDescription(), null).isCompleted()) return stepResult;
//加工模式策略
IMesStationMatchPsProcessMethodStrategyStepService strategyService = (IMesStationMatchPsProcessMethodStrategyStepService) SpringContextsUtil.getBean(MesExtEnumUtil.STATION_PROCESS_METHOD.valueOfStrategyClass(stationList.get(0).getProcessMethod()));
//【原料站点】获取容器条码上料明细表信息
MesContainerPackageDetailStationContext containerPackageDetailStationContext = strategyService.getContainerPackageDetailStationContext(reqBean.getOrganizeCode(), stationList2Ps);
if (null == containerPackageDetailStationContext) {
return stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult.nextTriggerEvent(MesPcnExtConstWords.NEXT_TRIGGER_EVENT_FEEDING), "匹配原料站点时验证[原料]站点当前已无进料信息!");
}
//从上下文中取出生产线对象
MesWorkCenter workCenter = productionProcessContext.getWorkCenter();
//从上下文中取出工位当前要使用的设备
MesCellEquipContext cellEquipContext = productionProcessContext.getCurCellEquip();
//获取上下文产出零件信息
List<MesProductionPartContext> productionPartContextList = productionDispatchContextStepService.getProductionPartContext(reqBean);
//剔除空腔
List<MesProductionPartContext> productionPartContextList2UnFinish = CollectionUtils.isEmpty(productionPartContextList) ? null : productionPartContextList.stream().filter(o -> (null != o && o.getIsFinishCode().compareTo(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()) == 0)).collect(Collectors.toList());
//进料主条码数据信息
List<MesProductionPsInContext> productionPsInContextList = null;
//加工规则数据信息集合
List<MesProdRuleContext> prodRuleContextList = new ArrayList<>();
//获取工步参数
Optional<Map<String, MesProdRouteOptParam>> stepParamMap = getStepParams(reqBean);
//是否验证工艺路线配置
String isCheckCraft = (null != stepParamMap && stepParamMap.isPresent() && stepParamMap.get().containsKey(MesPcnExtConstWords.IS_CHECK_CRAFT_CFG)) ? stepParamMap.get().get(MesPcnExtConstWords.IS_CHECK_CRAFT_CFG).getParamValue() : null;
List<String> stationNameList = containerPackageDetailStationContext.getStationList().stream().filter(o -> null != o).map(MesStation::getStation).collect(Collectors.toList());
List<ReentrantLock> acquiredLocks = new ArrayList<>();
try {
if (!MesReentrantLockUtil.tryLock(acquiredLocks, stationNameList, MesPcnExtConstWords.MATCH_STATION_PRODUCT_SN_CONTEXT + MesPcnExtConstWords.COLON, 3000L)) {
return stepDynamicsCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog().checkRepeat(), stepResult, false,
MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT, "匹配原料站点时LOCK失败,即将重试!");
}
// 结尾需要缓存锁定的数据
List<MesContainerPackageDetailContext> needCachedList = null;
//循环到全部验证成功或根据场景验证失败结束
for (int i = 0; i >= 0; i ++) {
stepResult = StepResult.getSuccessComplete();
//【原料站点】获取进料主条码信息
List<MesContainerPackageDetailContext> containerPackageDetailContextList = strategyService.getContainerPackageDetailContext(reqBean, containerPackageDetailStationContext, cellEquipContext.getCavity(), !CollectionUtils.isEmpty(productionPartContextList2UnFinish));
//验证是否满足腔数【前置验证】
if (!strategyService.checkIsMatchCavity(getListSize(containerPackageDetailContextList), getListSize(prodRuleContextList), getListSize(productionPartContextList2UnFinish), cellEquipContext.getCavity(), true)) {
return stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult.nextTriggerEvent(MesPcnExtConstWords.NEXT_TRIGGER_EVENT_FEEDING), "匹配原料站点时验证[原料]站点当前进料不足!");
}
//封装主条码信息上下文
List<MesEquipVariableCollectContext> equipVariableCollectContextList = new ArrayList<>();
containerPackageDetailContextList.stream().filter(o -> null != o).forEach(o ->
equipVariableCollectContextList.add(new MesEquipVariableCollectContext(reqBean.getOrganizeCode(), o.getBarCode(), MesExtEnumUtil.CELL_MESSAGE_SOURCE.READ.getValue()).qty(o.getQty())));
//处理条码验证逻辑 【条码验证失败直接抛出异常】
productionPsInContextList = productSnCheckStepService.checkProduceSnValid(reqBean, resultBean, stepResult, productionProcessContext, equipVariableCollectContextList, productionPsInContextList);
if (!stepResult.isCompleted()) stepSendGuideAndThrowEx(reqBean, new StationResultBean(), "主条码验证失败!请人工处理!");
//显示装配件扫描项工步【非排序】【业务处理】
assemblyShowNosortStepService.doHandleProdRuleContext(reqBean, new StationResultBean().isIgnore(true), stepResult, workCenter, productionProcessContext, cellEquipContext, prodRuleContextList, productionPartContextList, productionPsInContextList);
//前道工艺防错工步【非排序】
if (stepResult.isCompleted() && !StringUtils.isEmpty(isCheckCraft) && !(((IStepService) SpringContextsUtil.getBean("mesProdCraftRouteCheckNosortStepService")).executeInState(reqBean)).isCompleted()) {
stepSendGuideAndThrowEx(reqBean, new StationResultBean(), "主条码前道工艺防错验证失败!请人工处理!");
}
//验证是否满足腔数【后置验证】
Boolean result = strategyService.checkIsMatchCavity(getListSize(containerPackageDetailContextList), getListSize(prodRuleContextList), getListSize(productionPartContextList2UnFinish), cellEquipContext.getCavity(), false);
if (null != result && !result) {
stepNonCompleteAndSendMsg(reqBean, resultBean.writeDbLog(), stepResult, stepResult.getMsg());
stepSendGuideAndThrowEx(reqBean, new StationResultBean(), "加工规则匹配失败!请人工处理!");
}
if (stepResult.isCompleted()) {
if (CollectionUtils.isEmpty(needCachedList)) needCachedList = new ArrayList<>();
needCachedList.addAll(containerPackageDetailContextList);
}
if (null != result && result) break;
//result为null需要继续循环处理
containerPackageDetailContextList.get(0).matchResult(stepResult.isCompleted() ? CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValueStr() : CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValueStr());
}
//锁定当前已被验证了的主条码或容器条码
strategyService.dispatchContainerPackageDetailPs(reqBean, needCachedList);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return stepDynamicsCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog().checkRepeat(), stepResult, false,
MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT, "匹配原料站点异常,即将重试!");
} finally {
MesReentrantLockUtil.unLockAll(acquiredLocks);
}
//显示装配件扫描项
assemblyShowNosortStepService.showProductionAssembly(reqBean, resultBean, workCenter, prodRuleContextList);
//生产零件条码业务处理
productSnGenerateStepService.doHandleProductSnGenerate(reqBean, resultBean, stepResult, productionProcessContext, productionPartContextList, productionPsInContextList, prodRuleContextList, prodShiftContext);
return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, "匹配原料站点验证成功!", MesPcnEnumUtil.PROMPT_SOUND.SUCCESS.getValue());
}
//获取集合的个数
private Integer getListSize(List list) { return CollectionUtils.isEmpty(list) ? MesPcnExtConstWords.ZERO : list.size(); }
//搜集设备站点 【进料】【原料站点&&混料站点】
private List<MesStation> filterStationList2Ps(StationRequestBean reqBean, StationResultBean resultBean, List<MesStation> stationList) {
//剔除没有加工模式的站点数据
List<MesStation> filterList = stationList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getProcessMethod()))).collect(Collectors.toList());
//原料站点
List<MesStation> stationList10 = productionProcessContextStepService.dispatchEquipmentStationContext(filterList, Stream.of(MesExtEnumUtil.STATION_TYPE.STATION_TYPE_10.getValue()).collect(Collectors.toList()));
//混料站点
List<MesStation> stationList40 = productionProcessContextStepService.dispatchEquipmentStationContext(filterList, Stream.of(MesExtEnumUtil.STATION_TYPE.STATION_TYPE_40.getValue()).collect(Collectors.toList()));
//原料站点根据加工模式分组
Map<Integer, List<MesStation>> processMethodMap10 = CollectionUtils.isEmpty(stationList10) ? null : stationList10.stream().filter(o -> null != o).collect(Collectors.groupingBy(MesStation::getProcessMethod));
//混料站点根据加工模式分组
Map<Integer, List<MesStation>> processMethodMap40 = CollectionUtils.isEmpty(stationList40) ? null : stationList40.stream().filter(o -> null != o).collect(Collectors.groupingBy(MesStation::getProcessMethod));
if (CollectionUtils.isEmpty(processMethodMap10) && CollectionUtils.isEmpty(processMethodMap40)) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), String.format("匹配原料站点时验证设备未关联有效的[%s]站点!",
new StringJoiner(MesPcnExtConstWords.SLANT_R).add(MesExtEnumUtil.STATION_TYPE.STATION_TYPE_10.getDescription()).add(MesExtEnumUtil.STATION_TYPE.STATION_TYPE_40.getDescription()).toString()));
//验证加工模式, 原料站点只能维护一种加工模式
if (!CollectionUtils.isEmpty(processMethodMap10) && processMethodMap10.size() != 1) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), "匹配原料站点时验证设备关联的原料站点的加工模式配置错误!");
//验证加工模式, 原料站点不存在的时候, 混料站点只能维护一种加工模式
if (CollectionUtils.isEmpty(processMethodMap10) && processMethodMap40.size() != 1) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), "匹配原料站点时验证设备关联的混料站点的加工模式配置错误!");
//存在原料站点时,合并跟原料站点相同加工模式的混料站点
if (!CollectionUtils.isEmpty(stationList10)) {
stationList40 = CollectionUtils.isEmpty(stationList40) ? null : stationList40.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getProcessMethod()) && o.getProcessMethod().compareTo(stationList10.get(0).getProcessMethod()) == 0)).collect(Collectors.toList());
if (!CollectionUtils.isEmpty(stationList40)) stationList10.addAll(stationList40);
return stationList10;
}
//不存在原料站点时, 返回混料站点
return stationList40;
}
//前置验证不同类型的站点是否至少存在一个保底的容器条码用于存放产成品
private StepResult beforeCheckIsExistContainerSn(StationRequestBean reqBean, StationResultBean resultBean, StepResult stepResult,
List<MesStation> stationList, String suffix, MesExtEnumUtil.CONTAINER_PACKAGE_STATUS containerPackageStatus) {
if (CollectionUtils.isEmpty(stationList)) return stepResult;
//获取站点关联的容器条码【进料】
Map<String, List<MesContainerSnStation>> containerSnStationMap = stationContainerSnExtService.getContainerSnStationTopMap(reqBean.getOrganizeCode(), stationList);
List<String> containerSnList = CollectionUtils.isEmpty(containerSnStationMap) ? null : new ArrayList<>(containerSnStationMap.keySet());
//获取容器条码上料主表信息【进料】的一条数据
MesContainerPackage containerPackage = stationContainerSnExtService.getContainerPackageByContainerSn(
reqBean.getOrganizeCode(), containerSnList, null == containerPackageStatus ? null : containerPackageStatus.getValue());
if (null != containerPackage) return stepResult;
//成品|可疑场景下,如果上面查询的containerPackage不存在, 需要判断当前所有容器条码是否全部是已封箱的, 如果是则验证不通过 【不存在已关箱状态的数据即默认是未关箱的】
if (null != containerPackageStatus && MesExtEnumUtil.CONTAINER_PACKAGE_STATUS.STATUS_10.getValue() == containerPackageStatus.getValue()) {
List<MesContainerPackage> containerPackageList = stationContainerSnExtService.getContainerPackageListByContainerSn(
reqBean.getOrganizeCode(), containerSnList, MesExtEnumUtil.CONTAINER_PACKAGE_STATUS.STATUS_20.getValue());
List<String> containerSnListDistinct = CollectionUtils.isEmpty(containerPackageList) ? null :
(containerPackageList.stream().filter(o -> null != o).map(MesContainerPackage::getContainerSn).collect(Collectors.toList()))
.stream().filter(o -> !StringUtils.isEmpty(o)).distinct().collect(Collectors.toList());
if (!CollectionUtils.isEmpty(containerSnList) && (CollectionUtils.isEmpty(containerSnListDistinct) || containerSnListDistinct.size() != containerSnList.size())) return stepResult;
}
//保存站点用于绑定进料容器条码
productionDispatchContextStepService.dispatchMatchStationProductSnContext(reqBean, stationList);
return stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult.nextTriggerEvent(MesPcnExtConstWords.NEXT_TRIGGER_EVENT_FEEDING),
String.format("匹配原料站点时验证[%s]站点未绑定%s容器条码!", suffix, null == containerPackageStatus ? MesPcnExtConstWords.EMPTY : String.format("[%s]状态的", containerPackageStatus.getDescription())));
}
}

@ -401,7 +401,7 @@ public class MesProductionCustomContextStepService extends BaseStepService imple
public String getContainerPackageDetailAtomicityKey(String organizeCode, MesContainerPackageDetailContext context) {
return new StringJoiner(MesPcnExtConstWords.COLON)
.add(organizeCode)
.add(MesPcnExtConstWords.CONTAINER_SN_REMAIN_CONTEXT)
.add(MesPcnExtConstWords.MATCH_STATION_ASSEMBLY_CONTEXT)
.add(context.getStation())
.add(context.getContainerSn())
.add(new StringJoiner(MesPcnExtConstWords.AND).add(context.getBarCode()).add(context.getId().toString()).toString())
@ -432,6 +432,7 @@ public class MesProductionCustomContextStepService extends BaseStepService imple
return containerPackageDetailContextList;
}
//重置原料条码的缓存库存
@Override
public void dispatchContainerPackageDetailContext(String organizeCode, Map<String, MesContainerPackageDetailContext> remainQtyMap2Cache) {
for (Map.Entry<String, MesContainerPackageDetailContext> entry : remainQtyMap2Cache.entrySet()) {
@ -441,4 +442,29 @@ public class MesProductionCustomContextStepService extends BaseStepService imple
dispatchFsmBusiData(organizeCode, containerPackageDetailContext.getRemainKey(), containerPackageDetailContext.getRemainQty().toString(), MesPcnEnumUtil.EXPIRE_TIME.DEFAULT.getValue());
}
}
//可扣减条码的缓存key
@Override
public String getContainerPackageDetailPsKey(String organizeCode, String suffix, String psOrContainerSnAppendId) {
return new StringJoiner(MesPcnExtConstWords.COLON)
.add(organizeCode)
.add(MesPcnExtConstWords.MATCH_STATION_PRODUCT_SN_CONTEXT)
.add(suffix)
.add(psOrContainerSnAppendId)
.toString();
}
//验证主条码或容器条码是否被占用
@Override
public Boolean checkContainerPackageDetailPsIsUsed(StationRequestBean reqBean, String suffix, String psOrContainerSnAppendId) {
String location = getFsmBusiData(reqBean.getOrganizeCode(), getContainerPackageDetailPsKey(reqBean.getOrganizeCode(), suffix, psOrContainerSnAppendId));
return (StringUtils.isEmpty(location) || location.equals(reqBean.getClientInfo())) ? false : true;
}
//锁定主条码或容器条码
@Override
public void dispatchContainerPackageDetailPs(StationRequestBean reqBean, String suffix, String psOrContainerSnAppendId) {
dispatchFsmBusiData(reqBean.getOrganizeCode(), getContainerPackageDetailPsKey(reqBean.getOrganizeCode(), suffix, psOrContainerSnAppendId), reqBean.getClientInfo(), MesPcnEnumUtil.EXPIRE_TIME.ONE_QUARTER.getValue());
}
}

@ -21,9 +21,11 @@ import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.StringJoiner;
import java.util.stream.Collectors;
/**
* @Description : BUSI
@ -591,16 +593,37 @@ public class MesProductionDispatchContextStepService extends BaseStepService imp
//获取站点用于缺料时进行上料绑定
@Override
public List<MesStation> getMatchStationContext(StationRequestBean reqBean) {
String stationContext = getFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.MATCH_STATION_CONTEXT);
return !StringUtils.isEmpty(stationContext) ? JSONObject.parseArray(stationContext, MesStation.class) : null;
public List<MesStation> getMatchStationContext(StationRequestBean reqBean, String item) {
String stationContext = getFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), item);
List<MesStation> stationList = !StringUtils.isEmpty(stationContext) ? JSONObject.parseArray(stationContext, MesStation.class) : null;
if (!CollectionUtils.isEmpty(stationList)) stationList = stationList.stream().sorted(Comparator.comparing(MesStation::getStationType).thenComparing(MesStation::getCreateDatetime)).collect(Collectors.toList());
return stationList;
}
//保存站点用于缺料时进行上料绑定
//获取装配件站点用于缺料时进行上料绑定
@Override
public void dispatchMatchStationContext(StationRequestBean reqBean, List<MesStation> stationList) {
public List<MesStation> getMatchStationAssemblyContext(StationRequestBean reqBean) {
return getMatchStationContext(reqBean, MesPcnExtConstWords.MATCH_STATION_ASSEMBLY_CONTEXT);
}
//保存装配件站点用于缺料时进行上料绑定
@Override
public void dispatchMatchStationAssemblyContext(StationRequestBean reqBean, List<MesStation> stationList) {
if (CollectionUtils.isEmpty(stationList)) return;
dispatchFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.MATCH_STATION_CONTEXT, JSONObject.toJSONString(stationList));
dispatchFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.MATCH_STATION_ASSEMBLY_CONTEXT, JSONObject.toJSONString(stationList));
}
//获取站点用于进料时进行上料绑定
@Override
public List<MesStation> getMatchStationProductSnContext(StationRequestBean reqBean) {
return getMatchStationContext(reqBean, MesPcnExtConstWords.MATCH_STATION_PRODUCT_SN_CONTEXT);
}
//保存站点用于进料时进行上料绑定
@Override
public void dispatchMatchStationProductSnContext(StationRequestBean reqBean, List<MesStation> stationList) {
if (CollectionUtils.isEmpty(stationList)) return;
dispatchFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.MATCH_STATION_PRODUCT_SN_CONTEXT, JSONObject.toJSONString(stationList));
}
//获取站点用于扣料业务中进行LOCK
@ -630,18 +653,4 @@ public class MesProductionDispatchContextStepService extends BaseStepService imp
dispatchFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.MATCH_STATION_FEED_CONTAINER_SN_CONTEXT, sn);
}
//获取站点用于进料时进行上料绑定
@Override
public List<MesStation> getPsMatchStationContext(StationRequestBean reqBean) {
String stationContext = getFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.PS_MATCH_STATION_CONTEXT);
return !StringUtils.isEmpty(stationContext) ? JSONObject.parseArray(stationContext, MesStation.class) : null;
}
//保存站点用于进料时进行上料绑定
@Override
public void dispatchPsMatchStationContext(StationRequestBean reqBean, List<MesStation> stationList) {
if (CollectionUtils.isEmpty(stationList)) return;
dispatchFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.PS_MATCH_STATION_CONTEXT, JSONObject.toJSONString(stationList));
}
}

@ -46,16 +46,8 @@ public class MesWorkOrderCheckCompleteQtyStepService extends BaseStepService {
public List<MesWorkOrderCompleteQtyContext> dispatchWorkOrderCompleteQtyContext(StationRequestBean reqBean, StationResultBean resultBean,
StepResult stepResult, MesProductionProcessContext productionProcessContext,
List<MesProductionPartContext> productionPartContextList,
List<MesProductionPsInContext> productionPsInContextList) {
return dispatchWorkOrderCompleteQtyContext(reqBean, resultBean, stepResult, productionProcessContext, productionPartContextList, productionPsInContextList, null);
}
//验证加工单完成数量, 验证的前提条件: 每腔均已匹配到加工规则;存在工单;
public List<MesWorkOrderCompleteQtyContext> dispatchWorkOrderCompleteQtyContext(StationRequestBean reqBean, StationResultBean resultBean,
StepResult stepResult, MesProductionProcessContext productionProcessContext,
List<MesProductionPartContext> productionPartContextList,
List<MesProductionPsInContext> productionPsInContextList,
List<MesProductionPsOutContext> productionPsOutContextList) {
List<MesProdRuleContext> prodRuleContextList) {
//是否存在产成零件信息
if (!stepResult.isCompleted() || CollectionUtils.isEmpty(productionPartContextList)) return null;
@ -74,8 +66,8 @@ public class MesWorkOrderCheckCompleteQtyStepService extends BaseStepService {
Map<Integer, MesProductionPsInContext> productionPsInContextMap = CollectionUtils.isEmpty(productionPsInContextList) ? null :
productionPsInContextList.stream().filter(o -> !StringUtils.isEmpty(o.getForeignKey())).collect(Collectors.toMap(MesProductionPsInContext::getForeignKey, o -> o));
//根据foreignkey分组产出零件条码
Map<Integer, MesProductionPsOutContext> productionPsOutContextMap = CollectionUtils.isEmpty(productionPsOutContextList) ? null :
productionPsOutContextList.stream().filter(o -> !StringUtils.isEmpty(o.getForeignKey())).collect(Collectors.toMap(MesProductionPsOutContext::getForeignKey, o -> o));
Map<Integer, MesProdRuleContext> prodRuleContextMap = CollectionUtils.isEmpty(prodRuleContextList) ? null :
prodRuleContextList.stream().filter(o -> !StringUtils.isEmpty(o.getForeignKey())).collect(Collectors.toMap(MesProdRuleContext::getForeignKey, o -> o));
//生产线与工位信息
MesWorkCenter workCenter = productionProcessContext.getWorkCenter();
@ -90,7 +82,7 @@ public class MesWorkOrderCheckCompleteQtyStepService extends BaseStepService {
//验证加工单完成数量
MesWorkOrderCompleteQtyContext workOrderCompleteQtyContext = dispatchWorkOrderCompleteQty(
reqBean, resultBean, stepResult, workCenter, noCalcOrderQty, entry.getValue(), productionPsInContextMap, productionPsOutContextMap);
reqBean, resultBean, stepResult, workCenter, noCalcOrderQty, entry.getValue(), productionPsInContextMap, prodRuleContextMap);
//验证失败直接退出
if (!stepResult.isCompleted()) break;
@ -118,17 +110,17 @@ public class MesWorkOrderCheckCompleteQtyStepService extends BaseStepService {
StepResult stepResult, MesWorkCenter workCenter, Boolean noCalcOrderQty,
List<MesProductionPartContext> productionPartContextList,
Map<Integer, MesProductionPsInContext> productionPsInContextMap,
Map<Integer, MesProductionPsOutContext> productionPsOutContextMap) {
Map<Integer, MesProdRuleContext> prodRuleContextMap) {
Double calcCompleteQty = new Double(MesPcnExtConstWords.ZERO);
for (MesProductionPartContext productionPartContext : productionPartContextList) {
MesProductionPsInContext productionPsInContext = getProductionPsInContext(productionPsInContextMap, productionPartContext.getForeignKey());
MesProductionPsOutContext productionPsOutContext = getProductionPsOutContext(productionPsOutContextMap, productionPartContext.getForeignKey());
MesProdRuleContext prodRuleContext = getProdRuleContext(prodRuleContextMap, productionPartContext.getForeignKey());
//验证进料零件与产出零件是否一致
Boolean isSamePart = isSamePart(productionPsInContext, productionPartContext, null);
//验证是否计数
Boolean isCalcCompleteQty = isCalcCompleteQty(isSamePart, productionPsInContext, productionPartContext);
if (isCalcCompleteQty) calcCompleteQty = MathOperation.add(calcCompleteQty, null != productionPsOutContext ? productionPsOutContext.getQty() : new Double(MesPcnExtConstWords.ONE));
if (isCalcCompleteQty) calcCompleteQty = MathOperation.add(calcCompleteQty, null != prodRuleContext ? prodRuleContext.getEachCavityQty() : new Double(MesPcnExtConstWords.ONE));
}
//当前工单无须计算工单完成数
if (MathOperation.compareTo(calcCompleteQty, new Double(MesPcnExtConstWords.ZERO)) == 0) return null;
@ -184,10 +176,10 @@ public class MesWorkOrderCheckCompleteQtyStepService extends BaseStepService {
return productionPsInContextMap.get(foreignKey);
}
//根据数据关联键获取产出零件信息
private MesProductionPsOutContext getProductionPsOutContext(Map<Integer, MesProductionPsOutContext> productionPsOutContextMap, Integer foreignKey) {
if (CollectionUtils.isEmpty(productionPsOutContextMap) || StringUtils.isEmpty(foreignKey)) return null;
return productionPsOutContextMap.get(foreignKey);
//根据数据关联键获取加工规则数据
private MesProdRuleContext getProdRuleContext(Map<Integer, MesProdRuleContext> prodRuleContextMap, Integer foreignKey) {
if (CollectionUtils.isEmpty(prodRuleContextMap) || StringUtils.isEmpty(foreignKey)) return null;
return prodRuleContextMap.get(foreignKey);
}
//验证工单完成数

@ -0,0 +1,28 @@
package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step.method.stationpm;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesContainerPackageDetailContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesContainerPackageDetailStationContext;
import cn.estsh.i3plus.pojo.mes.bean.MesStation;
import cn.estsh.i3plus.pojo.mes.model.StationRequestBean;
import io.swagger.annotations.ApiOperation;
import java.util.List;
public interface IMesStationMatchPsProcessMethodStrategyStepService {
@ApiOperation(value = "【原料站点】获取容器条码上料明细表信息")
default MesContainerPackageDetailStationContext getContainerPackageDetailStationContext(String organizeCode, List<MesStation> stationList) { return null; }
@ApiOperation(value = "【原料站点】获取容器条码上料明细表信息")
default MesContainerPackageDetailStationContext getContainerPackageDetailStationContext(IMesStationMatchPsProcessMethodStrategyStepService decoratorService, String organizeCode, List<MesStation> stationList) { return null; }
@ApiOperation(value = "【原料站点】获取进料主条码信息")
default List<MesContainerPackageDetailContext> getContainerPackageDetailContext(StationRequestBean reqBean, MesContainerPackageDetailStationContext context, Integer cavity, Boolean isExistProductionPart) { return null; }
@ApiOperation(value = "【原料站点】验证进料主条码个数是否满足腔数 【count1=进料主条码个数 count2=加工规则对象个数 count3=产成零件个数[腔数] cavity=设备腔数】")
default Boolean checkIsMatchCavity(Integer count1, Integer count2, Integer count3, Integer cavity, Boolean isBeforeCheck) { return true; }
@ApiOperation(value = "【原料站点】锁定进料主条码信息")
default void dispatchContainerPackageDetailPs(StationRequestBean reqBean, List<MesContainerPackageDetailContext> needCachedList) {}
}

@ -0,0 +1,92 @@
package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step.method.stationpm;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionCustomContextStepService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesContainerPackageDetailContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesContainerPackageDetailStationContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseStepService;
import cn.estsh.i3plus.pojo.mes.bean.MesStation;
import cn.estsh.i3plus.pojo.mes.model.StationRequestBean;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* @Description : -
* @Author : wangjie
**/
@Slf4j
@Service("mesStationMatchPsProcessMethodContainerStepService")
public class MesStationMatchPsProcessMethodContainerStepService extends BaseStepService implements IMesStationMatchPsProcessMethodStrategyStepService {
@Autowired
private IMesStationMatchPsProcessMethodStrategyStepService defaultDecoratorService;
@Autowired
private IMesProductionCustomContextStepService productionCustomContextStepService;
//【原料站点】获取容器条码上料明细表信息
@Override
public MesContainerPackageDetailStationContext getContainerPackageDetailStationContext(String organizeCode, List<MesStation> stationList) {
return getContainerPackageDetailStationContext(defaultDecoratorService, organizeCode, stationList);
}
//【原料站点】获取容器条码上料明细表信息
@Override
public MesContainerPackageDetailStationContext getContainerPackageDetailStationContext(IMesStationMatchPsProcessMethodStrategyStepService decoratorService, String organizeCode, List<MesStation> stationList) {
MesContainerPackageDetailStationContext decoratorContext = decoratorService.getContainerPackageDetailStationContext(organizeCode, stationList);
if (null == decoratorContext) return decoratorContext;
return new MesContainerPackageDetailStationContext().addStationList(decoratorContext.getStationList()).addStationContainerSnDetailList(decoratorContext);
}
//【原料站点】获取进料主条码信息
@Override
public List<MesContainerPackageDetailContext> getContainerPackageDetailContext(StationRequestBean reqBean, MesContainerPackageDetailStationContext context, Integer cavity, Boolean isExistProductionPart) {
if (null == context) return null;
List<MesContainerPackageDetailStationContext> containerPackageDetailStationContextList = context.getStationContainerSnDetailList();
for (MesContainerPackageDetailStationContext containerPackageDetailStationContext : containerPackageDetailStationContextList) {
if (null == containerPackageDetailStationContext) continue;
LinkedHashMap<String, List<MesContainerPackageDetailContext>> containerSnDataMap = containerPackageDetailStationContext.getTopContainerSnDetailMap2Sort();
for (Map.Entry<String, List<MesContainerPackageDetailContext>> entry : containerSnDataMap.entrySet()) {
if (null == entry || !StringUtils.isEmpty(entry.getValue().get(0).getIsUsed())) continue;
//验证是否被使用
if (productionCustomContextStepService.checkContainerPackageDetailPsIsUsed(reqBean, MesPcnExtConstWords.CONTAINER_SN, entry.getKey())) {
//标记被使用
entry.getValue().get(0).isUsed();
continue;
}
//返回整箱
return entry.getValue();
}
}
return null;
}
//【原料站点】验证进料主条码个数是否满足腔数
// count1=进料主条码个数 count2=加工规则对象个数 count3=产成零件个数[腔数] cavity=设备腔数
@Override
public Boolean checkIsMatchCavity(Integer count1, Integer count2, Integer count3, Integer cavity, Boolean isBeforeCheck) {
//前置验证
if (isBeforeCheck) {
//不存在产成,按箱加工则不验证腔数,箱内条数即腔数
if (count3.compareTo(MesPcnExtConstWords.ZERO) == 0) return true;
//存在产成, 验证进料是否满足产成腔数
return count1.compareTo(count3) == 0;
}
//后置验证 为true或者false 均退出循环
return count1.compareTo(count2) == 0;
}
//【原料站点】锁定进料主条码信息
@Override
public void dispatchContainerPackageDetailPs(StationRequestBean reqBean, List<MesContainerPackageDetailContext> needCachedList) {
productionCustomContextStepService.dispatchContainerPackageDetailPs(reqBean, MesPcnExtConstWords.CONTAINER_SN, needCachedList.get(0).getTopContainerSnKey());
}
}

@ -0,0 +1,124 @@
package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step.method.stationpm;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesStationContainerSnExtService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesContainerPackageDetailContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesContainerPackageDetailStationContext;
import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseStepService;
import cn.estsh.i3plus.pojo.mes.bean.MesContainerPackage;
import cn.estsh.i3plus.pojo.mes.bean.MesContainerPackageDetail;
import cn.estsh.i3plus.pojo.mes.bean.MesContainerSnStation;
import cn.estsh.i3plus.pojo.mes.bean.MesStation;
import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.util.*;
import java.util.stream.Collectors;
/**
* @Description : - Decorator
* @Author : wangjie
**/
@Slf4j
@Primary
@Service("mesStationMatchPsProcessMethodDecoratorStepService")
public class MesStationMatchPsProcessMethodDecoratorStepService extends BaseStepService implements IMesStationMatchPsProcessMethodStrategyStepService {
@Autowired
private IMesStationContainerSnExtService stationContainerSnExtService;
@Override
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public MesContainerPackageDetailStationContext getContainerPackageDetailStationContext(String organizeCode, List<MesStation> stationList) {
//获取站点关联的容器条码
List<MesContainerSnStation> containerSnStationList = stationContainerSnExtService.getContainerSnStationList(organizeCode, stationList);
containerSnStationList = CollectionUtils.isEmpty(containerSnStationList) ? null :
containerSnStationList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getContainerSn()) && !StringUtils.isEmpty(o.getTopContainerSn()))).collect(Collectors.toList());
if (CollectionUtils.isEmpty(containerSnStationList)) return null;
//容器条码根据TOP容器条码分组
Map<String, List<MesContainerSnStation>> topContainerSnMap = CollectionUtils.isEmpty(containerSnStationList) ? null :
containerSnStationList.stream().filter(o -> null != o).collect(Collectors.groupingBy(MesContainerSnStation::getTopContainerSn));
//容器条码根据容器条码分组
Map<String, List<MesContainerSnStation>> containerSnMap = CollectionUtils.isEmpty(containerSnStationList) ? null :
containerSnStationList.stream().filter(o -> null != o).collect(Collectors.groupingBy(MesContainerSnStation::getContainerSn));
//容器条码根据创建时间正序 【暂不考虑seq, 因为站点没有顺序, 没法比较多站点的情况, 一个站点的情况下, 创建时间正序正常情况下等同于seq正序】
containerSnStationList = containerSnStationList.stream().filter(o -> null != o).sorted(Comparator.comparing(MesContainerSnStation::getCreateDatetime)).collect(Collectors.toList());
//根据TOP去重
List<MesContainerSnStation> containerSnStationList2TopDistinct = containerSnStationList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getTopContainerSn())))
.distinct().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(MesContainerSnStation::getTopContainerSn))), ArrayList::new));
//搜集料架车容器条码
List<String> topContainerSnList = containerSnStationList2TopDistinct.stream().filter(o -> (null != o && !o.getTopContainerSn().equals(o.getContainerSn()))).map(MesContainerSnStation::getTopContainerSn).collect(Collectors.toList());
//料桶容器条码
List<String> containerSnList = new ArrayList<>(containerSnMap.keySet());
//最外层料架车与料桶容器条码
List<String> allContainerSnList = new ArrayList<>(containerSnList);
//合并
if (!CollectionUtils.isEmpty(topContainerSnList)) allContainerSnList.addAll(topContainerSnList);
//去重
allContainerSnList = allContainerSnList.stream().filter(o -> !StringUtils.isEmpty(o)).distinct().collect(Collectors.toList());
//获取合并的容器条码上料主表信息【已关箱】
List<MesContainerPackage> containerPackageList = stationContainerSnExtService.getContainerPackageListByContainerSn(organizeCode, allContainerSnList, MesExtEnumUtil.CONTAINER_PACKAGE_STATUS.STATUS_20.getValue());
//料桶对应的上料主表数据
List<MesContainerPackage> containerPackageList2Detail = CollectionUtils.isEmpty(containerPackageList) ? null :
containerPackageList.stream().filter(o -> (null != o && containerSnList.contains(o.getContainerSn()))).collect(Collectors.toList());
if (CollectionUtils.isEmpty(containerPackageList) || CollectionUtils.isEmpty(containerPackageList2Detail)) return null;
//获取料桶对应的上料明细表信息【可扣减】
List<MesContainerPackageDetail> containerPackageDetailList = stationContainerSnExtService.getContainerPackageDetailList(organizeCode, containerPackageList2Detail);
if (CollectionUtils.isEmpty(containerPackageDetailList)) return null;
//已关箱的容器条码信息根据条码分组
Map<String, List<MesContainerPackage>> containerPackageMap = containerPackageList.stream().filter(o -> null != o).collect(Collectors.groupingBy(MesContainerPackage::getContainerSn));
//站点根据名称分组
Map<String, List<MesStation>> stationMap = stationList.stream().filter(o -> null != o).collect(Collectors.groupingBy(MesStation::getStation));
Map<String, MesStation> stationMap2Back = new HashMap<>();
//封装容器条码对应的【可扣减】的上料明细表信息
List<MesContainerPackageDetailContext> containerSnStationContextList = new ArrayList<>();
for (MesContainerPackageDetail containerPackageDetail : containerPackageDetailList) {
if (null == containerPackageDetail) continue;
MesContainerSnStation containerSnStation = containerSnMap.get(containerPackageDetail.getContainerSn()).get(0);
containerSnStationContextList.add(
new MesContainerPackageDetailContext(containerPackageDetail)
.containerSnStation(containerSnStation, containerPackageMap.get(containerSnStation.getTopContainerSn()).get(0).getId())
.station(stationMap.get(containerSnStation.getStation()).get(0))
);
if (!stationMap2Back.containsKey(containerSnStation.getStation())) stationMap2Back.put(containerSnStation.getStation(), stationMap.get(containerSnStation.getStation()).get(0));
}
//上料明细数据根据TOP容器条码分组
Map<String, List<MesContainerPackageDetailContext>> topContainerSnDetailMap = containerSnStationContextList.stream().filter(o -> null != o).collect(Collectors.groupingBy(MesContainerPackageDetailContext::getTopContainerSn));
//已关箱的料架车容器条码
List<String> topContainerSnList2Colsed = (CollectionUtils.isEmpty(containerPackageList) || CollectionUtils.isEmpty(topContainerSnList)) ? null :
containerPackageList.stream().filter(o -> (null != o && topContainerSnList.contains(o.getContainerSn()))).map(MesContainerPackage::getContainerSn).collect(Collectors.toList());
LinkedHashMap<String, List<MesContainerPackageDetailContext>> topContainerSnDetailMap2Sort = new LinkedHashMap<>();
//遍历 根据创建时间正序,TOP去重后的容器条码
for (MesContainerSnStation containerSnStation : containerSnStationList2TopDistinct) {
//跳过被扣减完的容器条码
if (null == containerSnStation || !topContainerSnDetailMap.containsKey(containerSnStation.getTopContainerSn())) continue;
//跳过未封箱的料架车
if (!containerSnStation.getTopContainerSn().equals(containerSnStation.getContainerSn()) && !topContainerSnList2Colsed.contains(containerSnStation.getTopContainerSn())) continue;
//将明细数据按照主表createDatetime,明细表createDatetime 正序 后, 存入有序集合内
List<MesContainerPackageDetailContext> detailList2Sort = topContainerSnDetailMap.get(containerSnStation.getTopContainerSn()).stream().filter(o -> null != o)
.sorted(Comparator.comparing(MesContainerPackageDetailContext::getCreateDatetime2Package).thenComparing(MesContainerPackageDetailContext::getCreateDatetime)).collect(Collectors.toList());
topContainerSnDetailMap2Sort.put(detailList2Sort.get(0).getTopContainerSnKey(), detailList2Sort);
}
return new MesContainerPackageDetailStationContext((List<MesStation>) stationMap2Back.values(), topContainerSnDetailMap2Sort);
}
}

@ -0,0 +1,15 @@
package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step.method.stationpm;
import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseStepService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* @Description : -
* @Author : wangjie
**/
@Slf4j
@Service("mesStationMatchPsProcessMethodManyContainerStepService")
public class MesStationMatchPsProcessMethodManyContainerStepService extends BaseStepService implements IMesStationMatchPsProcessMethodStrategyStepService {
//TODO
}

@ -0,0 +1,129 @@
package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step.method.stationpm;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionCustomContextStepService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesContainerPackageDetailContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesContainerPackageDetailStationContext;
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.MesStation;
import cn.estsh.i3plus.pojo.mes.model.StationRequestBean;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @Description : -
* @Author : wangjie
**/
@Slf4j
@Service("mesStationMatchPsProcessMethodSingleStepService")
public class MesStationMatchPsProcessMethodSingleStepService extends BaseStepService implements IMesStationMatchPsProcessMethodStrategyStepService {
@Autowired
private IMesStationMatchPsProcessMethodStrategyStepService defaultDecoratorService;
@Autowired
private IMesProductionCustomContextStepService productionCustomContextStepService;
//【原料站点】获取容器条码上料明细表信息
@Override
public MesContainerPackageDetailStationContext getContainerPackageDetailStationContext(String organizeCode, List<MesStation> stationList) {
return getContainerPackageDetailStationContext(defaultDecoratorService, organizeCode, stationList);
}
//【原料站点】获取容器条码上料明细表信息
@Override
public MesContainerPackageDetailStationContext getContainerPackageDetailStationContext(IMesStationMatchPsProcessMethodStrategyStepService decoratorService, String organizeCode, List<MesStation> stationList) {
MesContainerPackageDetailStationContext containerPackageDetailStationContext = null;
for (MesStation station : stationList) {
if (null == station) continue;
MesContainerPackageDetailStationContext decoratorContext = decoratorService.getContainerPackageDetailStationContext(organizeCode, stationList);
if (null == decoratorContext) continue;
if (null == containerPackageDetailStationContext) containerPackageDetailStationContext = new MesContainerPackageDetailStationContext();
containerPackageDetailStationContext.addStationList(decoratorContext.getStationList()).addStationContainerSnDetailList(decoratorContext);
}
return containerPackageDetailStationContext;
}
//【原料站点】获取进料主条码信息
@Override
public List<MesContainerPackageDetailContext> getContainerPackageDetailContext(StationRequestBean reqBean, MesContainerPackageDetailStationContext context, Integer cavity, Boolean isExistProductionPart) {
List<MesContainerPackageDetailContext> resultList = null;
if (null == context) return resultList;
List<MesContainerPackageDetailStationContext> containerPackageDetailStationContextList = context.getStationContainerSnDetailList();
for (MesContainerPackageDetailStationContext containerPackageDetailStationContext : containerPackageDetailStationContextList) {
if (null == containerPackageDetailStationContext) continue;
LinkedHashMap<String, List<MesContainerPackageDetailContext>> containerSnDataMap = containerPackageDetailStationContext.getTopContainerSnDetailMap2Sort();
LOOP:
for (Map.Entry<String, List<MesContainerPackageDetailContext>> entry : containerSnDataMap.entrySet()) {
if (null == entry) continue;
List<MesContainerPackageDetailContext> containerSnDetailList = entry.getValue();
for (MesContainerPackageDetailContext containerPackageDetailContext : containerSnDetailList) {
//验证是否已经被使用
if (null == containerPackageDetailContext || !StringUtils.isEmpty(containerPackageDetailContext.getIsUsed())) continue;
//已经被匹配成功 matchResult不为空只会是在存在产成的情况下, 下面会先标记为0
if (!StringUtils.isEmpty(containerPackageDetailContext.getMatchResult()) && containerPackageDetailContext.getMatchResult().equals(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValueStr())) continue;
//已经被匹配失败, 跳到下个站点进行验证第一个未匹配的进料主条码
if (!StringUtils.isEmpty(containerPackageDetailContext.getMatchResult()) && containerPackageDetailContext.getMatchResult().equals(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValueStr())) break LOOP;
//验证是否被使用
if (productionCustomContextStepService.checkContainerPackageDetailPsIsUsed(reqBean, MesPcnExtConstWords.PRODUCT_SN, containerPackageDetailContext.getBarCodeKey())) {
//标记被使用
containerPackageDetailContext.isUsed();
continue;
}
//如果存在产成, 标记即将进行匹配, 直接返回进行单腔验证, 支持跨站点按照站点内的容器条码顺序进行一个个匹配
if (isExistProductionPart) {
//一个个匹配才需要标记为0, 匹配完成之后需要将0的数据标记为1或者2
containerPackageDetailContext.matchResult(MesPcnExtConstWords.ZERO_STR);
return Stream.of(containerPackageDetailContext).collect(Collectors.toList());
}
//不存在产成, 按顺序添加进料主条码,直到满足设备腔数
if (CollectionUtils.isEmpty(resultList)) resultList = new ArrayList<>();
resultList.add(containerPackageDetailContext);
if (resultList.size() == cavity) return resultList;
}
}
}
return resultList;
}
//【原料站点】验证进料主条码个数是否满足腔数
// count1=进料主条码个数 count2=加工规则对象个数 count3=产成零件个数[腔数] cavity=设备腔数
@Override
public Boolean checkIsMatchCavity(Integer count1, Integer count2, Integer count3, Integer cavity, Boolean isBeforeCheck) {
//前置验证
if (isBeforeCheck) {
//不存在产成, 需要一次取出满足设备腔数个数的进料, 验证进料是否满足设备腔数
if (count3.compareTo(MesPcnExtConstWords.ZERO) == 0) return count1.compareTo(cavity) == 0;
//存在产成, 进料等于0则是一定不够腔数的,因为后面满足腔数就进入下一个工步集了
return count1.compareTo(MesPcnExtConstWords.ZERO) > 0;
}
//后置验证, 为true或者false 均退出循环
//不存在产成, 验证加工规则是否满足设备腔数
if (count3.compareTo(MesPcnExtConstWords.ZERO) == 0) return count2.compareTo(cavity) == 0;
//存在产成, 验证加工规则是否满足产成腔数, 为null继续循环处理
return count2.compareTo(count3) == 0 ? true : null;
}
//【原料站点】锁定进料主条码信息
@Override
public void dispatchContainerPackageDetailPs(StationRequestBean reqBean, List<MesContainerPackageDetailContext> needCachedList) {
needCachedList.forEach(o -> productionCustomContextStepService.dispatchContainerPackageDetailPs(reqBean, MesPcnExtConstWords.PRODUCT_SN, o.getBarCodeKey()));
}
}

@ -0,0 +1,46 @@
package cn.estsh.i3plus.ext.mes.pcn.apiservice.util;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
@Component
public class MesReentrantLockUtil {
private final static Map<String, ReentrantLock> lockMap = new ConcurrentHashMap<>();
public static Boolean tryLock(List<ReentrantLock> acquiredLocks, List<String> keyList, String prefix, Long milliseconds) throws InterruptedException {
Collections.sort(keyList);
long remaining = TimeUnit.MILLISECONDS.toNanos(milliseconds);
long endTime = System.nanoTime() + remaining;
for (String key : keyList) {
if (StringUtils.isEmpty(key)) continue;
ReentrantLock lock = lockMap.computeIfAbsent(prefix + key, o -> new ReentrantLock());
if (!lock.tryLock(remaining, TimeUnit.NANOSECONDS)) return false;
acquiredLocks.add(lock);
remaining = endTime - System.nanoTime();
}
return true;
}
public static void unLockAll(List<ReentrantLock> acquiredLocks) {
for (int i = acquiredLocks.size() - 1; i >= 0; i --) acquiredLocks.get(i).unlock();
}
}

@ -1,6 +1,7 @@
package cn.estsh.i3plus.ext.mes.pcn.pojo.context;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.mes.bean.MesContainerPackageDetail;
import cn.estsh.i3plus.pojo.mes.bean.MesContainerSnStation;
import cn.estsh.i3plus.pojo.mes.bean.MesStation;
@ -10,6 +11,7 @@ import org.springframework.beans.BeanUtils;
import org.springframework.util.StringUtils;
import java.io.Serializable;
import java.util.StringJoiner;
/**
* -
@ -49,6 +51,22 @@ public class MesContainerPackageDetailContext extends MesContainerPackageDetail
@ApiParam(name = "加工模式")
private Integer processMethod;
@ApiParam("顶层容器条码")
private String topContainerSn;
@ApiParam("顶层容器条码KEY")
private String topContainerSnKey;
@ApiParam("进料条码KEY")
private String barCodeKey;
//0=即将进行匹配, 1=成功, 2=失败
@ApiParam("匹配结果")
private String matchResult;
@ApiParam("是否被使用")
private String isUsed;
public MesContainerPackageDetailContext() {}
public MesContainerPackageDetailContext(MesContainerPackageDetail containerPackageDetail) {
@ -63,6 +81,16 @@ public class MesContainerPackageDetailContext extends MesContainerPackageDetail
this.station = containerSnStation.getStation();
this.seq = !StringUtils.isEmpty(containerSnStation.getSeq()) ? containerSnStation.getSeq() : MesPcnExtConstWords.ZERO;
this.createDatetime2Package = containerSnStation.getCreateDatetime();
this.topContainerSn = containerSnStation.getTopContainerSn();
return this;
}
public MesContainerPackageDetailContext containerSnStation(MesContainerSnStation containerSnStation, Long topContainerSnId) {
this.containerSnStation(containerSnStation);
//容器条码&ID
this.topContainerSnKey = new StringJoiner(MesPcnExtConstWords.AND).add(this.topContainerSn).add(topContainerSnId.toString()).toString();
//BARCODE&ID
this.barCodeKey = new StringJoiner(MesPcnExtConstWords.AND).add(super.getBarCode()).add(super.getId().toString()).toString();
return this;
}
@ -97,6 +125,16 @@ public class MesContainerPackageDetailContext extends MesContainerPackageDetail
return this;
}
public MesContainerPackageDetailContext matchResult(String matchResult) {
this.matchResult = matchResult;
return this;
}
public MesContainerPackageDetailContext isUsed() {
this.isUsed = CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValueStr();
return this;
}
public MesStation getStationInfo() {
MesStation station = new MesStation();
station.setEquipmentCode(this.equipmentCode);

@ -0,0 +1,51 @@
package cn.estsh.i3plus.ext.mes.pcn.pojo.context;
import cn.estsh.i3plus.pojo.mes.bean.MesStation;
import io.swagger.annotations.ApiParam;
import lombok.Data;
import org.springframework.util.CollectionUtils;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
/**
* -
*/
@Data
public class MesContainerPackageDetailStationContext implements Serializable {
private static final long serialVersionUID = -6056654777597346815L;
@ApiParam(name = "站点信息")
private List<MesStation> stationList;
@ApiParam(name = "站点信息")
private LinkedHashMap<String, List<MesContainerPackageDetailContext>> topContainerSnDetailMap2Sort;
//从这个里面存取数据
@ApiParam(name = "多个站点的容器条码上料明细")
private List<MesContainerPackageDetailStationContext> stationContainerSnDetailList;
public MesContainerPackageDetailStationContext() {}
public MesContainerPackageDetailStationContext(List<MesStation> stationList,
LinkedHashMap<String, List<MesContainerPackageDetailContext>> topContainerSnDetailMap2Sort) {
this.stationList = stationList;
this.topContainerSnDetailMap2Sort = topContainerSnDetailMap2Sort;
}
public MesContainerPackageDetailStationContext addStationList(List<MesStation> stationList) {
if (CollectionUtils.isEmpty(this.stationList)) this.stationList = new ArrayList<>();
this.stationList.addAll(stationList);
return this;
}
public MesContainerPackageDetailStationContext addStationContainerSnDetailList(MesContainerPackageDetailStationContext containerPackageDetailStationContext) {
if (CollectionUtils.isEmpty(this.stationContainerSnDetailList)) this.stationContainerSnDetailList = new ArrayList<>();
this.stationContainerSnDetailList.add(containerPackageDetailStationContext);
return this;
}
}

@ -97,6 +97,9 @@ public class MesEquipVariableCollectContext implements Serializable {
@ApiParam("是否被消费/是否被验证")
private Integer isConsume = CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue();
@ApiParam("数量")
private Double qty;
public MesEquipVariableCollectContext() {}
public MesEquipVariableCollectContext(Long equipVariableId) {
@ -143,4 +146,9 @@ public class MesEquipVariableCollectContext implements Serializable {
return this;
}
public MesEquipVariableCollectContext qty(Double qty) {
this.qty = qty;
return this;
}
}

@ -49,6 +49,9 @@ public class MesProductionPsInContext implements Serializable {
@ApiParam("零件条码状态【用于发送设备加工参数】")
private Integer snStatus;
@ApiParam(name = "数量")
private Double qty = new Double(1);
@ApiParam("打印状态")
private Integer printStatus;
@ -98,6 +101,9 @@ public class MesProductionPsInContext implements Serializable {
@ApiParam("裁片方案代码")
private String cutCode;
@ApiParam("容器匹配信息")
public String containerSnData;
public MesProductionPsInContext() {}
public MesProductionPsInContext(String organizeCode, String productSn) {
@ -153,4 +159,9 @@ public class MesProductionPsInContext implements Serializable {
return this;
}
public MesProductionPsInContext qty(Double qty) {
if (!StringUtils.isEmpty(qty)) this.qty = qty;
return this;
}
}

@ -491,6 +491,8 @@ public class MesPcnExtConstWords {
public static final String IS_FILTER_PARALLEL = "isFilterParallel";
//是否根据工序顺序号过滤后道[工步参数]
public static final String IS_FILTER_AFTER_CRAFT = "isFilterAfterCraft";
//是否验证工艺路线[工步参数]
public static final String IS_CHECK_CRAFT_CFG = "isCheckCraftCfg";
// 装配件显示规则配置[工位参数]
public static final String ASSEMBLY_SHOW_MR_CFG = "ASSEMBLY_SHOW_MR_CFG";
@ -695,8 +697,6 @@ public class MesPcnExtConstWords {
public static final String CHOOSE_SHIPPING_RFID_ROUTE_MODE = "CHOOSE_SHIPPING_RFID_ROUTE_MODE";
// 设备站点
public static final String EQUIPMENT_STATION_CONTEXT = "EQUIPMENT_STATION_CONTEXT";
// 容器条码扣减剩余上下文
public static final String CONTAINER_SN_REMAIN_CONTEXT = "CONTAINER_SN_REMAIN_CONTEXT";
// 上下文: 展示组件数据
public static final String MODULE_CONTENT_CONTEXT = "MODULE_CONTENT_CONTEXT";
@ -742,8 +742,15 @@ public class MesPcnExtConstWords {
public static final String PROD_TEMP_DATA_CONTEXT = "PROD_TEMP_DATA_CONTEXT";
// 上下文: 发运队列
public static final String SHIPPING_QUEUE_CONTEXT = "SHIPPING_QUEUE_CONTEXT";
// 用于缺料时进行上料绑定的站点
public static final String MATCH_STATION_CONTEXT = "MATCH_STATION_CONTEXT";
// 投料站点标识
public static final String MATCH_STATION_CONTEXT_FLAG = "MATCH_STATION_CONTEXT_FLAG";
// 用于缺料时进行上料绑定的装配件站点
public static final String MATCH_STATION_ASSEMBLY_CONTEXT = "MATCH_STATION_ASSEMBLY_CONTEXT";
// 用于缺料时进行上料绑定的进料站点
public static final String MATCH_STATION_PRODUCT_SN_CONTEXT = "MATCH_STATION_PRODUCT_SN_CONTEXT";
// 用于扣料业务中进行LOCK
public static final String LOCK_STATION_CONTEXT = "LOCK_STATION_CONTEXT";
@ -754,10 +761,6 @@ public class MesPcnExtConstWords {
// 工步上料关箱码
public static final String MATCH_STATION_FEED_CLOSE_PACKAGE = "MATCH_STATION_FEED_CLOSE_PACKAGE";
// 用于进料绑定的站点
public static final String PS_MATCH_STATION_CONTEXT = "PS_MATCH_STATION_CONTEXT";
//OPC_API_PARAM
public static final String OPC_LINK_URL = "OPC_LINK_URL";
public static final String VALUE = "value";

Loading…
Cancel
Save