LotOfEquipAction.java

package com.mycim.webapp.actions.operation.query;

import com.fa.sesa.i18n.I18nUtils;
import com.fa.sesa.threadlocal.LocalContext;
import com.mycim.framework.utils.beans.BeanUtils;
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.lang.time.DateUtils;
import com.mycim.framework.utils.msg.JsonUtils;
import com.mycim.valueobject.MessageIdList;
import com.mycim.valueobject.ObjectList;
import com.mycim.valueobject.bas.Relation;
import com.mycim.valueobject.consts.ActionPointList;
import com.mycim.valueobject.consts.LinkTypeList;
import com.mycim.valueobject.ems.Entity;
import com.mycim.valueobject.ems.Equipment;
import com.mycim.valueobject.prp.ContextValue;
import com.mycim.valueobject.prp.Recipe;
import com.mycim.valueobject.security.Station;
import com.mycim.valueobject.wip.*;
import com.mycim.valueobject.wip.dto.LotQueryParameterDto;
import com.mycim.webapp.Constants;
import com.mycim.webapp.actions.WipSetupAction;
import com.mycim.webapp.actions.operation.query.threadtask.ViewLotBuildTask;
import com.mycim.webapp.forms.LotOfEquipForm;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Supplier;
import java.util.stream.Collectors;

/**
 * CreateJobGetEquip4ExtAction
 *
 * @author Johnson.Wang
 * @version 6.0.0
 * @date 2019/9/19
 **/
public class LotOfEquipAction extends WipSetupAction {

    private final List<String> CATEGORY_ORDER = Arrays.asList("M", "S", "E", "D");

    private final List<String> STATUS_ORDER = Arrays.asList("WAITING", "HOLD");

    public Object request(Map params, LotOfEquipForm theform, HttpServletRequest request,
                          HttpServletResponse response) {

        if (MapUtils.getString(params, "viewLotList") != null) {
            // return viewLotList(params);
            // return viewLotListByLotQuery(params);
            return viewLotListOptimization(params);
        } else if (MapUtils.getString(params, "getLotInfo") != null) {
            return getLotInfo(params);
        } else if (MapUtils.getString(params, "viewJobList") != null) {
            return viewJobListByLotQuery(params);
            // return viewJobList(params);
        } else if (MapUtils.getString(params, "showOperateTip") != null) {
            return showOperateTip(params, theform, request, response);
        } else if (MapUtils.getString(params, "getJobBuffer") != null) {
            return getJobBuffer(params);
        } else if (MapUtils.getString(params, "checkEqptAndRecipe") != null) {
            return checkEqptAndRecipe(params);
        }

        return null;
    }

    public Map showOperateTip(Map params, LotOfEquipForm theform, HttpServletRequest request,
                              HttpServletResponse response) {

        Lot lot = null;
        Recipe recipe = null;
        Map result = new HashMap<>();
        StringBuffer instruction = new StringBuffer();
        String move = "";
        if (theform.getLotRrn() > 0) {
            lot = lotQueryService.getLot(theform.getLotRrn());
        }
        if (lot.getLotStatus().equals(ActionPointList.RUNNING_KEY)) {
            move = ActionPointList.MOVEOUT_KEY;
        } else {
            move = ActionPointList.MOVEIN_KEY;
        }
        Map item = BeanUtils.copyBeanToMap(lot);
        List<ContextValue> instructionByProducts = ctxExecService.getInstructionByProduct(lot.getProductRrn(),
                                                                                          lot.getProcessRrn(),
                                                                                          lot.getRouteRrn(),
                                                                                          lot.getOperationRrn(), move);
        List<ContextValue> instructionByProcesss = ctxExecService.getInstructionByProcess(lot.getProcessRrn(),
                                                                                          lot.getRouteRrn(),
                                                                                          lot.getOperationRrn(), move);
        List<ContextValue> instructionByLots = ctxExecService.getInstructionByLot(lot.getLotRrn(), lot.getRouteSeq(),
                                                                                  lot.getOperationSeq(),
                                                                                  lot.getProductRrn(),
                                                                                  lot.getProcessRrn(),
                                                                                  lot.getRouteRrn(),
                                                                                  lot.getOperationRrn(), move);

        String notice = "";
        String language = I18nUtils.getCurrentLanguage().toString();
        if (instructionByProducts != null && instructionByProducts.size() > 0) {
            if (StringUtils.equalsIgnoreCase("CN", language)) {
                instruction.append("按产品: ");
            } else {
                instruction.append("By Product: ");
            }
            for (Iterator<ContextValue> _it = instructionByProducts.iterator(); _it.hasNext(); ) {
                ContextValue instructionByProduct = _it.next();
                notice = instructionByProduct != null ? instructionByProduct.getResultValue1() : "";
                instruction.append(notice + "; ");
            }
            instruction.deleteCharAt(instruction.length() - 1);
            instruction.append("\n");
        }
        if (instructionByProcesss != null && instructionByProcesss.size() > 0) {
            if (StringUtils.equalsIgnoreCase("CN", language)) {
                instruction.append("按流程: ");
            } else {
                instruction.append("By Process: ");
            }
            for (Iterator<ContextValue> _it = instructionByProcesss.iterator(); _it.hasNext(); ) {
                ContextValue instructionByProcess = _it.next();
                notice = instructionByProcess != null ? instructionByProcess.getResultValue1() : "";
                instruction.append(notice + "; ");
            }
            instruction.deleteCharAt(instruction.length() - 1);
            instruction.append("\n");
        }
        if (instructionByLots != null && instructionByLots.size() > 0) {
            if (StringUtils.equalsIgnoreCase("CN", language)) {
                instruction.append("按批次: ");
            } else {
                instruction.append("By Lot: ");
            }
            for (Iterator<ContextValue> _it = instructionByLots.iterator(); _it.hasNext(); ) {
                ContextValue instructionByLot = _it.next();
                notice = instructionByLot != null ? instructionByLot.getResultValue1() : "";
                instruction.append(notice + "; ");
            }
            instruction.deleteCharAt(instruction.length() - 1);
            instruction.append("\n");
        }

        if (theform.getRecipeId() != null && theform.getRecipeId().length() > 0) {
            recipe = recipeService.getRecipe(theform.getRecipeId(), LocalContext.getFacilityRrn());
        } else {
            if (theform.getLotRrn() > 0) {
                lot.setEqptRrn(new Long(theform.getEquipRrn()));
                recipe = getRecipeByLot(lot);
            }
        }
        if (recipe != null && recipe.getInstanceRrn() > 0) {
            result.put("success", new Boolean(true));
            Map data = new HashMap<>();
            data.put("lotId", lot.getLotId());
            data.put("instanceId", recipe.getInstanceId());
            data.put("instanceDesc", recipe.getInstanceDesc());
            data.put("operateTip", recipe.getOperateTip());
            data.put("carrierId", lot.getCarrierId());
            if (instruction != null) {
                if (move.equals(ActionPointList.MOVEIN_KEY)) {
                    data.put("movein", instruction.toString());
                } else if (move.equals(ActionPointList.MOVEOUT_KEY)) {
                    data.put("moveout", instruction.toString());
                }
            }

            result.put("data", data);
        } else {
            result.put("success", new Boolean(false));
        }
        return result;
    }

    // public Map viewJobList(Map params) {
    //     final Map<String, Object> criterion = new HashMap();
    //     if (StringUtils.isEmpty(MapUtils.getStringCheckNull(params, "objectRrn"))) {
    //         LOGGER.info("viewJobList--->>>params: " + JsonUtils.toString(params));
    //         Map<String, Object> result = new HashMap<>(2);
    //         result.put("results", 0);
    //         result.put("rows", new ArrayList<>());
    //         return result;
    //     }
    //     String[] eqpRrns = MapUtils.getString(params, "objectRrn", "").split("#\\$#");
    //     List<Station> stations = securityService.getStationsByEquips(Long.parseLong(eqpRrns[0]));
    //     if (CollectionUtils.isNotEmpty(stations)) {
    //         Long stationRrn = stations.stream().map(Station::getInstanceRrn).distinct().findFirst().orElse(0L);
    //         criterion.put("stationRrn", String.valueOf(stationRrn));
    //     }
    //     String lotStatus = MapUtils.getString(params, "lotStatus");
    //     if (StringUtils.isNotEmpty(lotStatus)) {
    //         criterion.put(LOT_STATUS, StringUtils.splitAsList(lotStatus, ","));
    //     }
    //     criterion.put(DUMMY_FLAG, MapUtils.getString(params, "dummyFlag"));
    //     // TODO for spilt page
    //     criterion.put("PAGESIZE", 500);
    //     // will delete it
    //     criterion.put("jobGridFlag", MapUtils.getBooleanValue(params, "jobGridFlag"));
    //     criterion.put("objectType", MapUtils.getString(params, "objectType"));
    //     criterion.put("objectRrn", MapUtils.getString(params, "objectRrn"));
    //     Supplier<List<Map<String, Object>>> queryLotsFunc = () -> wipQueryService.listLotForOperatorPanel(criterion);
    //     Supplier<List<Map<String, Object>>> queryRcLotsFunc = () -> wipQueryService.listLotForOperatorPanelByRuncard(
    //             criterion);
    //     final List<Map<String, Object>> lots = new ArrayList<>();
    //     Arrays.asList(queryLotsFunc, queryRcLotsFunc).parallelStream().map(Supplier::get).forEach(lots::addAll);
    //     if (CollectionUtils.isEmpty(lots)) {//无结果直接返回。不在执行
    //         return new HashMap<String, Object>(2) {{
    //             put("results", 0);
    //             put("rows", new ArrayList<>());
    //         }};
    //     }
    //     List jsonArray = new ArrayList();
    //     for (Map<String, Object> lot : lots) {//TODO 暂无数据到这一步,待优化 by mingcz
    //         Long lotRrn = MapUtils.getLong(lot, "lotRrn");
    //         // 因为批次进站后,显示的是进站时用的recipe,即lot表中的recipe_string
    //         Lot curLot = lotQueryService.getLot(lotRrn);
    //         lotService.insertLotRecipe(lotRrn, curLot.getRecipeString());//TODO 循环rpc 待优化 by mingcz
    //         lot.put("recipeId", curLot.getRecipeString());
    //         //派工界面,点击lot Action时,取消lot lock
    //         // removeLotLock(LocalContext.getUserRrn(), curLot, TransactionNames.LOCK_MOVEOUT,
    //         //               "Cancel moveOut of operator panel, in LotOfEquipAction by: " + LocalContext.getUserId());
    //     }
    //
    //     if (StringUtils.isNotEmpty(MapUtils.getString(params, "equipmentRrn"))) {
    //         // &(*lots) 变更等于 lots 内部直接变更 不用赋值操作
    //         dispatch(lots, Long.parseLong(MapUtils.getString(params, "equipmentRrn")));
    //     }
    //
    //     for (Map<String, Object> lot : lots) {
    //         Map jsonObject = new HashMap<>();
    //         jsonObject.put("LotRRN", lot.get("lotRrn"));// 批次RRN
    //         jsonObject.put("LotID", lot.get("lotId"));// 批次号
    //         jsonObject.put("CarrierID", lot.get("carrierId"));// 晶舟号
    //         jsonObject.put("LotCategory", lot.get("lotType"));// 批次类型
    //         jsonObject.put("LotPiority", MapUtils.getStringCheckNull(lot, "hotFalg_priority"));// 优先级
    //         jsonObject.put("Qty1", lot.get("qty1"));// 数量
    //         jsonObject.put("ProductID", lot.get("productId"));// 产品号
    //
    //         // get stageId by context value
    //         jsonObject.put("StageID", MapUtils.getStringCheckNull(lot, "contextStageId"));
    //         jsonObject.put("RouteID", lot.get("routeId"));// 路径号
    //         jsonObject.put("RouteDesc", MapUtils.getStringCheckNull(lot, "routeDesc"));// 路径描述
    //         jsonObject.put("OperationID", lot.get("operationId"));// 步骤号
    //         jsonObject.put("operationDesc", lot.get("operationDesc"));// 步骤描述
    //         jsonObject.put("RecipeID", lot.get("recipeId"));// 工艺菜单号
    //         String phyRecipeId = MapUtils.getStringCheckNull(lot, "recipePhysicalId");
    //         jsonObject.put("physicalRecipeID", phyRecipeId == null ? StringUtils.EMPTY : phyRecipeId);
    //         jsonObject.put("documentFile", MapUtils.getStringCheckNull(lot, "recipeDocFile"));
    //         jsonObject.put("documentFileCompulsorydisplay",
    //                        MapUtils.getStringCheckNull(lot, "recipeDocFileCompulsorydisplay"));
    //         jsonObject.put("RecipePara", lot.get("recipeParam"));// 工艺规格
    //         jsonObject.put("QueueTime", lot.get("queueTimestamp"));// 等待时间
    //         jsonObject.put("equipRRN", lot.get("equipmentRrn"));
    //         jsonObject.put("equipId", MapUtils.getStringCheckNull(lot, "equipmentId"));
    //         jsonObject.put("pollutionLevel", lot.get("pollutionLevel"));// 污染等级
    //         jsonObject.put("jobRrn", lot.get("jobRrn"));
    //         jsonObject.put("LotStatus", lot.get("lotStatus"));
    //         jsonObject.put("operationRrn", lot.get("operationRrn"));
    //         jsonObject.put("flowSeq", MapUtils.getStringCheckNull(lot, "contextFlowSeq"));
    //         jsonObject.put("routeSeq", MapUtils.getStringCheckNull(lot, "routeSeq"));
    //         jsonObject.put("operationSeq", MapUtils.getStringCheckNull(lot, "operationSeq"));
    //         jsonObject.put("workArea", MapUtils.getStringCheckNull(lot, "operationWorkArea"));
    //
    //         jsonObject.put("hotFlag", lot.get("hotFlag"));
    //
    //         jsonObject.put("batchId", diffBatchQueryService.getLotBatchId(MapUtils.getLongValue(lot, "lotRrn")));
    //         jsonObject.put("rcFlag", MapUtils.getBooleanValue(lot, "rcFlag"));
    //         jsonObject.put("rcLotId", MapUtils.getStringCheckNull(lot, "rcLotId"));
    //         jsonArray.add(jsonObject);
    //     }
    //     Map result = new HashMap<>();
    //     result.put("results", jsonArray.size());
    //     result.put("rows", jsonArray);
    //
    //     return result;
    // }


    private Object viewJobListByLotQuery(Map params) {//查询运行中的
        if (MapUtils.isEmpty(params)) {
            LOGGER.info("viewJobList-->>>params:" + JsonUtils.toString(params));
            return new HashMap<String, Object>() {{
                put("results", 0);
                put("rows", Arrays.asList());
            }};
        }
        String type=  MapUtils.getString(params,"objectType");
        if(!StringUtils.equalsIgnoreCase(type,"ENTITY")){
            return new HashMap<String, Object>() {{
                put("results", 0);
                put("rows", Arrays.asList());
            }};
        }
        LotQueryParameterDto lotQueryParameterDto =convertParamForLotQuery(params,true);
        LotQueryParameterDto.OperatorPanelParam operatorPanelParam=lotQueryParameterDto.getOperatorPanelParam();//针对与某个equip rrn
        if(CollectionUtils.isEmpty(operatorPanelParam.getEqptGroupRrns())&&StringUtils.equalsIgnoreCase(MapUtils.getString(params,"objectType"),"ENTITY")){
            String[] treeStruct = MapUtils.getString(params, "objectRrn", "").split("#\\$#");
            if(treeStruct.length<=0){
                return new HashMap<String, Object>() {{
                    put("results", 0);
                    put("rows", Arrays.asList());
                }};
            }
            operatorPanelParam.setEqptRrn(Long.valueOf(treeStruct[0]));//这里的目的是为了只查当前设备 运行状态的lot
        }
        return doQuery(lotQueryParameterDto);
    }

    private Map<String,Object> viewLotListOptimization(Map<String,Object> params) {
        Map<String,Object> result = new HashMap<String, Object>() {{
            put("results", 0);
            put("rows", Arrays.asList());
        }};
        if (MapUtils.isEmpty(params)) {
            LOGGER.info("viewLotList-->>>params:" + JsonUtils.toString(params));
            return result;
        }
        String type = MapUtils.getString(params,"objectType");
        if (StringUtils.equalsIgnoreCase(type,"STATION")||StringUtils.equalsIgnoreCase(type,"ENTITYGROUP")){
            return result;
        }
        Long eqptRrn =  MapUtils.getLong(params,"objectRrn",0L);
        if(eqptRrn<=0){
            return result;
        }
        Equipment equipment=  emsService.getEquipment(eqptRrn);
        if(equipment==null){
            return result;
        }
        if(equipment.getParentEntityRrn()!=null&&equipment.getParentEntityRrn()>0){
            //用户点击 chamber
            params.put("objectRrn",equipment.getParentEntityRrn());//修改为父级 rrn
        }
        //待加工的lot 设备组下的 设备保持一致即可,因目前 2+ 特殊化没有用到  可以不用考虑设备过滤
        LotQueryParameterDto lotQueryParameterDto = convertParamForLotQuery(params,false);
        final List<Map<String, Object>> queryResult =  lotQueryService.queryLotByOperatorPanel(lotQueryParameterDto);
        if (CollectionUtils.isEmpty(queryResult)) {
            return result;
        }
        Map<String,Object> firstItem =queryResult.get(0);
        return new HashMap<String, Object>() {{
            put("results", Integer.parseInt(firstItem.get("lotCount").toString()));//总条数
            put("rows", queryResult);//结果集
        }};
    }

    private Map<String,Object> doQuery(LotQueryParameterDto lotQueryParameterDto){
        Map<String,Object> result = new HashMap<String, Object>() {{
            put("results", 0);
            put("rows", Arrays.asList());
        }};
        if(lotQueryParameterDto==null){
            return result;
        }
        final List<Map<String, Object>> queryResult = lotQueryService.queryLotListCache(lotQueryParameterDto);
        if (CollectionUtils.isEmpty(queryResult)) {
            return result;
        }

        queryResult.forEach(resultMap -> {
            String runMode = wipQueryService
                    .getLatestRunModeOfMoveIn(MapUtils.getString(resultMap, "eqptId"), MapUtils.getString(resultMap, "lotID"), MapUtils.getLong(resultMap, "lotRRN"), MapUtils.getLong(resultMap, "Step_Sequence"));
            resultMap.put("runMode", runMode);
        });

        Map<String,Object> firstItem =queryResult.get(0);
        return new HashMap<String, Object>() {{
            put("results", Integer.parseInt(firstItem.get("lotCount").toString()));//总条数
            put("rows", queryResult);//结果集
        }};
    }

    public Map<String, Object> getLotInfo(Map params) {
        String queryId = StringUtils.trimToUpperCase(MapUtils.getStringCheckNull(params, "lotId"));

        Lot lot = new Lot();
        if (StringUtils.isNotBlank(queryId)) {
            // 直接按照批次号查找
            lot = lotInqService.getLot(queryId);
        }

        Map<String, Object> result = new HashMap<>();
        if (lot.getLotRrn() > 0) {
            Map jsonObject = new HashMap<>();
            jsonObject.put("LotRRN", lot.getLotRrn());// 批次RRN
            jsonObject.put("LotID", lot.getLotId());// 批次号
            jsonObject.put("CarrierID", lot.getCarrierId());// 晶舟号
            jsonObject.put("LotCategory", lot.getLotType());// 批次类型

            jsonObject.put("LotPiority", getHotflagSplicingPriority(lot));// 优先级
            jsonObject.put("Qty1", lot.getQty1());// 数量
            jsonObject.put("ProductID", lot.getProductId());// 产品号
            jsonObject.put("StageID", lot.getStageId());// 路径段号
            jsonObject.put("RouteID", lot.getRouteId());// 路径号
            jsonObject.put("OperationID", lot.getOperationId());// 步骤号
            jsonObject.put("RecipeID", lot.getRecipeId());// 工艺菜单号
            jsonObject.put("RecipePara", lot.getRecipeParameter());// 工艺规格
            long spent = DateUtils.getDistanceTime4Now(lot.getQueueTimestamp()) / 60;
            jsonObject.put("QueueTime", spent);// 等待时间
            jsonObject.put("equipRRN", lot.getEqptRrn());
            jsonObject.put("pollutionLevel", lot.getPollutionLevel());// 污染等级
            jsonObject.put("jobRrn", lot.getJobRrn());
            jsonObject.put("status", lot.getLotStatus());
            result.put("lot", JsonUtils.toString(jsonObject));
            result.put("success", true);
        } else {
            result.put("success", false);
        }
        return result;
    }

    /**
     * Get jobBuffer .即 设备的最大作业批次数-正在设备running的批次个数;如果结果为1 则批次进站时就直接进入作业界面,否则进入已选批次框
     */
    public Map getJobBuffer(Map params) {
        Long eqptRrn = MapUtils.getLong(params, "eqptRrn");
        String eqptId = this.getInstanceId(eqptRrn);

        Job job = new Job();

        Map result = new HashMap<>();
        job.setEqptRrn(eqptRrn);
        job.setEqptId(eqptId);

        result.put("success", wipCheckService.validJobSizeIsEqualOne(job.getEqptRrn()));
        Entity entity = new Entity(eqptId, getNamedSpace(ObjectList.ENTITY_KEY, LocalContext.getFacilityRrn()),
                                   ObjectList.ENTITY_KEY);
        entity = emsService.getEntity(entity);
        if (StringUtils.equalsIgnoreCase(Constants.SEMI_AUTO_KEY, entity.getOperationMode())) {
            result.put("success", Boolean.FALSE);
        }

        return result;

    }

    // public Map<String,Object> viewLotListByLotQuery(Map<String,Object>params){
    //     if (MapUtils.isEmpty(params)) {
    //         LOGGER.info("viewLotList-->>>params:" + JsonUtils.toString(params));
    //         return new HashMap<String, Object>() {{
    //             put("results", 0);
    //             put("rows", Arrays.asList());
    //         }};
    //     }
    //     Long eqptRrn =  MapUtils.getLong(params,"objectRrn",0L);
    //     if(eqptRrn<=0){
    //         return new HashMap<String, Object>() {{
    //             put("results", 0);
    //             put("rows", Arrays.asList());
    //         }};
    //     }
    //     Equipment equipment= emsService.getEquipment(eqptRrn);
    //     if(equipment.getInstanceRrn()>0&&equipment.getParentEntityRrn()!=null&&equipment.getParentEntityRrn()>0){
    //         return new HashMap<String, Object>() {{//页面点击了chamber 设备
    //             put("results", 0);
    //             put("rows", Arrays.asList());
    //         }};
    //     }
    //     //待加工的lot 设备组下的 设备保持一致即可,因目前 2+ 特殊化没有用到  可以不用考虑设备过滤
    //     LotQueryParameterDto lotQueryParameterDto = convertParamForLotQuery(params,false);
    //     return doQuery(lotQueryParameterDto);
    // }


    /**
     * 为了兼容lotquery 页面的请求参数 这里进行一次转换
     * @param params
     * @return
     */
    private LotQueryParameterDto convertParamForLotQuery(Map<String, Object> params,boolean isRunQuery) {
        String startRow =  MapUtils.getString(params,"start","0");
        String pageSize =  MapUtils.getString(params,"limit","50");
        LotQueryParameterDto lotQueryParameterDto = new LotQueryParameterDto();
        lotQueryParameterDto.setStartRow(startRow);
        lotQueryParameterDto.setPageSize(pageSize);
        List<String> lotCategoryList = (List<String>) MapUtils.getObject(params, "lotCategory", new ArrayList<>());
        if (CollectionUtils.isNotEmpty(lotCategoryList)) {
            int index = lotCategoryList.indexOf("ALL");
            do {
                if (index != -1)
                    lotCategoryList.set(index, "");
            } while ((index = lotCategoryList.indexOf("ALL")) != -1);
            lotQueryParameterDto.setLotCategory(lotCategoryList.toArray(new String[lotCategoryList.size()]));
        }
        String statusStr= MapUtils.getString(params,"lotStatus");
        lotQueryParameterDto.setLotStatus(StringUtils.split(statusStr,","));
        String type = MapUtils.getString(params,"objectType");
        LotQueryParameterDto.OperatorPanelParam operatorPanelParam=lotQueryParameterDto.new OperatorPanelParam();
        lotQueryParameterDto.setOperatorPanelParam(operatorPanelParam);
        // if (StringUtils.equalsIgnoreCase(type,"STATION")||StringUtils.equalsIgnoreCase(type,"ENTITYGROUP")){
        //     Long stationRrn = MapUtils.getLong(params,"stationRrn",0L);
        //     List<Relation>relations =  baseService.getRelationsUseFromRrn(stationRrn,LinkTypeList.STATION_EQPT_KEY);
        //     if(CollectionUtils.isNotEmpty(relations)){
        //         Set<Long> eqptRrns= relations.stream().map(Relation::getToRrn).collect(Collectors.toSet());
        //         List<Relation> entityGroups= baseService.getRelationsUseFromRrns(eqptRrns,LinkTypeList.ENTITY_ENTITYROUP_KEY);
        //         if(CollectionUtils.isNotEmpty(entityGroups)){
        //             List<Long> entityGroupRrns =  entityGroups.stream().map(Relation::getToRrn).distinct().collect(Collectors.toList());
        //             operatorPanelParam.setEqptGroupRrns(entityGroupRrns);
        //         }
        //     }
        // }else

        if (StringUtils.equalsIgnoreCase(type,"ENTITY")){
            if(!isRunQuery){
                Long eqptRrn = MapUtils.getLong(params,"objectRrn",0L);
                if(eqptRrn!=0){
                    operatorPanelParam.setEqptRrn(eqptRrn);
                    List<Relation>relations= baseService.getRelationsUseFromRrn(eqptRrn,
                                                                                LinkTypeList.ENTITY_ENTITYROUP_KEY);
                    if(CollectionUtils.isNotEmpty(relations)){
                        List<Long> entityGroupRrns= relations.stream().map(Relation::getToRrn).distinct().collect(Collectors.toList());
                        operatorPanelParam.setEqptGroupRrns(entityGroupRrns);
                    }
                }
            }
        }
         if(params.containsKey("lotId")){
            lotQueryParameterDto.setLotId(MapUtils.getString(params,"lotId"));
        }
        if(params.containsKey("proId")){
            lotQueryParameterDto.setProductId(MapUtils.getString(params,"proId"));
        }
        lotQueryParameterDto.setUserRrn(LocalContext.getUserRrn());
        lotQueryParameterDto.setFacilityRrn(LocalContext.getFacilityRrn());
        return lotQueryParameterDto;
    }


    public Map<String, Object> viewLotList(Map<String, Object> params) {
        if (StringUtils.isEmpty(MapUtils.getStringCheckNull(params, "objectRrn"))) {
            LOGGER.info("viewLotList-->>>params:" + JsonUtils.toString(params));
            return new HashMap<String, Object>() {{
                put("results", 0);
                put("rows", Arrays.asList());
            }};
        }
        // 分页信息
        final int currentPage = MapUtils.getInteger(params, "page");
        final int start = MapUtils.getInteger(params, "start");
        final int limit = MapUtils.getInteger(params, "limit");
        // final String objectType = MapUtils.getString(params, "objectType");
        /*Station station = autoCancelMoveIn(params);*/

        //优先使用前端传来的 station rrn 避免一次批量查询
        //如果出现多个工作站都拥有同一设备的情况,就需要在前端传入工作站rrn,然后再准确获取对应工作站信息[
        Long stationRrn = MapUtils.getLong(params, "stationRrn", -1L);
        Station station = new Station();
        if (stationRrn > 0) {
            station.setInstanceRrn(stationRrn);
            station = securityService.getStation(station);
        } else {
            String[] eqpRrns = MapUtils.getString(params, "objectRrn", "").split("#\\$#");
            List<Station> stationsByEquips = securityService.getStationsByEquips(Long.parseLong(eqpRrns[0]));
            if (CollectionUtils.isNotEmpty(stationsByEquips)) {
                station = stationsByEquips.get(0);
            }
        }
        final Map criterion = new HashMap();
        if ("1".equals(station.getCheckOperationFlag())) {
            criterion.put("stationRrn", station.getInstanceRrn() + "");
        }
        String lotStatus = MapUtils.getString(params, "lotStatus");
        if (StringUtils.isNotEmpty(lotStatus)) {
            criterion.put("lotStatus", StringUtils.splitAsList(lotStatus, ","));
        }
        criterion.put(DUMMY_FLAG, MapUtils.getString(params, "dummyFlag"));
        // 添加分页功能
        criterion.put("currentPage", currentPage);
        criterion.put("pageSize", limit);
        criterion.put("startRow", start);
        criterion.put("pagingFlag", true);

        criterion.put("jobGridFlag", new Boolean(MapUtils.getString(params, "jobGridFlag")));
        criterion.put("objectType", MapUtils.getString(params, "objectType"));
        criterion.put("objectRrn", MapUtils.getString(params, "objectRrn"));

        // 派工页面查询
        criterion.put("Sapphire", MapUtils.getString(params, "Sapphire"));
        criterion.put("lotId", MapUtils.getString(params, "lotId"));
        String proId = MapUtils.getString(params, "proId");
        criterion.put("proId", proId);

        // lot category条件
        List<String> lotCategoryList = (List<String>) MapUtils.getObject(params, "lotCategory", new ArrayList<>());
        if (CollectionUtils.isNotEmpty(lotCategoryList)) {
            int index = lotCategoryList.indexOf("ALL");
            do {
                if (index != -1)
                    lotCategoryList.set(index, "");
            } while ((index = lotCategoryList.indexOf("ALL")) != -1);
        }
        criterion.put("lotCategory", lotCategoryList.toArray(new String[lotCategoryList.size()]));

        //闭包捕获
        Supplier<List<Map<String, Object>>> queryLotOP = () -> wipQueryService.listLotForOperatorPanel(criterion);
        Supplier<List<Map<String, Object>>> queryRcLotOP = () -> wipQueryService.listLotForOperatorPanelByRuncard(criterion);
        Supplier<Integer> queryTotalCount = () -> wipQueryService.countLotForOperatorPanel(criterion);
        final List<Map<String, Object>> lots = new ArrayList<>();
        AtomicInteger totalCount = new AtomicInteger();
        Arrays.asList(queryLotOP, queryRcLotOP, queryTotalCount).parallelStream().map(Supplier::get).forEach(result -> {
            if (result instanceof List) {
                lots.addAll((List) result);
            }
            if (result instanceof Integer) {
                totalCount.set((Integer) result);
            }
        });

        //没有查到数据直接 return
        if (CollectionUtils.isEmpty(lots) || totalCount.get() <= 0) {
            return new HashMap<String, Object>() {{
                put("results", 0);
                put("rows", Arrays.asList());
            }};
        }
        Long equipmentRrnParams = MapUtils.getLong(params, "equipmentRrn", -1L);
        if (equipmentRrnParams > 0) {
            dispatch(lots, equipmentRrnParams);
        }

        // Long equipmentRrn = MapUtils.getLong(params, "objectRrn",-1L);
        // Equipment equipment = new Equipment();
        // String equipmentId = StringUtils.EMPTY;
        // User user = new User();
        // if (equipmentRrn > 0) {
        //     equipment.setInstanceRrn(equipmentRrn);
        //     equipment = emsService.getEquipment(equipment);
        //     equipmentId = equipment.getInstanceId();
        //     user = securityService.getUser(LocalContext.getUserRrn());
        // }
        //
        // Map<String, Object> constrainMap = constrainService.getEqptConstrain4LotOperator(equipmentId);
        // List<Map<String, Object>> equipmentRecipes = recipeService.getRecipeList4Equipment(equipmentRrn);
        List<ViewLotBuildTask> viewLotBuildTasks = new ArrayList<>();
        for (Map<String, Object> lot : lots) {
            viewLotBuildTasks.add(new ViewLotBuildTask(lot, params));
        }
        List<Map<String, Object>> jsonArray = viewLotBuildTasks.parallelStream().map(ViewLotBuildTask::call)
                                                               .collect(Collectors.toList());
        sortLotList(jsonArray);
        Map<String, Object> result = new HashMap<>(2);
        result.put("results", totalCount.get());
        result.put("rows", jsonArray);

        return result;
    }

    public String checkEqptAndRecipe(Map params) {
        String lotId = MapUtils.getString(params, "lotId");
        Long eqptRrn = MapUtils.getLong(params, "eqptRrn");
        String recipeId = MapUtils.getString(params, "recipeId");
        Long userRrn = LocalContext.getUserRrn();
        Lot lot = lotQueryService.getLot(lotId, LocalContext.getFacilityRrn());
        String checkEqptAndRecipeResultMsg = StringUtils.EMPTY;
        if (lotRunCardQueryService.checkLotInRunCard(lot.getLotRrn())) {
            //如果是runcard lot 则需要检查当前设备 diff 是否启用
            //emsService.getEquipment(); //不知道为何 diffFlag 始终为null; 暂时使用下面的api
            Map<String, Object> equipmentMap = emsService.getEquipmentExtMap(eqptRrn);
            if (equipmentMap == null ||
                    StringUtils.equalsIgnoreCase("0", MapUtils.getString(equipmentMap, "diffFlag", "0"))) {
                //不是炉管设备 报错
                return I18nUtils.getMessage(MessageIdList.OPERATOR_PANEL_ADD_RUNCARD_LOT);
            }
        } else {
            checkEqptAndRecipeResultMsg = wipCheckService.checkEqptAndRecipeAndReticleAtJobIn(lot, eqptRrn, recipeId,
                                                                                              userRrn);
        }

        return checkEqptAndRecipeResultMsg;
    }

    /**
     * query lot list by stationId,equipmentId,lotStatus
     */
    private List<Map> getLotList4ExtAtEqpt(Map criterion) {
        List<Map> lots = lotQueryService.getLotList4ExtAtEqpt(criterion);
        MapUtils.getString(criterion, "objectType");
        return lots;
    }

    private void sortLotList(List<Map<String, Object>> lots) {
        Collections.sort(lots, new Comparator<Map<String, Object>>() {

            @Override
            public int compare(Map<String, Object> o1, Map<String, Object> o2) {
                String catergory1 = MapUtils.getString(o1, "LotCategory");
                String catergory2 = MapUtils.getString(o2, "LotCategory");

                int io1 = CATEGORY_ORDER.indexOf(catergory1);
                int io2 = CATEGORY_ORDER.indexOf(catergory2);

                if (io1 == io2) {

                    Double timeLimit1 =
                            o1.get("timeLimit") == null ? 0 : Double.parseDouble((String) o1.get("timeLimit"));
                    Double timeLimit2 =
                            o2.get("timeLimit") == null ? 0 : Double.parseDouble((String) o2.get("timeLimit"));

                    if (timeLimit1.equals(timeLimit2) || timeLimit1.intValue() == 0 || timeLimit2.intValue() == 0) {

                        String lotStaus1 = MapUtils.getString(o1, "LotStatus");
                        String lotStaus2 = MapUtils.getString(o2, "LotStatus");
                        io1 = STATUS_ORDER.indexOf(lotStaus1);
                        io2 = STATUS_ORDER.indexOf(lotStaus2);
                        return io1 - io2;
                    } else {
                        return (int) (timeLimit1 * 100) - (int) (timeLimit2 * 100);
                    }

                } else {
                    return io1 - io2;
                }

            }
        });

    }

    private Station autoCancelMoveIn(Map params) {
        Map criterionForAutoMoveIn = new HashMap<>();
        String[] eqpRrns = MapUtils.getString(params, "objectRrn").split("#\\$#");
        List<Station> stationsByEquips = securityService.getStationsByEquips(Long.parseLong(eqpRrns[0]));
        Station station = new Station();
        if (CollectionUtils.isNotEmpty(stationsByEquips)) {
            station = stationsByEquips.get(0);
        }
        // 如果出现多个工作站都拥有同一设备的情况,就需要在前端传入工作站rrn,然后再准确获取对应工作站信息[
        Long stationRrn = null;
        String tempStationRrn = MapUtils.getString(params, "stationRrn");
        if (StringUtils.isNotBlank(tempStationRrn)) {
            stationRrn = Long.valueOf(tempStationRrn);
        }
        if (stationRrn != null) {
            station.setInstanceRrn(stationRrn);
            station = securityService.getStation(station);
        }
        // 工作站准确定位结束
        if ("1".equals(station.getCheckOperationFlag())) {
            criterionForAutoMoveIn.put("stationRrn", station.getInstanceRrn() + "");
        }
        if (null != MapUtils.getString(params, "lotStatus")) {
            criterionForAutoMoveIn.put(LOT_STATUS, new ArrayList(Arrays.asList(new String[]{LotStatus.DISPATCH})));
        }
        criterionForAutoMoveIn.put(DUMMY_FLAG, MapUtils.getString(params, "dummyFlag"));
        criterionForAutoMoveIn.put("PAGESIZE", 500);// TODO for
        // spilt
        // page will
        // delete it
        criterionForAutoMoveIn.put("jobGridFlag", new Boolean(MapUtils.getString(params, "jobGridFlag")));
        criterionForAutoMoveIn.put("objectType", MapUtils.getString(params, "objectType"));
        criterionForAutoMoveIn.put("objectRrn", MapUtils.getString(params, "objectRrn"));
        List<Map> lots4Dispatch = this.getLotList4ExtAtEqpt(criterionForAutoMoveIn);

        String _equimentId = MapUtils.getString(params, "equimentId");
        String operationMode = "";
        if (StringUtils.isNotBlank(_equimentId)) {
            String[] eqptRrn = _equimentId.split("#\\$#");
            if (eqptRrn != null && eqptRrn.length > 0 && NumberUtils.isNumber((eqptRrn[0]))) {
                if (stationRrn != null) {
                    if (stationRrn != NumberUtils.toLong(eqptRrn[0])) {
                        Entity entity = new Entity();
                        entity.setInstanceRrn(new Long(eqptRrn[0]));
                        entity = emsService.getEntity(entity);
                        operationMode = entity.getOperationMode();
                    }
                }
            }
        }
        for (Map lot : lots4Dispatch) {
            // todo 待确认 目前所有 SEMI_AUTO_KEY也要自动取消
            //            if (StringUtils.equalsIgnoreCase(Constants.SEMI_AUTO_KEY, operationMode)) {
            //                Job job = wipQueryService.getJob(MapUtils.getLong(lot, "jobRrn"));
            //                if (job.getExecutionRrn() > 0) {
            //                    continue;
            //                }
            //            }
            Lot _lot = lotQueryService.getLot(MapUtils.getLongValue(lot, "lotRrn"));
            if (StringUtils.isNotBlank(_lot.getRecipePhysicalId())) {
                continue;
            }

            String reason = "SYSTEM 0 SYSTEM AutoCancelMoveIn";

            TransReason transReason = new TransReason();
            transReason.setReasonCode("SYSTEM");
            transReason.setReason(reason);

            Double qty2 = lot.get("qty2") == null ? new Double("0") : new Double(lot.get("qty2").toString());
            Double qty1 = lot.get("qty1") == null ? new Double("0") : new Double(lot.get("qty1").toString());
            transReason.setTransQty2(qty2);
            transReason.setTransQty1(qty1);
            lotService.autoCancelMoveIn(Long.parseLong(lot.get("lotRrn") + ""), lot.get("lotStatus") + "",
                                        Long.parseLong(lot.get("jobRrn") + ""), LocalContext.getUserId(),
                                        "System AutoCancelMoveIn", transReason);

        }
        return station;
    }

}