EmasAction.java

package com.mycim.webapp.actions;

import com.fa.sesa.exception.Assert;
import com.fa.sesa.exception.Errors;
import com.fa.sesa.threadlocal.LocalContext;
import com.mycim.framework.context.spring.SpringContext;
import com.mycim.framework.jdbc.Page;
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.server.emas.service.EmasService;
import com.mycim.server.spc.service.SpcService;
import com.mycim.utils.ChartNamingRule;
import com.mycim.utils.EmasUtil;
import com.mycim.valueobject.MessageIdList;
import com.mycim.valueobject.ObjectList;
import com.mycim.valueobject.bas.NamedObject;
import com.mycim.valueobject.bas.Relation;
import com.mycim.valueobject.consts.ReferenceDetailNames;
import com.mycim.valueobject.consts.SystemConstants;
import com.mycim.valueobject.consts.TransactionNames;
import com.mycim.valueobject.emas.dto.EmasModifyDTO;
import com.mycim.valueobject.emas.dto.EmasQueryDTO;
import com.mycim.valueobject.sys.ReferenceFileDetail;
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.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author kangzhang
 * @version 1.0.0
 * @date 2021/6/23
 **/
public class EmasAction extends EdcSpcSetupAction {
    public static final String REGEX_OF_DATE =
            "^((19|20)[0-9]{2})-(0?[1-9]|1[012])-" + "(0?[1-9]|[12][0-9]|3[01])\\s([01]?[0-9]|2[0-3])" +
                    ":[0-5][0-9]:[0-5][0-9]$";

    protected EmasService emasService = SpringContext.getBean(EmasService.class);

    protected SpcService spcService = SpringContext.getBean(SpcService.class);

    private Pattern pattern = Pattern.compile("^[0-9]{4}/[0-9]{2}/[0-9]{2}\\s{1}[0-9]{2}:[0-9]{2}:00$");

    @Override
    public ActionForward init(ActionMapping mapping, ActionForm form, HttpServletRequest request,
                              HttpServletResponse response) {
        return mapping.getInputForward();
    }

    /**
     * Action 方法
     */
    public List<Map<String, Object>> qryAreaList(Map<String, Object> params) {
        return getJobFieldInfo(params, "AreaID");
    }

    /**
     * Action 方法
     */
    public List<Map<String, Object>> qryJobList(Map<String, Object> params) {
        return getJobFieldInfo(params, "JobName");
    }

    /**
     * Action 方法
     */
    public Map<String, Object> queryEmasInfo(EmasQueryDTO queryDTO, Map map) {
        int  pageSize = MapUtils.getIntValue(map, "limit");
        int  pageNo   = MapUtils.getIntValue(map, "page");
        Page page     = new Page(pageNo, pageSize);
        queryDTO.setPage(page);
        page = emasService.getEmasInfoWithEventByPage(queryDTO);
        List<Map<String, Object>> list= (List<Map<String, Object>>) page.getResults();
        countWarnFlag(list);
        Map<String, Object> resultMap = new HashMap<String, Object>();
        resultMap.put("results", list);
        resultMap.put("totalCount", page.getTotalItems());
        return resultMap;
    }

    private void countWarnFlag(List<Map<String, Object>> list) {
        for (Map tempMap:list) {
            String checkType = MapUtils.getString(tempMap, "checkType");
            if (StringUtils.equals(checkType, EmasUtil.CheckType.TIME)) {
                String timePointStr = MapUtils.getString(tempMap, "timePoint"); //触发时间点
                String lastUploadTimeStr = MapUtils.getString(tempMap, "lastUploadTime"); //最近的上传时间
                long period = MapUtils.getLongValue(tempMap, "period") * 24; //周期(单位:小时)
                double bufferHourTime = MapUtils.getDoubleValue(tempMap, "bufferTime");
                String flag = MapUtils.getString(tempMap, "enableFlag");
                if (bufferHourTime <= 0 || StringUtils.equalsIgnoreCase(flag, EmasUtil.Status.ENABLE_FLAG_OFF)){
                    continue;
                }
                String lastSpecialCloseTime = MapUtils.getString(tempMap, "lastSpecialCloseTime", StringUtils.EMPTY);
                String emno = MapUtils.getString(tempMap, "lastOnGoingEvent", StringUtils.EMPTY);

                Date timePoint = DateUtils.parse(timePointStr);
                Date sysDate = new Date(System.currentTimeMillis());
                long intervalMinute = (sysDate.getTime() - timePoint.getTime()) / 1000 / 60;  //单位为分钟
                Long lastTime;
                //比较lastSpecialCloseTime 和 lastUploadTime大小
                long lastUploadTimeNum = StringUtils.isNotBlank(lastUploadTimeStr)?DateUtils.parse(lastUploadTimeStr).getTime():0L;
                long lastSpecialCloseTimeNum = StringUtils.isNotBlank(lastSpecialCloseTime)?DateUtils.parse(lastSpecialCloseTime).getTime():0L;
                lastTime = Math.max(lastUploadTimeNum, lastSpecialCloseTimeNum);

                if (!NumberUtils.LONG_ZERO.equals(lastTime)) {
                    intervalMinute = (sysDate.getTime() - lastTime) / 1000 / 60;
                }

                //if type is ByHour need /24
                if (EmasUtil.CheckType.CycleType.BY_HOUR.equalsIgnoreCase(MapUtils.getString(tempMap, "cycleType"))){
                    period = MapUtils.getLongValue(tempMap, "period");
                }
                double bufferMinute = (period - bufferHourTime) * 60; //触发event时间 需要加上bufferTime,预警需要减去bufferTime
                if (intervalMinute > bufferMinute && StringUtils.isBlank(emno)) {
                    //emno 不为空,及代表已经触发过Event,,并且还处于Ongoing状态。
                    tempMap.put("warnFlag", 1);
                }
            }

        }
    }

    /**
     * Action 方法
     */
    public Map<String, Object> getEmasHistory(EmasQueryDTO queryDTO, Map map) {
        int  pageSize = MapUtils.getIntValue(map, "limit");
        int  pageNo   = MapUtils.getIntValue(map, "page");
        Page page     = new Page(pageNo, pageSize);
        queryDTO.setPage(page);
        page = emasService.getEmasHistoryByPage(queryDTO);
        Map<String, Object> resultMap = new HashMap<String, Object>();
        resultMap.put("results", page.getResults());
        resultMap.put("totalCount", page.getTotalItems());
        return resultMap;
    }

    /**
     * Action 方法
     */
    public void addEmas(EmasModifyDTO modifyDTO) {

        // check 重复
        EmasQueryDTO queryDTO = new EmasQueryDTO();
        queryDTO.setEqpId(modifyDTO.getEqpId());
        queryDTO.setChartId(modifyDTO.getChartId());
        queryDTO.setCheckType(modifyDTO.getCheckType());
        Long emasSpecRrn = emasService
                .getEmasSpecRrn(modifyDTO.getEqpId(), modifyDTO.getCheckType(), modifyDTO.getChartId());
        Assert.isTrue(emasSpecRrn == null || emasSpecRrn <= 0L,
                      Errors.create().key(MessageIdList.NEWEMAS_SETTING_ALREADY_EXISTS)
                            .content("The setting already exists!").build());

        // 构建,检查数据
        buildAndCheckDTO(modifyDTO);
        modifyDTO.setUserNamed(LocalContext.getUserId());
        modifyDTO.setOperationType(TransactionNames.CREATE_KEY);
        checkChartIdPermission(modifyDTO);

        emasService.insertOrUpdateEmasInfo(modifyDTO);
    }

    public void batchUpdateEnableFLag(Map map) {
        String enableFlag = MapUtils.getString(map, "enableFlag");
        List<Map> dataArray = (List<Map>) MapUtils.getObject(map, "dataArray");
        String chartIds = StringUtils.EMPTY;
        for (Map emasMap : dataArray) {
            String chartId = MapUtils.getString(emasMap, "chartId");
            if (StringUtils.isBlank(chartIds)) {
                chartIds += chartId;
            }else {
                chartIds += StringUtils.SEMICOLON + chartId;
            }
        }

        if (StringUtils.isNotBlank(chartIds)) {
            EmasModifyDTO modifyDTO = new EmasModifyDTO();
            modifyDTO.setChartId(chartIds);
            checkChartIdPermission(modifyDTO);
        }

        if (StringUtils.isNotBlank(enableFlag) || CollectionUtils.isNotEmpty(dataArray)) {
            emasService.batchUpdateEnableFlag(dataArray, enableFlag);
        }
    }
    /**
     * Action 方法
     */
    public void modifyEmas(EmasModifyDTO modifyDTO) {
        // 构建,检查数据
        buildAndCheckDTO(modifyDTO);
        modifyDTO.setUserNamed(LocalContext.getUserId());
        modifyDTO.setOperationType(TransactionNames.MODIFY_KEY);
        checkChartIdPermission(modifyDTO);
        emasService.insertOrUpdateEmasInfo(modifyDTO);
    }

    /**
     * Action 方法
     */
    public void deleteEmas(EmasModifyDTO modifyDTO) {
        checkChartIdPermission(modifyDTO);
        emasService.deleteEmasInfo(modifyDTO.getEqpId(), modifyDTO.getChartId(), modifyDTO.getCheckType());
    }

    public boolean checkEqptIsChamber(Map map) {
        String eqptId = MapUtils.getString(map, "eqptId");
        long eqptRrn = getInstanceRrn(StringUtils.upperCase(eqptId), LocalContext.getFacilityRrn(),
                                      ObjectList.ENTITY_KEY);
        return emsService.checkEqptIsChildChamber(eqptRrn);
    }

    public List getWorkAreaForEmas() {
        List<String> allWorkAreaForEmas = emasService.getAllWorkAreaForEmas();
        List<Map> result = new ArrayList<>();

        for (String allWorkAreaForEma : allWorkAreaForEmas) {
            HashMap<String, String> map = MapUtils.newHashMap();
            map.put("key", allWorkAreaForEma);
            map.put("value", allWorkAreaForEma);
            result.add(map);
        }
        return result;
    }


    public List getWorkAreaForEmasH() {
        List<String> allWorkAreaForEmasH = emasService.getAllWorkAreaForEmasH();
        List<Map> result = new ArrayList<>();

        for (String workArea : allWorkAreaForEmasH) {
            HashMap<String, String> map = MapUtils.newHashMap();
            map.put("key", workArea);
            map.put("value", workArea);
            result.add(map);
        }
        return result;
    }

    private List<Map<String, Object>> getJobFieldInfo(Map<String, Object> params, String fieldName) {
        String eqptId  = MapUtils.getStringCheckNull(params, "eqptId");
        long   eqptRrn = getInstanceRrn(eqptId, LocalContext.getFacilityRrn(), ObjectList.ENTITY_KEY);
        String result  = null;
        if (eqptRrn > 0) {
            result = spcService.getNonRTJob(eqptId);
        }

        List<Map<String, Object>> resultList = new ArrayList<>();
        if (StringUtils.isNotBlank(result)) {
            resultList.addAll(JsonUtils.toObject(result, List.class));
        }

        // 获取 areaId\jobname(chartId)
        Set<String> fieldIdSet = new HashSet<>();
        for (Map<String, Object> m : resultList) {
            String fieldId = MapUtils.getString(m, fieldName);
            fieldIdSet.add(fieldId);
        }

        return fieldIdSet.stream().map(s -> {
            Map<String, Object> m = new HashMap();
            m.put(fieldName, s);
            return m;
        }).collect(Collectors.toList());
    }

    private void buildAndCheckDTO(EmasModifyDTO modifyDTO) {
        //EQP ID、EnableFlag、chartId、Area基本栏位校验
        long equipmentRrn = getInstanceRrn(modifyDTO.getEqpId(),
                                           getNamedSpace(ObjectList.ENTITY_KEY, LocalContext.getFacilityRrn()),
                                           ObjectList.ENTITY_KEY);
        Assert.isFalse(equipmentRrn <= 0,
                       Errors.create().key(MessageIdList.NEWEMAS_OBJECT_NOT_EXIST).content("The {} does not exist!")
                             .args("EQP ID").build());
        Assert.isFalse(StringUtils.isBlank(modifyDTO.getEqpId()),
                       Errors.create().key(MessageIdList.NEWEMAS_OBJECT_EMPTY).content("The {} can not be empty!")
                             .args("EQP ID").build());
        Assert.isFalse(StringUtils.isBlank(modifyDTO.getEnableFlag()),
                       Errors.create().key(MessageIdList.NEWEMAS_OBJECT_EMPTY).content("The {} can not be empty!")
                             .args("EnableFlag").build());
        Assert.isFalse(StringUtils.isBlank(modifyDTO.getChartId()),
                       Errors.create().key(MessageIdList.NEWEMAS_OBJECT_EMPTY).content("The {} can not be empty!")
                             .args("ChartId").build());

        Assert.isFalse(StringUtils.isBlank(modifyDTO.getArea()),
                       Errors.create().key(MessageIdList.NEWEMAS_OBJECT_EMPTY).content("The {} can not be empty!")
                             .args("Area").build());

        modifyDTO.setEqpRrn(equipmentRrn);
        String lastUploadTime = edcChartService.getEquipmentChartUploadTime(equipmentRrn, modifyDTO.getChartId());
        modifyDTO.setLastUploadTime(DateUtils.stringToTimestamp(lastUploadTime));
        String timePoint = modifyDTO.getTimePointDate();
        String triggerRecipe = modifyDTO.getTriggerRecipe();
        String constraintRecipe = modifyDTO.getConstraintRecipe();

        //根据类型校验字段
        if (StringUtils.equalsIgnoreCase(modifyDTO.getCheckType(), EmasUtil.CheckType.BATCH)) {
            Assert.isFalse(Objects.isNull(modifyDTO.getBatchIdCount()),
                           Errors.create().key(MessageIdList.NEWEMAS_OBJECT_EMPTY).content("The {} can not be empty!")
                                 .args("BatchIdCount").build());
            modifyDTO.setCountType(null);
            modifyDTO.setTriggerRecipe(triggerRecipe);
            modifyDTO.setConstraintRecipe(constraintRecipe);
        }

        if (StringUtils.equalsIgnoreCase(modifyDTO.getCheckType(), EmasUtil.CheckType.PM)) {
            modifyDTO.setTriggerRecipe(null);
            modifyDTO.setConstraintRecipe(constraintRecipe);
            modifyDTO.setCountType(null);
        }

        if (StringUtils.equalsIgnoreCase(modifyDTO.getCheckType(), EmasUtil.CheckType.TIME)) {
            Assert.isFalse(StringUtils.isBlank(modifyDTO.getCycleType()),
                           Errors.create().key(MessageIdList.NEWEMAS_OBJECT_EMPTY).content("The {} can not be empty!")
                                 .args("Cycle type").build());
            Assert.isFalse(Objects.isNull(modifyDTO.getPeriod()),
                           Errors.create().key(MessageIdList.NEWEMAS_OBJECT_EMPTY).content("The {} can not be empty!")
                                 .args("Period").build());
            if (Objects.isNull(modifyDTO.getBufferTime())){//不设置bufferTime,就默认为0
                modifyDTO.setBufferTime(0D);
            }
            if (EmasUtil.CheckType.CycleType.BY_HOUR.equalsIgnoreCase(modifyDTO.getCheckType())){
                Assert.isFalse(modifyDTO.getBufferTime() > modifyDTO.getPeriod(),
                               Errors.create().key(MessageIdList.BUFFER_TIME_CANNOT_GREATER_PERIOD).content("The buffer time cannot be greater than the period!").build());
            }

            modifyDTO.setTriggerRecipe(null);
            modifyDTO.setConstraintRecipe(constraintRecipe);
            modifyDTO.setToleranceTime(DateUtils.stringToTimestamp(timePoint));
            modifyDTO.setCountType(null);
        }

        if (StringUtils.equalsIgnoreCase(modifyDTO.getCheckType(), EmasUtil.CheckType.COUNT)) {
            Assert.isFalse(StringUtils.isBlank(modifyDTO.getCountType()),
                           Errors.create().key(MessageIdList.NEWEMAS_OBJECT_EMPTY).content("The {} can not be empty!")
                                 .args("CountType").build());
            modifyDTO.setTriggerRecipe(triggerRecipe);
            modifyDTO.setConstraintRecipe(constraintRecipe);
            modifyDTO.setToleranceTime(DateUtils.stringToTimestamp(timePoint));
            if (Objects.isNull(modifyDTO.getBufferTime())){//不设置bufferTime,就默认为0
                modifyDTO.setBufferTime(0D);
            }
        }
    }

    private void checkChartIdPermission(EmasModifyDTO modifyDTO) {
        String[] chartIdArr = StringUtils.split(modifyDTO.getChartId(), ";");

        List<Relation> userGroups = securityService.getUserGroups(LocalContext.getUserRrn());
        String userGroup = userGroups.stream().map(NamedObject::getInstanceId).collect(Collectors.joining(","));
        Map<String, String> referenceFileMap = getReferenceFileDetails(ReferenceDetailNames.SPC_CHART_OWNER).stream().collect(Collectors.toMap(
                ReferenceFileDetail::getKey1Value, ReferenceFileDetail::getData1Value, (key1, key2) -> key2));
       String chartIds = StringUtils.EMPTY;

        if (!StringUtils.contains(userGroup, SystemConstants.ADMIN_USER_GROUP)) {
            for (String str:chartIdArr){
                String chartIdUserGroup = referenceFileMap.getOrDefault(
                        ChartNamingRule.getCodeRepresentedAsPermissionUserGroup(str), StringUtils.EMPTY);
                if (StringUtils.isNotBlank(chartIdUserGroup) && !StringUtils.contains(userGroup, chartIdUserGroup)) {
                    if (StringUtils.isBlank(chartIds)) {
                        chartIds += str;
                    }else if (!StringUtils.contains(chartIds, str)){
                        chartIds += StringUtils.COMMA_SIGN + str;
                    }
                }
            }
            Assert.isFalse(StringUtils.isNotBlank(chartIds),
                           Errors.create().key(MessageIdList.NEWEMAS_CHART_PERM).content("没有这些Chart:{}的权限")
                                 .args(chartIds).build());
        }
    }

}