package cn.cecep.talroad.service.impl.analysis;

import cn.cecep.talroad.common.core.utils.DateUtils;
import cn.cecep.talroad.common.core.utils.StringUtils;
import cn.cecep.talroad.common.log.annotation.Log;
import cn.cecep.talroad.common.redis.service.RedisService;
import cn.cecep.talroad.domain.*;
import cn.cecep.talroad.domain.analysis.SRaHandworkEmissionsGas;
import cn.cecep.talroad.domain.analysis.SRaHandworkEmissionsWater;
import cn.cecep.talroad.domain.analysis.SRaOnlineEmissionsGas;
import cn.cecep.talroad.domain.analysis.SRaOnlineEmissionsWater;
import cn.cecep.talroad.domain.analysis.SRaSelfMonitoringData;
import cn.cecep.talroad.enums.InvalidStateEnum;
import cn.cecep.talroad.enums.ProblemTypeEnum;
import cn.cecep.talroad.enums.StopTypeEnum;
import cn.cecep.talroad.enums.TimeTypeEnum;
import cn.cecep.talroad.enums.WhiteListTypeEnum;
import cn.cecep.talroad.mapper.*;
import cn.cecep.talroad.mapper.analysis.SRaHandworkEmissionsGasMapper;
import cn.cecep.talroad.mapper.analysis.SRaHandworkEmissionsWaterMapper;
import cn.cecep.talroad.mapper.analysis.SRaOnlineEmissionsGasMapper;
import cn.cecep.talroad.mapper.analysis.SRaOnlineEmissionsWaterMapper;
import cn.cecep.talroad.mapper.analysis.SRaSelfMonitoringDataMapper;
import cn.cecep.talroad.service.IAmProblemFiService;
import cn.cecep.talroad.service.IBMainPollDisGasMoutService;
import cn.cecep.talroad.service.IOdsOnlineOlPortinfoAService;
import cn.cecep.talroad.service.IOdsOnlineOlPsWhitelistAService;
import cn.cecep.talroad.service.IOdsOnlineOlStopinfoAService;
import cn.cecep.talroad.service.IPcControlRequirementsService;
import cn.cecep.talroad.service.ISEnvGasMonHourService;
import cn.cecep.talroad.service.ISEnvGasMonRealService;
import cn.cecep.talroad.service.ISEnvWaterMonDayService;
import cn.cecep.talroad.service.ISEnvWaterMonHourService;
import cn.cecep.talroad.service.ISEnvWaterMonRealService;
import cn.cecep.talroad.service.analysis.IConcentrationMathService;
import cn.cecep.talroad.service.analysis.IDischargeMathService;
import cn.cecep.talroad.service.analysis.ISRaOnlineEmissionsGasService;
import cn.cecep.talroad.service.analysis.ISRaOnlineEmissionsWaterService;
import cn.cecep.talroad.util.EmissionsConstants;
import cn.cecep.talroad.util.EmissionsUtils;
import cn.cecep.talroad.vo.analysis.*;
import cn.hutool.core.collection.ListUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.Format;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

import static org.apache.xmlbeans.impl.store.Public2.test;

/**
 * 排放量计算服务实现类
 */
@Service
@Slf4j
public class DischargeMathServiceImpl implements IDischargeMathService {

    @Autowired
    private EmissionsConstants emissionsConstants;
    @Autowired
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    @Autowired
    private ISRaOnlineEmissionsGasService sRaOnlineEmissionsGasService;

    @Autowired
    private ISRaOnlineEmissionsWaterService sRaOnlineEmissionsWaterService;

    @Resource
    private PcFactoryMapper factoryMapper;

    @Resource
    private PcOutletMapper pcOutletMapper;

    @Resource
    private BMainPollDisGasMoutMapper mainPollDisGasMoutMapper;

    @Resource
    private SRaOnlineEmissionsGasMapper sRaOnlineEmissionsGasMapper;

    @Resource
    private SRaOnlineEmissionsWaterMapper sRaOnlineEmissionsWaterMapper;
    @Autowired
    private ISEnvGasMonRealService isEnvGasMonRealService;

    @Autowired
    private ISEnvGasMonHourService isEnvGasMonHourService;

    @Autowired
    private SRaSelfMonitoringDataMapper sRaSelfMonitoringDataMapper;

    @Resource
    private ISEnvWaterMonRealService isEnvWaterMonRealService;

    @Resource
    private ISEnvWaterMonHourService isEnvWaterMonHourService;

    @Resource
    private BMainPollDisWaterMoutMapper mainPollDisWaterMoutMapper;

    @Resource
    private BMainEmissionPollutionWaterMapper bMainEmissionPollutionWaterMapper;

    @Resource
    private BMainEmissionPollutionAirMapper bMainEmissionPollutionAirMapper;

    @Resource
    private BMainAllowablePollutionAirMapper bMainAllowablePollutionAirMapper;

    @Resource
    private BMainAllowablePollutionWaterMapper bMainAllowablePollutionWaterMapper;

    @Resource
    private IAmProblemFiService amProblemFiService;

    @Autowired
    private IConcentrationMathService concentrationMathService;
    @Autowired
    private IOdsOnlineOlStopinfoAService odsOnlineOlStopinfoAService;
    @Autowired
    private ISEnvWaterMonDayService isEnvWaterMonDayService;
    @Autowired
    private IPcControlRequirementsService pcControlRequirementsService;


    private List<AmProblemFi> problemList = new CopyOnWriteArrayList<>();



    /**
     * 大气污染物在线小时排放量
     * @version 1.0
     */
    @Override
    public void doGasPollutantHourDischarge(String mathDate) throws ParseException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {

        //获取全部排污许可期限内的企业
        List<PermitEmissionsFactoryVO> permitEmissionsFactoryVOS;
        //查询所有排口信息
        Map<String ,List<PcOutletPermitPollutantVO>> pcOutletMap = new ConcurrentHashMap<>();
        //查询当前小时数据
        List<SEnvGasMonHour> gasRealList;
        //查询企业缓存
//        if (StringUtils.isNotBlank(redisService.getCacheObject("selectPermitEmissionsFactoryList"))){
//            permitEmissionsFactoryVOS = JSONObject.parseArray(redisService.getCacheObject("selectPermitEmissionsFactoryList"),PermitEmissionsFactoryVO.class);
//        }else{
//            permitEmissionsFactoryVOS= factoryMapper.selectPermitEmissionsFactoryList();
//            String data = JSONObject.toJSONString(permitEmissionsFactoryVOS);
//            redisService.setCacheObject("selectPermitEmissionsFactoryList",data);
//        }
        //初始化排污许可企业数据，规定排口容器的长度
        permitEmissionsFactoryVOS= factoryMapper.selectPermitEmissionsFactoryList();
        if(permitEmissionsFactoryVOS == null && permitEmissionsFactoryVOS.size() == 0){
            log.info("没有查询到企业，终止任务");
            return;
        }
        for (PermitEmissionsFactoryVO permitEmissionsFactoryVO : permitEmissionsFactoryVOS) {
            pcOutletMap.put(permitEmissionsFactoryVO.getFactoryId(),new ArrayList<>());
        }
        //查询排口缓存
//        if (StringUtils.isNotBlank(redisService.getCacheObject("selectPermitEmissionsFactoryList"))){
//            pcOutletMap = JSONObject.parseObject(redisService.getCacheObject("selectPermitEmissionsFactoryList"),
//                    Map.class);
//        }else{
//            pcOutletMap = new ConcurrentHashMap<>();
//            List<PcOutlet> ListOutlet = pcOutletMapper.selectPermitOutletList("1","1");
//            for (PcOutlet pcOutlet : ListOutlet) {
//                if (pcOutletMap.containsKey(pcOutlet.getFactoryId())) {
//                    pcOutletMap.get(pcOutlet.getFactoryId()).add(pcOutlet);
//                }else{
//                    pcOutletMap.put(pcOutlet.getFactoryId(), Arrays.asList(pcOutlet));
//                }
//            }
//            String data = JSONObject.toJSONString(permitEmissionsFactoryVOS);
//            redisService.setCacheObject("selectPermitEmissionsFactoryList",data);
//        }
        //查询排口下的所有监测点位信息
        List<PcOutlet> ListOutlet = pcOutletMapper.selectPermitOutletList("1","1");
        if(ListOutlet == null && ListOutlet.size() == 0){
            log.info("没有查询到排口的监测点位，终止任务");
            return;
        }
        //获取需要计算排放量的排口因子列表
        List<OutletPermitPollutantVO> outletPermitPollutantVOS = mainPollDisGasMoutMapper.selectGasOutletPermitPollutant();
        //只有排污许可企业下的排口监测点位才会被统计
        for (PcOutlet pcOutlet : ListOutlet) {
            if (pcOutletMap.containsKey(pcOutlet.getFactoryId())) {
                //初始化排口污染因子复合实体
                PcOutletPermitPollutantVO pcOutletPermitPollutantVO = new PcOutletPermitPollutantVO(pcOutlet.getOutletCode(), pcOutlet.getFactoryId(), pcOutlet, new HashMap<>());
                for (OutletPermitPollutantVO outletPermitPollutantVO : outletPermitPollutantVOS) {
                    if (outletPermitPollutantVO.getFactoryId().equalsIgnoreCase(pcOutlet.getFactoryId())
                            && outletPermitPollutantVO.getOutletCode().equalsIgnoreCase(pcOutlet.getOutletCode())) {
                        pcOutletPermitPollutantVO.getOutletPermitPollutantVOMap().put(outletPermitPollutantVO.getPollutantCode(),outletPermitPollutantVO);
                    }
                }
                //装载实体
                pcOutletMap.get(pcOutlet.getFactoryId()).add(pcOutletPermitPollutantVO);
            }
        }
        //查询最新小时数据
        LocalDateTime date = LocalDateTime.now().minus(1, ChronoUnit.HOURS);
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:00:00");
        String dateStr = date.format(dateTimeFormatter);
        if(StringUtils.isNotBlank(mathDate)){
            dateStr = mathDate;
        }
        QueryWrapper<SEnvGasMonHour> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("monitoring_time",dateStr);
        queryWrapper.eq("data_type",TimeTypeEnum.HOUR.getCode());
        queryWrapper.and(wp->{
           wp.isNull("data_flag").or().notIn("data_flag",Arrays.asList("C","M","D","MD","K","P","Vgd","VGD","TD","ST","SD","B","STA","F","FA"));
        });
        gasRealList = isEnvGasMonHourService.list(queryWrapper);
        final String alarmDate = dateStr;
        //初始化排放量容器，多个点位累加计算获得最终排放量
        Map<String,SRaOnlineEmissionsGas> batchDataMap = new ConcurrentHashMap<>();
        for (PermitEmissionsFactoryVO permitEmissionsFactoryVO : permitEmissionsFactoryVOS) {
            String factoryId = permitEmissionsFactoryVO.getFactoryId();
            List<PcOutletPermitPollutantVO> pcOutletPermitPollutantVOS = pcOutletMap.get(factoryId);
            //根据当前年份计算需要获取第几年的排污许可限值
            int startYear = Integer.parseInt(permitEmissionsFactoryVO.getStartDate());
            int nowYear = date.getYear();
            if(pcOutletPermitPollutantVOS != null && pcOutletPermitPollutantVOS.size()>0){
                //排口逐一进行处理，检查排口状态，跟排口的状态进行获取不同的数据
                for (PcOutletPermitPollutantVO pcOutlet : pcOutletPermitPollutantVOS) {
                    //筛选监测数据是否有该排口数据
                    SEnvGasMonHour sEnvGasMonRealIndex =null;
                    for (SEnvGasMonHour sEnvGasMonReal : gasRealList) {
                        if (StringUtils.isNotBlank(sEnvGasMonReal.getOutletId())
                                && sEnvGasMonReal.getOutletId().equalsIgnoreCase(pcOutlet.getPcOutlet().getId())
                                && sEnvGasMonReal.getFactoryId().equalsIgnoreCase(pcOutlet.getFactoryId())) {
                            sEnvGasMonRealIndex = sEnvGasMonReal;
                            break;
                        }
                    }
                    if(sEnvGasMonRealIndex == null){
                        //没有监测数据直接跳过，进行下一个排口检查
                        continue;
                    }
                    for (Map.Entry<String, String> stringStringEntry : emissionsConstants.getGasPollutants().entrySet()) {
                        //检查是否需要计算排放量，根据排污许可的污染因子比对
                        OutletPermitPollutantVO outletPermitPollutantVO = pcOutlet.getOutletPermitPollutantVOMap().get(stringStringEntry.getKey());
                        if(outletPermitPollutantVO == null){
                            //排污许可无该因子的限值，跳过
                            continue;
                        }
                        if (!EmissionsUtils.isNeedMathPermitEmissions(nowYear-startYear,outletPermitPollutantVO)) {
                            //排污许可是/的 不参与计算
                            continue;
                        }
                        //进行计算,查看该排口是否已有数据
                        if (batchDataMap.get(pcOutlet.getFactoryId()+":"+pcOutlet.getOutletCode()+":"+outletPermitPollutantVO.getPollutantCode()) == null) {
                            SRaOnlineEmissionsGas sRaOnlineEmissionsGas = new SRaOnlineEmissionsGas(
                                    sEnvGasMonRealIndex.getFactoryId(),
                                    pcOutlet.getOutletCode(),
                                    pcOutlet.getPcOutlet().getPollutantType(),
                                    new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(sEnvGasMonRealIndex.getMonitoringTime()),
                                    sEnvGasMonRealIndex.getOxygen(),
                                    "");
                            sRaOnlineEmissionsGas.setPollutantEmissions("0");
                            batchDataMap.put(pcOutlet.getFactoryId()+":"+pcOutlet.getOutletCode()+":"+outletPermitPollutantVO.getPollutantCode(),sRaOnlineEmissionsGas);
                        }
                        SRaOnlineEmissionsGas sRaOnlineEmissionsGas = batchDataMap.get(pcOutlet.getFactoryId()+":"+pcOutlet.getOutletCode()+":"+outletPermitPollutantVO.getPollutantCode());
                        sRaOnlineEmissionsGas.setPollutantName(outletPermitPollutantVO.getPollutantsType());
                        sRaOnlineEmissionsGas.setPollutantCode(outletPermitPollutantVO.getPollutantCode());
                        //获取污染因子排放量,如果没有，就需要查询同时段手工数据
                        Method method = SEnvGasMonHour.class.getMethod("get" + stringStringEntry.getValue() + "Emission");
                        //获取因子浓度
                        Method methodConcentration = SEnvGasMonHour.class.getMethod("get" + stringStringEntry.getValue() + "Convert");
                        String result = (String)method.invoke(sEnvGasMonRealIndex);
                        String concentrationValue = (String)methodConcentration.invoke(sEnvGasMonRealIndex);
                        Method methodFlag = SEnvGasMonHour.class.getMethod("get" + stringStringEntry.getValue() + "Flag");
                        // 污染物标识
                        String flag = (String)methodFlag.invoke(sEnvGasMonRealIndex);
                        // 污染物标识是否为无效标识，无效污染物浓度取0
                        String pulltantFlag = InvalidStateEnum.getNameByCode(flag);

                        if(StringUtils.isEmpty(concentrationValue)||StringUtils.isNotEmpty(pulltantFlag)){
                            concentrationValue = "0";
                        }
                        BigDecimal mathEmissions;
                        if(StringUtils.isNotBlank(result)){
                            //排口会有多个点位，对应多条监测数据
                            mathEmissions = new BigDecimal(result);
                            //把数据给到超标计算器，检查是否超标(仅在线数据会被监测)
                            String finalConcentrationValue = concentrationValue;
                            threadPoolTaskExecutor.execute(()-> {
                                try {
                                    concentrationMathService.checkExceedingTheStandard(pcOutlet.getPcOutlet(),outletPermitPollutantVO,new BigDecimal(finalConcentrationValue),alarmDate,"PollutantsMgHour","003002");
                                } catch (NoSuchMethodException e) {
                                    throw new RuntimeException(e);
                                } catch (InvocationTargetException e) {
                                    throw new RuntimeException(e);
                                } catch (IllegalAccessException e) {
                                    throw new RuntimeException(e);
                                } catch (ParseException e) {
                                    throw new RuntimeException(e);
                                }
                            });
                        }else{
                            //查询手工数据，进行计算排放量
                            List<SRaSelfMonitoringData> selfDatas = sRaSelfMonitoringDataMapper.selectList(new LambdaQueryWrapper<SRaSelfMonitoringData>()
                                .eq(SRaSelfMonitoringData::getMonitorTime, date)
                                .eq(SRaSelfMonitoringData::getFactoryId, pcOutlet.getFactoryId())
                                .eq(SRaSelfMonitoringData::getMonitoringName, pcOutlet.getPcOutlet().getMonitoringPointName())
                                .eq(SRaSelfMonitoringData::getPollutantsCode,outletPermitPollutantVO.getPollutantCode())
                                .eq(SRaSelfMonitoringData::getPollutantsType,"2"));
                            if(selfDatas != null && selfDatas.size()>0){
                                SRaSelfMonitoringData gasData = selfDatas.get(0);
                                String monitorVal = gasData.getActualConcentration();
                                String flueGasFlow = gasData.getFlow();
                                mathEmissions = new BigDecimal(monitorVal)
                                        .multiply(new BigDecimal(flueGasFlow))
                                        .divide(new BigDecimal(1000000), RoundingMode.HALF_DOWN);
                            }else{
                                //也没用手工数据，那么直接对0计算
                                mathEmissions = new BigDecimal(0);
                            }
                        }
                        //进行累加
                        BigDecimal pollutantEmissions = new BigDecimal(sRaOnlineEmissionsGas.getPollutantEmissions());
                        pollutantEmissions = pollutantEmissions.add(mathEmissions);
                        sRaOnlineEmissionsGas.setPollutantEmissions(pollutantEmissions.toString());
                    }
                }
            }
        }
        //进行整合入库
        if(batchDataMap.size() > 0){
            //覆盖数据
            sRaOnlineEmissionsGasService.remove(new LambdaQueryWrapper<SRaOnlineEmissionsGas>()
                    .eq(SRaOnlineEmissionsGas::getMonitorTime,new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(dateStr)));
            sRaOnlineEmissionsGasService.saveBatch(batchDataMap.values());
        }
        concentrationMathService.insertBatch();

    }
    /**
     * 水污染物在线日排放量
     */
    @Override
    public void doWaterPollutantDayDischarge(String mathDate) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, ParseException {
        //获取全部排污许可期限内的企业
        List<PermitEmissionsFactoryVO> permitEmissionsFactoryVOS;
        //查询所有排口信息
        Map<String ,List<PcOutletPermitPollutantVO>> pcOutletMap = new ConcurrentHashMap<>();
        //查询当前小时数据
        List<SEnvWaterMonDay> gasRealList;
        //查询企业缓存
//        if (StringUtils.isNotBlank(redisService.getCacheObject("selectPermitEmissionsFactoryList"))){
//            permitEmissionsFactoryVOS = JSONObject.parseArray(redisService.getCacheObject("selectPermitEmissionsFactoryList"),PermitEmissionsFactoryVO.class);
//        }else{
//            permitEmissionsFactoryVOS= factoryMapper.selectPermitEmissionsFactoryList();
//            String data = JSONObject.toJSONString(permitEmissionsFactoryVOS);
//            redisService.setCacheObject("selectPermitEmissionsFactoryList",data);
//        }
        //初始化排污许可企业数据，规定排口容器的长度
        permitEmissionsFactoryVOS= factoryMapper.selectPermitEmissionsFactoryList();
        if(permitEmissionsFactoryVOS == null && permitEmissionsFactoryVOS.size() == 0){
            log.info("没有查询到企业，终止任务");
            return;
        }
        for (PermitEmissionsFactoryVO permitEmissionsFactoryVO : permitEmissionsFactoryVOS) {
            pcOutletMap.put(permitEmissionsFactoryVO.getFactoryId(),new ArrayList<>());
        }
        //查询排口缓存
//        if (StringUtils.isNotBlank(redisService.getCacheObject("selectPermitEmissionsFactoryList"))){
//            pcOutletMap = JSONObject.parseObject(redisService.getCacheObject("selectPermitEmissionsFactoryList"),
//                    Map.class);
//        }else{
//            pcOutletMap = new ConcurrentHashMap<>();
//            List<PcOutlet> ListOutlet = pcOutletMapper.selectPermitOutletList("1","1");
//            for (PcOutlet pcOutlet : ListOutlet) {
//                if (pcOutletMap.containsKey(pcOutlet.getFactoryId())) {
//                    pcOutletMap.get(pcOutlet.getFactoryId()).add(pcOutlet);
//                }else{
//                    pcOutletMap.put(pcOutlet.getFactoryId(), Arrays.asList(pcOutlet));
//                }
//            }
//            String data = JSONObject.toJSONString(permitEmissionsFactoryVOS);
//            redisService.setCacheObject("selectPermitEmissionsFactoryList",data);
//        }
        //查询排口下的所有监测点位信息
        List<PcOutlet> ListOutlet = pcOutletMapper.selectPermitOutletList("2","0");
        if(ListOutlet == null && ListOutlet.size() == 0){
            log.info("没有查询到排口的监测点位，终止任务");
            return;
        }
        //获取需要计算排放量的排口因子列表
        List<OutletPermitPollutantVO> outletPermitPollutantVOS = mainPollDisWaterMoutMapper.selectWaterOutletPermitPollutant();
        //只有排污许可企业下的排口监测点位才会被统计
        for (PcOutlet pcOutlet : ListOutlet) {
            if (pcOutletMap.containsKey(pcOutlet.getFactoryId())) {
                //初始化排口污染因子复合实体
                PcOutletPermitPollutantVO pcOutletPermitPollutantVO = new PcOutletPermitPollutantVO(pcOutlet.getOutletCode(), pcOutlet.getFactoryId(), pcOutlet, new HashMap<>());
                for (OutletPermitPollutantVO outletPermitPollutantVO : outletPermitPollutantVOS) {
                    if (outletPermitPollutantVO.getFactoryId().equalsIgnoreCase(pcOutlet.getFactoryId())
                            && outletPermitPollutantVO.getOutletCode().equalsIgnoreCase(pcOutlet.getOutletCode())) {
                        pcOutletPermitPollutantVO.getOutletPermitPollutantVOMap().put(outletPermitPollutantVO.getPollutantCode(),outletPermitPollutantVO);
                    }
                }
                //装载实体
                pcOutletMap.get(pcOutlet.getFactoryId()).add(pcOutletPermitPollutantVO);
            }
        }
        //查询最新日数据
        LocalDateTime date = LocalDateTime.now().minus(1, ChronoUnit.DAYS);
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd 00:00:00");
        String dateStr = date.format(dateTimeFormatter);
        if(StringUtils.isNotBlank(mathDate)){
            dateStr = mathDate;
        }
        QueryWrapper<SEnvWaterMonDay> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("monitoring_time",dateStr);
        queryWrapper.eq("data_type",TimeTypeEnum.DAY.getCode());
        queryWrapper.and(wp->{
            wp.isNull("data_flag").or().notIn("data_flag",Arrays.asList("C","M","D","MD","K","P","Vgd","VGD","TD","ST","SD","B","STA","F","FA"));
        });

        gasRealList = isEnvWaterMonDayService.list(queryWrapper);
        //初始化排放量容器，多个点位累加计算获得最终排放量
        Map<String,SRaOnlineEmissionsWater> batchDataMap = new ConcurrentHashMap<>();
        for (PermitEmissionsFactoryVO permitEmissionsFactoryVO : permitEmissionsFactoryVOS) {
            String factoryId = permitEmissionsFactoryVO.getFactoryId();
            List<PcOutletPermitPollutantVO> pcOutletPermitPollutantVOS = pcOutletMap.get(factoryId);
            //根据当前年份计算需要获取第几年的排污许可限值
            int startYear = Integer.parseInt(permitEmissionsFactoryVO.getStartDate());
            int nowYear = date.getYear();
            final String alarmDate = dateStr;
            if(pcOutletPermitPollutantVOS != null && pcOutletPermitPollutantVOS.size()>0){
                //排口逐一进行处理，检查排口状态，跟排口的状态进行获取不同的数据
                for (PcOutletPermitPollutantVO pcOutlet : pcOutletPermitPollutantVOS) {
                    //筛选监测数据是否有该排口数据
                    SEnvWaterMonDay sEnvWaterMonRealIndex =null;
                    for (SEnvWaterMonDay sEnvWaterMonReal : gasRealList) {
                        if (StringUtils.isNotBlank(sEnvWaterMonReal.getOutletId())
                                && sEnvWaterMonReal.getOutletId().equalsIgnoreCase(pcOutlet.getPcOutlet().getId())
                                && sEnvWaterMonReal.getFactoryId().equalsIgnoreCase(pcOutlet.getFactoryId())) {
                            sEnvWaterMonRealIndex = sEnvWaterMonReal;
                            break;
                        }
                    }
                    if(sEnvWaterMonRealIndex == null){
                        //没有监测数据直接跳过，进行下一个排口检查
                        continue;
                    }
                    for (Map.Entry<String, String> stringStringEntry : emissionsConstants.getWaterPollutants().entrySet()) {
                        //检查是否需要计算排放量，根据排污许可的污染因子比对
                        OutletPermitPollutantVO outletPermitPollutantVO = pcOutlet.getOutletPermitPollutantVOMap().get(stringStringEntry.getKey());
                        if(outletPermitPollutantVO == null){
                            //排污许可无该因子的限值，跳过
                            continue;
                        }
                        if (!EmissionsUtils.isNeedMathPermitEmissions(nowYear-startYear,outletPermitPollutantVO)) {
                            //排污许可是/的 不参与计算
                            continue;
                        }
                        //进行计算,查看该排口是否已有数据
                        if (batchDataMap.get(pcOutlet.getFactoryId()+":"+pcOutlet.getOutletCode()+":"+outletPermitPollutantVO.getPollutantCode()) == null) {
                            SRaOnlineEmissionsWater sRaOnlineEmissionsWater = new SRaOnlineEmissionsWater(
                                    pcOutlet.getFactoryId(),
                                    pcOutlet.getOutletCode(),
                                    pcOutlet.getPcOutlet().getPollutantType(),
                                    new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(sEnvWaterMonRealIndex.getMonitoringTime()),
                                    sEnvWaterMonRealIndex.getWastewaterFlow());
                            sRaOnlineEmissionsWater.setPollutantEmissions("0");
                            batchDataMap.put(pcOutlet.getFactoryId()+":"+pcOutlet.getOutletCode()+":"+outletPermitPollutantVO.getPollutantCode(),sRaOnlineEmissionsWater);
                        }
                        SRaOnlineEmissionsWater sRaOnlineEmissionsWater = batchDataMap.get(pcOutlet.getFactoryId()+":"+pcOutlet.getOutletCode()+":"+outletPermitPollutantVO.getPollutantCode());
                        sRaOnlineEmissionsWater.setPollutantName(outletPermitPollutantVO.getPollutantsType());
                        sRaOnlineEmissionsWater.setPollutantCode(outletPermitPollutantVO.getPollutantCode());
                        //获取污染因子排放量,如果没有，就需要查询同时段手工数据
                        Method method = SEnvWaterMonDay.class.getMethod("get" + stringStringEntry.getValue() + "Emission");
                        String result = (String)method.invoke(sEnvWaterMonRealIndex);

                        Method methodFlag = SEnvWaterMonDay.class.getMethod("get" + stringStringEntry.getValue() + "Flag");
                        // 污染物标识
                        String flag = (String)methodFlag.invoke(sEnvWaterMonRealIndex);
                        // 污染物标识是否为无效标识，无效污染物浓度取0
                        String pulltantFlag = InvalidStateEnum.getNameByCode(flag);
                        if(StringUtils.isNotEmpty(pulltantFlag)){
                            result = "0";
                        }
                        BigDecimal mathEmissions;
                        if(StringUtils.isNotBlank(result)){
                            //排口会有多个点位，对应多条监测数据
                            mathEmissions = new BigDecimal(result);
                            //把数据给到超标计算器，检查是否超标(仅在线数据会被监测)
                            threadPoolTaskExecutor.execute(()-> {
                                try {
                                    concentrationMathService.checkExceedingTheStandard(pcOutlet.getPcOutlet(),outletPermitPollutantVO,mathEmissions,alarmDate,"PollutantsMgRate","003002");
                                } catch (NoSuchMethodException e) {
                                    throw new RuntimeException(e);
                                } catch (InvocationTargetException e) {
                                    throw new RuntimeException(e);
                                } catch (IllegalAccessException e) {
                                    throw new RuntimeException(e);
                                } catch (ParseException e) {
                                    throw new RuntimeException(e);
                                }
                            });
                        }else{
                            //查询手工数据，进行计算排放量
                            List<SRaSelfMonitoringData> selfDatas = sRaSelfMonitoringDataMapper.selectList(new LambdaQueryWrapper<SRaSelfMonitoringData>()
                                    .eq(SRaSelfMonitoringData::getMonitorTime, date)
                                    .eq(SRaSelfMonitoringData::getFactoryId, pcOutlet.getFactoryId())
                                    .eq(SRaSelfMonitoringData::getMonitoringName, pcOutlet.getPcOutlet().getMonitoringPointName())
                                    .eq(SRaSelfMonitoringData::getPollutantsCode,outletPermitPollutantVO.getPollutantCode())
                                    .eq(SRaSelfMonitoringData::getPollutantsType,"1"));
                            if(selfDatas != null && selfDatas.size()>0){
                                SRaSelfMonitoringData selfData = selfDatas.get(0);
                                String monitorVal = selfData.getActualConcentration();
                                String wasteWaterFlow = selfData.getFlow();
                                mathEmissions = new BigDecimal(monitorVal)
                                        .multiply(new BigDecimal(wasteWaterFlow))
                                        .divide(new BigDecimal(1000000), RoundingMode.HALF_DOWN);
                            }else{
                                //也没用手工数据，那么直接对0计算
                                mathEmissions = new BigDecimal(0);
                            }
                        }
                        //进行累加
                        BigDecimal pollutantEmissions = new BigDecimal(sRaOnlineEmissionsWater.getPollutantEmissions());
                        pollutantEmissions = pollutantEmissions.add(mathEmissions);
                        sRaOnlineEmissionsWater.setPollutantEmissions(pollutantEmissions.toString());
                    }
                }
            }
        }
        //进行整合入库
        if(batchDataMap.size() > 0){
            //覆盖数据
            sRaOnlineEmissionsWaterService.remove(new LambdaQueryWrapper<SRaOnlineEmissionsWater>()
                    .eq(SRaOnlineEmissionsWater::getMonitorTime,new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(dateStr)));
            sRaOnlineEmissionsWaterService.saveBatch(batchDataMap.values());
        }

    }


    /**
     * 水污染物在线排放量统计值
     */
    @Override
    public void doWaterPollutantDayDischargeTotal(String mathDate) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, ParseException {
        //获取全部排污许可期限内的企业
        List<PermitEmissionsFactoryVO> permitEmissionsFactoryVOS;
        //初始化排污许可企业数据，规定排口容器的长度
        permitEmissionsFactoryVOS= factoryMapper.selectPermitEmissionsFactoryList();
        if(permitEmissionsFactoryVOS == null && permitEmissionsFactoryVOS.size() == 0){
            log.info("没有查询到企业，终止任务");
            return;
        }
        LocalDateTime date = LocalDateTime.now().minus(1, ChronoUnit.DAYS);
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd 00:00:00");
        String dateStr = date.format(dateTimeFormatter);
        if(StringUtils.isNotBlank(mathDate)){
            dateStr = mathDate;
        }
        final String dateFinal = dateStr;
        //查询上一日企业下所有废水排口排放量数据
        for (PermitEmissionsFactoryVO permitEmissionsFactoryVO : permitEmissionsFactoryVOS) {
            List<SRaOnlineEmissionsWater> sRaOnlineEmissionsWaters = sRaOnlineEmissionsWaterMapper.selectList(new LambdaQueryWrapper<SRaOnlineEmissionsWater>()
                    .eq(SRaOnlineEmissionsWater::getFactoryId, permitEmissionsFactoryVO.getFactoryId())
                    .eq(SRaOnlineEmissionsWater::getMonitorTime, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(dateStr))
                    .orderByAsc(SRaOnlineEmissionsWater::getFactoryId));
            //进行累加更新
            BMainEmissionPollutionWater bMainEmissionPollutionWater;
            List<BMainEmissionPollutionWater> sRaOnlineEmissionsWaterList = bMainEmissionPollutionWaterMapper.selectList(new LambdaQueryWrapper<BMainEmissionPollutionWater>()
                    .eq(BMainEmissionPollutionWater::getFactoryId, permitEmissionsFactoryVO.getFactoryId())
                    .eq(BMainEmissionPollutionWater::getPollYear,String.valueOf(date.getYear())));
            if(sRaOnlineEmissionsWaterList == null || sRaOnlineEmissionsWaterList.size() == 0){
                log.info("企业无年度排放趋势数据，进行初始化");
                bMainEmissionPollutionWater = new BMainEmissionPollutionWater();
                bMainEmissionPollutionWater.setFactoryId(permitEmissionsFactoryVO.getFactoryId());
                bMainEmissionPollutionWater.setPollYear(String.valueOf(date.getYear()));
                bMainEmissionPollutionWater.setDataSource("系统核算");
                //获取许可排放量
                int startYear = Integer.parseInt(permitEmissionsFactoryVO.getStartDate().substring(0,3));
                List<BMainAllowablePollutionWater> bMainAllowablePollutionWaters = bMainAllowablePollutionWaterMapper.selectList(new LambdaQueryWrapper<BMainAllowablePollutionWater>()
                        .eq(BMainAllowablePollutionWater::getFactoryId, permitEmissionsFactoryVO.getFactoryId()));
                if(bMainAllowablePollutionWaters != null && bMainAllowablePollutionWaters.size()>0){
                    for (BMainAllowablePollutionWater bMainAllowablePollutionWater : bMainAllowablePollutionWaters) {
                        //反射初始化企业年排放量
                        String methodName = emissionsConstants.getWaterAllowableEmissionMap().get(bMainAllowablePollutionWater.getPollutionCategory());
                        if(StringUtils.isNotBlank(methodName)){
                            Method methodSet = BMainEmissionPollutionWater.class.getMethod("setAllowableEmission" + methodName,String.class);
                            methodSet.setAccessible(true);
                            methodSet.invoke(bMainEmissionPollutionWater,new BigDecimal(EmissionsUtils.choseWaterYearPollutantsTotalData(date.getYear() - startYear,bMainAllowablePollutionWater)).multiply(new BigDecimal(1000)).toString());
                        }
                    }
                }
                bMainEmissionPollutionWaterMapper.insert(bMainEmissionPollutionWater);
            }else{
                bMainEmissionPollutionWater = sRaOnlineEmissionsWaterList.get(0);
            }
            for (SRaOnlineEmissionsWater sRaOnlineEmissionsWater : sRaOnlineEmissionsWaters) {
                //反射处理因子
                String methodName = emissionsConstants.getWaterActuallyEmittingMap().get(sRaOnlineEmissionsWater.getPollutantName());
                if(StringUtils.isNotBlank(methodName)){
                    Method methodSet = BMainEmissionPollutionWater.class.getMethod("setActuallyEmitting" + methodName,String.class);
                    Method methodGet = BMainEmissionPollutionWater.class.getMethod("getActuallyEmitting" + methodName);
                    methodSet.setAccessible(true);
                    String resultGet = (String)methodGet.invoke(bMainEmissionPollutionWater);
                    String mathResult = new BigDecimal(StringUtils.isBlank(resultGet)? "0" : resultGet)
                            .add(new BigDecimal(StringUtils.isBlank(sRaOnlineEmissionsWater.getPollutantEmissions())?"0":sRaOnlineEmissionsWater.getPollutantEmissions())).toString();
                    methodSet.invoke(bMainEmissionPollutionWater,mathResult);
                }
            }
            //排放量超标/预警计算
            this.threadPoolTaskExecutor.execute(()-> {
                try {
                    checkExceedingTheStandardAndAlarm(bMainEmissionPollutionWater,BMainEmissionPollutionWater.class,emissionsConstants.getWaterAllowableEmissionMap(),permitEmissionsFactoryVO,dateFinal);
                } catch (NoSuchMethodException e) {
                    throw new RuntimeException(e);
                } catch (InvocationTargetException e) {
                    throw new RuntimeException(e);
                } catch (IllegalAccessException e) {
                    throw new RuntimeException(e);
                } catch (ParseException e) {
                    throw new RuntimeException(e);
                }
            });
            //防止多线程插入时被执行clear操作
            synchronized (problemList){
                amProblemFiService.saveBatch(problemList);
                problemList.clear();
            }
            bMainEmissionPollutionWaterMapper.updateById(bMainEmissionPollutionWater);
        }
    }

    /**
     * 废气在线排放量统计值
     */
    @Override
    public void doGasPollutantHourDischargeTotal(String mathDate) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, ParseException {
        //获取全部排污许可期限内的企业
        List<PermitEmissionsFactoryVO> permitEmissionsFactoryVOS;
        //初始化排污许可企业数据，规定排口容器的长度
        permitEmissionsFactoryVOS= factoryMapper.selectPermitEmissionsFactoryList();
        if(permitEmissionsFactoryVOS == null && permitEmissionsFactoryVOS.size() == 0){
            log.info("没有查询到企业，终止任务");
            return;
        }
        LocalDateTime date = LocalDateTime.now().minus(1, ChronoUnit.DAYS);
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd 00:00:00");
        String dateStr = date.format(dateTimeFormatter);
        if(StringUtils.isNotBlank(mathDate)){
            dateStr = mathDate;
        }
        final String dateFinal = dateStr;
        //查询上一日企业下所有废气排口排放量数据
        for (PermitEmissionsFactoryVO permitEmissionsFactoryVO : permitEmissionsFactoryVOS) {
            List<SRaOnlineEmissionsGas> sRaOnlineEmissionsGases = sRaOnlineEmissionsGasMapper.selectList(new LambdaQueryWrapper<SRaOnlineEmissionsGas>()
                    .eq(SRaOnlineEmissionsGas::getFactoryId, permitEmissionsFactoryVO.getFactoryId())
                    .ge(SRaOnlineEmissionsGas::getMonitorTime, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(dateStr))
                    .lt(SRaOnlineEmissionsGas::getMonitorTime, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(LocalDateTime.parse(dateStr,DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")).plus(1,ChronoUnit.DAYS).format(dateTimeFormatter))));
            //进行累加更新
            BMainEmissionPollutionAir bMainEmissionPollutionAir;
            List<BMainEmissionPollutionAir> sRaOnlineEmissionsAirList = bMainEmissionPollutionAirMapper.selectList(new LambdaQueryWrapper<BMainEmissionPollutionAir>()
                    .eq(BMainEmissionPollutionAir::getFactoryId, permitEmissionsFactoryVO.getFactoryId())
                    .eq(BMainEmissionPollutionAir::getPollYear,String.valueOf(date.getYear())));
            if(sRaOnlineEmissionsAirList == null || sRaOnlineEmissionsAirList.size() == 0){
                log.info("企业无年度排放趋势数据，进行初始化");
                bMainEmissionPollutionAir = new BMainEmissionPollutionAir();
                bMainEmissionPollutionAir.setFactoryId(permitEmissionsFactoryVO.getFactoryId());
                bMainEmissionPollutionAir.setPollYear(String.valueOf(date.getYear()));
                bMainEmissionPollutionAir.setDataSource("系统核算");
                //获取许可排放量
                int startYear = Integer.parseInt(permitEmissionsFactoryVO.getStartDate().substring(0,3));
                List<BMainAllowablePollutionAir> bMainAllowablePollutionAirs = bMainAllowablePollutionAirMapper.selectList(new LambdaQueryWrapper<BMainAllowablePollutionAir>()
                        .eq(BMainAllowablePollutionAir::getFactoryId, permitEmissionsFactoryVO.getFactoryId()));
                if(bMainAllowablePollutionAirs != null && bMainAllowablePollutionAirs.size()>0){
                    for (BMainAllowablePollutionAir bMainAllowablePollutionAir : bMainAllowablePollutionAirs) {
                        //反射初始化企业年排放量
                        String methodName = emissionsConstants.getGasAllowableEmissionMap().get(bMainAllowablePollutionAir.getPollutionCategory());
                        if(StringUtils.isNotBlank(methodName)){
                            Method methodSet = BMainEmissionPollutionAir.class.getMethod("setAllowableEmission" + methodName,String.class);
                            methodSet.setAccessible(true);
                            String mathValue = EmissionsUtils.choseGasYearPollutantsTotalData(date.getYear() - startYear,bMainAllowablePollutionAir);
                            BigDecimal temp = new BigDecimal(0);
                            if (!mathValue.equalsIgnoreCase("/")) {
                                temp = new BigDecimal(mathValue);
                            }
                            methodSet.invoke(bMainEmissionPollutionAir,temp.multiply(new BigDecimal(1000)).toString());
                        }
                    }
                }
                bMainEmissionPollutionAirMapper.insert(bMainEmissionPollutionAir);
            }else{
                bMainEmissionPollutionAir = sRaOnlineEmissionsAirList.get(0);
            }
            for (SRaOnlineEmissionsGas sRaOnlineEmissionsGas : sRaOnlineEmissionsGases) {
                //反射处理因子,该企业所有排口的所有小时数据全部累加
                String methodName = emissionsConstants.getGasActuallyEmittingMap().get(sRaOnlineEmissionsGas.getPollutantCode());
                if(StringUtils.isNotBlank(methodName)){
                    Method methodSet = BMainEmissionPollutionAir.class.getMethod("setActuallyEmitting" + methodName,String.class);
                    Method methodGet = BMainEmissionPollutionAir.class.getMethod("getActuallyEmitting" + methodName);
                    methodSet.setAccessible(true);
                    String resultGet = (String)methodGet.invoke(bMainEmissionPollutionAir);
                    String mathResult = new BigDecimal(StringUtils.isBlank(resultGet)? "0" : resultGet)
                            .add(new BigDecimal(StringUtils.isBlank(sRaOnlineEmissionsGas.getPollutantEmissions())?"0":sRaOnlineEmissionsGas.getPollutantEmissions())).toString();
                    methodSet.invoke(bMainEmissionPollutionAir,mathResult);
                }
            }
            //排放量超标/预警计算
            this.threadPoolTaskExecutor.execute(()-> {
                try {
                    checkExceedingTheStandardAndAlarm(bMainEmissionPollutionAir,BMainEmissionPollutionAir.class,emissionsConstants.getGasAllowableEmissionMap(),permitEmissionsFactoryVO,dateFinal);
                } catch (NoSuchMethodException e) {
                    throw new RuntimeException(e);
                } catch (InvocationTargetException e) {
                    throw new RuntimeException(e);
                } catch (IllegalAccessException e) {
                    throw new RuntimeException(e);
                } catch (ParseException e) {
                    throw new RuntimeException(e);
                }
            });
            //防止多线程插入时被执行clear操作
            synchronized (problemList){
                amProblemFiService.saveBatch(problemList);
                problemList.clear();
            }
            bMainEmissionPollutionAirMapper.updateById(bMainEmissionPollutionAir);
        }
    }

    /**
     * 企业排放量超标预警计算器
     * @param target 实例对象
     * @param targetClass 实力class类型
     * @param permitEmissionsFactoryVO 企业对象
     */
    private void checkExceedingTheStandardAndAlarm(Object target,
                                                   Class<?> targetClass,
                                                   Map<String,String> pollutantMap,
                                                   PermitEmissionsFactoryVO permitEmissionsFactoryVO,
                                                   String dateStr) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, ParseException {
        String alarmCode = "";
        int alarmType = -1;
        String alramMessage = "";
        boolean triggerOpen = false;
        for (Map.Entry<String, String> stringStringEntry : pollutantMap.entrySet()) {
            Method allowableEmissionMethod = targetClass.getMethod("getAllowableEmission" + stringStringEntry.getValue());
            Method actuallyEmittingMethod = targetClass.getMethod("getActuallyEmitting" + stringStringEntry.getValue());
            Method exceedingMethod = targetClass.getMethod("getExceedingRate" + stringStringEntry.getValue());
            String allowableValue = (String)allowableEmissionMethod.invoke(target);
            String actuallyValue = (String)actuallyEmittingMethod.invoke(target);
            String exceedingValue = (String) exceedingMethod.invoke(target);
            //无超标情况，检查预警要求是否达到,排污许可限值是0的不计算
            if(StringUtils.isNotBlank(allowableValue)
                    && StringUtils.isNotBlank(actuallyValue)
                    && new BigDecimal(allowableValue).compareTo(BigDecimal.ZERO) >0){
                //初始化排放差，超出百分比，注意，newSubtractRate可能为0，可能没有超标，那么超出百分比必是0
                BigDecimal subtract = new BigDecimal(actuallyValue).subtract(new BigDecimal(allowableValue));
                BigDecimal newSubtractRate = subtract.divide(new BigDecimal(allowableValue), RoundingMode.HALF_DOWN)
                        .multiply(new BigDecimal(100));
                if(StringUtils.isBlank(exceedingValue)){
                    BigDecimal rate = new BigDecimal(actuallyValue).divide(new BigDecimal(allowableValue), 2, RoundingMode.HALF_DOWN).multiply(new BigDecimal(100));
                    //大于90但是没有超标，预警
                    if(rate.compareTo(new BigDecimal(90)) >= 0 && new BigDecimal(actuallyValue).compareTo(new BigDecimal(allowableValue))<=0){
                        triggerOpen = true;
                        alarmCode = "003005";
                        alarmType = 1;
                        alramMessage = "上限90%预警";
                    }
                    //检查是否首次超标
                    if (subtract.compareTo(BigDecimal.ZERO) > 0) {
                        triggerOpen = true;
                        alarmCode = "003004";
                        alarmType = 0;
                        alramMessage = "超标报警";
                        targetClass.getMethod("setExceedingRate"+stringStringEntry.getValue()).invoke(target,newSubtractRate.toString());
                    }
                }else{
                    if (newSubtractRate.subtract(new BigDecimal(exceedingValue)).compareTo(new BigDecimal(1)) >= 0) {
                        triggerOpen = true;
                        //超过原超标率一个百分比以上，继续报警
                        alarmCode = "003004";
                        alarmType = 0;
                        alramMessage = "超标报警";
                        targetClass.getMethod("setExceedingRate"+stringStringEntry.getValue()).invoke(target,newSubtractRate.toString());
                    }
                }
                //先计算预警，再检查是否超标，预警只报警一次，超标则为每超出1个百分比报警一次
                if(triggerOpen){
                    AmProblemFi amProblemFi = new AmProblemFi();
                    amProblemFi.setFactoryId(permitEmissionsFactoryVO.getFactoryId());
                    amProblemFi.setProblemSources("1");
                    amProblemFi.setProblemType(alarmCode);
                    amProblemFi.setType(alarmType);
                    amProblemFi.setAnalyseTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(dateStr));
                    amProblemFi.setProblemDetails(permitEmissionsFactoryVO.getFactoryName()+":发生排放量"+alramMessage+"，污染因子："+stringStringEntry.getKey()+","+"排污许可值为："+allowableValue+",实际排放为："+actuallyValue);
                    amProblemFi.setPollutantSourceAi("1");
                    Map<String, Object> extra = new HashMap<>();
                    extra.put("type", target instanceof BMainEmissionPollutionWater ? "water" : "gas"); // gas:废气, water:废水
                    extra.put("pollutantCode", stringStringEntry.getKey()); // 污染因子编码
                    extra.put("allowableValue", allowableValue); // 限值
                    amProblemFi.setExtra(JSON.toJSONString(extra));

                    problemList.add(amProblemFi);
                }
            }
        }
//        //有超标触发，执行更新
//        if(triggerOpen){
//            if(target instanceof BMainEmissionPollutionAir){
//                bMainEmissionPollutionAirMapper.updateById((BMainEmissionPollutionAir)target);
//            }else{
//                bMainEmissionPollutionWaterMapper.updateById((BMainEmissionPollutionWater)target);
//            }
//        }
    }

    /**
     * 废气手工月排放量
     */
    @Override
    public void doGasHandiworkMonthDischarge() {
//        List<PermitEmissionsFactoryVO> permitEmissionsFactoryVOS;
//        //初始化排污许可企业数据，规定排口容器的长度
//        permitEmissionsFactoryVOS= factoryMapper.selectPermitEmissionsFactoryList();
//        if(permitEmissionsFactoryVOS == null && permitEmissionsFactoryVOS.size() == 0){
//            log.info("没有查询到企业，终止任务");
//        }
//        LocalDateTime date = LocalDateTime.now().minus(1, ChronoUnit.MONTHS);
//        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-01 00:00:00");
//        String dateStr = date.format(dateTimeFormatter);
//        //查询上个月企业下所有废气排口手工监测数据
//        for (PermitEmissionsFactoryVO permitEmissionsFactoryVO : permitEmissionsFactoryVOS) {
//            List<SRaHandworkEmissionsGas> sRaHandworkEmissionsGases = handworkEmissionsGasMapper.selectAgvDataList(permitEmissionsFactoryVO.getFactoryId(), dateStr,LocalDateTime.now().format(dateTimeFormatter));
//            //如果上个月没查到，那么再往前一个月查询，如还是没有，求平均值
//            if(sRaHandworkEmissionsGases.size() ==0){
//                sRaHandworkEmissionsGases = handworkEmissionsGasMapper.selectAgvDataList(
//                        permitEmissionsFactoryVO.getFactoryId(),
//                        date.minusMonths(1).format(dateTimeFormatter),
//                        dateStr);
//                if(sRaHandworkEmissionsGases.size() == 0){
//                    sRaHandworkEmissionsGases = handworkEmissionsGasMapper.selectAgvDataList(permitEmissionsFactoryVO.getFactoryId(),
//                            date.getYear()+"-01-01 00:00:00",
//                            date.getYear()+"-12-31 23:59:59");
//                }
//            }
//            //进行累加更新
//            BMainEmissionPollutionAir bMainEmissionPollutionAir;
//            List<BMainEmissionPollutionAir> sRaOnlineEmissionsAirList = bMainEmissionPollutionAirMapper.selectList(new LambdaQueryWrapper<BMainEmissionPollutionAir>()
//                    .eq(BMainEmissionPollutionAir::getFactoryId, permitEmissionsFactoryVO.getFactoryId())
//                    .eq(BMainEmissionPollutionAir::getPollYear,date.getYear()));
//            if(sRaOnlineEmissionsAirList == null && sRaOnlineEmissionsAirList.size() == 0){
//                log.info("企业无年度排放趋势数据，进行初始化");
//                bMainEmissionPollutionAir = new BMainEmissionPollutionAir();
//                bMainEmissionPollutionAir.setFactoryId(permitEmissionsFactoryVO.getFactoryId());
//                bMainEmissionPollutionAir.setPollYear(String.valueOf(date.getYear()));
//                bMainEmissionPollutionAir.setDataSource("系统核算");
//                //获取许可排放量
//                int startYear = Integer.parseInt(permitEmissionsFactoryVO.getStartDate());
//                List<BMainPollDisGasTout> bMainPollDisGasTouts = bMainPollDisGasToutMapper.selectList(new LambdaQueryWrapper<BMainPollDisGasTout>()
//                        .eq(BMainPollDisGasTout::getFactoryId, permitEmissionsFactoryVO.getFactoryId()));
//                if(bMainPollDisGasTouts != null && bMainPollDisGasTouts.size()>0){
//                    for (BMainPollDisGasTout bMainPollDisGasTout : bMainPollDisGasTouts) {
//                        if (bMainPollDisGasTout.getPollutantsType().equalsIgnoreCase("颗粒物")) {
//                            bMainEmissionPollutionAir.setAllowableEmissionPm(EmissionsUtils.choseGasYearPollutantsTotalData(date.getYear() - startYear,bMainPollDisGasTout));
//                        }else if (bMainPollDisGasTout.getPollutantsType().equalsIgnoreCase("VOCs")){
//                            bMainEmissionPollutionAir.setAllowableEmissionVocs(EmissionsUtils.choseGasYearPollutantsTotalData(date.getYear() - startYear,bMainPollDisGasTout));
//                        }else if (bMainPollDisGasTout.getPollutantsType().equalsIgnoreCase("NOx")){
//                            bMainEmissionPollutionAir.setAllowableEmissionNox(EmissionsUtils.choseGasYearPollutantsTotalData(date.getYear() - startYear,bMainPollDisGasTout));
//                        }else if (bMainPollDisGasTout.getPollutantsType().equalsIgnoreCase("SO₂")){
//                            bMainEmissionPollutionAir.setAllowableEmissionSo2(EmissionsUtils.choseGasYearPollutantsTotalData(date.getYear() - startYear,bMainPollDisGasTout));
//                        }
//                    }
//                }
//                bMainEmissionPollutionAirMapper.insert(bMainEmissionPollutionAir);
//            }else{
//                bMainEmissionPollutionAir = sRaOnlineEmissionsAirList.get(0);
//            }
//            for (SRaHandworkEmissionsGas sRaHandworkEmissionsGas : sRaHandworkEmissionsGases) {
//                //手工监测数据为 浓度乘以流量乘以运行小时数 没有运行小时数按24小时*当月天数算
//                if(StringUtils.isBlank(sRaHandworkEmissionsGas.getCheckRunTime())){
//                    int num = date.getMonth().length(date.getYear()%400 == 0 || (date.getYear() %4 ==0 && date.getYear()%100 >0)) * 24;
//                    sRaHandworkEmissionsGas.setCheckRunTime(String.valueOf(num));
//                }
//                BigDecimal multiply = new BigDecimal(sRaHandworkEmissionsGas.getMonitorVal())
//                        .multiply(new BigDecimal(sRaHandworkEmissionsGas.getFlueGasFlow()))
//                        .multiply(new BigDecimal(sRaHandworkEmissionsGas.getCheckRunTime()));
//                if (sRaHandworkEmissionsGas.getPollutantName().equalsIgnoreCase("pm")) {
//                    bMainEmissionPollutionAir.setActuallyEmittingPm(new BigDecimal(bMainEmissionPollutionAir.getActuallyEmittingPm()).add(multiply).toString());
//                }else if (sRaHandworkEmissionsGas.getPollutantName().equalsIgnoreCase("Vocs")) {
//                    bMainEmissionPollutionAir.setActuallyEmittingVocs(new BigDecimal(bMainEmissionPollutionAir.getActuallyEmittingVocs()).add(multiply).toString());
//                }else if (sRaHandworkEmissionsGas.getPollutantName().equalsIgnoreCase("NOX")) {
//                    bMainEmissionPollutionAir.setActuallyEmittingNox(new BigDecimal(bMainEmissionPollutionAir.getActuallyEmittingNox()).add(multiply).toString());
//                }else if (sRaHandworkEmissionsGas.getPollutantName().equalsIgnoreCase("SO2")) {
//                    bMainEmissionPollutionAir.setActuallyEmittingSo2(new BigDecimal(bMainEmissionPollutionAir.getActuallyEmittingSo2()).add(multiply).toString());
//                }
//            }
//            bMainEmissionPollutionAirMapper.updateById(bMainEmissionPollutionAir);
//        }
    }
    /**
     * 废水手工月排放量
     */
    @Override
    public void doWaterHandiworkMonthDischarge() {
//        //获取全部排污许可期限内的企业
//        List<PermitEmissionsFactoryVO> permitEmissionsFactoryVOS;
//        //初始化排污许可企业数据，规定排口容器的长度
//        permitEmissionsFactoryVOS= factoryMapper.selectPermitEmissionsFactoryList();
//        if(permitEmissionsFactoryVOS == null && permitEmissionsFactoryVOS.size() == 0){
//            log.info("没有查询到企业，终止任务");
//        }
//        LocalDateTime date = LocalDateTime.now().minus(1, ChronoUnit.MONTHS);
//        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-01 00:00:00");
//        String dateStr = date.format(dateTimeFormatter);
//        //查询上一月企业下所有废水排口排放量数据
//        for (PermitEmissionsFactoryVO permitEmissionsFactoryVO : permitEmissionsFactoryVOS) {
//            List<SRaHandworkEmissionsWater> sRaHandworkEmissionsWaters = handworkEmissionsWaterMapper.selectAgvDataList(
//                    permitEmissionsFactoryVO.getFactoryId(),
//                    dateStr,
//                    LocalDateTime.now().format(dateTimeFormatter));
//            //如果上个月没查到，那么再往前一个月查询，如还是没有，求当年平均值
//            if(sRaHandworkEmissionsWaters.size() ==0){
//                sRaHandworkEmissionsWaters = handworkEmissionsWaterMapper.selectAgvDataList(
//                        permitEmissionsFactoryVO.getFactoryId(),
//                        date.minusMonths(1).format(dateTimeFormatter),
//                        dateStr);
//                if(sRaHandworkEmissionsWaters.size() == 0){
//                    sRaHandworkEmissionsWaters = handworkEmissionsWaterMapper.selectAgvDataList(permitEmissionsFactoryVO.getFactoryId(),
//                            date.getYear()+"-01-01 00:00:00",
//                            date.getYear()+"-12-31 23:59:59");
//                }
//            }
//            //进行累加更新
//            BMainEmissionPollutionWater bMainEmissionPollutionWater;
//            List<BMainEmissionPollutionWater> sRaOnlineEmissionsWaterList = bMainEmissionPollutionWaterMapper.selectList(new LambdaQueryWrapper<BMainEmissionPollutionWater>()
//                    .eq(BMainEmissionPollutionWater::getFactoryId, permitEmissionsFactoryVO.getFactoryId())
//                    .eq(BMainEmissionPollutionWater::getPollYear,date.getYear()));
//            if(sRaOnlineEmissionsWaterList == null && sRaOnlineEmissionsWaterList.size() == 0){
//                log.info("企业无年度排放趋势数据，进行初始化");
//                bMainEmissionPollutionWater = new BMainEmissionPollutionWater();
//                bMainEmissionPollutionWater.setFactoryId(permitEmissionsFactoryVO.getFactoryId());
//                bMainEmissionPollutionWater.setPollYear(String.valueOf(date.getYear()));
//                bMainEmissionPollutionWater.setDataSource("系统核算");
//                //获取许可排放量
//                int startYear = Integer.parseInt(permitEmissionsFactoryVO.getStartDate());
//                List<BMainPollDisWaterTout> bMainPollDisWaterTouts = bMainPollDisWaterToutMapper.selectList(new LambdaQueryWrapper<BMainPollDisWaterTout>()
//                        .eq(BMainPollDisWaterTout::getFactoryId, permitEmissionsFactoryVO.getFactoryId()));
//                if(bMainPollDisWaterTouts != null && bMainPollDisWaterTouts.size()>0){
//                    for (BMainPollDisWaterTout bMainPollDisWaterTout : bMainPollDisWaterTouts) {
//                        if (bMainPollDisWaterTout.getPollutantsType().equalsIgnoreCase("CODcr")) {
//                            bMainEmissionPollutionWater.setAllowableEmissionCod(EmissionsUtils.choseWaterYearPollutantsTotalData(date.getYear() - startYear,bMainPollDisWaterTout));
//                        }else if (bMainPollDisWaterTout.getPollutantsType().equalsIgnoreCase("总氮（以N计）")){
//                            bMainEmissionPollutionWater.setAllowableEmissionTn(EmissionsUtils.choseWaterYearPollutantsTotalData(date.getYear() - startYear,bMainPollDisWaterTout));
//                        }else if (bMainPollDisWaterTout.getPollutantsType().equalsIgnoreCase("氨氮")){
//                            bMainEmissionPollutionWater.setAllowableEmissionNhn(EmissionsUtils.choseWaterYearPollutantsTotalData(date.getYear() - startYear,bMainPollDisWaterTout));
//                        }else if (bMainPollDisWaterTout.getPollutantsType().equalsIgnoreCase("总磷（以P计）")){
//                            bMainEmissionPollutionWater.setAllowableEmissionTp(EmissionsUtils.choseWaterYearPollutantsTotalData(date.getYear() - startYear,bMainPollDisWaterTout));
//                        }
//                    }
//                }
//                bMainEmissionPollutionWaterMapper.insert(bMainEmissionPollutionWater);
//            }else{
//                bMainEmissionPollutionWater = sRaOnlineEmissionsWaterList.get(0);
//            }
//            for (SRaHandworkEmissionsWater sRaHandworkEmissionsWater : sRaHandworkEmissionsWaters) {
//                if(StringUtils.isBlank(sRaHandworkEmissionsWater.getCheckRunTime())){
//                    int num = date.getMonth().length(date.getYear()%400 == 0 || (date.getYear() %4 ==0 && date.getYear()%100 >0)) * 24;
//                    sRaHandworkEmissionsWater.setCheckRunTime(String.valueOf(num));
//                }
//                BigDecimal multiply = new BigDecimal(sRaHandworkEmissionsWater.getMonitorVal())
//                        .multiply(new BigDecimal(sRaHandworkEmissionsWater.getWasteWaterFlow()))
//                        .multiply(new BigDecimal(sRaHandworkEmissionsWater.getCheckRunTime()));
//                if (sRaHandworkEmissionsWater.getPollutantName().equalsIgnoreCase("COD")) {
//                    bMainEmissionPollutionWater.setActuallyEmittingCod(new BigDecimal(bMainEmissionPollutionWater.getActuallyEmittingCod()).add(multiply).toString());
//                }else if (sRaHandworkEmissionsWater.getPollutantName().equalsIgnoreCase("总磷")) {
//                    bMainEmissionPollutionWater.setActuallyEmittingTp(new BigDecimal(bMainEmissionPollutionWater.getActuallyEmittingTp()).add(multiply).toString());
//                }else if (sRaHandworkEmissionsWater.getPollutantName().equalsIgnoreCase("总氮")) {
//                    bMainEmissionPollutionWater.setActuallyEmittingTn(new BigDecimal(bMainEmissionPollutionWater.getActuallyEmittingTn()).add(multiply).toString());
//                }else if (sRaHandworkEmissionsWater.getPollutantName().equalsIgnoreCase("氨氮")) {
//                    bMainEmissionPollutionWater.setActuallyEmittingNhn(new BigDecimal(bMainEmissionPollutionWater.getActuallyEmittingNhn()).add(multiply).toString());
//                }
//            }
//            bMainEmissionPollutionWaterMapper.updateById(bMainEmissionPollutionWater);
//        }
    }
    /**
     * 废气排放量超标
     */
    @Override
    public void doGasDischargeExceeded() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        //获取全部排污许可期限内的企业
        List<PermitEmissionsFactoryVO> permitEmissionsFactoryVOS;
        //初始化排污许可企业数据，规定排口容器的长度
        permitEmissionsFactoryVOS= factoryMapper.selectPermitEmissionsFactoryList();
        if(permitEmissionsFactoryVOS == null && permitEmissionsFactoryVOS.size() == 0){
            log.info("没有查询到企业，终止任务");
        }
        LocalDateTime date = LocalDateTime.now();
        List<AmProblemFi> amProblemFiList = new ArrayList<>();
        for (PermitEmissionsFactoryVO permitEmissionsFactoryVO : permitEmissionsFactoryVOS) {
            List<BMainEmissionPollutionAir> bMainEmissionPollutionAirs = bMainEmissionPollutionAirMapper.selectList(new LambdaQueryWrapper<BMainEmissionPollutionAir>()
                    .eq(BMainEmissionPollutionAir::getPollYear, String.valueOf(date.getYear()))
                    .eq(BMainEmissionPollutionAir::getFactoryId, permitEmissionsFactoryVO.getFactoryId()));
            if (bMainEmissionPollutionAirs!= null) {
                for (BMainEmissionPollutionAir bMainEmissionPollutionAir : bMainEmissionPollutionAirs) {
                    for (Map.Entry<String, String> stringStringEntry : emissionsConstants.getGasActuallyEmittingMap().entrySet()) {
                        Class clazz = BMainEmissionPollutionAir.class;
                        Method methodGetActually = clazz.getMethod("getActuallyEmitting" + stringStringEntry.getValue());
                        String resultActually = (String)methodGetActually.invoke(bMainEmissionPollutionAir);
                        Method methodGetAllowable = clazz.getMethod("getAllowableEmission" + stringStringEntry.getValue());
                        String resultAllowable = (String)methodGetAllowable.invoke(bMainEmissionPollutionAir);
                        if (new BigDecimal(StringUtils.isBlank(resultActually)?"0":resultActually)
                                .compareTo(new BigDecimal(StringUtils.isBlank(resultAllowable)?"0":resultAllowable)) >0) {
                            AmProblemFi amProblemFi = new AmProblemFi();
                            amProblemFi.setFactoryId(permitEmissionsFactoryVO.getFactoryId());
                            amProblemFi.setProblemSources("3");
                            amProblemFi.setProblemType("005002");
                            amProblemFi.setCreateTime(new Date());
                            amProblemFi.setProblemStartTime(date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
                            amProblemFi.setProblemDetails(permitEmissionsFactoryVO.getFactoryName()+":发生排放量超标报警，报警因子："+stringStringEntry.getKey()+","+"排污许可值为："+(StringUtils.isBlank(resultAllowable)?"0":resultAllowable)+",实际排放为："+resultActually);
                            amProblemFiList.add(amProblemFi);
                        }
                    }
                }
            }
        }
        if (amProblemFiList.size()>0) {
            amProblemFiService.saveBatch(amProblemFiList);
        }
    }
    /**
     * 废水排放量超标
     */
    @Override
    public void doWaterDischargeExceeded() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        //获取全部排污许可期限内的企业
        List<PermitEmissionsFactoryVO> permitEmissionsFactoryVOS;
        //查询所有排口信息
        Map<String ,List<PcOutlet>> pcOutletMap = new ConcurrentHashMap<>();
        //初始化排污许可企业数据，规定排口容器的长度
        permitEmissionsFactoryVOS= factoryMapper.selectPermitEmissionsFactoryList();
        if(permitEmissionsFactoryVOS == null && permitEmissionsFactoryVOS.size() == 0){
            log.info("没有查询到企业，终止任务");
        }
        LocalDateTime date = LocalDateTime.now();
        List<AmProblemFi> amProblemFiList = new ArrayList<>();
        for (PermitEmissionsFactoryVO permitEmissionsFactoryVO : permitEmissionsFactoryVOS) {
            List<BMainEmissionPollutionWater> bMainEmissionPollutionWaters = bMainEmissionPollutionWaterMapper.selectList(new LambdaQueryWrapper<BMainEmissionPollutionWater>()
                    .eq(BMainEmissionPollutionWater::getPollYear, String.valueOf(date.getYear()))
                    .eq(BMainEmissionPollutionWater::getFactoryId, permitEmissionsFactoryVO.getFactoryId()));
            if (bMainEmissionPollutionWaters!= null) {
                for (BMainEmissionPollutionWater bMainEmissionPollutionWater : bMainEmissionPollutionWaters) {
                    for (Map.Entry<String, String> stringStringEntry : emissionsConstants.getWaterActuallyEmittingMap().entrySet()) {
                        Class<BMainEmissionPollutionWater> bMainEmissionPollutionWaterClass = BMainEmissionPollutionWater.class;
                        Method methodActually = bMainEmissionPollutionWaterClass.getMethod("getActuallyEmitting" + stringStringEntry.getValue());
                        Method methodAllowable = bMainEmissionPollutionWaterClass.getMethod("getAllowableEmission" + stringStringEntry.getValue());
                        String resultActually = (String)methodActually.invoke(bMainEmissionPollutionWater);
                        String resultAllowable = (String)methodAllowable.invoke(bMainEmissionPollutionWater);
                        if (new BigDecimal(StringUtils.isBlank(resultActually)?"0":resultActually)
                                .compareTo(new BigDecimal(StringUtils.isBlank(resultAllowable)?"0":resultAllowable)) >0) {
                            AmProblemFi amProblemFi = new AmProblemFi();
                            amProblemFi.setFactoryId(permitEmissionsFactoryVO.getFactoryId());
                            amProblemFi.setProblemSources("3");
                            amProblemFi.setProblemType("005002");
                            amProblemFi.setCreateTime(new Date());
                            amProblemFi.setProblemStartTime(date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
                            amProblemFi.setProblemDetails(permitEmissionsFactoryVO.getFactoryName()+":发生排放量超标报警，报警因子："+stringStringEntry.getKey()+","+"排污许可值为："+(StringUtils.isBlank(resultActually)?"0":resultActually)+",实际排放为："+resultActually);
                            amProblemFiList.add(amProblemFi);
                        }
                    }
                }
            }
        }
        if (amProblemFiList.size()>0) {
            amProblemFiService.saveBatch(amProblemFiList);
        }
    }
    /**
     * 废气排放量预警
     */
    @Override
    public void doGasDischargeAlarm() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        //获取全部排污许可期限内的企业
        List<PermitEmissionsFactoryVO> permitEmissionsFactoryVOS;
        //查询所有排口信息
        Map<String ,List<PcOutlet>> pcOutletMap = new ConcurrentHashMap<>();
        //初始化排污许可企业数据，规定排口容器的长度
        permitEmissionsFactoryVOS= factoryMapper.selectPermitEmissionsFactoryList();
        if(permitEmissionsFactoryVOS == null && permitEmissionsFactoryVOS.size() == 0){
            log.info("没有查询到企业，终止任务");
        }
        LocalDateTime date = LocalDateTime.now();
        int intervalMonth = date.getMonthValue() - date.getMonth().firstMonthOfQuarter().getValue();
        String dateSeason = date.format(DateTimeFormatter.ofPattern("yyyy-MM-01 00:00:00"));
        if(intervalMonth > 0){
            dateSeason = date.minusMonths(intervalMonth).format(DateTimeFormatter.ofPattern("yyyy-MM-01 00:00:00"));
        }
        List<AmProblemFi> amProblemFiList = new ArrayList<>();
        for (PermitEmissionsFactoryVO permitEmissionsFactoryVO : permitEmissionsFactoryVOS) {
            List<BMainEmissionPollutionAir> bMainEmissionPollutionAirs = bMainEmissionPollutionAirMapper.selectList(new LambdaQueryWrapper<BMainEmissionPollutionAir>()
                    .eq(BMainEmissionPollutionAir::getPollYear, String.valueOf(date.getYear()))
                    .eq(BMainEmissionPollutionAir::getFactoryId, permitEmissionsFactoryVO.getFactoryId()));
            if (bMainEmissionPollutionAirs!= null && bMainEmissionPollutionAirs.size()>0) {
                BMainEmissionPollutionAir bMainEmissionPollutionAir = bMainEmissionPollutionAirs.get(0);
                //获取当月累计排放 和 当季累计排放
                List<MonthTotalEmissionsVO> listMonth = sRaOnlineEmissionsGasMapper.selectMonthTotalData(permitEmissionsFactoryVO.getFactoryId(),date.format(DateTimeFormatter.ofPattern("yyyy-MM-01 00:00:00")),1);
                List<MonthTotalEmissionsVO> listSeason = sRaOnlineEmissionsGasMapper.selectMonthTotalData(permitEmissionsFactoryVO.getFactoryId(),dateSeason,2);
                listMonth.addAll(listSeason);
                if (listMonth != null && listMonth.size() > 0) {
                    for (MonthTotalEmissionsVO monthTotalEmissionsVO : listMonth) {
                        BigDecimal rateEmissions = new BigDecimal(monthTotalEmissionsVO.getTotalEmissions());
                        String methodName = emissionsConstants.getGasPollutants().get(monthTotalEmissionsVO.getPollutantName());
                        if(StringUtils.isNotBlank(methodName)){
                            Class<BMainEmissionPollutionAir> bMainEmissionPollutionAirClass = BMainEmissionPollutionAir.class;
                            Method methodGet = bMainEmissionPollutionAirClass.getMethod("getAllowableEmission" + methodName);
                            String result = (String)methodGet.invoke(bMainEmissionPollutionAir);
                            String alarmDateType = "月度";
                            BigDecimal mathType = new BigDecimal(12);
                            if(monthTotalEmissionsVO.getSelectType() == 2){
                                mathType = new BigDecimal(4);
                                alarmDateType = "季度";
                            }
                            BigDecimal allowableEmissionResult = new BigDecimal(result).divide(mathType, 2, RoundingMode.HALF_DOWN);
                            if(allowableEmissionResult.compareTo(new BigDecimal(0)) <=0){
                                log.info("{} 因子的数值为0，停止计算",methodName);
                                continue;
                            }
                            rateEmissions = rateEmissions.divide(allowableEmissionResult, 2, RoundingMode.HALF_DOWN).multiply(BigDecimal.valueOf(100));
                            if(rateEmissions.compareTo(BigDecimal.valueOf(90))>0){
                                AmProblemFi amProblemFi = new AmProblemFi();
                                amProblemFi.setFactoryId(permitEmissionsFactoryVO.getFactoryId());
                                amProblemFi.setProblemSources("3");
                                amProblemFi.setProblemType("005002");
                                amProblemFi.setCreateTime(new Date());
                                amProblemFi.setProblemStartTime(date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
                                amProblemFi.setProblemDetails(permitEmissionsFactoryVO.getFactoryName()+":产生"+alarmDateType+"排放总量预警，预警因子："+methodName+","+"排污许可值为："+allowableEmissionResult+",实际排放为："+rateEmissions);
                                amProblemFiList.add(amProblemFi);
                            }
                        }
                    }
                }
            }
        }
        if(amProblemFiList.size()>0){
            amProblemFiService.saveBatch(amProblemFiList);
        }
    }
    /**
     * 废水排放量预警
     */
    @Override
    public void doWaterDischargeAlarm() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        //获取全部排污许可期限内的企业
        List<PermitEmissionsFactoryVO> permitEmissionsFactoryVOS;
        //初始化排污许可企业数据，规定排口容器的长度
        permitEmissionsFactoryVOS= factoryMapper.selectPermitEmissionsFactoryList();
        if(permitEmissionsFactoryVOS == null && permitEmissionsFactoryVOS.size() == 0){
            log.info("没有查询到企业，终止任务");
        }
        LocalDateTime date = LocalDateTime.now();
        int intervalMonth = date.getMonthValue() - date.getMonth().firstMonthOfQuarter().getValue();
        String dateSeason = date.format(DateTimeFormatter.ofPattern("yyyy-MM-01 00:00:00"));
        if(intervalMonth > 0){
            dateSeason = date.minusMonths(intervalMonth).format(DateTimeFormatter.ofPattern("yyyy-MM-01 00:00:00"));
        }
        List<AmProblemFi> amProblemFiList = new ArrayList<>();
        for (PermitEmissionsFactoryVO permitEmissionsFactoryVO : permitEmissionsFactoryVOS) {
            List<BMainEmissionPollutionWater> bMainEmissionPollutionWaters = bMainEmissionPollutionWaterMapper.selectList(new LambdaQueryWrapper<BMainEmissionPollutionWater>()
                    .eq(BMainEmissionPollutionWater::getPollYear, String.valueOf(date.getYear()))
                    .eq(BMainEmissionPollutionWater::getFactoryId, permitEmissionsFactoryVO.getFactoryId()));
            if (bMainEmissionPollutionWaters!= null) {
                BMainEmissionPollutionWater bMainEmissionPollutionWater = bMainEmissionPollutionWaters.get(0);
                //获取当月累计排放 和 当季累计排放
                List<MonthTotalEmissionsVO> listMonth = sRaOnlineEmissionsWaterMapper.selectMonthTotalData(permitEmissionsFactoryVO.getFactoryId(),date.format(DateTimeFormatter.ofPattern("yyyy-MM-01 00:00:00")),1);
                List<MonthTotalEmissionsVO> listSeason = sRaOnlineEmissionsWaterMapper.selectMonthTotalData(permitEmissionsFactoryVO.getFactoryId(),dateSeason,2);
                listMonth.addAll(listSeason);
                if (listMonth != null && listMonth.size() > 0) {
                    for (MonthTotalEmissionsVO monthTotalEmissionsVO : listMonth) {
                        BigDecimal rateEmissions = new BigDecimal(monthTotalEmissionsVO.getTotalEmissions());
                        String methodName = emissionsConstants.getWaterActuallyEmittingMap().get(monthTotalEmissionsVO.getPollutantName());
                        if(StringUtils.isNotBlank(methodName)){
                            Class<BMainEmissionPollutionWater> bMainEmissionPollutionWaterClass = BMainEmissionPollutionWater.class;
                            Method methodGet = bMainEmissionPollutionWaterClass.getMethod("getAllowableEmission" + methodName);
                            String result = (String)methodGet.invoke(bMainEmissionPollutionWater);
                            String alarmDateType = "月度";
                            BigDecimal mathType = new BigDecimal(12);
                            if(monthTotalEmissionsVO.getSelectType() == 2){
                                mathType = new BigDecimal(4);
                                alarmDateType = "季度";
                            }
                            BigDecimal allowableEmissionResult = new BigDecimal(StringUtils.isBlank(result)?"0":result).divide(mathType, 2, RoundingMode.HALF_DOWN);
                            if(allowableEmissionResult.compareTo(new BigDecimal(0)) <= 0){
                                log.info("{}因子的值为0，停止计算",methodName);
                                continue;
                            }
                            rateEmissions = rateEmissions.divide(allowableEmissionResult, 2, RoundingMode.HALF_DOWN).multiply(BigDecimal.valueOf(100));
                            if(rateEmissions.compareTo(BigDecimal.valueOf(90))>0){
                                AmProblemFi amProblemFi = new AmProblemFi();
                                amProblemFi.setFactoryId(permitEmissionsFactoryVO.getFactoryId());
                                amProblemFi.setProblemSources("3");
                                amProblemFi.setProblemType("005002");
                                amProblemFi.setCreateTime(new Date());
                                amProblemFi.setProblemStartTime(date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
                                amProblemFi.setProblemDetails(permitEmissionsFactoryVO.getFactoryName()+":产生"+alarmDateType+"排放总量预警，预警因子："+methodName+","+"排污许可值为："+allowableEmissionResult+",实际排放为："+rateEmissions);
                                amProblemFiList.add(amProblemFi);
                            }
                        }
                    }
                }
            }
        }
        if(amProblemFiList.size()>0){
            amProblemFiService.saveBatch(amProblemFiList);
        }
    }

    @Override
    public void doProcessGasStationDataFlag() {
        long start = System.currentTimeMillis();
        log.info("空气监测停产标记开始##");
        List<SEnvGasMonHour> list = new ArrayList<>();

        Date curr = new Date();
        Date lastHourBegin = DateUtils.parseFormatDate("yyyy-MM-dd HH:00:00", DateUtils.addDateHours(curr,-1));
        Date lastHourEnd = DateUtils.parseFormatDate("yyyy-MM-dd HH:59:59",DateUtils.addDateHours(curr,-1));
        Date minHour = DateUtils.parseFormatDate("yyyy-MM-dd HH:00:00",DateUtils.addDateHours(curr,-720));


        QueryWrapper<OdsOnlineOlStopinfoA> stopinfoQueryWrapper = new QueryWrapper<>();
        stopinfoQueryWrapper.le("start_time_format",lastHourBegin);
        stopinfoQueryWrapper.gt("end_time_format",lastHourBegin);
        stopinfoQueryWrapper.eq("enable","1");
        List<OdsOnlineOlStopinfoA> stopList = odsOnlineOlStopinfoAService.list(stopinfoQueryWrapper);
        log.info("空气监测停产标记停产记录："+stopList.size());
        if(stopList!=null&&stopList.size()>0){
            stopList.forEach(real ->{
                // 停产标记
                String dataFlag = StopTypeEnum.getNameByCode(real.getDcsType());
                List<PcOutlet> gasStationList = pcOutletMapper.selectEnableList(real.getFactoryId(),"1",real.getPortName());
                log.info("空气监测停产标记站点数量："+gasStationList.size()+"站点名称:"+real.getPortName());
                gasStationList.forEach(s ->{
                    QueryWrapper<SEnvGasMonHour> gasQueryWrapper = new QueryWrapper<>();
                    gasQueryWrapper.eq("factory_id",s.getFactoryId());
                    gasQueryWrapper.eq("outlet_id",s.getId());
                    gasQueryWrapper.eq("data_type","H");
                    gasQueryWrapper.eq("monitoring_time",DateUtils.parseDateToStr("yyyy-MM-dd HH:00:00",lastHourBegin));
                    List<SEnvGasMonHour> gasRealHourList = isEnvGasMonHourService.list(gasQueryWrapper);
                    log.info("空气监测停产标记站点小时数量："+gasRealHourList.size()+"站点ID："+s.getId());
                    if(gasRealHourList!=null&&gasRealHourList.size()>0) {
                        gasRealHourList.forEach(h -> {
                            h.setDataFlag(dataFlag);
                            list.add(h);
                        });
                    }

                    UpdateWrapper<SEnvGasMonReal> updateWrapper = new UpdateWrapper<>();
                    updateWrapper.eq("factory_id",s.getFactoryId());
                    updateWrapper.eq("outlet_id",s.getId());
                    updateWrapper.eq("data_type","M");
                    if(lastHourBegin.getTime()>real.getStartTime().getTime()) {
                        if(lastHourEnd.getTime()>real.getEndTime().getTime()) {
                            updateWrapper.between("monitoring_time", DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:00",lastHourBegin), DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:00",real.getEndTime()));
                        }else{
                            updateWrapper.between("monitoring_time", DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:00",lastHourBegin), DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:00",lastHourEnd));
                        }
                    }else{
                        if(lastHourEnd.getTime()>real.getEndTime().getTime()) {
                            updateWrapper.between("monitoring_time", DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:00",real.getStartTime()), DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:00",real.getEndTime()));
                        }else{
                            updateWrapper.between("monitoring_time", DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:00",real.getStartTime()), DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:00",lastHourEnd));
                        }
                    }
                    updateWrapper.set("data_flag",dataFlag);
                    isEnvGasMonRealService.update(updateWrapper);

                });
            });
        }

        if(list!=null&&list.size()>0){
            List<List<SEnvGasMonHour>> part = ListUtil.partition(list, 2000);
            part.forEach(i->{
                isEnvGasMonHourService.saveOrUpdateBatch(i);
            });
        }

        List<SEnvGasMonHour> flagList = new ArrayList<>();
        List<SEnvGasMonHour> gasHourList = isEnvGasMonHourService.selectLastHourData("1",DateUtils.parseDateToStr("yyyy-MM-dd HH:00:00",lastHourBegin));
        log.info("小时数据数量:"+gasHourList.size()+"日期:"+DateUtils.parseDateToStr("yyyy-MM-dd HH:00:00",lastHourBegin));
        if (gasHourList != null && gasHourList.size() > 0) {
            gasHourList.forEach(h -> {
                String so2Flag = WhiteListTypeEnum.getNameByCode(h.getSo2Flag());
                String noxflag = WhiteListTypeEnum.getNameByCode(h.getNoxFlag());
                String smokeflag = WhiteListTypeEnum.getNameByCode(h.getSmokeDustFlag());

                QueryWrapper<SEnvGasMonHour> maxQueryWrapper = new QueryWrapper<>();
                maxQueryWrapper.select("round(max(cast(so2_emission as decimal)),2) as so2_emission,round(max(cast(nox_emission as decimal)),2) as nox_emission,round(max(cast(smoke_dust_emission as decimal)),2) as smoke_dust_emission");
                maxQueryWrapper.eq("factory_id", h.getFactoryId());
                maxQueryWrapper.eq("outlet_id", h.getOutletId());
                maxQueryWrapper.eq("data_type", "H");
                maxQueryWrapper.ge("monitoring_time", minHour);
                maxQueryWrapper.lt("monitoring_time", lastHourBegin);
                SEnvGasMonHour maxHourData = isEnvGasMonHourService.getOne(maxQueryWrapper);
                log.info("720小时最大排放量:"+JSONObject.toJSONString(maxHourData));
                String so2Invalid = InvalidStateEnum.getNameByCode(h.getSo2Flag());
                // 无效时段数据，取前720小时内最大值，作为修约排放量，上限最大值1000kg
                if(StringUtils.isNotEmpty(so2Invalid)){
                    if(maxHourData!=null&&maxHourData.getSo2Emission()!=null){
                        if(Double.valueOf(maxHourData.getSo2Emission())>Double.valueOf(1000)){
                            h.setSo2CorrectEmission("1000");
                        }else {
                            h.setSo2CorrectEmission(maxHourData.getSo2Emission());
                        }
                    }
                }

                String noxInvalid = InvalidStateEnum.getNameByCode(h.getNoxFlag());
                // 无效时段数据，取前720小时内最大值，作为修约排放量，上限最大值1000kg
                if(StringUtils.isNotEmpty(noxInvalid)){
                    if(maxHourData!=null&&maxHourData.getNoxEmission()!=null){
                        if(Double.valueOf(maxHourData.getNoxEmission())>Double.valueOf(1500)){
                            h.setNoxCorrectEmission("1500");
                        }else {
                            h.setNoxCorrectEmission(maxHourData.getNoxEmission());
                        }
                    }
                }

                String smokeInvalid = InvalidStateEnum.getNameByCode(h.getSmokeDustFlag());
                // 无效时段数据，取前720小时内最大值，作为修约排放量，上限最大值1000kg
                if(StringUtils.isNotEmpty(smokeInvalid)){
                    if(maxHourData!=null&&maxHourData.getSmokeDustEmission()!=null){
                        if(Double.valueOf(maxHourData.getSmokeDustEmission())>Double.valueOf(300)){
                            h.setSmokeDustCorrectEmission("300");
                        }else {
                            h.setSmokeDustCorrectEmission(maxHourData.getSmokeDustEmission());
                        }
                    }
                }
                if(StringUtils.isNotEmpty(so2Invalid)||StringUtils.isNotEmpty(smokeInvalid)||StringUtils.isNotEmpty(noxInvalid)) {
                    flagList.add(h);
                }
            });
        }

        if(flagList!=null&&flagList.size()>0){
            List<List<SEnvGasMonHour>> part = ListUtil.partition(flagList, 2000);
            part.forEach(i->{
                isEnvGasMonHourService.saveOrUpdateBatch(i);
            });
        }

        long end = System.currentTimeMillis();
        log.info("空气监测停产标记结束##耗时:"+(end-start)+"毫秒");
    }


    @Override
    public void doProcessWaterStationDataFlag() {
        List<SEnvWaterMonHour> list = new ArrayList<>();

        Date curr = new Date();
        Date lastDayBegin = DateUtils.parseFormatDate("yyyy-MM-dd 00:00:00",DateUtils.addDateDays(curr,-1));
        Date lastDayEnd = DateUtils.parseFormatDate("yyyy-MM-dd 23:59:59",DateUtils.addDateDays(curr,-1));

        List<String> hList = DateUtils.getRangeTimes("H",DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss",lastDayBegin),DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss",lastDayEnd));
        hList.forEach(lastHour->{
            Date lastHourDate = DateUtils.parseDate(lastHour);
            Date lastHourEnd = DateUtils.parseFormatDate("yyyy-MM-dd HH:59:59",lastHourDate);
            QueryWrapper<OdsOnlineOlStopinfoA> stopinfoQueryWrapper = new QueryWrapper<>();
            stopinfoQueryWrapper.le("start_time_format",lastHourDate);
            stopinfoQueryWrapper.gt("end_time_format",lastHourDate);
            stopinfoQueryWrapper.eq("enable","1");
            List<OdsOnlineOlStopinfoA> stopList = odsOnlineOlStopinfoAService.list(stopinfoQueryWrapper);
            log.info("废水监测停产标记停产记录："+stopList.size());
            if(stopList!=null&&stopList.size()>0){
                stopList.forEach(real ->{

                    // 停产标记
                    String dataFlag = StopTypeEnum.getNameByCode(real.getDcsType());
                    List<PcOutlet> stationList = pcOutletMapper.selectEnableList(real.getFactoryId(),"2",real.getPortName());
                    stationList.forEach(s ->{
                        QueryWrapper<SEnvWaterMonHour> waterQueryWrapper = new QueryWrapper<>();
                        waterQueryWrapper.eq("factory_id",s.getFactoryId());
                        waterQueryWrapper.eq("outlet_id",s.getId());
                        waterQueryWrapper.eq("data_type","H");
                        waterQueryWrapper.eq("monitoring_time",lastHourDate);

                        List<SEnvWaterMonHour> gasRealHourList = isEnvWaterMonHourService.list(waterQueryWrapper);
                        if(gasRealHourList!=null&&gasRealHourList.size()>0) {
                            gasRealHourList.forEach(h -> {
                                h.setDataFlag(dataFlag);
                                list.add(h);
                            });
                        }

                        UpdateWrapper<SEnvWaterMonReal> updateWrapper = new UpdateWrapper<>();
                        updateWrapper.eq("factory_id",s.getFactoryId());
                        updateWrapper.eq("outlet_id",s.getId());
                        updateWrapper.eq("data_type","M");
                        if(lastHourDate.getTime()>real.getStartTime().getTime()) {
                            if(lastHourEnd.getTime()>real.getEndTime().getTime()) {
                                updateWrapper.between("monitoring_time", lastHourDate, real.getEndTime());
                            }else{
                                updateWrapper.between("monitoring_time", lastHourDate, lastHourEnd);
                            }
                        }else{
                            if(lastHourEnd.getTime()>real.getEndTime().getTime()) {
                                updateWrapper.between("monitoring_time", real.getStartTime(), real.getEndTime());
                            }else{
                                updateWrapper.between("monitoring_time", real.getStartTime(), lastHourEnd);
                            }
                        }
                        updateWrapper.set("data_flag",dataFlag);
                        isEnvWaterMonRealService.update(updateWrapper);

                    });

                });
            }
        });

        if(list!=null&&list.size()>0){
            List<List<SEnvWaterMonHour>> part = ListUtil.partition(list, 2000);
            part.forEach(i-> {
                isEnvWaterMonHourService.saveOrUpdateBatch(i);
            });
        }

        List<SEnvWaterMonHour> flagList = new ArrayList<>();
        List<SEnvWaterMonHour> gasHourList = isEnvWaterMonHourService.selectLastDayData("2",lastDayBegin,lastDayEnd);
        if (gasHourList != null && gasHourList.size() > 0) {
            gasHourList.forEach(h -> {

                Date minHour = DateUtils.parseFormatDate("yyyy-MM-dd 00:00:00",DateUtils.addDateDays(h.getDateTime(),-30));
                String codFlag = WhiteListTypeEnum.getNameByCode(h.getCodFlag());
                String aFlag = WhiteListTypeEnum.getNameByCode(h.getAmmoniaNitrogenFlag());
                String pFlag = WhiteListTypeEnum.getNameByCode(h.getPhosphorusConcentrationFlag());
                String nFlag = WhiteListTypeEnum.getNameByCode(h.getNitrogenConcentrationFlag());

                QueryWrapper<SEnvWaterMonDay> maxQueryWrapper = new QueryWrapper<>();
                maxQueryWrapper.select("round(max(cast(cod_emission as decimal)),2) as cod_emission,round(max(cast(ammonia_nitrogen_emission as decimal)),2) as ammonia_nitrogen_emission,round(max(cast(nitrogen_concentration_emission as decimal)),2) as nitrogen_concentration_emission,round(max(cast(phosphorus_concentration_emission as decimal)),2) as phosphorus_concentration_emission");
                maxQueryWrapper.eq("factory_id", h.getFactoryId());
                maxQueryWrapper.eq("outlet_id", h.getOutletId());
                maxQueryWrapper.eq("data_type", "D");
                maxQueryWrapper.ge("monitoring_time", minHour);
                maxQueryWrapper.lt("monitoring_time", h.getMonitoringTime());
                SEnvWaterMonDay codMax = isEnvWaterMonDayService.getOne(maxQueryWrapper);

                String codInvalid = InvalidStateEnum.getNameByCode(h.getCodFlag());
                // 无效时段数据，取前720小时内最大值，作为修约排放量，上限最大值1000kg
                if(StringUtils.isNotEmpty(codInvalid)){
                    if(codMax!=null&&codMax.getCodEmission()!=null){
                        h.setCodCorrectEmission(codMax.getCodEmission());
                    }
                }
                String ammInvalid = InvalidStateEnum.getNameByCode(h.getAmmoniaNitrogenFlag());
                // 无效时段数据，取前720小时内最大值，作为修约排放量，上限最大值1000kg
                if(StringUtils.isNotEmpty(ammInvalid)){
                    if(codMax!=null&&codMax.getAmmoniaNitrogenEmission()!=null){
                        h.setAmmoniaCorrectEmission(codMax.getAmmoniaNitrogenEmission());
                    }
                }
                String nitInvalid = InvalidStateEnum.getNameByCode(h.getNitrogenConcentrationFlag());
                // 无效时段数据，取前720小时内最大值，作为修约排放量，上限最大值1000kg
                if(StringUtils.isNotEmpty(nitInvalid)){
                    if(codMax!=null&&codMax.getNitrogenConcentrationEmission()!=null){
                        h.setNitrogenCorrectEmission(codMax.getNitrogenConcentrationEmission());
                    }
                }
                String phInvalid = InvalidStateEnum.getNameByCode(h.getPhosphorusConcentrationFlag());
                // 无效时段数据，取前720小时内最大值，作为修约排放量，上限最大值1000kg
                if(StringUtils.isNotEmpty(phInvalid)){
                    if(codMax!=null&&codMax.getPhosphorusConcentrationEmission()!=null){
                        h.setPhosphorusCorrectEmission(codMax.getPhosphorusConcentrationEmission());
                    }
                }

                flagList.add(h);
            });
        }
        if(flagList!=null&&flagList.size()>0){
            List<List<SEnvWaterMonHour>> part = ListUtil.partition(flagList, 2000);
            part.forEach(i-> {
                isEnvWaterMonHourService.saveOrUpdateBatch(i);
            });
        }

    }

    @Override
    public void doProcessHourPollutantConcentration() {
        long st = System.currentTimeMillis();
        log.info("废气污染物连续8小时处于标准值20%定时任务开始");
        String str = "(\\d+\\.\\d+)";
        Pattern r = Pattern.compile(str);

        List<AmProblemFi> problemList = new ArrayList<>();

        Date curr = new Date();
        Date lastHourBegin = DateUtils.parseFormatDate("yyyy-MM-dd HH:00:00",DateUtils.addDateHours(curr,-9));
        QueryWrapper<PcOutlet> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("pollutant_type","4");
        queryWrapper.eq("pollutant_outlet_type","1");
        queryWrapper.eq("is_status","1");
        List<PcOutlet> gasStationList = pcOutletMapper.selectList(queryWrapper);
        if(gasStationList!=null&&gasStationList.size()>0){
            gasStationList.forEach(h->{

                QueryWrapper<PcControlRequirements> controlQueryWrapper = new QueryWrapper<>();
                controlQueryWrapper.eq("factory_id",h.getFactoryId());
                controlQueryWrapper.eq("outlet_id",h.getId());
                controlQueryWrapper.notIn("permissible_concentration_lim_hour","/");
                controlQueryWrapper.isNotNull("permissible_concentration_lim_hour");
                List<PcControlRequirements> cList = pcControlRequirementsService.list(controlQueryWrapper);
                if(cList!=null&&cList.size()>0){
                    cList.forEach(t->{
                        Matcher m = r.matcher(t.getPermissibleConcentrationLimHour());
                        if(m.matches()) {
                            try {
                                Double d = Double.valueOf(t.getPermissibleConcentrationLimHour());
                                BigDecimal minValue = new BigDecimal(0.2).multiply(new BigDecimal(d));
                                String param = emissionsConstants.getGasPollutants().get(t.getPollutantId());
                                if(StringUtils.isNotEmpty(param)) {
                                    QueryWrapper<SEnvGasMonHour> gasQueryWrapper = new QueryWrapper<>();
                                    gasQueryWrapper.eq("factory_id", t.getFactoryId());
                                    gasQueryWrapper.eq("outlet_id", t.getOutletId());
                                    gasQueryWrapper.eq("data_type", "H");
                                    gasQueryWrapper.ge("date_time", lastHourBegin);
                                    gasQueryWrapper.lt(param.toLowerCase(), minValue);
                                    List<SEnvGasMonHour> gasHourList = isEnvGasMonHourService.list(gasQueryWrapper);
                                    // 连续8小时低于，排放浓度20%
                                    if (gasHourList != null && gasHourList.size() >= 8) {
                                        StringBuffer sb = new StringBuffer();
                                        sb.append(h.getStationName()).append("污染物").append(param).append("连续8小时处于标准值").append(d).append("的20%以下，请及时排查。");
                                        AmProblemFi problemFi = new AmProblemFi();
                                        problemFi.setFactoryId(t.getFactoryId());
                                        problemFi.setProblemSources("1");
                                        problemFi.setProblemType(ProblemTypeEnum.STABLE_LOW.getCode());
                                        problemFi.setCreateTime(new Date());
                                        problemFi.setStationId(h.getStationId());
                                        problemFi.setStationName(h.getStationName());
                                        problemFi.setParamProperty(param);
                                        problemFi.setType(0);
                                        problemFi.setProblemDetails(sb.toString());
                                        problemList.add(problemFi);
                                    }
                                }
                            } catch (NumberFormatException e) {
                                log.error("查询异常");
                            }
                        }
                    });
                }
            });
        }
        if(problemList!=null&&problemList.size()>0){
            List<List<AmProblemFi>> part = ListUtil.partition(problemList, 2000);
            part.forEach(i->{
                amProblemFiService.saveBatch(i);
            });
            problemList.clear();
        }
        long end = System.currentTimeMillis();
        log.info("废气污染物连续8小时处于标准值20%定时任务结束-耗时:"+(end-st)+"毫秒");

        log.info("废气污染物连续8小时处于标准值20%定时任务开始");
        long waterSt = System.currentTimeMillis();
        QueryWrapper<PcOutlet> waterQueryWrapper = new QueryWrapper<>();
        waterQueryWrapper.eq("pollutant_type","4");
        waterQueryWrapper.eq("pollutant_outlet_type","2");
        waterQueryWrapper.eq("is_status","1");
        List<PcOutlet> waterStationList = pcOutletMapper.selectList(waterQueryWrapper);
        if(waterStationList!=null&&waterStationList.size()>0){
            waterStationList.forEach(w->{
                QueryWrapper<PcControlRequirements> controlQueryWrapper = new QueryWrapper<>();
                controlQueryWrapper.eq("factory_id",w.getFactoryId());
                controlQueryWrapper.eq("outlet_id",w.getId());
                controlQueryWrapper.notIn("permissible_concentration_lim_hour","/");
                controlQueryWrapper.isNotNull("permissible_concentration_lim_hour");
                List<PcControlRequirements> cList = pcControlRequirementsService.list(controlQueryWrapper);
                if(cList!=null&&cList.size()>0){
                    cList.forEach(t->{
                        Matcher m = r.matcher(t.getPermissibleConcentrationLimHour());
                        if(m.matches()) {
                            try {
                                Double d = Double.valueOf(t.getPermissibleConcentrationLimHour());
                                BigDecimal minValue = new BigDecimal(0.2).multiply(new BigDecimal(d));
                                String param = emissionsConstants.getWaterPollutants().get(t.getPollutantId());
                                if(StringUtils.isNotEmpty(param)) {
                                    QueryWrapper<SEnvWaterMonReal> gasQueryWrapper = new QueryWrapper<>();
                                    gasQueryWrapper.eq("factory_id", t.getFactoryId());
                                    gasQueryWrapper.eq("outlet_id", t.getOutletId());
                                    gasQueryWrapper.eq("data_type", "H");
                                    gasQueryWrapper.ge("date_time", lastHourBegin);
                                    gasQueryWrapper.lt(param.toLowerCase(), minValue);
                                    List<SEnvWaterMonReal> waterHourList = isEnvWaterMonRealService.list(gasQueryWrapper);
                                    // 连续8小时低于，排放浓度20%
                                    if (waterHourList != null && waterHourList.size() >= 8) {
                                        StringBuffer sb = new StringBuffer();
                                        sb.append(w.getStationName()).append("污染物").append(param).append("连续8小时处于标准值").append(d).append("的20%以下，请及时排查。");
                                        AmProblemFi problemFi = new AmProblemFi();
                                        problemFi.setFactoryId(t.getFactoryId());
                                        problemFi.setProblemSources("1");
                                        problemFi.setProblemType(ProblemTypeEnum.STABLE_LOW.getCode());
                                        problemFi.setCreateTime(new Date());
                                        problemFi.setStationId(w.getStationId());
                                        problemFi.setStationName(w.getStationName());
                                        problemFi.setParamProperty(param);
                                        problemFi.setType(0);
                                        problemFi.setProblemDetails(sb.toString());
                                        problemList.add(problemFi);
                                    }
                                }
                            } catch (NumberFormatException e) {
                                log.error("查询异常");
                            }
                        }
                    });
                }

            });
        }

        if(problemList!=null&&problemList.size()>0){
            List<List<AmProblemFi>> part = ListUtil.partition(problemList, 2000);
            part.forEach(i->{
                amProblemFiService.saveBatch(i);
            });
        }
        long waterEnd = System.currentTimeMillis();
        log.info("废水污染物连续8小时处于标准值20%定时任务结束-耗时:"+(waterEnd-waterSt)+"毫秒");
    }
}
