ViewEdcValueOfLotHistoryAction.java

package com.mycim.webapp.actions.lot.edcvalueoflothistory;


import com.fa.sesa.i18n.I18nUtils;
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.time.DateUtils;
import com.mycim.valueobject.ObjectList;
import com.mycim.valueobject.SystemConstant;
import com.mycim.valueobject.consts.TransactionNames;
import com.mycim.valueobject.prp.Operation;
import com.mycim.valueobject.wip.Lot;
import com.mycim.valueobject.wip.Unit;
import com.mycim.webapp.TemplateLocation;
import com.mycim.webapp.WebUtils;
import com.mycim.webapp.actions.WipSetupAction;
import com.mycim.webapp.actions.lot.edcvalueoflothistory.threadtask.EdcValueOfLotHistoryTask;
import org.apache.commons.lang3.math.NumberUtils;
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.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 批次采集数据
 *
 * @author weike.li
 * @version 6.0.0
 * @date 2019/9/27
 **/
public class ViewEdcValueOfLotHistoryAction extends WipSetupAction {

    private static final String CN = "CN";

    @Override
    public ActionForward init(ActionMapping mapping, ActionForm form, HttpServletRequest request,
                              HttpServletResponse response) {
        request.setAttribute(SystemConstant.Str.SPECIAL_ROLE, isSpecialRole());
        return mapping.findForward("lothistorybyunit");
    }

    public Map<String,Object> query(Map map) throws ParseException {
        //base
        long facility = LocalContext.getFacilityRrn();
        String unitId =MapUtils.getString(map,"unitId","").trim();
        String lotId = MapUtils.getString(map,"lotId","").trim();
        Lot lot = null;
        Long lotRrn=null;
        boolean byUnitFlag = StringUtils.isNotEmpty(unitId);
        Unit unit=null;
        if (byUnitFlag) {
            unit = wipQueryService.getUnit(facility, unitId.toUpperCase());
            if(unit!=null){
                List<Map<String,Long>>unitRrns = wipQueryService.getLotRrnFromUnitStepRangeHistory(unit.getUnitId());
                if(CollectionUtils.isNotEmpty(unitRrns)){
                    Map<String,Long> item =  unitRrns.get(0);
                    lotRrn = MapUtils.getLong(item,"LOT_RRN");
                    // lotId = lotQueryService.getLot(lotRrn).getLotId();
                    lot = isSpecialRole()?lotInqService.getLotWhitDataPermission(lotRrn):lotInqService.getLot(lotRrn);
                }
            }
        } else if (StringUtils.isNotEmpty(lotId)) {
            // lotRrn = lotQueryService.getLot(StringUtils.trim(lotId), facility).getLotRrn();
            lot = isSpecialRole()?lotInqService.getLotWhitDataPermission(lotId):lotInqService.getLot(lotId);

        }
        if (!Objects.isNull(lot)){
            lotId = lot.getLotId();
            lotRrn = lot.getLotRrn();
        } else {
            lotId = StringUtils.EMPTY;
            lotRrn = 0L;
        }
        //build page lot info
        Map<String,Object> lotBaseInfo = new HashMap<>();
        lotBaseInfo.put("unitRrn", unit!=null ? unit.getUnitRrn() : "");
        lotBaseInfo.put("unitStatus", unit!=null ? unit.getUnitStatus() : "");
        lotBaseInfo.put("lotId", lotId);
        lotBaseInfo.put("unitId", unitId);

        //query
        List<Map<String,Object>> lotHistory = lotQueryService.qryLotHistoryExp(lotRrn);
        List<Map<String,Object>>resultArray = Collections.synchronizedList(new ArrayList<>());

        //build result
        Map<String,Object>returnResult = new HashMap<>();
        returnResult.put("lotBaseInfo",lotBaseInfo);
        returnResult.put("rows", resultArray);
        returnResult.put("success", "true");

        //npe check
        if (CollectionUtils.isEmpty(lotHistory)) {
            return returnResult;
        }

        Set<Long> stepSeqs =new HashSet<>();
        //1********************  preprocessing start ***************
        //fetch step
        for(Map<String,Object> item:lotHistory){
            String key =  MapUtils.getString(item,"operationRrn");
            if(item.containsKey(key)){
                List<Map<String,Object>> operationList = (List<Map<String, Object>>) item.get(key);
                Map<String,Object> firstOperationItem  = operationList.stream().findFirst().orElse(new HashMap<>());
                if(MapUtils.isNotEmpty(firstOperationItem)){
                   final Long seq  =  MapUtils.getLong(firstOperationItem,"step_sequence");
                   stepSeqs.add(seq);
                }
            }
        }
        Map<Long,List<Map<String,Object>>> parameterDataMap = edcService.getParameterDataMap(lotRrn, stepSeqs);
        //过滤删元素
        Set<String> routeIds =new HashSet<>();
        Set<Long> operationRrns = new HashSet<>();
        final int resultSize= lotHistory.size();
        for(int i = resultSize-1;i>=0;i--){
            Map<String,Object> item = lotHistory.get(i);
            List<Map<String,Object>> operationList = (List) item.get(item.get("operationRrn"));
            Map<String,Object> firstOperationItem  = operationList.stream().findFirst().orElse(new HashMap<>());
            if(MapUtils.isNotEmpty(firstOperationItem)){
                final Long seq  =  MapUtils.getLong(firstOperationItem,"step_sequence");
                List<Map<String,Object>> paramList = parameterDataMap.get(seq);
                if(CollectionUtils.isEmpty(paramList)){
                    //直接删
                    lotHistory.remove(i);
                    continue;
                }
                boolean delete =true;
                for (Map<String,Object> parameterDatum : paramList) {
                    if (!byUnitFlag || StringUtils.equalsIgnoreCase(MapUtils.getString(parameterDatum,"unitId"), unitId.trim())) {
                        delete=false;
                    }
                }
                if(delete){
                    lotHistory.remove(i);
                    continue;
                }
                final String routeId= MapUtils.getString(firstOperationItem,"route_id");
                routeIds.add(routeId);
                final Long operationRrn = MapUtils.getLong(firstOperationItem,"operation_rrn");
                operationRrns.add(operationRrn);
            }
        }
        if(CollectionUtils.isEmpty(lotHistory)){
            return  returnResult;
        }
        //2 ********************  preprocessing end *************

        //3 ******************** batch fetch ********************
        Map<String,String> routeDescMap  =super.getInstanceDesc(routeIds,getNamedSpace(ObjectList.WFL_KEY,LocalContext.getFacilityRrn()),ObjectList.WFL_KEY);
        Map<Long,Map<String,Object>> operationMap= prpService.getOperationMap(operationRrns);
        Map<Long,List<Map<String,Object>>> operationParamMap = prpService.getOperationParameterMap(lotRrn,stepSeqs);
        Map<Long,List<Map<String,Object>>> stepCommentMap= lotQueryService.queryLotStepHistoryComments(lotRrn,stepSeqs);
        //3******************** batch fetch end ****************
        AtomicInteger seq = new AtomicInteger(1);
        List<EdcValueOfLotHistoryTask> tasks = new ArrayList<>();
        for(int i = 0 ; i < lotHistory.size();i++){
            tasks.add(new EdcValueOfLotHistoryTask(resultArray,lotHistory.get(i),byUnitFlag,unitId,routeDescMap,operationMap,parameterDataMap,operationParamMap,stepCommentMap,seq));
        }
        tasks.parallelStream().forEach(EdcValueOfLotHistoryTask::run);

        //4******************** sorting ****************
        List<Map<String,Object>> resultList = (List<Map<String,Object>>) returnResult.get("rows");
        for(Map<String, Object> result : resultList){
            result.put("collectionTime",new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
                    .parse(MapUtils.getString(result,"collectionTimestamp")).getTime());
        }
        resultArray.sort(Comparator.comparingLong(a -> MapUtils.getLongValue(
                (Map<String,Object>) a,"collectionTime")).reversed());

        //5******************** filter & paging ****************
        return filterResultByConditions(returnResult,map);
    }

    private Map<String, Object> filterResultByConditions(Map<String, Object> returnResult, Map<String, Object> condition) throws ParseException {
        String flowSeq = MapUtils.getString(condition,"flowSeq",StringUtils.EMPTY).trim();
        String edcId = MapUtils.getString(condition,"edcId",StringUtils.EMPTY).trim();
        String productId = MapUtils.getString(condition,"productId",StringUtils.EMPTY).trim();
        String parameterId = MapUtils.getString(condition,"parameterId",StringUtils.EMPTY).trim();
        int pageSize = MapUtils.getIntValue(condition, "limit", 20);
        int start = MapUtils.getIntValue(condition, "start", 0);

        List<Map<String,Object>> resultArray = (List<Map<String,Object>>) returnResult.get("rows");
        //过滤数据
        List<Map<String, Object>> resultFilterList = resultArray.stream().filter(result -> (
                fuzzyMatching(MapUtils.getString(result, "flowSeq"), flowSeq) &&
                fuzzyMatching(MapUtils.getString(result, "productId"), productId) &&
                fuzzyMatching(MapUtils.getString(result, "edcPlanId"), edcId) &&
                fuzzyMatching(MapUtils.getString(result, "edcId"), parameterId))).collect(Collectors.toList());

        //分页处理
        List<Map<String, Object>> resultPageList = resultFilterList.stream().skip(start).limit(pageSize)
                                                         .collect(Collectors.toList());

        if (CollectionUtils.isNotEmpty(resultFilterList) && resultPageList.size() == 0) {
            resultPageList = resultFilterList;
        }
        // 升序处理
        resultPageList = resultPageList.stream().sorted(Comparator.comparingInt(
                e -> Integer.valueOf((String) e.get("readingSequence")))).collect(Collectors.toList());
        AtomicInteger seq = new AtomicInteger(++start);
        resultPageList.forEach(result -> {
            result.put("stepSeq",seq.get());
            seq.incrementAndGet();
        });
        returnResult.put("rows",resultPageList);
        returnResult.put("totalCount", resultFilterList.size());
        return returnResult;
    }

    public ActionForward export(HttpServletRequest request, HttpServletResponse response) throws Exception {

        String unitId = StringUtils.trim(request.getParameter("unitId"));
        String lotId = StringUtils.trim(request.getParameter("lotId"));

        Map map = new HashMap();
        map.put("unitId", unitId);
        map.put("lotId", lotId);
        map.put("flowSeq",StringUtils.trim(request.getParameter("flowSeq")));
        map.put("edcId",StringUtils.trim(request.getParameter("edcId")));
        map.put("productId",StringUtils.trim(request.getParameter("productId")));
        map.put("parameterId",StringUtils.trim(request.getParameter("parameterId")));
        map.put("pageNo",request.getParameter("pageNo"));
        map.put("pageSize",request.getParameter("pageSize"));
        map.put("limit",request.getParameter("limit"));

        List<Map> edcValueOfLotHistory = (List<Map>) query(map).get("rows");

        Map<String, Object> titles = WebUtils.getExportTitles(request);
        if (CN.equals(I18nUtils.getCurrentLanguage())) {
            titles.put("stepSeq", "序号");
            titles.put("title", "批次历史采集数据");
            titles.put("titleWaferId", "圆片号:" + unitId);
            titles.put("titleLotId", "批次号:" + lotId);
        } else {
            titles.put("stepSeq", "No.");
            titles.put("title", "Lot history collection");
            titles.put("titleWaferId", "wafer Id:" + unitId);
            titles.put("titleLotId", "lot Id:" + lotId);
        }

        String exportDateTime = DateUtils.getNowTime(DateUtils.DATE_FORMAT4NOSPLICING);
        String fileName = "lotHistoryStore_" + exportDateTime + ".xlsx";

        WebUtils.exportExcel(fileName, titles, edcValueOfLotHistory, TemplateLocation.EDC_VALUE_OF_LOT_HISTORY,
                             response);
        return WebUtils.NULLActionForward;
    }



    private String convertNull2Blank(Object obj) {
        String str = "";
        if (obj != null && (obj instanceof String) && !"null".equals(obj)) {
            return obj.toString();
        }
        return str;
    }

    private boolean fuzzyMatching(String sourceString,String targetString){
        if(StringUtils.isBlank(targetString)){
            return true;
        }else {
            if(targetString.contains("*")){
                return Pattern.matches(targetString.replace("*",".*"),sourceString);
            }else{
                return sourceString.contains(targetString);
            }
        }
    }

}