WflInfoGridAction.java

package com.mycim.webapp.actions.wflinfo;

import com.fa.sesa.exception.Assert;
import com.fa.sesa.exception.Errors;
import com.fa.sesa.threadlocal.LocalContext;
import com.mycim.framework.utils.lang.StringUtils;
import com.mycim.framework.utils.lang.collections.CollectionUtils;
import com.mycim.framework.utils.lang.collections.MapUtils;
import com.mycim.framework.utils.lang.math.NumberUtils;
import com.mycim.framework.utils.msg.JsonUtils;
import com.mycim.valueobject.MessageIdList;
import com.mycim.valueobject.ObjectList;
import com.mycim.valueobject.bas.NamedObject;
import com.mycim.valueobject.consts.TransRoutineNames;
import com.mycim.valueobject.consts.TransactionNames;
import com.mycim.valueobject.ems.pilot.PiLotView;
import com.mycim.valueobject.prp.*;
import com.mycim.valueobject.wip.Lot;
import com.mycim.webapp.Constants;
import com.mycim.webapp.WebUtils;
import com.mycim.webapp.actions.PrpSetupAction;
import com.mycim.webapp.forms.WflInfoForm;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.Override;
import java.util.*;

/**
 * @author Johnson.Wang
 * @version 6.0.0
 * @date 2019/9/3
 **/
public class WflInfoGridAction extends PrpSetupAction {

    private final String TREE_BEFORE = "treebefore";

    private final String TREE_BEFORE_CURRENT = "treebeforeandcurrent";

    private final String TREE_AFTER = "treeafter";

    private final String TREE_AFTER_CURRENT = "treeafterandcurrent";

    private final String TREE_GRID_ALL = "treeGridAll";

    private final String FILTER_TYPE = "FILTERTYPE";

    private final String EXECUTIONRRN = "EXECUTIONRRN";

    private final String TREE_REWORK_ALL = "treeReworkAll";

    private final String TREE_ALL_WITH_SPECIAL = "treeallwithspecial";

    @Override
    public ActionForward init(ActionMapping mapping, ActionForm form, HttpServletRequest request,
                              HttpServletResponse response) throws Exception {
        WflInfoForm theform = (WflInfoForm) form;

        parseCondtionForWflInfo(theform, request);
        String qryActiveOrFrozenVersionFlag = WebUtils.getParameter("qryActiveOrFrozenVersionFlag", request);
        String noEditFlag = WebUtils.getParameter("noEditFlag", request);
        String isActive = request.getParameter("isActive");
        String processVer = request.getParameter("processVer");
        // 是否显示stage id栏位
        String showStageFlag = request.getParameter("showStageFlag");
        String type = request.getParameter("type");
        // 是否显示流程返工信息
        String containsRework = WebUtils.getParameter("containsRework", request);
        // 是否显示流程情境值信息
        String showContextSet = WebUtils.getParameter("showContextSet", request);
        // 是否需要定位到当前工步
        String orientateCurrByFLowSeq = WebUtils.getParameter("orientateCurrByFLowSeq", request);
        // 是否进入rework流程
        boolean isRework = WebUtils.getParameterBoolean("isRework", request);
        // 必须显示数据的列,没有就从前面的有数据的版本获取;[例如:flowSeq]
        String mustViewColumn = WebUtils.getParameterNoTrim("mustViewColumn", request);
        String from = WebUtils.getParameterNoTrim("from", request);
        String treeReworkAll = WebUtils.getParameterNoTrim("treeReworkAll", request);
        long lotRrn = WebUtils.getParameterLong("lotRrn", request);
        request.setAttribute("lotRrn", lotRrn);

        if (StringUtils.isNotBlank(from)) {
            request.setAttribute("from", from);
        }

        if (isRework) {
            request.setAttribute("isRework", isRework);
            String routeId = WebUtils.getParameter("routeId", request);
            request.setAttribute("routeId", routeId);
        }
        request.setAttribute("mustViewColumn", mustViewColumn);
        request.setAttribute("orientateCurrByFLowSeq",
                             StringUtils.isNotBlank(orientateCurrByFLowSeq) ? orientateCurrByFLowSeq : "");
        request.setAttribute("containsRework", StringUtils.equalsIgnoreCase("Y", containsRework) ? "Y" : "");
        request.setAttribute("showContextSet", StringUtils.equalsIgnoreCase("Y", showContextSet) ? "Y" : "");
        request.setAttribute("callbackFlag", request.getParameter("callbackFlag"));
        request.setAttribute("routeSeq", request.getParameter("routeSeq"));
        request.setAttribute("operationSeq", request.getParameter("operationSeq"));

        if (StringUtils.equalsIgnoreCase("route", type)) {
            request.setAttribute("targetReqCode", "qryWflInfoGridForRoute");
            request.setAttribute("type", "route");
        } else {
            request.setAttribute("targetReqCode", "qryWflInfoGridForProcess");
            request.setAttribute("type", "");
        }

        if (StringUtils.equalsIgnoreCase("Y", qryActiveOrFrozenVersionFlag)) {
            request.setAttribute("qryActiveOrFrozenVersionFlag", "Y");
        }
        if (StringUtils.equalsIgnoreCase("Y", noEditFlag)) {
            request.setAttribute("noEditFlag", "Y");
        }
        if (StringUtils.isNotBlank(isActive)) {
            request.setAttribute("isActive", isActive);
        }

        if (StringUtils.isNotBlank(processVer)) {
            request.setAttribute("processVer", processVer);
        }
        if (StringUtils.isNotBlank(showStageFlag)) {
            request.setAttribute("showStageFlag", StringUtils.trimToUpperCase(showStageFlag));
        }
        if (StringUtils.isNotBlank(treeReworkAll)) {
            request.setAttribute("filterType", treeReworkAll);
        }
        request.setAttribute("CONDTIONFORM_INIT_VALUES", JsonUtils.toString(theform));
        request.setAttribute("IDS", JsonUtils.toString(theform));

        return mapping.findForward("init");
    }

    public List<Map<String, Object>> parseWflTreeForGrid(List wflTree, Long productRrn, String fliterCondition,
                                                         HttpServletRequest request) {
        List<Map<String, Object>> nodes = new ArrayList<Map<String, Object>>();
        if (CollectionUtils.isEmpty(wflTree)) {
            return nodes;
        }
        String routeSeq = null;
        String routeId = null;
        String routeDesc = null;
        long routeRrn = 0;
        for (int i = 0; i < wflTree.size(); i++) {
            Map<String, Object> node = new HashMap<>();
            String[] treeNodes = (String[]) wflTree.get(i);
            if ("0".equals(treeNodes[7])) {
                routeSeq = StringUtils.substringBefore(treeNodes[2], "---");
                routeId = StringUtils.substringAfter(treeNodes[2], "---");
                routeDesc = treeNodes[5];
                node.put("routeSeq", routeSeq);
                node.put("routeId", routeId);
                node.put("routeDesc", routeDesc);
                node.put("isRoute", new Boolean(true));
                routeRrn = NumberUtils.toLong(treeNodes[4], 0);
                // nodes.add(node);不用显示工序了
            } else if ("1".equals(treeNodes[7])) {
                String operationSeq = StringUtils.substringBefore(treeNodes[2], "---");
                node.put("routeSeq", routeSeq);
                node.put("operationSeq", operationSeq);
                node.put("routeId", routeId);
                node.put("routeDesc", routeDesc);
                String operationId = StringUtils.substringAfter(treeNodes[2], "---");
                node.put("operationId", operationId);
                long operationRrn = NumberUtils.toLong(treeNodes[4], 0);

                Operation oper = prpService.getOperation(operationRrn);
                if (StringUtils.isNotBlank(fliterCondition) &&
                        (!StringUtils.equals(oper.getMvouWflId(), fliterCondition))) {
                    continue;
                }

                String wflStep = treeNodes[6];
                node.put("stepPath", wflStep);
                node.put("stepNumber", wflStep);

                String[] wflStepArray = StringUtils.split(wflStep, ".");
                node.put("productRrn", productRrn);
                node.put("processRrn", NumberUtils.toLong(wflStepArray[0], 0));
                node.put("processVersion", NumberUtils.toInt(wflStepArray[1], 0));
                node.put("routeRrn", routeRrn);
                node.put("operationRrn", operationRrn);
                node.put("facilityRrn", LocalContext.getFacilityRrn());

                // 从情景值查询operationDesc 和 FlowSeq
                String flowSeq = ctxExecService.getFlowSeqByProcessInfo(NumberUtils.toLong(wflStepArray[0], 0),
                                                                        NumberUtils.toInt(wflStepArray[1], 0),
                                                                        operationRrn, routeRrn);
                node.put("flowSeq", flowSeq);
                node.put("reSeq", flowSeq);
                node.put("operationDesc", ctxExecService.getOperationDescByProcessInfo(productRrn, NumberUtils.toLong(
                        wflStepArray[0], 0), NumberUtils.toInt(wflStepArray[1], 0), routeRrn, operationRrn));
                String stageId = ctxExecService.getStageByProcessInfo(productRrn,
                                                                      NumberUtils.toLong(wflStepArray[0], 0),
                                                                      NumberUtils.toInt(wflStepArray[1], 0), routeRrn,
                                                                      operationRrn);
                if (StringUtils.isNotBlank(stageId)) {
                    node.put("stageId", stageId);
                }

                if (filterGridTree(request, nodes, node, operationId)) {
                    continue;
                }

                nodes.add(node);
            }
        }
        return nodes;
    }

    public List<Map> parseWflTree(ArrayList<String[]> wflTree) {
        List<Map> nodes = new ArrayList<>();
        for (int i = 0; i < wflTree.size(); i++) {
            Map routeNode = null;
            String[] node = wflTree.get(i);
            if ("0".equals(node[7])) {
                routeNode = new HashMap<>(4);
                routeNode.put("text", node[2]);
                routeNode.put("cls", "folder");
                routeNode.put("children", new ArrayList<>());
                routeNode.put("id", node[6]);
                nodes.add(routeNode);
            } else if ("1".equals(node[7])) {
                Map operationNode = new HashMap<>();
                operationNode.put("text", node[2] + "---" + node[5]);
                operationNode.put("leaf", new Boolean(true));
                operationNode.put("id", node[6]);
                Map curRouteNode = nodes.get(nodes.size() - 1);
                List curRouteChildNodes = (List) curRouteNode.get("children");
                curRouteChildNodes.add(operationNode);
            }
        }
        return nodes;
    }

    public List<Map<String, Object>> qryWflInfoGridForRoute(Map<String, Object> theform, HttpServletRequest request,
                                                            HttpServletResponse response) {

        String processId = MapUtils.getString(theform, "processId");
        Long processRrn = null;
        Assert.isTrue(StringUtils.isNotBlank(processId), Errors.create().content("process.empty_id").build());
        processId = StringUtils.trimToUpperCase(processId);
        NamedObject processObj = baseService.getNamedObject(
                new NamedObject(processId, getNamedSpace(ObjectList.WFL_KEY, LocalContext.getFacilityRrn()),
                                ObjectList.WFL_KEY));
        Assert.notNull(processObj,
                       Errors.create().key(MessageIdList.PROCESS_MISSING_PROCESS).content("Process does not exist!")
                             .build());
        processRrn = new Long(processObj.getInstanceRrn());

        List<Map<String, Object>> routeList = prpService.getAllRouteByProcess(processId, MapUtils.getInteger(theform,
                                                                                                             "processVer"));

        List<Map<String, Object>> nodes = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(routeList)) {
            for (int i = 0; i < routeList.size(); i++) {
                Map node = new HashMap<>();
                Map<String, Object> routeMap = routeList.get(i);
                node.put("routeId", MapUtils.getString(routeMap, "routeId"));
                node.put("routeDesc", MapUtils.getString(routeMap, "routeDesc"));
                node.put("isMain", MapUtils.getString(routeMap, "isMain"));

                nodes.add(node);
            }
        }

        return nodes;
    }

    /**
     * @param theform
     * @param request
     * @return
     */
    public List<Map<String, Object>> qryWflInfoGridForProcess(Map<String, Object> theform, HttpServletRequest request) {
        String containsRework = MapUtils.getString(theform, "containsRework");
        // 必须显示数据的列,没有就从前面的有数据的版本获取;
        // [例如:flowSeq]
        String mustViewColumn = MapUtils.getString(theform, "mustViewColumn");

        String productId = MapUtils.getString(theform, "productId");
        int productVersion = MapUtils.getIntValue(theform, "productVersion");
        Long productRrn = null;
        if (StringUtils.isNotBlank(productId)) {
            productId = StringUtils.trimToUpperCase(productId);
            NamedObject productObj = baseService.getNamedObject(
                    new NamedObject(productId, getNamedSpace(ObjectList.PRODUCT_KEY, LocalContext.getFacilityRrn()),
                                    ObjectList.PRODUCT_KEY));
            Assert.notNull(productObj,
                           Errors.create().key(MessageIdList.PRODUCT_PRODUCT_MISSING).content("Product does not exist!")
                                 .build());
            productRrn = productObj.getInstanceRrn();
        }

        String processId = MapUtils.getString(theform, "processId");
        Long processRrn = null;
        Assert.isTrue(StringUtils.isNotBlank(processId), Errors.create().content("process.empty_id").build());
        processId = StringUtils.trimToUpperCase(processId);
        NamedObject processObj = baseService.getNamedObject(
                new NamedObject(processId, getNamedSpace(ObjectList.WFL_KEY, LocalContext.getFacilityRrn()),
                                ObjectList.WFL_KEY));
        Assert.notNull(processObj,
                       Errors.create().key(MessageIdList.PROCESS_PROCESS_MISSING).content("Process does not exist!")
                             .build());
        processRrn = processObj.getInstanceRrn();

        Map<String, Object> matchingRules = new HashMap<>();
        matchingRules.put("productRrn", productRrn);
        matchingRules.put("processRrn", processRrn);

        String qryActiveOrFrozenVersionFlag = MapUtils.getString(theform, "qryActiveOrFrozenVersionFlag");
        if (StringUtils.isNotBlank(qryActiveOrFrozenVersionFlag)) {
            matchingRules.put("qryActiveOrFrozenVersionFlag", qryActiveOrFrozenVersionFlag);
        }

        /**
         * 1.产品设置界面:过滤的Bond和Debond工步 2.前后跳步
         */
        List wflTree = new ArrayList();
        String filterNode = StringUtils.EMPTY;
        String filterType = MapUtils.getString(theform, "filterType");
        if (StringUtils.isNotBlank(filterType)) {// 查询主流程
            if (StringUtils.equals(filterType, TREE_BEFORE)) {
                // wflTree = getProcessManager().getWorkFlowTreeBefore(theform.getExecutionRrn());
                matchingRules.put("executionRrn", MapUtils.getLongValue(theform, ""));
                wflTree = getWFLInfo(matchingRules, "treebefore");

                return parseWflList(wflTree, productRrn, filterNode);
            } else if (StringUtils.equals(filterType, TREE_AFTER)) {
                matchingRules.put("executionRrn", MapUtils.getLongValue(theform, "executionRrn"));
                wflTree = getWFLInfo(matchingRules, "treeafter");
                return parseWflList(wflTree, productRrn, filterNode);
            } else if (StringUtils.equals(filterType, TREE_ALL_WITH_SPECIAL)) {
                String reworkRouteId = MapUtils.getString(theform, "reworkRouteId");
                matchingRules.put("executionRrn", MapUtils.getLongValue(theform, "executionRrn"));
                wflTree = getWFLInfo(matchingRules, "treeallwithspecial");
                return parseWflList(wflTree, productRrn, filterNode);
            } else if (StringUtils.equals(filterType, TREE_BEFORE_CURRENT)) {
                String operationSeq = MapUtils.getString(theform, "operationSeq");
                operationSeq = StringUtils.replace(operationSeq, Constants.WFL_STEP_START, "0");
                String routeSeq = MapUtils.getString(theform, "routeSeq");
                routeSeq = StringUtils.replace(routeSeq, Constants.WFL_ROUTE_START, "0");

                int version = getQueryVersion(theform, processRrn);
                String reworkRouteId = MapUtils.getString(theform, "reworkRouteId");

                List<Map<String, Object>> allProcessStep = prpService.getProcessAllStepInfo(processRrn, version,
                                                                                            NumberUtils.toLong(
                                                                                                    operationSeq),
                                                                                            NumberUtils.toLong(
                                                                                                    routeSeq),
                                                                                            new Long(-99999),
                                                                                            productRrn, null, 0);
                return buildProcessAllStepInfo(allProcessStep, productRrn, productVersion,
                                               StringUtils.equalsIgnoreCase("y", containsRework), reworkRouteId);
            } else if (StringUtils.equals(filterType, TREE_AFTER_CURRENT)) {
                String operationSeq = WebUtils.getParameter("operationSeq", request);
                operationSeq = StringUtils.replace(operationSeq, Constants.WFL_STEP_START, "0");
                String routeSeq = WebUtils.getParameter("routeSeq", request);
                routeSeq = StringUtils.replace(routeSeq, Constants.WFL_ROUTE_START, "0");

                int version = getQueryVersion(theform, processRrn);
                String reworkRouteId = WebUtils.getParameter("reworkRouteId", request);

                List<Map<String, Object>> allProcessStep = prpService.getProcessAllStepInfo(processRrn, version,
                                                                                            NumberUtils.toLong(
                                                                                                    operationSeq),
                                                                                            NumberUtils.toLong(
                                                                                                    routeSeq),
                                                                                            new Long(99999), productRrn,
                                                                                            null, 0);

                return buildProcessAllStepInfo(allProcessStep, productRrn, productVersion,
                                               StringUtils.equalsIgnoreCase("y", containsRework), reworkRouteId);
            } else if (StringUtils.equals(filterType, TREE_GRID_ALL)) {// 改变工艺流程
                // 获取最新的process 和 context 都 active的version
                int processVer = specService.getLatestActivatedProcessVersion(productRrn, processRrn);

                wflTree = prpService.getWorkFlowTree(processRrn, processVer, matchingRules);
                return parseWflTreeForGrid(wflTree, productRrn, filterNode, request);
            } else if (StringUtils.equals(filterType, TREE_REWORK_ALL)) {//查询返工流程
                int version = getQueryVersion(theform, processRrn);
                String versionStatus = baseService.getVersionStatus(processRrn, version);
                int lastHasFlowSeqProVer = 0;
                // 只有UNFROZEN状态下执行
                if (StringUtils.equals(mustViewColumn, "1") &&
                        (StringUtils.equals(versionStatus, TransactionNames.UNFROZEN_KEY) ||
                                StringUtils.equals(versionStatus, TransactionNames.FROZEN_KEY))) {
                    lastHasFlowSeqProVer = prpService.getLastHasFlowSeqProcessVersion(processRrn, version);
                }

                String reworkRouteId = MapUtils.getString(theform, "reworkRouteId");
                List<Map<String, Object>> allProcessStep = prpService.getProcessAllStepInfo(processRrn, version, null,
                                                                                            null, 99999L, productRrn,
                                                                                            null, lastHasFlowSeqProVer);
                return getAllReworkRouteStep(allProcessStep, productRrn,
                                             StringUtils.equalsIgnoreCase("y", containsRework), reworkRouteId);

            } else {// 产品设置过滤 bond 和debond 工步
                // 获取最新的process 和 context 都 active的version
                int processVer = 0;
                ProductSpecInfo productSpecInfo = specService.getLatestActivatedProductSpecItemInfo(productRrn,
                                                                                                    processRrn);

                if (!Objects.isNull(productSpecInfo)) {
                    processVer = productSpecInfo.getProcessVersion();
                }

                wflTree = prpService.getWorkFlowTree(processRrn, processVer, matchingRules);
                filterNode = filterType;

                if (StringUtils.equals(filterNode, TransRoutineNames.MOVEOUT_AUTODEBONDED_STD) &&
                        !StringUtils.equalsIgnoreCase(MapUtils.getString(theform, "objectType"), "debondToStep")) {
                    List<Map<String, Object>> allProcessStep = prpService.getProcessAllStepInfo(processRrn, processVer,
                                                                                                null, null, 99999L,
                                                                                                productRrn, null, 0);

                    return parseWflTreeForBondOrDebond(allProcessStep, productRrn, filterNode, request);
                } else {
                    return parseWflTreeForGrid(wflTree, productRrn, filterNode, request);
                }
            }
        } else {// 查询所有流程
            int version = getQueryVersion(theform, processRrn);
            String versionStatus = baseService.getVersionStatus(processRrn, version);
            int lastHasFlowSeqProVer = 0;
            // 只有UNFROZEN状态下执行
            if (StringUtils.equals(mustViewColumn, "1") &&
                    (StringUtils.equals(versionStatus, TransactionNames.UNFROZEN_KEY) ||
                            StringUtils.equals(versionStatus, TransactionNames.FROZEN_KEY))) {
                lastHasFlowSeqProVer = prpService.getLastHasFlowSeqProcessVersion(processRrn, version);
            }

            String reworkRouteId = MapUtils.getString(theform, "reworkRouteId");
            List<Map<String, Object>> allProcessStep = prpService.getProcessAllStepInfo(processRrn, version, null, null,
                                                                                        99999L, productRrn,
                                                                                        productVersion,
                                                                                        lastHasFlowSeqProVer);
            List<Map<String, Object>> nodes = buildProcessAllStepInfo(allProcessStep, productRrn, productVersion,
                                                                      StringUtils.equalsIgnoreCase("y", containsRework),
                                                                      reworkRouteId);

            // 处理pilot 子母批跳步 #41886
            long lotRrn = MapUtils.getLongValue(theform, "lotRrn");
            if (lotRrn > 0) {
                return buildPilotRepositionStep(lotRrn, nodes);
            } else {
                return nodes;
            }
        }

    }

    public ReworkRouteContextValue buildNewReworkRouteContextValue(Map<String, Object> operationInfo) {
        ReworkRouteContextValue contextValue = ctxExecService.buildNewReworkRouteContextValue();
        contextValue.setContextKey2(MapUtils.getString(operationInfo, "processRrn"));
        contextValue.setContextKey3(MapUtils.getString(operationInfo, "routeRrn"));
        contextValue.setContextKey4(MapUtils.getString(operationInfo, "operationRrn"));
        contextValue.setContextKey8(MapUtils.getString(operationInfo, "processVersion"));
        return contextValue;
    }

    private List<Map<String, Object>> parseWflTreeForBondOrDebond(List<Map<String, Object>> list, Long productRrn,
                                                                  String fliterCondition, HttpServletRequest request) {
        List<Map<String, Object>> nodes = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            Map<String, Object> node = new HashMap<>();
            Map<String, Object> map = list.get(i);
            long operationRrn = MapUtils.getLong(map, "operationRrn");
            Operation oper = prpService.getOperation(operationRrn);
            if (StringUtils.isNotBlank(fliterCondition) &&
                    (!StringUtils.equals(oper.getMvouWflId(), fliterCondition))) {
                continue;
            }

            node.put("isMain", MapUtils.getString(map, "isMain", "1"));
            node.put("operationSeq", MapUtils.getString(map, "operationRouteSeq"));
            node.put("routeSeq", MapUtils.getString(map, "routeProcessSeq"));
            node.put("routeId", MapUtils.getString(map, "routeId"));
            node.put("routeDesc", MapUtils.getString(map, "routeDesc"));
            node.put("routeRrn", MapUtils.getString(map, "routeRrn"));
            node.put("operationId", MapUtils.getString(map, "operationId"));
            node.put("operationRrn", MapUtils.getString(map, "operationRrn"));


            StringBuffer wflStepBuffer = new StringBuffer();
            wflStepBuffer.append(MapUtils.getString(map, "processRrn")).append(".")
                         .append(MapUtils.getString(map, "processVersion")).append(".")
                         .append(MapUtils.getString(map, "routeStepRrn")).append("|")
                         .append(MapUtils.getString(map, "routeRrn")).append(".")
                         .append(MapUtils.getString(map, "routeVersion")).append(".")
                         .append(MapUtils.getString(map, "operationStepRrn"));

            node.put("stepPath", wflStepBuffer.toString());
            node.put("stepNumber", wflStepBuffer.toString());

            node.put("productRrn", productRrn);
            node.put("processRrn", MapUtils.getString(map, "processRrn"));
            node.put("processVersion", MapUtils.getString(map, "processVersion"));
            node.put("contextKey2", MapUtils.getString(map, "processVersion"));
            node.put("facilityRrn", LocalContext.getFacilityRrn());
            node.put("eqptGroupId", MapUtils.getString(map, "eqptGroupId"));
            node.put("flowSeq", MapUtils.getString(map, "flowSeq"));
            node.put("reSeq", MapUtils.getString(map, "flowSeq"));
            node.put("processStepIdVersion", MapUtils.getString(map, "routeId"));
            node.put("operationDesc", MapUtils.getString(map, "contextOperationDesc"));
            node.put("stageId", MapUtils.getString(map, "stageId"));
            node.put("recipeId", MapUtils.getString(map, "recipeId"));
            node.put("processLocation", MapUtils.getString(map, "processLocation"));

            if (filterGridTree(request, nodes, node, oper.getInstanceId())) {
                continue;
            }
            nodes.add(node);
        }

        return nodes;
    }

    private ArrayList getWFLInfo(Map<String, Object> matchingRules, String type) {
        Long processRrn = MapUtils.getLong(matchingRules, "processRrn");
        Long productRrn = MapUtils.getLong(matchingRules, "productRrn");
        Long executionRrn = MapUtils.getLong(matchingRules, "executionRrn");
        Long lotRrn = lotQueryService.getLotRrnByExecutionRrn(executionRrn);
        Lot lot = lotQueryService.getLot(lotRrn);
        // String currentStep = getLotManager().getExecutionCurrentStep(executionRrn);
        // String[] strs = currentStep.split(".");
        Integer processVersion = lot.getProcessVersion();
        Long operationRrn = lot.getOperationRrn();
        List<Map<String, Object>> viewProcessInfo = prpService.getProcessAllMainStepInfo(processRrn, processVersion);
        // reconstruct 支线
        List<Map<String, Object>> allProcessStep = prpService.getProcessAllStepInfo(processRrn, processVersion, null,
                                                                                    null, new Long(99999), null, null,
                                                                                    0);
        viewProcessInfo = buildViewProcessInfo4Branch(viewProcessInfo, allProcessStep);
        viewProcessInfo = buildViewProcessInfo4Type(viewProcessInfo, lot, type);

        return (ArrayList) viewProcessInfo;
    }

    private boolean filterGridTree(HttpServletRequest request, List<Map<String, Object>> nodes,
                                   Map<String, Object> node, String operationId) {
        String from = WebUtils.getParameterNoTrim("from", request);
        if (StringUtils.isNotBlank(from)) {
            if (StringUtils.equals(from, "subcon")) {
                // subcon 只查询operation type是 D 的
                if (StringUtils.equals(baseService.getInstanceDesc(
                        getInstanceRrn(operationId, LocalContext.getFacilityRrn(), ObjectList.OPERATION_KEY)), "D")) {
                    nodes.add(node);
                }
            }
            return true;
        }
        return false;
    }

    private List<Map<String, Object>> buildProcessAllStepInfo(List<Map<String, Object>> list, Long productRrn,
                                                              Integer productVersion, boolean containsReworkFlag,
                                                              String reworkRouteId) {
        List nodes = new ArrayList<>();
        List reworkNodes = new ArrayList();

        Map<String, String> flipTypeMap = processSpecService.getFlipTypeKeyMap();

        for (int i = 0; i < list.size(); i++) {
            Map node = new HashMap();
            Map<String, Object> map = list.get(i);

            if (containsReworkFlag) {
                // 添加 rework 信息
                Map<String, Object> reworkStartContextMap = new HashMap<String, Object>();
                reworkStartContextMap.put("productRrn", productRrn);
                reworkStartContextMap.put("processRrn", MapUtils.getString(map, "processRrn"));
                reworkStartContextMap.put("routeRrn", MapUtils.getString(map, "routeRrn"));
                reworkStartContextMap.put("operationRrn", MapUtils.getString(map, "operationRrn"));
                reworkStartContextMap.put("processVersion", MapUtils.getString(map, "processVersion"));
                reworkStartContextMap.put("productVersion", productVersion);
                List<Map<String, Object>> reworkList = this.buildReworkWflInfo(reworkStartContextMap);
                boolean breakFlag = false;
                for (int j = 0; j < reworkList.size(); j++) {
                    Map reworkNode = new HashMap();
                    Map<String, Object> reworkMap = reworkList.get(j);
                    String reworkPorcessRouteId = MapUtils.getString(reworkMap, "routeId");
                    reworkNode.put("facilityRrn", LocalContext.getFacilityRrn());
                    reworkNode.put("productRrn", productRrn);
                    reworkNode.put("processRrn", MapUtils.getString(reworkMap, "processRrn"));
                    reworkNode.put("processVersion", MapUtils.getString(reworkMap, "processVersion"));
                    reworkNode.put("routeRrn", MapUtils.getString(reworkMap, "routeRrn"));
                    reworkNode.put("routeId", reworkPorcessRouteId);
                    reworkNode.put("operationRrn", MapUtils.getString(reworkMap, "operationRrn"));
                    reworkNode.put("operationId", MapUtils.getString(reworkMap, "operationId"));
                    reworkNode.put("flowSeq", MapUtils.getString(reworkMap, "flowSeq"));
                    reworkNode.put("reSeq", MapUtils.getString(reworkMap, "flowSeq"));
                    reworkNode.put("operationDesc", MapUtils.getString(reworkMap, "operationDesc"));
                    reworkNode.put("stageId", MapUtils.getString(reworkMap, "stageId"));
                    reworkNode.put("recipeId", MapUtils.getString(reworkMap, "recipeId"));
                    reworkNode.put("eqptGroupId", MapUtils.getString(reworkMap, "eqptGroupId"));
                    reworkNode.put("processLocation", MapUtils.getString(reworkMap, "processLocation"));
                    reworkNode.put("stepPath", MapUtils.getString(reworkMap, "stepPath"));
                    reworkNode.put("isRework", "1");
                    reworkNode.put("stepNumber", MapUtils.getString(reworkMap, "stepNumber"));
                    node.put("isMain", MapUtils.getString(map, "isMain", "-1"));

                    // reworkRouteId不为空,表示当前进入了某个rework流程,
                    // 则只显示当前的rework流程,其它rework刘晨不显示
                    if (StringUtils.isNotBlank(reworkRouteId)) {
                        if (StringUtils.equalsIgnoreCase(reworkRouteId, reworkPorcessRouteId)) {
                            breakFlag = true;
                            if (!reworkNodes.contains(reworkNode)) {
                                reworkNodes.add(reworkNode);
                            }
                        }
                    } else {
                        if (!reworkNodes.contains(reworkNode)) {
                            reworkNodes.add(reworkNode);
                        }
                    }

                    if (StringUtils.isNotBlank(reworkRouteId) &&
                            !StringUtils.equalsIgnoreCase(reworkRouteId, reworkPorcessRouteId) && breakFlag) {
                        break;
                    }
                }
            }

            node.put("isMain", MapUtils.getString(map, "isMain", "1"));
            node.put("operationSeq", MapUtils.getString(map, "operationRouteSeq"));
            node.put("routeSeq", MapUtils.getString(map, "routeProcessSeq"));
            node.put("routeId", MapUtils.getString(map, "routeId"));
            node.put("routeDesc", MapUtils.getString(map, "routeDesc"));
            node.put("routeRrn", MapUtils.getString(map, "routeRrn"));
            node.put("operationId", MapUtils.getString(map, "operationId"));
            node.put("operationRrn", MapUtils.getString(map, "operationRrn"));

            String wflStep =
                    MapUtils.getString(map, "processRrn") + "." + MapUtils.getString(map, "processVersion") + "." +
                            MapUtils.getString(map, "routeStepRrn") + "|" + MapUtils.getString(map, "routeRrn") + "." +
                            MapUtils.getString(map, "routeVersion") + "." + MapUtils.getString(map, "operationStepRrn");

            node.put("stepPath", wflStep);
            node.put("stepNumber", wflStep);

            node.put("productRrn", productRrn);
            node.put("processRrn", MapUtils.getString(map, "processRrn"));
            node.put("processVersion", MapUtils.getString(map, "processVersion"));
            node.put("contextKey2", MapUtils.getString(map, "processVersion"));
            node.put("facilityRrn", LocalContext.getFacilityRrn());
            node.put("eqptGroupId", specService.getEqptGroupIds(MapUtils.getLong(map, "processRrn"),
                                                                MapUtils.getInteger(map, "processVersion"),
                                                                MapUtils.getLong(map, "routeRrn"),
                                                                MapUtils.getLong(map, "operationRrn")));

            node.put("flowSeq", MapUtils.getString(map, "flowSeq"));
            node.put("reSeq", MapUtils.getString(map, "flowSeq"));
            node.put("processStepIdVersion", MapUtils.getString(map, "routeId"));
            node.put("operationDesc", MapUtils.getString(map, "contextOperationDesc"));
            node.put("stageId", MapUtils.getString(map, "stageId"));
            node.put("recipeId", MapUtils.getString(map, "recipeId"));
            node.put("processLocation", MapUtils.getString(map, "processLocation"));
            node.put("flipType", MapUtils.getString(map, "flipType"));
            node.put("flipTypeDesc",
                     MapUtils.getString(flipTypeMap, MapUtils.getString(map, "flipType"), StringUtils.EMPTY));
            nodes.add(node);
        }

        nodes.addAll(reworkNodes);
        return nodes;
    }

    private List<Map<String, Object>> buildReworkWflInfo(Map<String, Object> operationInfo) {
        List<Map<String, Object>> wflInfos = new ArrayList<>();
        long reworkRouteRrn = ctxExecService.getProcessReworkRouteRrn(operationInfo);

        ReworkRouteContextValue reworkRouteContextValue = this.buildNewReworkRouteContextValue(operationInfo);
        ContextValue contextValue = ctxService.simulateContextValue(reworkRouteContextValue);

        if (reworkRouteRrn > 0) {
            int reworkRouteVersion = 0;
            if (StringUtils.isNotBlank(contextValue.getResultValue5())) {
                reworkRouteVersion = Integer.parseInt(contextValue.getResultValue5());
            }
            List<String[]> wflTree;
            if (reworkRouteVersion > 0) {
                wflTree = prpService.getWorkFlowTree(reworkRouteRrn, reworkRouteVersion, new HashMap());
            } else {
                wflTree = prpService.getWorkFlowTree(reworkRouteRrn, new HashMap());
            }

            String routeSeq = "";
            Long routeRrn = reworkRouteRrn;
            String routeId = getInstanceId(reworkRouteRrn);
            String routeDesc = getInstanceDesc(reworkRouteRrn);
            for (int i = 0; i < wflTree.size(); i++) {
                Map<String, Object> wflInfo = new HashMap<String, Object>();
                String[] treeNodes = wflTree.get(i);
                if ("0".equals(treeNodes[7])) {
                    routeSeq = StringUtils.substringBefore(treeNodes[2], "-");
                    routeId = StringUtils.substringAfterLast(treeNodes[2], "---");
                    routeRrn = NumberUtils.createLong(treeNodes[4]);
                    routeDesc = treeNodes[5];
                } else if ("1".equals(treeNodes[7])) {
                    Long productRrn = MapUtils.getLong(operationInfo, "productRrn");
                    int productVersion = MapUtils.getIntValue(operationInfo, "productVersion");
                    wflInfo.put("productRrn", productRrn);
                    wflInfo.put("productVersion", productVersion);
                    wflInfo.put("routeRrn", routeRrn);
                    wflInfo.put("routeSeq", routeSeq);
                    wflInfo.put("routeProcessSeq", routeSeq);
                    wflInfo.put("routeId", routeId);
                    wflInfo.put("routeDesc", routeDesc);
                    wflInfo.put("isRework", "1");
                    wflInfo.put("isMain", "0");
                    Long operationRrn = NumberUtils.createLong(treeNodes[4]);
                    wflInfo.put("operationRrn", operationRrn);
                    String operationSeq = StringUtils.substringBefore(treeNodes[2], "-");
                    wflInfo.put("operationSeq", operationSeq);
                    wflInfo.put("operationRouteSeq", operationSeq);
                    String operationId = StringUtils.substringAfterLast(treeNodes[2], "---");
                    wflInfo.put("operationId", operationId);
                    String operationDesc = StringUtils.substringAfterLast(treeNodes[5], "---");

                    String wflStep = treeNodes[6];
                    wflInfo.put("stepPath", wflStep);
                    Map conditionM = new HashMap();

                    String[] wflStepArray = StringUtils.split(wflStep, ".");
                    // wflInfo.put("processRrn", NumberUtils.toLong(wflStepArray[0], 0));
                    wflInfo.put("processRrn", MapUtils.getLong(operationInfo, "processRrn"));
                    // wflInfo.put("processVersion", NumberUtils.toInt(wflStepArray[1], 0));
                    wflInfo.put("processVersion", MapUtils.getLong(operationInfo, "processVersion"));
                    wflInfo.put("operationRrn", operationRrn);
                    wflInfo.put("operationRouteSeq", operationSeq);
                    wflInfo.put("facilityRrn", LocalContext.getFacilityRrn());

                    wflInfo.put("stepNumber", MapUtils.getString(wflInfo, "stepPath"));
                    // 从情景值查询operationDesc 和 FlowSeq
                    Map<String, Object> flowSeqParam = new HashMap<String, Object>();
                    flowSeqParam.put("facilityRrn", LocalContext.getFacilityRrn());
                    flowSeqParam.put("processRrn", operationInfo.get("processRrn"));
                    flowSeqParam.put("routeRrn", wflInfo.get("routeRrn"));
                    flowSeqParam.put("productRrn", operationInfo.get("productRrn"));
                    flowSeqParam.put("operationRrn", wflInfo.get("operationRrn"));
                    flowSeqParam.put("processVersion", operationInfo.get("processVersion"));
                    String flowSeq = ctxExecService.getFlowSeqByProcessInfo(flowSeqParam);
                    wflInfo.put("flowSeq", flowSeq);
                    wflInfo.put("reSeq", flowSeq);
                    wflInfo.put("processStepIdVersion", MapUtils.getString(wflInfo, "routeId"));
                    wflInfo.put("operationDesc", ctxExecService.getOperationDescByProcessInfo(flowSeqParam));
                    String stageId = ctxExecService.getStageByProcessInfo(wflInfo);
                    if (StringUtils.isNotBlank(stageId)) {
                        wflInfo.put("stageId", stageId);
                    }
                    String recipeId = ctxExecService.getProcessRecipeId(wflInfo);
                    if (StringUtils.isNotBlank(recipeId)) {
                        wflInfo.put("recipeId", recipeId);
                    }
                    String processLocation = ctxExecService.getProcessLocation(wflInfo);
                    wflInfo.put("processLocation", processLocation);
                    // 获取operation上的设备组
                    Operation operation = prpService.getOperation(MapUtils.getLongValue(wflInfo, "operationRrn"));
                    long entityGroupRrn = operation.getEntityGroupRrn();
                    wflInfo.put("eqptGroupId", getInstanceId(entityGroupRrn));

                    wflInfos.add(wflInfo);
                }
            }
        }

        return wflInfos;
    }

    /**
     * 流程最新的版本号,不分状态
     */
    private int getQueryVersion(Map<String, Object> theform, Long processRrn) {
        int version = 0;
        if (MapUtils.getString(theform, "isActive") == null ||
                StringUtils.equalsIgnoreCase("", MapUtils.getString(theform, "isActive"))) {
            ProcessPlanning processPlanning = new ProcessPlanning();
            processPlanning.setInstanceRrn(processRrn);
            List<ProcessVersion> processVersions = prpService.getProcessVersions(processPlanning);
            for (ProcessVersion processVersion : processVersions) {
                String status = processVersion.getVersionStatus();

                if (StringUtils.equals(TransactionNames.FROZEN_KEY, status) ||
                        StringUtils.equals(TransactionNames.ACTIVE_KEY, status) ||
                        StringUtils.equals(TransactionNames.UNFROZEN_KEY, status)) {
                    if (processVersion.getInstanceVersion() > version) {
                        version = processVersion.getInstanceVersion();
                    }
                }
            }
        } else {
            version = MapUtils.getIntValue(theform, "processVer");
            if (version == 0) {
                version = baseService.getActiveVersion(processRrn, true);
            }
        }
        return version;
    }

    private List<Map<String, Object>> buildViewProcessInfo4Branch(List<Map<String, Object>> viewProcessInfo,
                                                                  List<Map<String, Object>> allProcessStep) {

        if (!viewProcessInfo.isEmpty() && !allProcessStep.isEmpty()) {
            for (int i = 0; i < viewProcessInfo.size(); i++) {
                Map<String, Object> mainProStep = viewProcessInfo.get(i);
                for (int j = 0; j < allProcessStep.size(); j++) {
                    Map<String, Object> tempStep = allProcessStep.get(j);
                    if (MapUtils.getLongValue(mainProStep, "routeRrn") == MapUtils.getLongValue(tempStep, "routeRrn") &&
                            MapUtils.getLongValue(mainProStep, "operationRrn") ==
                                    MapUtils.getLongValue(tempStep, "operationRrn") &&
                            StringUtils.equals(MapUtils.getString(mainProStep, "routeProcessSeq"),
                                               MapUtils.getString(tempStep, "routeProcessSeq")) &&
                            StringUtils.equals(MapUtils.getString(mainProStep, "operationRouteSeq"),
                                               MapUtils.getString(tempStep, "operationRouteSeq"))) {
                        mainProStep.put("isMain", '1');
                        allProcessStep.set(j, mainProStep);
                        break;
                    }
                }
            }
        } else {
            return viewProcessInfo;
        }

        return allProcessStep;
    }

    private List<Map<String, Object>> buildViewProcessInfo4Type(List<Map<String, Object>> viewProcessInfo, Lot lot,
                                                                String type) {
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        List<Map<String, Object>> reworkList = new ArrayList<Map<String, Object>>();
        Long operationRrn = lot.getOperationRrn();
        Long routeRrn = lot.getRouteRrn();
        String operationSeq = lot.getOperationSeq();
        boolean opreationFlag = false;
        for (int i = 0; i < viewProcessInfo.size(); i++) {
            Map<String, Object> mainProStep = viewProcessInfo.get(i);
            Long tempOperationRrn = MapUtils.getLong(mainProStep, "operationRrn");
            Long tempRouteRrn = MapUtils.getLong(mainProStep, "routeRrn");
            String stepSeq = MapUtils.getString(mainProStep, "operationRouteSeq");
            String stepNumber = MapUtils.getLong(mainProStep, "processRrn") + "." +
                    MapUtils.getIntValue(mainProStep, "processVersion") + "." +
                    MapUtils.getLong(mainProStep, "routeStepRrn") + "|" + MapUtils.getLong(mainProStep, "routeRrn") +
                    "." + MapUtils.getIntValue(mainProStep, "routeVersion") + "." +
                    MapUtils.getLong(mainProStep, "operationStepRrn");
            mainProStep.put("stepNumber", stepNumber);
            mainProStep.put("stepPath", stepNumber);
            mainProStep.put("routeSeq", MapUtils.getString(mainProStep, "routeProcessSeq"));
            mainProStep.put("operationSeq", MapUtils.getString(mainProStep, "operationRouteSeq"));
            mainProStep.put("productRrn", lot.getProductRrn());
            if (StringUtils.equalsIgnoreCase("treebefore", type)) {
                if (!opreationFlag) {
                    list.add(mainProStep);
                } else {
                    break;
                }
            }
            if (StringUtils.equalsIgnoreCase("treeafter", type)) {
                if (opreationFlag) {
                    list.add(mainProStep);
                }
            }
            if (operationRrn.longValue() == tempOperationRrn.longValue() &&
                    routeRrn.longValue() == tempRouteRrn.longValue() &&
                    StringUtils.equalsIgnoreCase(operationSeq, stepSeq)) {
                opreationFlag = true;
            }
            if (StringUtils.equalsIgnoreCase(TREE_ALL_WITH_SPECIAL, type)) {
                list.add(mainProStep);
            }
        }
        if (!opreationFlag) {
            for (int i = 0; i < viewProcessInfo.size(); i++) {
                Map<String, Object> mainProStep = viewProcessInfo.get(i);
                List reworkinfo = buildReworkWflInfo(mainProStep);
                if (reworkinfo.size() > 0 && !reworkList.containsAll(reworkinfo)) {
                    reworkList.addAll(reworkinfo);
                }
            }
            viewProcessInfo.addAll(reworkList);
            return viewProcessInfo;
        }

        return list;
    }

    private List<Map<String, Object>> getAllReworkRouteStep(List<Map<String, Object>> list, Long productRrn,
                                                            boolean containsReworkFlag, String reworkRouteId) {
        List nodes = new ArrayList<>();
        List reworkNodes = new ArrayList();
        for (int i = 0; i < list.size(); i++) {
            Map node = new HashMap();
            Map<String, Object> map = list.get(i);

            if (containsReworkFlag) {
                // 添加 rework 信息
                Map<String, Object> reworkStartContextMap = new HashMap<String, Object>();
                reworkStartContextMap.put("productRrn", productRrn);
                reworkStartContextMap.put("processRrn", MapUtils.getString(map, "processRrn"));
                reworkStartContextMap.put("routeRrn", MapUtils.getString(map, "routeRrn"));
                reworkStartContextMap.put("operationRrn", MapUtils.getString(map, "operationRrn"));
                reworkStartContextMap.put("processVersion", MapUtils.getString(map, "processVersion"));
                List<Map<String, Object>> reworkList = this.buildReworkWflInfo(reworkStartContextMap);
                boolean breakFlag = false;
                for (int j = 0; j < reworkList.size(); j++) {
                    Map reworkNode = new HashMap();
                    Map<String, Object> reworkMap = reworkList.get(j);
                    String reworkPorcessRouteId = MapUtils.getString(reworkMap, "routeId");
                    reworkNode.put("facilityRrn", LocalContext.getFacilityRrn());
                    reworkNode.put("productRrn", productRrn);
                    reworkNode.put("processRrn", MapUtils.getString(reworkMap, "processRrn"));
                    reworkNode.put("processVersion", MapUtils.getString(reworkMap, "processVersion"));
                    reworkNode.put("routeRrn", MapUtils.getString(reworkMap, "routeRrn"));
                    reworkNode.put("routeId", reworkPorcessRouteId);
                    reworkNode.put("operationRrn", MapUtils.getString(reworkMap, "operationRrn"));
                    reworkNode.put("operationId", MapUtils.getString(reworkMap, "operationId"));
                    reworkNode.put("flowSeq", MapUtils.getString(reworkMap, "flowSeq"));
                    reworkNode.put("reSeq", MapUtils.getString(reworkMap, "flowSeq"));
                    reworkNode.put("operationDesc", MapUtils.getString(reworkMap, "operationDesc"));
                    reworkNode.put("stageId", MapUtils.getString(reworkMap, "stageId"));
                    reworkNode.put("recipeId", MapUtils.getString(reworkMap, "recipeId"));
                    reworkNode.put("eqptGroupId", MapUtils.getString(reworkMap, "eqptGroupId"));
                    reworkNode.put("processLocation", MapUtils.getString(reworkMap, "processLocation"));
                    reworkNode.put("stepPath", MapUtils.getString(reworkMap, "stepPath"));
                    reworkNode.put("isRework", "1");
                    reworkNode.put("stepNumber", MapUtils.getString(reworkMap, "stepNumber"));
                    node.put("isMain", MapUtils.getString(map, "isMain", "-1"));

                    // reworkRouteId不为空,表示当前进入了某个rework流程,
                    // 则只显示当前的rework流程,其它rework刘晨不显示
                    if (StringUtils.isNotBlank(reworkRouteId)) {
                        if (StringUtils.equalsIgnoreCase(reworkRouteId, reworkPorcessRouteId)) {
                            breakFlag = true;
                            if (!reworkNodes.contains(reworkNode)) {
                                reworkNodes.add(reworkNode);
                            }
                        }
                    } else {
                        if (!reworkNodes.contains(reworkNode)) {
                            reworkNodes.add(reworkNode);
                        }
                    }

                    if (StringUtils.isNotBlank(reworkRouteId) &&
                            !StringUtils.equalsIgnoreCase(reworkRouteId, reworkPorcessRouteId) && breakFlag) {
                        break;
                    }
                }
            }
        }

        nodes.addAll(reworkNodes);
        return nodes;
    }

    // 构建pilot子母批 跳步
    private List<Map<String, Object>> buildPilotRepositionStep(Long lotRrn, List<Map<String, Object>> nodes) {
        Lot lot = lotQueryService.getLot(lotRrn);
        PiLotView view = wipQueryService.getPiLotViewIdByLotRrn(lot.getLotRrn(), lot.getBasedLotRrn());
        if (ObjectUtils.isEmpty(view)) {
            return nodes;
        }
        Map<String, Object> startMap = new HashMap<>();
        Map<String, Object> endMap = new HashMap<>();
        for (Map<String, Object> map : nodes) {
            if (StringUtils.equalsIgnoreCase(view.getStartRoute(), MapUtils.getString(map, "routeId")) &&
                    StringUtils.equalsIgnoreCase(view.getStartStep(), MapUtils.getString(map, "operationId"))) {
                startMap = map;
            }
            if (StringUtils.equalsIgnoreCase(view.getEndRoute(), MapUtils.getString(map, "routeId")) &&
                    StringUtils.equalsIgnoreCase(view.getEndStep(), MapUtils.getString(map, "operationId"))) {
                endMap = map;
            }
        }
        List<Map<String, Object>> mapList = new ArrayList<>();
        for (Map<String, Object> pilotMap : nodes) {
            if (MapUtils.getLongValue(pilotMap, "flowSeq") >= MapUtils.getLongValue(startMap, "flowSeq") &&
                    MapUtils.getLongValue(pilotMap, "flowSeq") < MapUtils.getLongValue(endMap, "flowSeq")) {
                mapList.add(pilotMap);
            }
        }
        return mapList;
    }

    protected List<Map<String, Object>> parseWflList(List wflTree, Long productRrn, String fliterCondition) {
        List<Map<String, Object>> nodes = new ArrayList<>();
        String routeSeq = null;
        String routeId = null;
        String routeDesc = null;
        long routeRrn = 0;
        for (int i = 0; i < wflTree.size(); i++) {
            Map treeNodes = (Map) wflTree.get(i);
            Map<String, Object> node = new HashMap<>();
            node.putAll(treeNodes);
            node.put("productRrn", productRrn);
            // 从情景值查询operationDesc 和 FlowSeq
            // Map flowSeqMap = new ResequenceContextValueMapper().buildContextValue(new Facility
            // (facilityRrn), node,
            // 0);
            // String flowSeq = MapUtils.getString(flowSeqMap, "orderOperationSeq");
            node.put("facilityRrn", LocalContext.getFacilityRrn());
            String isRework = MapUtils.getString(node, "isRework");
            if (isRework == null || !StringUtils.equalsIgnoreCase("1", isRework)) {
                String flowSeq = ctxExecService.getFlowSeqByProcessInfo(node);
                node.put("flowSeq", flowSeq);
                node.put("reSeq", flowSeq);
                node.put("operationDesc", ctxExecService.getOperationDescByProcessInfo(node));
                String activeStage = ctxExecService.getStageByProcessInfo(node);
                if (StringUtils.isNotEmpty(activeStage)) {
                    node.put("stageId", activeStage);
                }
            }

            nodes.add(node);
        }
        return nodes;
    }

}