package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.busi.station.ep;

import cn.estsh.i3plus.ext.mes.pcn.api.busi.IWorkCenterContainerLocationService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.bean.MesWorkCenterContainerLocation;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.SxPutPalletModuleModel;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.ep.EpPutPalletPlcDataModel;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtEnumUtil;
import cn.estsh.i3plus.mes.pcn.api.iservice.base.IWorkCellParamCfgService;
import cn.estsh.i3plus.mes.pcn.api.iservice.busi.IShippingDispatchService;
import cn.estsh.i3plus.mes.pcn.serviceimpl.base.BaseModuleService;
import cn.estsh.i3plus.mes.pcn.util.LocaleUtil;
import cn.estsh.i3plus.mes.pcn.util.PojoAttrUtil;
import cn.estsh.i3plus.platform.common.exception.ImppExceptionEnum;
import cn.estsh.i3plus.platform.common.util.MesPcnConstWords;
import cn.estsh.i3plus.platform.plugin.opc.iservice.IOpcUAService;
import cn.estsh.i3plus.platform.plugin.opc.service.OpcUAService;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil;
import cn.estsh.i3plus.pojo.hardswitch.bean.OpcUAParam;
import cn.estsh.i3plus.pojo.mes.bean.MesPlc;
import cn.estsh.i3plus.pojo.mes.bean.MesStateMachineStatus;
import cn.estsh.i3plus.pojo.mes.bean.MesWorkCellParamCfg;
import cn.estsh.i3plus.pojo.mes.model.AttrBean;
import cn.estsh.i3plus.pojo.mes.model.StationRequestBean;
import cn.estsh.i3plus.pojo.mes.model.StationResultBean;
import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder;
import cn.estsh.impp.framework.boot.util.ImppRedis;
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 javax.annotation.Resource;
import java.text.MessageFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description : 展示组件：EP本体装托
 * @Reference :
 * @Author :wangjie
 * @CreateDate : 2020-06-26 11:18 上午
 * @Modify:
 **/
@Slf4j
@Service("epPutPalletModuleService")
public class EpPutPalletModuleService extends BaseModuleService {

    @Resource(name = MesPcnExtConstWords.REDIS_RES_PCN)
    private ImppRedis redisMesPcn;

    @Autowired
    private IWorkCenterContainerLocationService workCenterContainerLocationService;

    @Autowired
    private IShippingDispatchService shippingDispatchService;

    @Autowired
    private IWorkCellParamCfgService workCellParamCfgService;

    private static final String PUT_PALLET_DATA = "PUT_PALLET_DATA";

    private static final String CUR_PROD_TYPE = "CUR_PROD_TYPE";
    private static final String CUR_WORK_ORDER_NO = "CUR_WORK_ORDER_NO";
    private static final String CUR_PART_NO = "CUR_PART_NO";
    private static final String CUR_WORK_ORDER_TYPE = "CUR_WORK_ORDER_TYPE";
    private static final String CUR_LOCK_CTLOCATIONNO = "CUR_LOCK_CTLOCATIONNO";
    private static final String CUR_CT_NO = "CUR_CT_NO";
    private static final String CUR_CT_QTY = "CUR_CT_QTY";
    private static final String CUR_EXEC_PACKAGE_NO = "CUR_EXEC_PACKAGE_NO";
    private static final String CUR_PLC_DATA = "CUR_PLC_DATA";
    private static final String CUR_EXEC_PLC_TASK = "CUR_EXEC_PLC_TASK";

    private static final String CMD_WORK_ORDER = "CMD_WORK_ORDER";
    private static final String CMD_DELETE_PACK = "CMD_DELETE_PACK";
    private static final String CMD_RESET_CT_NO = "CMD_RESET_CT_NO";
    private static final String CMD_CHANGE_PROD_TYPE = "CMD_CHANGE_PROD_TYPE";
    private static final String CMD_FORCE_PUT_PALLET = "CMD_FORCE_PUT_PALLET";
    private static final String CMD_PLC_PUT_PALLET = "CMD_PLC_PUT_PALLET";

    @Override
    public void init(StationRequestBean reqBean) {

        log.info("工厂{}生产线{}工位{}:ACTOR INIT --- PUT PALLET MODULE --- START --- StationRequestBean[{}]",
                reqBean.getOrganizeCode(), reqBean.getWorkCenterCode(), reqBean.getWorkCellCode(), reqBean.toString());

        StationResultBean resultBean = new StationResultBean();
        //初始化生产模式
        String curProdType = initProdType(reqBean);

        log.info("工厂{}生产线{}工位{}:ACTOR INIT --- PUT PALLET MODULE --- 1 --- ",
                reqBean.getOrganizeCode(), reqBean.getWorkCenterCode(), reqBean.getWorkCellCode());

        //初始化当前位置
        MesWorkCenterContainerLocation curLocation = initWccl(reqBean, resultBean);

        log.info("工厂{}生产线{}工位{}:ACTOR INIT --- PUT PALLET MODULE --- 2 --- ",
                reqBean.getOrganizeCode(), reqBean.getWorkCenterCode(), reqBean.getWorkCellCode());

        resultBean.setBusiType(MesPcnEnumUtil.STATION_BUSI_TYPE.MODULE_CONTENT.getValue());
        resultBean.setDataType(MesPcnEnumUtil.STATION_DATA_TYPE.CUSTOM.getValue());
        resultBean.setCustomPageName(MesPcnExtConstWords.EP_PUT_PALLET_MODULE);
        resultBean.setDataAttrList(packDataAttrList(reqBean));
        resultBean.setSpecialDisplayData(getStepColIndent(reqBean));

        //判断当前工位是否存在容器
        EpPutPalletPlcDataModel ctNoModel = (EpPutPalletPlcDataModel) doHandleCurCtNo(reqBean, 1, null);

        log.info("工厂{}生产线{}工位{}:ACTOR INIT --- PUT PALLET MODULE --- 3 --- ",
                reqBean.getOrganizeCode(), reqBean.getWorkCenterCode(), reqBean.getWorkCellCode());

        List<SxPutPalletModuleModel> putPalletModuleModelList = (null == ctNoModel || !ctNoModel.getBoo()) ? null :
                (List<SxPutPalletModuleModel>) doHandlePackageDataByCtNo(reqBean, ctNoModel.getCtNo(), 1, null);
        if (!CollectionUtils.isEmpty(putPalletModuleModelList)) {

            log.info("工厂{}生产线{}工位{}:ACTOR INIT --- PUT PALLET MODULE --- 4 --- ",
                    reqBean.getOrganizeCode(), reqBean.getWorkCenterCode(), reqBean.getWorkCellCode());

            putPalletModuleModelList = putPalletModuleModelList.stream().sorted(Comparator.comparing(SxPutPalletModuleModel :: getScanDatetime).reversed()).collect(Collectors.toList());
            resultBean.setResultList(putPalletModuleModelList);
        }
        resultBean.setResultMap(packResultMap(reqBean, ctNoModel, putPalletModuleModelList, curProdType, curLocation));

        log.info("工厂{}生产线{}工位{}:ACTOR INIT --- PUT PALLET MODULE --- 5 --- ",
                reqBean.getOrganizeCode(), reqBean.getWorkCenterCode(), reqBean.getWorkCellCode());

        this.sendMessage(reqBean, resultBean);

        log.info("工厂{}生产线{}工位{}:ACTOR INIT --- PUT PALLET MODULE --- 6 --- ",
                reqBean.getOrganizeCode(), reqBean.getWorkCenterCode(), reqBean.getWorkCellCode());

        reqBean.setScanInfo(null);
    }

    private String initProdType(StationRequestBean reqBean) {
        String curProdType = (String) doHandleCurProdType(reqBean, 1, null);
        if (StringUtils.isEmpty(curProdType)) {
            curProdType = !CollectionUtils.isEmpty(reqBean.getWcpcMap()) ? reqBean.getWcpcMap().get(MesPcnExtConstWords.DEFAULT_PROD_TYPE) : null;
            curProdType = (!StringUtils.isEmpty(curProdType) && !StringUtils.isEmpty(MesPcnExtEnumUtil.EP_PUT_PALLET_PROD_TYPE.codeOfDescription(curProdType)))
                    ? curProdType : MesPcnExtEnumUtil.EP_PUT_PALLET_PROD_TYPE.HAND_WORK.getCode();
            doHandleCurProdType(reqBean, 2, curProdType);
        }

        Map<String, String> wcpcMap = reqBean.getWcpcMap();
        if (CollectionUtils.isEmpty(wcpcMap)) {
            wcpcMap = new HashMap<>();
        }
        if (MesPcnExtEnumUtil.EP_PUT_PALLET_PROD_TYPE.HAND_WORK.getCode().equals(curProdType)) {
            wcpcMap.remove(MesPcnExtConstWords.DISABLE_SCAN);
        } else {
            wcpcMap.put(MesPcnExtConstWords.DISABLE_SCAN, "1");
        }
        reqBean.setWcpcMap(wcpcMap);

        return curProdType;
    }

    private MesWorkCenterContainerLocation initWccl(StationRequestBean reqBean, StationResultBean resultBean) {
        MesWorkCenterContainerLocation curLocation = (MesWorkCenterContainerLocation) doHandleCurLocation(reqBean, 1, null);
        if (null == curLocation) {
            curLocation = workCenterContainerLocationService.getWcclByCenter(reqBean.getOrganizeCode(), reqBean.getWorkCenterCode());
            if (null != curLocation) {
                doHandleCurLocation(reqBean, 2, curLocation);
            } else {
                String err = String.format(LocaleUtil.transferLanguage(reqBean.getUserInfo(), "生产线[%s]未配置产线托盘位置"), reqBean.getWorkCenterCode());
                this.sendMessage(reqBean, resultBean, err, MesPcnEnumUtil.STATION_BUSI_TYPE.GUIDE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                        .setErrorDetail("生产线[%s]未配置产线托盘位置", reqBean.getWorkCenterCode())
                        .build();
            }
        }
        return curLocation;
    }

    private Map<String, Object> packResultMap(StationRequestBean reqBean, EpPutPalletPlcDataModel ctNoModel, List<SxPutPalletModuleModel> putPalletModuleModelList,
                                              String curProdType, MesWorkCenterContainerLocation curLocation) {
        String curWorkOrderNo = (String) doHandleCurWorkOrderNo(reqBean, 1, null);

        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put(MesPcnExtConstWords.CUR_WORK_TYPE, curProdType);
        resultMap.put(MesPcnExtConstWords.CUR_WORK_TYPE_NAME, StringUtils.isEmpty(curProdType) ? null : MesPcnExtEnumUtil.EP_PUT_PALLET_PROD_TYPE.codeOfDescription(curProdType));
        if (!StringUtils.isEmpty(curWorkOrderNo)) {
            resultMap.put(MesPcnExtConstWords.CUR_WORK_ORDER_NO, curWorkOrderNo);
        } else {
            resultMap.put(MesPcnExtConstWords.CUR_WORK_ORDER_NO, "");
        }

        if (null != curLocation) {
            resultMap.put(MesPcnExtConstWords.CUR_LOCATION_NO, curLocation.getCtLocationNo());
            resultMap.put(MesPcnExtConstWords.CUR_LOCATION_DESC, curLocation.getLocationDesc());
        } else {
            resultMap.put(MesPcnExtConstWords.CUR_LOCATION_NO, "");
            resultMap.put(MesPcnExtConstWords.CUR_LOCATION_DESC, "");
        }

        if (null != ctNoModel && ctNoModel.getBoo()) {
            resultMap.put(MesPcnExtConstWords.CT_NO, ctNoModel.getCtNo());
            Integer ctQty = (Integer) doHandleCurCtQty(reqBean, 1, null);
            if (null != ctQty) {
                resultMap.put(MesPcnExtConstWords.QTY, ctQty);
            } else {
                resultMap.put(MesPcnExtConstWords.QTY, "");
            }
        } else {
            resultMap.put(MesPcnExtConstWords.CT_NO, "");
            resultMap.put(MesPcnExtConstWords.QTY, "");
        }
        resultMap.put(MesPcnExtConstWords.COMPLETE_QTY, !CollectionUtils.isEmpty(putPalletModuleModelList) ? putPalletModuleModelList.size() : 0);

        return resultMap;
    }

    private List<AttrBean> packDataAttrList(StationRequestBean reqBean) {
        List<AttrBean> attrBeanList = new ArrayList<>();
        PojoAttrUtil.loadPojoAttrs(attrBeanList, MesPcnExtConstWords.PART_NO, LocaleUtil.transferLanguage(reqBean.getUserInfo(), "物料编码"));
        PojoAttrUtil.loadPojoAttrs(attrBeanList, MesPcnExtConstWords.LOT_NO, LocaleUtil.transferLanguage(reqBean.getUserInfo(), "批次号"));
        PojoAttrUtil.loadPojoAttrs(attrBeanList, MesPcnExtConstWords.PACKAGENO, LocaleUtil.transferLanguage(reqBean.getUserInfo(), "包装条码"));
        PojoAttrUtil.loadPojoAttrs(attrBeanList, MesPcnExtConstWords.SCAN_DATE_TIME, LocaleUtil.transferLanguage(reqBean.getUserInfo(), "扫描时间"));
        return attrBeanList;
    }

    @Override
    public boolean doFunction(StationRequestBean reqBean) {
        Boolean result = false;
        String err;
        String curProdType = (String) doHandleCurProdType(reqBean, 1, null);
        Map<String, Object> dataMap = reqBean.getDataMap();
        String command = (String) dataMap.get(MesPcnExtConstWords.COMMAND);
        Object value = dataMap.get(MesPcnExtConstWords.VALUE);
        String pwd = (String) dataMap.get(MesPcnExtConstWords.PWD);
        if (StringUtils.isEmpty(command)) {
            err = LocaleUtil.transferLanguage(reqBean.getUserInfo(), "后端未获取到业务功能指令");
            this.sendMessage(reqBean,  null, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
            return result;
        }

        switch (command) {
            case CMD_WORK_ORDER :
                if (StringUtils.isEmpty(value)) {
                    err = LocaleUtil.transferLanguage(reqBean.getUserInfo(), "请选择工单");
                    this.sendMessage(reqBean,  null, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
                    return result;
                }
                String curWorkOrderNo = (String)doHandleCurWorkOrderNo(reqBean, 1, null);
                if (!StringUtils.isEmpty(curWorkOrderNo) && curWorkOrderNo.equals(value.toString())) {
                    return result;
                }
                if (StringUtils.isEmpty(doHandleSelectWorkOrderNo(reqBean, 1, null))) {
                    doHandleSelectWorkOrderNo(reqBean, 2, value.toString());
                    result = true;
                }
                break;
            case CMD_DELETE_PACK :
                if (StringUtils.isEmpty(value)) {
                    err = LocaleUtil.transferLanguage(reqBean.getUserInfo(), "请选择包装条码");
                    this.sendMessage(reqBean,  null, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
                    return result;
                }
                if (StringUtils.isEmpty(doHandleDeletePack(reqBean, 1, null))) {
                    doHandleDeletePack(reqBean, 2, value.toString());
                    result = true;
                }
                break;
            case CMD_CHANGE_PROD_TYPE :
                if (StringUtils.isEmpty(value)) {
                    err = LocaleUtil.transferLanguage(reqBean.getUserInfo(), "请选择生产模式");
                    this.sendMessage(reqBean,  null, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
                    return result;
                }
                if (StringUtils.isEmpty(pwd)) {
                    err = LocaleUtil.transferLanguage(reqBean.getUserInfo(), "切换生产模式需要验证密码");
                    this.sendMessage(reqBean,  null, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
                    return result;
                }
                MesWorkCellParamCfg paramCfg = workCellParamCfgService.getWorkCellParamCfgByCode(reqBean.getOrganizeCode(), reqBean.getWorkCenterCode(), reqBean.getWorkCellCode(), MesPcnExtConstWords.PWD);
                if (null != paramCfg && !StringUtils.isEmpty(paramCfg.getParamValue()) && !paramCfg.getParamValue().equals(pwd)) {
                    err = LocaleUtil.transferLanguage(reqBean.getUserInfo(), "切换生产模式密码错误");
                    this.sendMessage(reqBean,  null, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
                    return result;
                }
                if (!StringUtils.isEmpty(curProdType) && curProdType.equals(value.toString())) {
                    return result;
                }
                if (StringUtils.isEmpty(doHandleChangeProdType(reqBean, 1, null))) {
                    doHandleChangeProdType(reqBean, 2, value.toString());
                    result = true;
                }
                break;
            case CMD_RESET_CT_NO :
                if (StringUtils.isEmpty(curProdType)) {
                    err = LocaleUtil.transferLanguage(reqBean.getUserInfo(), "请先设置人工模式后再执行容器重置");
                    this.sendMessage(reqBean,  null, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
                    return result;
                }
                if (MesPcnExtEnumUtil.EP_PUT_PALLET_PROD_TYPE.PLC_WORK.getCode().equals(curProdType)) {
                    err = LocaleUtil.transferLanguage(reqBean.getUserInfo(), "PLC模式下不能执行容器重置操作");
                    this.sendMessage(reqBean,  null, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
                    return result;
                }
                EpPutPalletPlcDataModel ctNoModel = (EpPutPalletPlcDataModel) doHandleCurCtNo(reqBean, 1, null);
                if (null == ctNoModel || !ctNoModel.getBoo()) {
                    err = LocaleUtil.transferLanguage(reqBean.getUserInfo(), "当前未固定容器,不能执行容器重置操作");
                    this.sendMessage(reqBean,  null, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
                    return result;
                }
                List<SxPutPalletModuleModel> putPalletModuleModelList = (List<SxPutPalletModuleModel>) doHandlePackageDataByCtNo(reqBean, ctNoModel.getCtNo(), 1, null);
                if (!CollectionUtils.isEmpty(putPalletModuleModelList)) {
                    err = LocaleUtil.transferLanguage(reqBean.getUserInfo(), "当前存在已装托的产品,不能执行容器重置操作");
                    this.sendMessage(reqBean,  null, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
                    return result;
                }
                EpPutPalletPlcDataModel curExecPackageNoModel = (EpPutPalletPlcDataModel) doHandleCacheCurExecPackageNo(reqBean, 1, null);
                if (null != curExecPackageNoModel) {
                    err = String.format(LocaleUtil.transferLanguage(reqBean.getUserInfo(), "当前存在正在执行且未装托成功的包装条码[%s],不能执行容器重置操作"), curExecPackageNoModel.getPackageNo());
                    this.sendMessage(reqBean,  null, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
                    return result;
                }
                if (StringUtils.isEmpty(doHandleResetCtNo(reqBean, 1, null))) {
                    doHandleResetCtNo(reqBean, 2, true);
                    result = true;
                }
                break;
            case CMD_FORCE_PUT_PALLET :
                if (StringUtils.isEmpty(value)) {
                    err = LocaleUtil.transferLanguage(reqBean.getUserInfo(), "入参缺少强制装托的工步代码");
                    this.sendMessage(reqBean,  null, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
                    return result;
                }
                if (StringUtils.isEmpty(curProdType)) {
                    err = LocaleUtil.transferLanguage(reqBean.getUserInfo(), "请先设置人工模式后再执行强制装托操作");
                    this.sendMessage(reqBean,  null, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
                    return result;
                }
                if (MesPcnExtEnumUtil.EP_PUT_PALLET_PROD_TYPE.PLC_WORK.getCode().equals(curProdType)) {
                    err = LocaleUtil.transferLanguage(reqBean.getUserInfo(), "PLC模式下不能执行强制装托操作");
                    this.sendMessage(reqBean,  null, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
                    return result;
                }
                if (StringUtils.isEmpty(doHandleForcePutPallet(reqBean, 1, null))) {
                    doHandleForcePutPallet(reqBean, 2, value.toString());
                    result = true;
                }
                break;
            default:
                break;
        }

        if (!result) {
            err = String.format(LocaleUtil.transferLanguage(reqBean.getUserInfo(), "操作太频繁"), reqBean.getWorkCenterCode());
            this.sendMessage(reqBean,  null, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
        } else {
            //跳过工序
            reqBean.setClientInfo(shippingDispatchService.getActorClientInfo(reqBean));
            reqBean.setInterfaceType(MesPcnConstWords.SHIPPING);
            reqBean.setBusiType(MesPcnConstWords.WS_CMD_DO_SCAN);
            reqBean.setForceJumpProcess(true);
            shippingDispatchService.doSendScanQueueNextExec(reqBean);
        }
        return result;
    }

    @Override
    public boolean execute(StationRequestBean reqBean) {
        return true;
    }

    @Override
    public boolean execStateModule(StationRequestBean reqBean, List<MesStateMachineStatus> states, Map<String, String> wcpcMap) {
        init(reqBean);
        return true;
    }

    private String getDataKey(StationRequestBean reqBean) {
        return new StringJoiner(MesPcnExtConstWords.COLON)
                .add(reqBean.getOrganizeCode()).add(PUT_PALLET_DATA).add(reqBean.getWorkCenterCode()).toString();
    }

    public Object doHandleCurWorkOrderNo(StationRequestBean reqBean, Integer flag, String curWorkOrderNo) {
        switch (flag) {
            case 1:
                return redisMesPcn.getHash(getDataKey(reqBean), CUR_WORK_ORDER_NO);
            case 2:
                return redisMesPcn.putHash(getDataKey(reqBean), CUR_WORK_ORDER_NO, curWorkOrderNo, MesPcnEnumUtil.EXPIRE_TIME.NEVER.getValue());
            case 3:
                redisMesPcn.deleteHash(getDataKey(reqBean), CUR_WORK_ORDER_NO);
                return true;
            default:
                return null;
        }
    }

    public Object doHandleCurPartNo(StationRequestBean reqBean, Integer flag, String curPartNo) {
        switch (flag) {
            case 1:
                return redisMesPcn.getHash(getDataKey(reqBean), CUR_PART_NO);
            case 2:
                return redisMesPcn.putHash(getDataKey(reqBean), CUR_PART_NO, curPartNo, MesPcnEnumUtil.EXPIRE_TIME.NEVER.getValue());
            case 3:
                redisMesPcn.deleteHash(getDataKey(reqBean), CUR_PART_NO);
                return true;
            default:
                return null;
        }
    }

    public Object doHandleCurWorkOrderType(StationRequestBean reqBean, Integer flag, Integer workOrderType) {
        switch (flag) {
            case 1:
                return redisMesPcn.getHash(getDataKey(reqBean), CUR_WORK_ORDER_TYPE);
            case 2:
                return redisMesPcn.putHash(getDataKey(reqBean), CUR_WORK_ORDER_TYPE, workOrderType, MesPcnEnumUtil.EXPIRE_TIME.NEVER.getValue());
            case 3:
                redisMesPcn.deleteHash(getDataKey(reqBean), CUR_WORK_ORDER_TYPE);
                return true;
            default:
                return null;
        }
    }

    public synchronized Object doHandleSelectWorkOrderNo(StationRequestBean reqBean, Integer flag, String selectWorkOrderNo) {
        switch (flag) {
            case 1:
                return redisMesPcn.getHash(getDataKey(reqBean), CMD_WORK_ORDER);
            case 2:
                return redisMesPcn.putHash(getDataKey(reqBean), CMD_WORK_ORDER, selectWorkOrderNo, MesPcnEnumUtil.EXPIRE_TIME.NEVER.getValue());
            case 3:
                redisMesPcn.deleteHash(getDataKey(reqBean), CMD_WORK_ORDER);
                return true;
            default:
                return null;
        }
    }

    public synchronized Object doHandleDeletePack(StationRequestBean reqBean, Integer flag, String packageNo) {
        switch (flag) {
            case 1:
                return redisMesPcn.getHash(getDataKey(reqBean), CMD_DELETE_PACK);
            case 2:
                return redisMesPcn.putHash(getDataKey(reqBean), CMD_DELETE_PACK, packageNo, MesPcnEnumUtil.EXPIRE_TIME.NEVER.getValue());
            case 3:
                redisMesPcn.deleteHash(getDataKey(reqBean), CMD_DELETE_PACK);
                return true;
            default:
                return null;
        }
    }

    public Object doHandleCurLocation(StationRequestBean reqBean, Integer flag, MesWorkCenterContainerLocation curLocation) {
        switch (flag) {
            case 1:
                return redisMesPcn.getHash(getDataKey(reqBean), CUR_LOCK_CTLOCATIONNO);
            case 2:
                return redisMesPcn.putHash(getDataKey(reqBean), CUR_LOCK_CTLOCATIONNO, curLocation, MesPcnEnumUtil.EXPIRE_TIME.NEVER.getValue());
            case 3:
                redisMesPcn.deleteHash(getDataKey(reqBean), CUR_LOCK_CTLOCATIONNO);
                return true;
            default:
                return null;
        }
    }

    public synchronized Object doHandleCurCtNo(StationRequestBean reqBean, Integer flag, EpPutPalletPlcDataModel ctNoModel) {
        switch (flag) {
            case 1:
                return redisMesPcn.getHash(getDataKey(reqBean), CUR_CT_NO);
            case 2:
                return redisMesPcn.putHash(getDataKey(reqBean), CUR_CT_NO, ctNoModel, MesPcnEnumUtil.EXPIRE_TIME.NEVER.getValue());
            case 3:
                redisMesPcn.deleteHash(getDataKey(reqBean), CUR_CT_NO);
                return true;
            default:
                return null;
        }
    }

    public synchronized Object doHandleResetCtNo(StationRequestBean reqBean, Integer flag, Boolean value) {
        switch (flag) {
            case 1:
                return redisMesPcn.getHash(getDataKey(reqBean), CMD_RESET_CT_NO);
            case 2:
                return redisMesPcn.putHash(getDataKey(reqBean), CMD_RESET_CT_NO, value, MesPcnEnumUtil.EXPIRE_TIME.NEVER.getValue());
            case 3:
                redisMesPcn.deleteHash(getDataKey(reqBean), CMD_RESET_CT_NO);
                return true;
            default:
                return null;
        }
    }

    public Object doHandleCurPlcData(StationRequestBean reqBean, Integer flag, EpPutPalletPlcDataModel plcDateModel) {
        switch (flag) {
            case 1:
                return redisMesPcn.getHash(getDataKey(reqBean), CUR_PLC_DATA);
            case 2:
                return redisMesPcn.putHash(getDataKey(reqBean), CUR_PLC_DATA, plcDateModel, MesPcnEnumUtil.EXPIRE_TIME.NEVER.getValue());
            case 3:
                redisMesPcn.deleteHash(getDataKey(reqBean), CUR_PLC_DATA);
                return true;
            default:
                return null;
        }
    }

    public Object doHandleCmdPlcPutPallet(StationRequestBean reqBean, Integer flag, String value) {
        switch (flag) {
            case 1:
                return redisMesPcn.getHash(getDataKey(reqBean), CMD_PLC_PUT_PALLET);
            case 2:
                return redisMesPcn.putHash(getDataKey(reqBean), CMD_PLC_PUT_PALLET, value, MesPcnEnumUtil.EXPIRE_TIME.NEVER.getValue());
            case 3:
                redisMesPcn.deleteHash(getDataKey(reqBean), CMD_PLC_PUT_PALLET);
                return true;
            default:
                return null;
        }
    }

    public Object doHandleCurExecPlcTask(StationRequestBean reqBean, Integer flag, Integer value) {
        switch (flag) {
            case 1:
                return redisMesPcn.getHash(getDataKey(reqBean), CUR_EXEC_PLC_TASK);
            case 2:
                return redisMesPcn.putHash(getDataKey(reqBean), CUR_EXEC_PLC_TASK, value, MesPcnEnumUtil.EXPIRE_TIME.NEVER.getValue());
            case 3:
                redisMesPcn.deleteHash(getDataKey(reqBean), CUR_EXEC_PLC_TASK);
                return true;
            default:
                return null;
        }
    }

    public Object doHandleCurCtQty(StationRequestBean reqBean, Integer flag, Integer ctQty) {
        switch (flag) {
            case 1:
                return redisMesPcn.getHash(getDataKey(reqBean), CUR_CT_QTY);
            case 2:
                return redisMesPcn.putHash(getDataKey(reqBean), CUR_CT_QTY, ctQty, MesPcnEnumUtil.EXPIRE_TIME.NEVER.getValue());
            case 3:
                redisMesPcn.deleteHash(getDataKey(reqBean), CUR_CT_QTY);
                return true;
            default:
                return null;
        }
    }

    public Object doHandlePackageDataByCtNo(StationRequestBean reqBean, String ctNo, Integer flag, SxPutPalletModuleModel putPalletModuleModel) {
        if (null != putPalletModuleModel && !StringUtils.isEmpty(putPalletModuleModel.getPackageNo())) {
            putPalletModuleModel.setPackageNo(putPalletModuleModel.getPackageNo().toUpperCase());
        }
        List<SxPutPalletModuleModel> putPalletModuleModelList;
        switch (flag) {
            case 1:
                return redisMesPcn.getHash(getDataKey(reqBean), ctNo);
            case 2:
                putPalletModuleModelList = (List<SxPutPalletModuleModel>) redisMesPcn.getHash(getDataKey(reqBean), ctNo);
                if (CollectionUtils.isEmpty(putPalletModuleModelList)) {
                    putPalletModuleModelList = new ArrayList<>();
                }
                Optional<SxPutPalletModuleModel> modelOptional = CollectionUtils.isEmpty(putPalletModuleModelList) ? null :
                        putPalletModuleModelList.stream().filter(o -> (null != o && o.getPackageNo().equals(putPalletModuleModel.getPackageNo()))).findFirst();
                if (null != modelOptional && modelOptional.isPresent()) {
                    return false;
                } else {
                    putPalletModuleModelList.add(putPalletModuleModel);
                    return redisMesPcn.putHash(getDataKey(reqBean), ctNo, putPalletModuleModelList, MesPcnEnumUtil.EXPIRE_TIME.NEVER.getValue());
                }
            case 0:
                putPalletModuleModelList = (List<SxPutPalletModuleModel>) redisMesPcn.getHash(getDataKey(reqBean), ctNo);
                if (CollectionUtils.isEmpty(putPalletModuleModelList)) {
                    putPalletModuleModelList = new ArrayList<>();
                }
                Optional<SxPutPalletModuleModel> modelOptional1 = CollectionUtils.isEmpty(putPalletModuleModelList) ? null :
                        putPalletModuleModelList.stream().filter(o -> (null != o && o.getPackageNo().equals(putPalletModuleModel.getPackageNo()))).findFirst();
                if (null != modelOptional1 && modelOptional1.isPresent()) {
                    return false;
                } else {
                    return true;
                }
            case 3:
                redisMesPcn.deleteHash(getDataKey(reqBean), ctNo);
                return true;
            case 4:
                putPalletModuleModelList = (List<SxPutPalletModuleModel>) redisMesPcn.getHash(getDataKey(reqBean), ctNo);
                if (!CollectionUtils.isEmpty(putPalletModuleModelList)) {
                    List<SxPutPalletModuleModel> putPalletModuleModelList2 = putPalletModuleModelList.stream().filter(o -> (null != o && !o.getPackageNo().equals(putPalletModuleModel.getPackageNo()))).collect(Collectors.toList());
                    if (CollectionUtils.isEmpty(putPalletModuleModelList2) || putPalletModuleModelList2.size() == putPalletModuleModelList.size() - 1) {
                        redisMesPcn.putHash(getDataKey(reqBean), ctNo, putPalletModuleModelList2, MesPcnEnumUtil.EXPIRE_TIME.NEVER.getValue());
                        return true;
                    }
                }
                return false;
            default:
                return null;
        }
    }

    public synchronized Object doHandleChangeProdType(StationRequestBean reqBean, Integer flag, String prodType) {
        switch (flag) {
            case 1:
                return redisMesPcn.getHash(getDataKey(reqBean), CMD_CHANGE_PROD_TYPE);
            case 2:
                return redisMesPcn.putHash(getDataKey(reqBean), CMD_CHANGE_PROD_TYPE, prodType, MesPcnEnumUtil.EXPIRE_TIME.NEVER.getValue());
            case 3:
                redisMesPcn.deleteHash(getDataKey(reqBean), CMD_CHANGE_PROD_TYPE);
                return true;
            default:
                return null;
        }
    }

    public synchronized Object doHandleCurProdType(StationRequestBean reqBean, Integer flag, String prodType) {
        switch (flag) {
            case 1:
                return redisMesPcn.getHash(getDataKey(reqBean), CUR_PROD_TYPE);
            case 2:
                return redisMesPcn.putHash(getDataKey(reqBean), CUR_PROD_TYPE, prodType, MesPcnEnumUtil.EXPIRE_TIME.NEVER.getValue());
            case 3:
                redisMesPcn.deleteHash(getDataKey(reqBean), CUR_PROD_TYPE);
                return true;
            default:
                return null;
        }
    }

    public synchronized Object doHandleForcePutPallet(StationRequestBean reqBean, Integer flag, String forceSpecStepCode) {
        switch (flag) {
            case 1:
                return redisMesPcn.getHash(getDataKey(reqBean), CMD_FORCE_PUT_PALLET);
            case 2:
                return redisMesPcn.putHash(getDataKey(reqBean), CMD_FORCE_PUT_PALLET, forceSpecStepCode, MesPcnEnumUtil.EXPIRE_TIME.NEVER.getValue());
            case 3:
                redisMesPcn.deleteHash(getDataKey(reqBean), CMD_FORCE_PUT_PALLET);
                return true;
            default:
                return null;
        }
    }

    public Object doHandleCachePlc(StationRequestBean reqBean, Integer flag, String code, MesPlc plc) {
        switch (flag) {
            case 1:
                return redisMesPcn.getHash(getDataKey(reqBean), code);
            case 2:
                return redisMesPcn.putHash(getDataKey(reqBean), code, plc, MesPcnEnumUtil.EXPIRE_TIME.NEVER.getValue());
            case 3:
                redisMesPcn.deleteHash(getDataKey(reqBean), code);
                return true;
            default:
                return null;
        }
    }

    public Object doHandleCacheCurExecPackageNo(StationRequestBean reqBean, Integer flag, EpPutPalletPlcDataModel packageNoModel) {
        switch (flag) {
            case 1:
                return redisMesPcn.getHash(getDataKey(reqBean), CUR_EXEC_PACKAGE_NO);
            case 2:
                return redisMesPcn.putHash(getDataKey(reqBean), CUR_EXEC_PACKAGE_NO, packageNoModel, MesPcnEnumUtil.EXPIRE_TIME.NEVER.getValue());
            case 3:
                redisMesPcn.deleteHash(getDataKey(reqBean), CUR_EXEC_PACKAGE_NO);
                return true;
            default:
                return null;
        }
    }

    public Object doReadOpcParamValue(MesPlc plc) {
        IOpcUAService opcService = new OpcUAService();
        String tagAddress = MessageFormat.format("{0}.{1}.{2}", plc.getChannel(), plc.getDevice(), plc.getTagAddress());
        OpcUAParam opcParam = new OpcUAParam();
        opcParam.setServerUrl(plc.getOpcUrl());
        opcParam.setTagAddress(tagAddress);
        opcParam.setNamespaceIndex(plc.getNameSpaceIndex());
        opcParam.setTagValueType(plc.getDataType());
        Object result = opcService.getOpcParamValue(opcParam);
        opcService.disConnection();
        return result;
    }

    public Boolean doWriteOpcParamValue(MesPlc plc, String value) {
        IOpcUAService opcService = new OpcUAService();
        String tagAddress = MessageFormat.format("{0}.{1}.{2}", plc.getChannel(), plc.getDevice(), plc.getTagAddress());
        OpcUAParam opcParam = new OpcUAParam();
        opcParam.setServerUrl(plc.getOpcUrl());
        opcParam.setTagAddress(tagAddress);
        opcParam.setNamespaceIndex(plc.getNameSpaceIndex());
        opcParam.setTagValueType(plc.getDataType());
        opcParam.setTagValue(value);
        Boolean result = opcService.editOpcParamValue(opcParam);
        opcService.disConnection();
        return result;
    }

}
