package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step.context;

import cn.estsh.i3plus.ext.mes.pcn.api.base.IMesEquipmentExtService;
import cn.estsh.i3plus.ext.mes.pcn.api.base.IMesProdOrgExtService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionProcessContextStepService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesQueueOrderPushService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesStationContainerSnExtService;
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.IFsmRouteDataService;
import cn.estsh.i3plus.mes.pcn.api.iservice.base.IConfigService;
import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseStepService;
import cn.estsh.i3plus.platform.common.tool.TimeTool;
import cn.estsh.i3plus.pojo.base.codemaker.SnowflakeIdMaker;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.mes.bean.*;
import cn.estsh.i3plus.pojo.mes.model.StationKvBean;
import cn.estsh.i3plus.pojo.mes.model.StationRequestBean;
import cn.estsh.i3plus.pojo.mes.model.StationResultBean;
import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
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.stream.Collectors;

/**
 * @Description : 获取生产过程上下文对象接口实现【BASE】
 * @Author : wangjie
 **/
@Slf4j
@Service("mesProductionProcessContextStepService")
public class MesProductionProcessContextStepService extends BaseStepService implements IMesProductionProcessContextStepService {

    @Autowired
    private IMesProdOrgExtService prodOrgExtService;

    @Autowired
    private IMesEquipmentExtService equipmentExtService;

    @Autowired
    private IFsmRouteDataService fsmRouteDataService;

    @Autowired
    private IConfigService configService;

    @Autowired
    private IMesQueueOrderPushService queueOrderPushService;

    @Autowired
    private SnowflakeIdMaker snowflakeIdMaker;

    @Autowired
    private IMesStationContainerSnExtService stationContainerSnExtService;

    private String getContextKey(StationRequestBean reqBean) {
        return getFsmBusikey(reqBean, new StringJoiner(MesPcnExtConstWords.COLON).add(MesPcnExtConstWords.PRODUCTION_PROCESS_CONTEXT).add(MesPcnExtConstWords.BASE_DATA_CONTEXT).toString());
    }

    private String getContextKey(String organizeCode, String workCenterCode, String workCellCode) {
        return new StringJoiner(MesPcnExtConstWords.COLON).add(organizeCode).add(workCenterCode).add(workCellCode).add(MesPcnExtConstWords.PRODUCTION_PROCESS_CONTEXT).add(MesPcnExtConstWords.BASE_DATA_CONTEXT).toString();
    }

    //清除上下文中的所有基础数据
    @Override
    public void flushProductionProcessContext(StationRequestBean reqBean) {
        removeFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean));
    }

    //存储生产过程上下文对象【工步根据业务实际情况执行,配置错误等情况无需执行】
    @Override
    public Boolean dispatchProductionProcessContext(StationRequestBean reqBean, MesProductionProcessContext productionProcessContext) {
        if (!productionProcessContext.getIsNeedCache()) return true;
        return dispatchFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.BASE_DATA_CONTEXT, JSONObject.toJSONString(productionProcessContext));
    }

    //获取生产过程上下文对象
    @Override
    public MesProductionProcessContext getProductionProcessContext(StationRequestBean reqBean, Boolean isCheckProcess) {

        MesProductionProcessContext productionProcessContext = getProductionProcessContextBaseData(reqBean, isCheckProcess);

        //验证组织模型有效性
        return checkBaseData(reqBean, productionProcessContext, isCheckProcess);

    }

    //获取生产过程上下文对象
    @Override
    public MesProductionProcessContext getProductionProcessContext(StationRequestBean reqBean) {

        MesProductionProcessContext productionProcessContext = getProductionProcessContextBaseData(reqBean, true);

        //验证组织模型有效性
        return checkBaseData(reqBean, productionProcessContext, true);

    }

    //获取生产过程上下文对象
    private MesProductionProcessContext getProductionProcessContextBaseData(StationRequestBean reqBean, Boolean isCheckProcess) {

        //获取缓存的生产过程上下文对象
        MesProductionProcessContext productionProcessContext = (MesProductionProcessContext) getFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.BASE_DATA_CONTEXT, MesProductionProcessContext.class);

        if (null == productionProcessContext) productionProcessContext = new MesProductionProcessContext(reqBean.getOrganizeCode());

        //生产过程上下文对象结果初始化
        productionProcessContext.success();

        //生产过程上下文对象赋值生产线信息
        if (StringUtils.isEmpty(productionProcessContext.getWorkCenterJson())) productionProcessContext.workCenterJson(prodOrgExtService.getWorkCenterDb(reqBean.getOrganizeCode(), reqBean.getWorkCenterCode()));

        //生产过程上下文对象赋值工位信息
        if (StringUtils.isEmpty(productionProcessContext.getWorkCellJson())) productionProcessContext.workCellJson(prodOrgExtService.getWorkCellDb(reqBean.getOrganizeCode(), reqBean.getWorkCenterCode(), reqBean.getWorkCellCode(), true));

        //生产过程上下文对象赋值工序工艺信息
        if (isCheckProcess && (StringUtils.isEmpty(productionProcessContext.getProcessCode()) || !productionProcessContext.getProcessCode().equals(reqBean.getProcessCode()))) processContext(reqBean, productionProcessContext);

        //生产过程上下文对象赋值生产过程控制全局密码
        if (StringUtils.isEmpty(productionProcessContext.getFinishCode()) || StringUtils.isEmpty(productionProcessContext.getCraftJumpCode()) ||
                StringUtils.isEmpty(productionProcessContext.getAssemblySkipCode()) || StringUtils.isEmpty(productionProcessContext.getAssemblyCavitySkipCode()) ||
                StringUtils.isEmpty(productionProcessContext.getSortSuspiciousCode())) productionPwdContext(reqBean, productionProcessContext);

        return productionProcessContext;

    }

    //获取工序工艺信息
    @Override
    public MesProductionProcessContext processContext(StationRequestBean reqBean) {
        return processContext(reqBean, getProductionProcessContext(reqBean));
    }

    //获取工序工艺信息
    @Override
    public MesProductionProcessContext processContext(StationRequestBean reqBean, MesProductionProcessContext productionProcessContext) {

        if (!productionProcessContext.getSuccess()) return productionProcessContext;

        if (!StringUtils.isEmpty(productionProcessContext.getProcessCode()) && productionProcessContext.getProcessCode().equals(reqBean.getProcessCode())) return productionProcessContext;

        MesProcessCraftCfg processCraftCfg = fsmRouteDataService.handleFsmProcessCraftData(reqBean, reqBean.getProcessCode());

        //生产过程上下文对象赋值当前工艺工序,未配置默认赋值工序代码,不强验证
        productionProcessContext.processCode(reqBean.getProcessCode(), null != processCraftCfg ? processCraftCfg.getProcessName() : reqBean.getProcessCode());

        return productionProcessContext.craftCode((null != processCraftCfg && !StringUtils.isEmpty(processCraftCfg.getCraftCode())) ? processCraftCfg.getCraftCode() : reqBean.getProcessCode(),
                (null != processCraftCfg && !StringUtils.isEmpty(processCraftCfg.getCraftName())) ? processCraftCfg.getCraftName() : productionProcessContext.getProcessName());

    }

    //获取生产过程控制全局密码
    @Override
    public MesProductionProcessContext productionPwdContext(StationRequestBean reqBean, MesProductionProcessContext productionProcessContext) {
        List<MesConfig> configList = configService.doCachedConfigList(MesPcnExtConstWords.PRODUCTION_PWD_CFG, reqBean.getOrganizeCode());
        Map<String, List<MesConfig>> cfgKeyMap =  CollectionUtils.isEmpty(configList) ? null : configList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getCfgKey()))).collect(Collectors.groupingBy(MesConfig::getCfgKey));
        return productionProcessContext.finishCode((!CollectionUtils.isEmpty(cfgKeyMap) && cfgKeyMap.containsKey(MesPcnExtConstWords.CAVITY_FINISH_CODE)) ? cfgKeyMap.get(MesPcnExtConstWords.CAVITY_FINISH_CODE).get(0).getCfgValue().toUpperCase() : MesPcnExtConstWords.CAVITY_FINISH_CODE)
                .craftJumpCode((!CollectionUtils.isEmpty(cfgKeyMap) && cfgKeyMap.containsKey(MesPcnExtConstWords.CRAFT_JUMP_CODE)) ? cfgKeyMap.get(MesPcnExtConstWords.CRAFT_JUMP_CODE).get(0).getCfgValue().toUpperCase() : MesPcnExtConstWords.CRAFT_JUMP_CODE)
                .assemblySkipCode((!CollectionUtils.isEmpty(cfgKeyMap) && cfgKeyMap.containsKey(MesPcnExtConstWords.ASSEMBLY_SKIP_CODE)) ? cfgKeyMap.get(MesPcnExtConstWords.ASSEMBLY_SKIP_CODE).get(0).getCfgValue().toUpperCase() : MesPcnExtConstWords.ASSEMBLY_SKIP_CODE)
                .assemblyCavitySkipCode((!CollectionUtils.isEmpty(cfgKeyMap) && cfgKeyMap.containsKey(MesPcnExtConstWords.ASSEMBLY_CAVITY_SKIP_CODE)) ? cfgKeyMap.get(MesPcnExtConstWords.ASSEMBLY_CAVITY_SKIP_CODE).get(0).getCfgValue().toUpperCase() : MesPcnExtConstWords.ASSEMBLY_CAVITY_SKIP_CODE)
                .sortSuspiciousCode((!CollectionUtils.isEmpty(cfgKeyMap) && cfgKeyMap.containsKey(MesPcnExtConstWords.SORT_SUSPICIOUS_CODE)) ? cfgKeyMap.get(MesPcnExtConstWords.SORT_SUSPICIOUS_CODE).get(0).getCfgValue().toUpperCase() : MesPcnExtConstWords.SORT_SUSPICIOUS_CODE)
                .containerBindClosePackage((!CollectionUtils.isEmpty(cfgKeyMap) && cfgKeyMap.containsKey(MesPcnExtConstWords.MATCH_STEP_CONTAINER_BIND_CLOSE_PACKAGE)) ? cfgKeyMap.get(MesPcnExtConstWords.MATCH_STEP_CONTAINER_BIND_CLOSE_PACKAGE).get(0).getCfgValue().toUpperCase() : MesPcnExtConstWords.MATCH_STEP_CONTAINER_BIND_CLOSE_PACKAGE);
    }

    //验证组织模型有效性
    @Override
    public MesProductionProcessContext checkBaseData(StationRequestBean reqBean, MesProductionProcessContext productionProcessContext, Boolean isCheckProcess) {

        if (StringUtils.isEmpty(productionProcessContext.getWorkCenterJson())) return productionProcessContext.message(String.format("请检查组织模型生产线[%s]信息的有效性!", reqBean.getWorkCenterCode()));

        if (StringUtils.isEmpty(MesExtEnumUtil.WORK_CENTER_TYPE.valueOfDescription(productionProcessContext.getWorkCenter().getCenterType()))) return productionProcessContext.message(String.format("请检查组织模型生产线,生产线[%s]信息未设置产线类型!", reqBean.getWorkCenterCode()));

        if (StringUtils.isEmpty(productionProcessContext.getWorkCellJson())) return productionProcessContext.message(String.format("请检查组织模型生产线[%s]工位[%s]信息的有效性!", reqBean.getWorkCenterCode(), reqBean.getWorkCellCode()));

        if (isCheckProcess && StringUtils.isEmpty(productionProcessContext.getProcessCode())) return productionProcessContext.message(String.format("请检查工序信息,生产线[%s]工位[%s]对应工序代码[%s]的有效性!", reqBean.getWorkCenterCode(), reqBean.getWorkCellCode(), reqBean.getProcessCode()));

        return productionProcessContext;

    }

    //获取工位设备集合信息
    @Override
    public MesProductionProcessContext getCellEquipmentList(StationRequestBean reqBean) {
        return getCellEquipmentList(reqBean, getProductionProcessContext(reqBean));
    }

    //获取工位设备集合信息
    @Override
    public MesProductionProcessContext getCellEquipmentList(StationRequestBean reqBean, MesProductionProcessContext productionProcessContext) {

        if (!productionProcessContext.getSuccess()) return productionProcessContext;

        //生产过程上下文对象赋值设备信息
        if (StringUtils.isEmpty(productionProcessContext.getCellEquipListJson())) productionProcessContext.cellEquipListJson(equipmentExtService.getCellEquipmentList(reqBean.getOrganizeCode(), reqBean.getWorkCenterCode(), reqBean.getWorkCellCode()));

        return productionProcessContext;

    }

    //获取工位当前设备信息
    @Override
    public MesProductionProcessContext dispatchCurCellEquipment(StationRequestBean reqBean) {
        return dispatchCurCellEquipment(reqBean, getCellEquipmentList(reqBean));
    }

    //获取工位当前设备信息
    @Override
    public MesProductionProcessContext dispatchCurCellEquipment(StationRequestBean reqBean, MesProductionProcessContext productionProcessContext) {

        if (!productionProcessContext.getSuccess()) return productionProcessContext;

        return dispatchCurCellEquipment(reqBean, productionProcessContext, getStepParams(reqBean));

    }

    //获取工位当前设备信息
    @Override
    public MesProductionProcessContext dispatchCurCellEquipment(StationRequestBean reqBean, Optional<Map<String, MesProdRouteOptParam>> stepParamMap) {
        return dispatchCurCellEquipment(reqBean, getCellEquipmentList(reqBean), stepParamMap);
    }

    //获取工位当前设备信息
    @Override
    public MesProductionProcessContext dispatchCurCellEquipment(StationRequestBean reqBean, MesProductionProcessContext productionProcessContext, Optional<Map<String, MesProdRouteOptParam>> stepParamMap) {

        if (!productionProcessContext.getSuccess()) return productionProcessContext;

        if (StringUtils.isEmpty(productionProcessContext.getCellEquipListJson())) getCellEquipmentList(reqBean, productionProcessContext);

        //获取当前工步的设备参数
        String equipmentCode = (null != stepParamMap && stepParamMap.isPresent() && stepParamMap.get().containsKey(MesPcnExtConstWords.EQUIPMENT_CODE_UC)) ? stepParamMap.get().get(MesPcnExtConstWords.EQUIPMENT_CODE_UC).getParamValue() : null;

        //判断生产过程上下文对象是否存在当前设备信息
        if (!StringUtils.isEmpty(productionProcessContext.getCurCellEquipJson()) && (StringUtils.isEmpty(equipmentCode) || equipmentCode.equals(productionProcessContext.getCurCellEquip().getEquipmentCode()))) return productionProcessContext;

        //从工位设备集合信息中获取当前设备信息
        MesCellEquipContext cellEquipmentContext = productionProcessContext.filterCurCellEquip(equipmentCode);

        //保存上下文工位扫描监控信息【设备信息】
        if (null != cellEquipmentContext) dispatchScanMonitorContext(reqBean,
                dispatchScanMonitorContext(reqBean, true).equipment(cellEquipmentContext.getEquipId(), cellEquipmentContext.getEquipmentCode(), cellEquipmentContext.getEquipmentName()), false);

        //生产过程上下文对象赋值当前设备代码
        if (null != cellEquipmentContext) return productionProcessContext.curCellEquipJson(cellEquipmentContext.kepwareFlagJson(equipmentExtService.getEquipmentChannelList(reqBean.getOrganizeCode(), cellEquipmentContext.getEquipmentCode())));

        return StringUtils.isEmpty(equipmentCode) ? productionProcessContext.message(String.format("请检查组织模型,生产线[%s]工位[%s]未维护设备信息!", reqBean.getWorkCenterCode(), reqBean.getWorkCellCode())) :
                productionProcessContext.message(String.format("请检查组织模型,生产线[%s]工位[%s]未维护工步参数[%s]配置的设备[%s]!", reqBean.getWorkCenterCode(), reqBean.getWorkCellCode(), MesPcnExtConstWords.EQUIPMENT_CODE_UC, equipmentCode));

    }

    //获取设备数据变量接口逻辑信息
    @Override
    public MesProductionProcessContext getEquipmentVariableCfgList(StationRequestBean reqBean) {
        return getEquipmentVariableCfgList(dispatchCurCellEquipment(reqBean));
    }

    //获取设备数据变量接口逻辑信息
    @Override
    public MesProductionProcessContext getEquipmentVariableCfgList(MesProductionProcessContext productionProcessContext) {

        if (!productionProcessContext.getSuccess()) return productionProcessContext;

        //判断生产过程上下文对象是否存在数据变量接口逻辑信息
        if (!CollectionUtils.isEmpty(productionProcessContext.getEquipVariableCfgListByVct())) return productionProcessContext;

        MesCellEquipContext cellEquipmentContext = productionProcessContext.getCurCellEquip();

        if (null == cellEquipmentContext || !productionProcessContext.getSuccess()) return productionProcessContext;

        List<MesEquipmentVariableCfg> equipmentVariableCfgList = equipmentExtService.getEquipmentVariableCfgList(productionProcessContext.getOrganizeCode(), cellEquipmentContext.getVariableCfgType());

        //生产过程上下文对象赋值设备数据变量接口逻辑集合信息
        if (!CollectionUtils.isEmpty(equipmentVariableCfgList)) productionProcessContext.equipVariableCfgJson(equipmentVariableCfgList);

        return productionProcessContext;

    }

    //根据变量类别搜集设备数据变量接口逻辑信息
    @Override
    public List<MesEquipmentVariableCfg> collectEquipmentVariableCfgList(List<MesEquipmentVariableCfg> equipmentVariableCfgList, String... variableCategory) {
        List<String> variableCategoryList = null == variableCategory ? null : Arrays.asList(variableCategory);
        return (CollectionUtils.isEmpty(equipmentVariableCfgList) || CollectionUtils.isEmpty(variableCategoryList)) ? null : equipmentVariableCfgList.stream().filter(o -> (null != o && variableCategoryList.contains(o.getVariableCategory()))).collect(Collectors.toList());
    }

    //验证设备数据变量接口逻辑信息中是否存在必要的变量类型信息
    @Override
    public MesProductionProcessContext checkNecessaryEquipmentVariableCfg(MesProductionProcessContext productionProcessContext, MesCellEquipContext cellEquipContext, List<MesEquipmentVariableCfg> equipmentVariableCfgList, String... variableCategory) {
        List<String> variableCategoryList = null == variableCategory ? null : Arrays.asList(variableCategory);
        Optional<MesEquipmentVariableCfg> optional = (CollectionUtils.isEmpty(equipmentVariableCfgList) || CollectionUtils.isEmpty(variableCategoryList)) ? null : equipmentVariableCfgList.stream().filter(o -> (null != o && variableCategoryList.contains(o.getVariableCategory()))).findFirst();
        return (null != optional && optional.isPresent()) ? productionProcessContext : productionProcessContext.message(String.format("请检查设备数据变量接口逻辑信息,设备[%s]未配置变量配置类型[%s]变量类别%s相关的数据变量接口逻辑信息!", cellEquipContext.getEquipmentName(), cellEquipContext.getVariableCfgType(), variableCategoryList.toString()));
    }

    //验证设备数据变量接口逻辑信息中是否存在必要的变量类型信息,并且参考值不能为空
    @Override
    public MesProductionProcessContext checkNecessaryEquipmentVariableCfgAndValue(MesProductionProcessContext productionProcessContext, MesCellEquipContext cellEquipContext, List<MesEquipmentVariableCfg> equipmentVariableCfgList, String... variableCategory) {
        List<String> variableCategoryList = null == variableCategory ? null : Arrays.asList(variableCategory);
        List<MesEquipmentVariableCfg> filterList = (CollectionUtils.isEmpty(equipmentVariableCfgList) || CollectionUtils.isEmpty(variableCategoryList)) ? null : equipmentVariableCfgList.stream().filter(o -> (null != o && variableCategoryList.contains(o.getVariableCategory()))).collect(Collectors.toList());
        Optional<MesEquipmentVariableCfg> optional = CollectionUtils.isEmpty(filterList) ? null : filterList.stream().filter(o -> (null != o && StringUtils.isEmpty(o.getValue()))).findFirst();
        return (!CollectionUtils.isEmpty(filterList) && (null == optional || !optional.isPresent())) ? productionProcessContext : productionProcessContext.message(String.format("请检查设备数据变量接口逻辑信息,设备[%s]未配置有效的变量配置类型[%s]变量类别%s相关的数据变量接口逻辑信息!", cellEquipContext.getEquipmentName(), cellEquipContext.getVariableCfgType(), variableCategoryList.toString()));
    }

    //搜集设备数据变量接口逻辑信息中的二级变量
    @Override
    public List<String> collectCategoryLevelTwoList(List<MesEquipmentVariableCfg> equipmentVariableCfgList) {
        return CollectionUtils.isEmpty(equipmentVariableCfgList) ? null :
                (equipmentVariableCfgList.stream().filter(o -> null != o).map(MesEquipmentVariableCfg::getCategoryLevelTwo).collect(Collectors.toList())).stream().filter(o -> !StringUtils.isEmpty(o)).distinct().collect(Collectors.toList());
    }

    //获取设备数据变量信息
    @Override
    public MesProductionProcessContext getEquipmentVariableList(StationRequestBean reqBean, Integer variableType) {
        return getEquipmentVariableList(getEquipmentVariableCfgList(reqBean), variableType);
    }

    //获取设备数据变量信息
    @Override
    public MesProductionProcessContext getEquipmentVariableList(MesProductionProcessContext productionProcessContext, Integer variableType) {

        if (!productionProcessContext.getSuccess() || StringUtils.isEmpty(variableType)) return productionProcessContext;

        MesCellEquipContext cellEquipmentContext = productionProcessContext.getCurCellEquip();

        //判断生产过程上下文对象是否存在数据变量信息
        if (!CollectionUtils.isEmpty(productionProcessContext.getEquipVariableListByEquVt(cellEquipmentContext.getEquipmentCode(), variableType))) return productionProcessContext;

        List<MesEquipmentVariable> equipmentVariableDbList = equipmentExtService.getEquipmentVariableList(productionProcessContext.getOrganizeCode(), cellEquipmentContext.getEquipmentCode(), variableType);

        //生产过程上下文对象赋值设备数据变量信息
        if (null != equipmentVariableDbList) productionProcessContext.equipVariableJson(equipmentVariableDbList);

        return productionProcessContext;

    }

    //获取设备数据变量信息
    @Override
    public List<MesEquipmentVariable> findEquipmentVariableList(MesProductionProcessContext productionProcessContext, Integer variableType) {

        if (!productionProcessContext.getSuccess() || StringUtils.isEmpty(variableType)) return null;

        MesCellEquipContext cellEquipmentContext = productionProcessContext.getCurCellEquip();

        //判断生产过程上下文对象是否存在数据变量信息
        List<MesEquipmentVariable> equipmentVariableDbList = productionProcessContext.getEquipVariableListByEquVt(cellEquipmentContext.getEquipmentCode(), variableType);
        if (!CollectionUtils.isEmpty(equipmentVariableDbList)) return equipmentVariableDbList;

        equipmentVariableDbList = equipmentExtService.getEquipmentVariableList(productionProcessContext.getOrganizeCode(), cellEquipmentContext.getEquipmentCode(), variableType);

        //生产过程上下文对象赋值设备数据变量信息
        if (null != equipmentVariableDbList) productionProcessContext.equipVariableJson(equipmentVariableDbList);

        return equipmentVariableDbList;

    }

    //根据变量类型与二级变量获取设备数据变量信息
    @Override
    public List<MesEquipmentVariable> findEquipmentVariableList(MesProductionProcessContext productionProcessContext, Integer variableType, List<String> categoryLevelTwoList) {
        List<MesEquipmentVariable> equipmentVariableList = findEquipmentVariableList(productionProcessContext, variableType);
        return findEquipmentVariableList(equipmentVariableList, variableType, categoryLevelTwoList);
    }

    //获取设备数据变量信息
    @Override
    public List<MesEquipmentVariable> findEquipmentVariableList(List<MesEquipmentVariable> equipmentVariableList, Integer variableType, List<String> categoryLevelTwoList) {
        return (CollectionUtils.isEmpty(equipmentVariableList) || CollectionUtils.isEmpty(categoryLevelTwoList)) ? null :
                equipmentVariableList.stream().filter(o -> (null != o && categoryLevelTwoList.contains(o.getCategoryLevelTwo()) && o.getVariableType().compareTo(variableType) == 0)).collect(Collectors.toList());
    }

    //验证设备数据变量信息是否为空
    @Override
    public MesProductionProcessContext checkIsEmptyEquipmentVariableList(MesProductionProcessContext productionProcessContext, MesCellEquipContext cellEquipContext, List<MesEquipmentVariable> equipmentVariableList, MesExtEnumUtil.EQUIP_VARIABLE_TYPE variableType, List<String> categoryLevelTwoList) {
        if (!CollectionUtils.isEmpty(equipmentVariableList)) return productionProcessContext;
        return productionProcessContext.message(String.format("请检查设备数据变量信息,根据设备[%s]对应的数据变量接口逻辑信息,未配置变量类型[%s]二级变量%s相关的数据变量信息!", cellEquipContext.getEquipmentName(), variableType.getDescription(), categoryLevelTwoList.toString()));
    }

    //查询工位设备装配件规则信息
    @Override
    public List<MesProductionAssemblyNosortContext> findAssemblyNosortCfgList(StationRequestBean reqBean) {
        String assemblyNosortCfgJson = getFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.ASSEMBLY_NOSORT_CFG_CONTEXT);
        return !StringUtils.isEmpty(assemblyNosortCfgJson) ? JSONObject.parseArray(assemblyNosortCfgJson, MesProductionAssemblyNosortContext.class) : null;
    }

    //存储设备的装配件清单
    @Override
    public Boolean dispatchAssemblyNosortCfgContext(StationRequestBean reqBean, List<MesProductionAssemblyNosortContext> assemblyNosortCfgList) {
        return dispatchFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.ASSEMBLY_NOSORT_CFG_CONTEXT, JSONObject.toJSONString(assemblyNosortCfgList));
    }

    //获取手动选择的腔数及工单信息上下文
    @Override
    public List<StationKvBean> getFunctionChooseCavityOrderContext(StationRequestBean reqBean) {
        String chooseCavityOrderJson = getFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.FUNCTION_CHOOSE_CAVITY_ORDER);
        return !StringUtils.isEmpty(chooseCavityOrderJson) ? JSONObject.parseArray(chooseCavityOrderJson, StationKvBean.class) : null;
    }

    //保存选择/扫描/读取的腔数及工单信息上下文   腔数=工单个数  数据格式: [StationKvBean(key=cavity, name=腔数, value=3, seq=0), StationKvBean(key=cellMessageSource, name=工位信息来源, value=10, seq=1), StationKvBean(key=workOrderNo, name=加工单, value=工单1;工单2;工单3, seq=2)]
    @Override
    public Boolean dispatchFunctionChooseCavityOrderContext(StationRequestBean reqBean, List<StationKvBean> resultList) {
        if (CollectionUtils.isEmpty(resultList)) return false;
        return dispatchFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.FUNCTION_CHOOSE_CAVITY_ORDER, JSONObject.toJSONString(resultList));
    }

    //删除手动选择的腔数及工单信息上下文
    @Override
    public void removeFunctionChooseCavityOrderContext(StationRequestBean reqBean) {
        removeFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.FUNCTION_CHOOSE_CAVITY_ORDER);
    }

    //获取手动选择的腔数及零件信息上下文
    @Override
    public List<StationKvBean> getFunctionChooseCavityPartContext(StationRequestBean reqBean) {
        String chooseCavityPartJson = getFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.FUNCTION_CHOOSE_CAVITY_PART);
        return !StringUtils.isEmpty(chooseCavityPartJson) ? JSONObject.parseArray(chooseCavityPartJson, StationKvBean.class) : null;
    }

    //保存选择/扫描/读取的腔数及零件信息上下文   腔数=工单个数  数据格式: [StationKvBean(key=cavity, name=腔数, value=3, seq=0), StationKvBean(key=cellMessageSource, name=工位信息来源, value=10, seq=1), StationKvBean(key=partNo, name=零件编码, value=零件1;零件2;零件3, seq=2)]
    @Override
    public Boolean dispatchFunctionChooseCavityPartContext(StationRequestBean reqBean, List<StationKvBean> resultList) {
        if (CollectionUtils.isEmpty(resultList)) return false;
        return dispatchFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.FUNCTION_CHOOSE_CAVITY_PART, JSONObject.toJSONString(resultList));
    }

    //删除手动选择的腔数及工单信息上下文
    @Override
    public void removeFunctionChooseCavityPartContext(StationRequestBean reqBean) {
        removeFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.FUNCTION_CHOOSE_CAVITY_PART);
    }

    //获取上下文工位扫描监控信息, 没有就重新封装工位扫描监控信息, 同时处理基础上下文信息 【其他地方调用 isSave 必须传 true 】
    @Override
    public MesScanMonitorContext dispatchScanMonitorContext(StationRequestBean reqBean, Boolean isSave) {

        MesScanMonitorContext scanMonitorContext = getScanMonitorContext(reqBean);

        //封装工位扫描监控信息, 同时处理基础上下文信息
        if (null == scanMonitorContext) {

            //获取生产过程上下文对象
            MesProductionProcessContext productionProcessContext = getProductionProcessContext(reqBean);

            //存储生产过程上下文对象
            dispatchProductionProcessContext(reqBean, productionProcessContext);

            scanMonitorContext = new MesScanMonitorContext(reqBean.getOrganizeCode(),
                    productionProcessContext.getProcessCode(), productionProcessContext.getProcessName(), productionProcessContext.getCraftCode(), productionProcessContext.getCraftName());

            MesWorkCell workCell = productionProcessContext.getWorkCell();

            if (null != workCell) BeanUtils.copyProperties(workCell, scanMonitorContext);

            if (isSave) dispatchScanMonitorContext(reqBean, scanMonitorContext, true);

        }

        return scanMonitorContext;

    }

    //保存上下文工位扫描监控信息
    @Override
    public Boolean dispatchScanMonitorContext(StationRequestBean reqBean) {
        MesScanMonitorContext scanMonitorContext = dispatchScanMonitorContext(reqBean, false);
        return dispatchScanMonitorContext(reqBean, scanMonitorContext, true);
    }

    //保存上下文工位扫描监控信息
    private Boolean dispatchScanMonitorContext(StationRequestBean reqBean, MesScanMonitorContext scanMonitorContext, Boolean isSetMouldRecordId) {
        if (null == scanMonitorContext) return false;
        //开模记录ID, 工序开始时间
        if (isSetMouldRecordId) scanMonitorContext.mouldRecordId(snowflakeIdMaker.nextId()).startDateTime(TimeTool.getNowTime(true));
        log.info("工厂{}生产线{}工位{}:工序缓存工位扫描监控信息:{}", reqBean.getOrganizeCode(), reqBean.getWorkCenterCode(), reqBean.getWorkCellCode(), JSONObject.toJSONString(scanMonitorContext));
        return dispatchFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.SCAN_MONITOR_CONTEXT, JSONObject.toJSONString(scanMonitorContext));
    }

    //获取上下文工位扫描监控信息
    private MesScanMonitorContext getScanMonitorContext(StationRequestBean reqBean) {
        String scanMonitorContextJson = getFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.SCAN_MONITOR_CONTEXT);
        return !StringUtils.isEmpty(scanMonitorContextJson) ? JSONObject.parseObject(scanMonitorContextJson, MesScanMonitorContext.class) : null;
    }

    //获取上下文工位扫描监控信息的开模记录ID
    @Override
    public String getScanMonitorContextMouldRecordId(StationRequestBean reqBean) {
        MesScanMonitorContext scanMonitorContext = getScanMonitorContext(reqBean);
        return (null != scanMonitorContext && !StringUtils.isEmpty(scanMonitorContext.getMouldRecordId())) ? scanMonitorContext.getMouldRecordId().toString() : null;
    }

    //获取上下文工位扫描监控信息
    @Override
    public MesScanMonitorContext getScanMonitorContext(String organizeCode, String workCenterCode, String workCellCode) {
        String scanMonitorContextJson = getFsmBusiData(organizeCode, getContextKey(organizeCode, workCenterCode, workCellCode), MesPcnExtConstWords.SCAN_MONITOR_CONTEXT);
        return !StringUtils.isEmpty(scanMonitorContextJson) ? JSONObject.parseObject(scanMonitorContextJson, MesScanMonitorContext.class) : null;
    }

    //删除上下文工位扫描监控信息
    @Override
    public void removeScanMonitorContext(StationRequestBean reqBean) {
        removeFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.SCAN_MONITOR_CONTEXT);
    }

    //获取生产线类型
    @Override
    public Integer getCenterType(StationRequestBean reqBean) {
        if (!StringUtils.isEmpty(reqBean.getCenterType())) return reqBean.getCenterType();
        MesProductionProcessContext productionProcessContext = getProductionProcessContext(reqBean, false);
        //获取生产过程上下文对象有异常信息 抛出异常
        if (!productionProcessContext.getSuccess()) stepExpSendMsgAndThrowEx(reqBean, new StationResultBean().writeDbLog(), productionProcessContext.getMessage());
        dispatchProductionProcessContext(reqBean, productionProcessContext);
        reqBean.setCenterType(productionProcessContext.getWorkCenter().getCenterType());
        return reqBean.getCenterType();
    }

    //获取生产线下的工位集合
    @Override
    public Map<String, MesWorkCell> dispatchWorkCellMap(StationRequestBean reqBean) {
        String workCellMapJson = getFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.WORK_CELL_MAP_CONTEXT);
        if (!StringUtils.isEmpty(workCellMapJson)) return JSONObject.parseObject(workCellMapJson, new TypeReference<Map<String, MesWorkCell>>() {});
        List<MesWorkCell> workCellList = prodOrgExtService.getWorkCellList(reqBean.getOrganizeCode(), reqBean.getWorkCenterCode());
        Map<String, MesWorkCell> workCellMap = CollectionUtils.isEmpty(workCellList) ? null : workCellList.stream().filter(o -> null != o).collect(Collectors.toMap(MesWorkCell::getWorkCellCode, o -> o));
        if (!CollectionUtils.isEmpty(workCellList)) dispatchFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.WORK_CELL_MAP_CONTEXT, JSONObject.toJSONString(workCellMap));
        return workCellMap;
    }

    //获取包装规则信息
    @Override
    public Map<String, MesPackageRuleContext> getPackageRuleContext(StationRequestBean reqBean) {
        String packageRuleContextJson = getFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.PACKAGE_RULE_CONTEXT);
        return !StringUtils.isEmpty(packageRuleContextJson) ? JSONObject.parseObject(packageRuleContextJson, new TypeReference<Map<String, MesPackageRuleContext>>() {}): null;
    }

    //保存包装规则信息
    @Override
    public Boolean dispatchPackageRuleContext(StationRequestBean reqBean, Map<String, MesPackageRuleContext> packageRuleContextMap) {
        return dispatchFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.PACKAGE_RULE_CONTEXT, JSONObject.toJSONString(packageRuleContextMap));
    }

    //删除包装规则信息
    @Override
    public void removePackageRuleContext(StationRequestBean reqBean) {
        removeFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.PACKAGE_RULE_CONTEXT);
    }

    //获取设备点检上下文对象
    @Override
    public MesEquipSpotCheckContext dispatchEquipSpotCheckContext(StationRequestBean reqBean, String equipmentCode) {
        String item = new StringJoiner(MesPcnExtConstWords.AND).add(MesPcnExtConstWords.EQUIP_SPOT_CHECK_CONTEXT).add(equipmentCode).toString();
        String equipSpotCheckContextJson = getFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), item);
        if (!StringUtils.isEmpty(equipSpotCheckContextJson)) return JSONObject.parseObject(equipSpotCheckContextJson, MesEquipSpotCheckContext.class);
        MesEquipSpotCheckContext equipSpotCheckContext = equipmentExtService.getEquipSpotCheckContext(reqBean.getOrganizeCode(), reqBean.getWorkCenterCode(), equipmentCode);
        if (null != equipSpotCheckContext) dispatchFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), item, JSONObject.toJSONString(equipSpotCheckContext));
        return equipSpotCheckContext;
    }

    //处理加工不可用规则
    @Override
    public MesProductionProcessContext dispatchProdRuleIgnoreCfgContext(StationRequestBean reqBean) {
        return dispatchProdRuleIgnoreCfgContext(reqBean, getCellEquipmentList(reqBean));
    }

    //处理加工不可用规则
    @Override
    public MesProductionProcessContext dispatchProdRuleIgnoreCfgContext(StationRequestBean reqBean, MesProductionProcessContext productionProcessContext) {
        MesCellEquipContext cellEquipmentContext = productionProcessContext.getCurCellEquip();
        if (null == cellEquipmentContext) cellEquipmentContext = dispatchCurCellEquipment(reqBean, productionProcessContext).getCurCellEquip();
        if (!productionProcessContext.getSuccess() || !StringUtils.isEmpty(productionProcessContext.getProdRuleIgnoreCfg())) return productionProcessContext;

        List<MesProdRuleIgnoreCfg> prodRuleIgnoreCfgList;
        if (getCenterType(reqBean).compareTo(MesExtEnumUtil.WORK_CENTER_TYPE.NOSORT.getValue()) == 0) {
            //如果是非排序线, 则根据工位当前设备代码查询加工不可用规则信息
            prodRuleIgnoreCfgList = equipmentExtService.getProdRuleIgnoreCfgListByEquip(reqBean.getOrganizeCode(), cellEquipmentContext.getEquipmentCode());
        } else if (!StringUtils.isEmpty(productionProcessContext.getWorkCell().getIsEndWorkCell()) && productionProcessContext.getWorkCell().getIsEndWorkCell().compareTo(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()) == 0) {
            //如果是排序线末道工位,需要查询生产线所有设备的不可用规则, 因为末道工位可能会补装配前道
            prodRuleIgnoreCfgList = equipmentExtService.getProdRuleIgnoreCfgListByCenter(reqBean.getOrganizeCode(), reqBean.getWorkCenterCode());
        } else {
            //如果是排序线,需要查询当前工位下所有设备的不可用规则, 排序线一个工位对应多个设备, 例如不同扭距枪的装配件对应不同的设备
            prodRuleIgnoreCfgList = equipmentExtService.getProdRuleIgnoreCfgListByCell(reqBean.getOrganizeCode(), reqBean.getWorkCenterCode(), reqBean.getWorkCellCode());
        }

        //存储不可用规则到上下文
        if (!CollectionUtils.isEmpty(prodRuleIgnoreCfgList)) {
            dispatchFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.PROD_RULE_IGNORE_CFG_CONTEXT, JSONObject.toJSONString(prodRuleIgnoreCfgList));
        }

        productionProcessContext.prodRuleIgnoreCfg(!CollectionUtils.isEmpty(prodRuleIgnoreCfgList) ? CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValueStr() : CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValueStr()).isNeedCache();
        return productionProcessContext;
    }

    //获取加工不可用规则
    @Override
    public List<MesProdRuleIgnoreCfg> getProdRuleIgnoreCfgContext(StationRequestBean reqBean, MesProductionProcessContext productionProcessContext) {
        if (StringUtils.isEmpty(productionProcessContext.getProdRuleIgnoreCfg())) dispatchProductionProcessContext(reqBean, dispatchProdRuleIgnoreCfgContext(reqBean, productionProcessContext));
        if (!productionProcessContext.getSuccess()) return null;
        if (StringUtils.isEmpty(productionProcessContext.getProdRuleIgnoreCfg()) || productionProcessContext.getProdRuleIgnoreCfg().equals(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValueStr())) return null;
        String prodRuleIgnoreCfgContextJson = getFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.PROD_RULE_IGNORE_CFG_CONTEXT);
        return !StringUtils.isEmpty(prodRuleIgnoreCfgContextJson) ? JSONObject.parseArray(prodRuleIgnoreCfgContextJson, MesProdRuleIgnoreCfg.class) : null;
    }

    //获取加工不可用规则, key = 数据来源&来源ID
    @Override
    public Map<String, List<MesProdRuleIgnoreCfg>> getProdRuleIgnoreCfgContextMap(StationRequestBean reqBean, MesProductionProcessContext productionProcessContext) {
        List<MesProdRuleIgnoreCfg> prodRuleIgnoreCfgList = getProdRuleIgnoreCfgContext(reqBean, productionProcessContext);
        return CollectionUtils.isEmpty(prodRuleIgnoreCfgList) ? null :
                prodRuleIgnoreCfgList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getDataSource()) && !StringUtils.isEmpty(o.getEquipmentCode()) && !StringUtils.isEmpty(o.getSourceId())))
                        .collect(Collectors.groupingBy(o -> new StringJoiner(MesPcnExtConstWords.AND).add(o.getDataSource().toString()).add(o.getEquipmentCode().toUpperCase()).add(o.getSourceId().toString()).toString()));
    }

    //处理排序线推单配置上下文, 返回推送工位类型对应的配置信息
    @Override
    public List<MesQueueOrderPushCellCfg> dispatchQueueOrderPushCellCfgContext(StationRequestBean reqBean, Integer pushType) {
        List<MesQueueOrderPushCellCfg> queueOrderPushCellCfgList = dispatchQueueOrderPushCellCfgContext(reqBean);
        return CollectionUtils.isEmpty(queueOrderPushCellCfgList) ? null :
                queueOrderPushCellCfgList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getPushType()) && o.getPushType().compareTo(pushType) == 0)).collect(Collectors.toList());
    }

    //处理排序线推单配置上下文
    private List<MesQueueOrderPushCellCfg> dispatchQueueOrderPushCellCfgContext(StationRequestBean reqBean) {
        String queuePushCfgJson = getFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.QUEUE_PUSH_CFG_CONTEXT);
        if (!StringUtils.isEmpty(queuePushCfgJson)) return JSONObject.parseArray(queuePushCfgJson, MesQueueOrderPushCellCfg.class);
        //根据生产线代码查询生产队列推送工位配置信息
        List<MesQueueOrderPushCellCfg> queueOrderPushCellCfgList = queueOrderPushService.getQueueOrderPushCellCfgList(reqBean.getOrganizeCode(), reqBean.getWorkCenterCode());
        //搜集该工位对应的配置信息
        List<MesQueueOrderPushCellCfg> filterList = CollectionUtils.isEmpty(queueOrderPushCellCfgList) ? null :
                queueOrderPushCellCfgList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getPushSourceCode()) &&
                        !StringUtils.isEmpty(o.getPushType()) && !StringUtils.isEmpty(o.getWorkCellCode()) && o.getWorkCellCode().equals(reqBean.getWorkCellCode()))).collect(Collectors.toList());

        if (CollectionUtils.isEmpty(filterList)) return null;

        //验证是否存在查询队列需要考虑竞争的代码, 赋值是否需要锁定
        for (MesQueueOrderPushCellCfg queueOrderPushCellCfg : filterList) {
            if (null == queueOrderPushCellCfg || queueOrderPushCellCfg.getPushType().compareTo(MesExtEnumUtil.QUEUE_ORDER_CELL_PUSH_TYPE.SOURCE.getValue()) == 0) continue;
            Optional<MesQueueOrderPushCellCfg> optional = queueOrderPushCellCfgList.stream().filter(o -> (null != o
                    && !StringUtils.isEmpty(o.getWorkCellCode()) && !o.getWorkCellCode().equals(reqBean.getWorkCellCode())
                    && !StringUtils.isEmpty(o.getPushType()) && o.getPushType().compareTo(MesExtEnumUtil.QUEUE_ORDER_CELL_PUSH_TYPE.TARGET.getValue()) == 0)
                    && !StringUtils.isEmpty(o.getPushSourceCode()) && o.getPushSourceCode().equals(queueOrderPushCellCfg.getPushSourceCode())).findFirst();
            if (null != optional && optional.isPresent()) queueOrderPushCellCfg.setIsNeedLock(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValueStr());
        }

        //保存排序线推单配置上下文
        if (!CollectionUtils.isEmpty(queueOrderPushCellCfgList)) dispatchFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.QUEUE_PUSH_CFG_CONTEXT, JSONObject.toJSONString(filterList));
        return filterList;
    }

    //处理工位零件打印机配置
    @Override
    public List<MesWorkCellPartPrinterCfg> disPatchWorkCellPartPrinterCfg(StationRequestBean reqBean, Boolean pcNosortPrinterCfg) {
        if (!pcNosortPrinterCfg) return null;
        String context = getFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.CELL_PART_PRINTER_CONTEXT);
        if (!StringUtils.isEmpty(context)) return context.equals(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValueStr()) ? null : JSONObject.parseArray(context, MesWorkCellPartPrinterCfg.class);
        List<MesWorkCellPartPrinterCfg> workCellPartPrinterCfgList = prodOrgExtService.getWorkCellPartPrinterCfgList(reqBean.getOrganizeCode(), reqBean.getWorkCenterCode(), reqBean.getWorkCellCode());
        dispatchFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.CELL_PART_PRINTER_CONTEXT,
                !CollectionUtils.isEmpty(workCellPartPrinterCfgList) ? JSONObject.toJSONString(workCellPartPrinterCfgList) : CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValueStr());
        return workCellPartPrinterCfgList;
    }

    //获取发运RFID生产模式
    @Override
    public String getShippingRfidRouteModeContext(StationRequestBean reqBean) {
        return getFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.SHIPPING_RFID_ROUTE_MODE_CONTEXT);
    }

    //处理发运RFID生产模式
    @Override
    public String disPatchShippingRfidRouteModeContext(StationRequestBean reqBean) {
        //当前生产模式
        String routeMode = getShippingRfidRouteModeContext(reqBean);
        //选择的生产模式
        String chooseRouteMode = getFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.CHOOSE_SHIPPING_RFID_ROUTE_MODE);
        //生产模式默认自动
        if (StringUtils.isEmpty(routeMode)) routeMode = CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValueStr();
        if (StringUtils.isEmpty(chooseRouteMode)) return routeMode;
        //删除切换发运RFID生产模式的标志
        removeFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.CHOOSE_SHIPPING_RFID_ROUTE_MODE);
        //切换发运RFID生产模式
        if (routeMode.equals(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValueStr())) routeMode = CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValueStr();
        else routeMode = CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValueStr();
        //保存发运RFID生产模式
        dispatchFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.SHIPPING_RFID_ROUTE_MODE_CONTEXT, routeMode);
        return routeMode;
    }

    //处理切换发运RFID生产模式的标志
    @Override
    public Boolean disPatchChooseShippingRfidRouteMode(StationRequestBean reqBean) {
        return dispatchFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.CHOOSE_SHIPPING_RFID_ROUTE_MODE, CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValueStr());
    }

    //处理设备站点
    @Override
    public List<MesStation> dispatchEquipmentStationContext(StationRequestBean reqBean, String equipmentCode) {
        String station = getFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.EQUIPMENT_STATION_CONTEXT);
        if (!StringUtils.isEmpty(station)) return JSONObject.parseArray(station, MesStation.class);
        List<MesStation> stationList = stationContainerSnExtService.getStationList(reqBean.getOrganizeCode(), equipmentCode);
        if (!CollectionUtils.isEmpty(stationList)) dispatchFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.EQUIPMENT_STATION_CONTEXT, JSONObject.toJSONString(stationList));
        return stationList;
    }

    //处理设备站点
    @Override
    public List<MesStation> dispatchEquipmentStationContext(StationRequestBean reqBean, String equipmentCode, List<Integer> stationTypeList) {
        List<MesStation> stationList = dispatchEquipmentStationContext(reqBean, equipmentCode);
        return CollectionUtils.isEmpty(stationList) ? null :
                stationList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getStationType()) && stationTypeList.contains(o.getStationType()))).collect(Collectors.toList());
    }

}
