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

import cn.cecep.talroad.mapper.effective.*;
import cn.cecep.talroad.service.effective.BasTargetService;
import cn.cecep.talroad.service.effective.ReportManageService;
import cn.cecep.talroad.util.effective.FieldCache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


/**
 * @author zhangshiji
 * @date 2022/9/15
 */
@Service
public class BasTargetServiceImpl implements BasTargetService {

    private static final Logger log = LoggerFactory.getLogger(BasTargetService.class);

    @Autowired
    private QEnvgasWqDayMapper qEnvgasWqDayMapper;
    @Autowired
    private QEnvgasWqMonthMapper qEnvgasWqMonthMapper;
    @Autowired
    private QEnvgasWqYearMapper qEnvgasWqYearMapper;
    @Autowired
    private QEnvgasAreaTargetMapper qEnvgasAreaTargetMapper;
    @Autowired
    private QTargetConfigMapper qTargetConfigMapper;
    @Autowired
    private PCodeIndexPollutantMapper pCodeIndexPollutantMapper;
    @Autowired
    private FieldCache fieldCache;
    @Autowired
    private ReportManageService reportManageService;
    @Autowired
    private PCodeRegionMapper pCodeRegionMapper;



/*

    @Override
    public int[] findTargetConfig(String regionCode, String factor) {
        int[] arr;
        QTargetConfig config = qTargetConfigMapper.findConfigByRegionCode(regionCode);
        if (config == null) {
            throw new BussinessException("当前因子未设置高值月份及计算数值,请先联系管理员添加配置");
        }
        if (factor.equals("pm25")) {
            arr = new int[]{config.getPm25Control(), config.getPm25Month()};
        } else if (factor.equals("pm10")) {
            arr = new int[]{config.getPm10Control(), config.getPm10Month()};
        } else if (factor.equals("so2")) {
            arr = new int[]{config.getSo2Control(), config.getSo2Month()};
        } else if (factor.equals("no2")) {
            arr = new int[]{config.getNo2Control(), config.getNo2Month()};
        } else {
            arr = new int[]{2, 6};
        }
        return arr;
    }

    @Override
    public Map<String, BigDecimal[]> fourFactorTargets(String regionCode, String factor, BigDecimal target) throws BussinessException {
        //查询近三年因子值
        Date date;
        //去年 前年 大前年
        int year;
        int i = 0;
        //三年 12月单因子数据  月份降序排序
        Map<String, BigDecimal[]> valueMap = new HashMap<>(16);
        while (i < 5) {
            date = NewDateUtil.addDateYears(new Date(), -i);
            year = getYear(date);
            //全年12月数据
            valueMap.put("arr" + i, monthListToArray(qEnvgasWqMonthMapper.selectAreaYearData(regionCode, year), factor));
            i++;
        }
        //计算月份数值同比变化率 理论上只有三个数组
        Map<String, BigDecimal[]> percentMap = new HashMap<>(16);
        for (int j = 1; j <= 3; j++) {
            BigDecimal[] percentArr = new BigDecimal[12];
            //本年数值
            BigDecimal[] arr1 = valueMap.get("arr" + j);
            //本年同期数值
            BigDecimal[] arr2 = valueMap.get("arr" + (j + 1));
            for (int c = 0; c < 12; c++) {
                percentArr[c] = BasTargetUtil.monthTongBiPercent(arr1[c], arr2[c]);
            }
            percentMap.put("percent" + j, percentArr);
        }
        //去年比前年
        BigDecimal[] percentMap1 = percentMap.get("percent1");
        //前年比大前年
        BigDecimal[] percentMap2 = percentMap.get("percent2");
        //大前年比大大前年
        BigDecimal[] percentMap3 = percentMap.get("percent3");
        //计算同比变化率均值
        BigDecimal[] percentAvg = new BigDecimal[12];
        for (int d = 0; d < 12; d++) {
            List<BigDecimal> avgValues = new ArrayList<>();
            avgValues.add(percentMap1[d]);
            avgValues.add(percentMap2[d]);
            avgValues.add(percentMap3[d]);
            //过滤空值零值
            avgValues = avgValues.stream().filter(e -> e != null && e.compareTo(BigDecimal.ZERO) != 0).collect(Collectors.toList());
            BigDecimal avg = AirDataConverseUtil.decimalAvgValue(avgValues);
            percentAvg[d] = avg == null ? BigDecimal.ZERO : avg;
        }
        //查询区域因子计算配置
        int[] config = findTargetConfig(regionCode, factor);
        BigDecimal[] finalTargets = null;
        finalTargets = calcTarget(valueMap.get("arr0"), valueMap.get("arr1"), percentAvg, config[0], config[1], target);
        Map<String, BigDecimal[]> map = new HashMap();
        map.put("targets", finalTargets);
        map.put("actuals", valueMap.get("arr0"));
        return map;
    }

    *//**
     * 计算今年目标值
     *
     * @param currentYearValues 当前年各月均值
     * @param lastYearValues    去年各月均值
     * @param avgPercents       月度同比变化率均值
     * @param control           因子最大月度控制量
     * @param controlMonth      控制月份数量
     * @return
     *//*
    @Override
    public BigDecimal[] calcTarget(BigDecimal[] currentYearValues, BigDecimal[] lastYearValues, BigDecimal[] avgPercents, int control, int controlMonth, BigDecimal targetValue) throws BussinessException {
        //实际值不包含本月
        int currentMonth = DateUtil.getCurrentMonth();
        currentYearValues[currentMonth - 1] = null;
        BigDecimal controlDecimal = new BigDecimal(control);
        BigDecimal[] targets = new BigDecimal[12];
        //存放去年不存在均值的月份值
        List<Map<String, Object>> calcMap = new ArrayList<>();
        for (int i = 0; i < 12; i++) {
            if (currentYearValues[i] != null) {
                targets[i] = currentYearValues[i];
            } else {
                //如果去年没有实际值,不计算初始目标值
                if (lastYearValues[i] == null) {
                    targets[i] = null;
                } else {
                    targets[i] = lastYearValues[i].subtract(lastYearValues[i].multiply(avgPercents[i])).setScale(0, BigDecimal.ROUND_HALF_EVEN);
                }
                Map<String, Object> calcObj = new HashMap<>();
                calcObj.put("month", i);
                calcObj.put("value", targets[i]);
                calcMap.add(calcObj);
            }
        }
        calcMap = arrayToSortList(calcMap);
        if (calcMap == null || calcMap.size() == 0) {
            throw new BussinessException("本区域去年全月无数值,请补充数据后重新计算");
        } else {
            if (calcMap.size() < 12) {
                throw new BussinessException("本区域去年部分因子存在空值月份,请补充数据后重新计算");
            }
        }
        //初始目标值综总和
        BigDecimal calcTargetSumValue = AirDataConverseUtil.decimalSumValue(Arrays.stream(targets).collect(Collectors.toList()));
        //设定目标值总和
        BigDecimal target = targetValue.multiply(BasTargetUtil.MONTH_LENGTH);
        //计算推算值年度差
        BigDecimal subtract = calcTargetSumValue.subtract(target);
        boolean isOver = subtract.compareTo(BigDecimal.ZERO) == 1;
        subtract = isOver ? subtract : subtract.negate();
        //分配剩余控制量至初始目标值
        List<Map<String, Object>> beforeSix;
        List<Map<String, Object>> behindSix;
        if (calcMap.size() > controlMonth) {
            beforeSix = calcMap.subList(0, controlMonth);
            behindSix = calcMap.subList(controlMonth, calcMap.size());
        } else {
            beforeSix = calcMap.subList(0, calcMap.size()) == null ? new ArrayList<>() : calcMap.subList(0, calcMap.size());
            behindSix = new ArrayList<>();
        }
        //部分月份高值控制量
        BigDecimal highValueControl = new BigDecimal(control * beforeSix.size()).setScale(0, BigDecimal.ROUND_HALF_EVEN);
        //控制量余量
        BigDecimal surplus = subtract.subtract(highValueControl).setScale(0, BigDecimal.ROUND_HALF_EVEN);
        //判断高值月份数量是否小于配置数量
        if (beforeSix.size() < controlMonth) {
            int index = 0;
            for (int i = 0; i < subtract.intValue(); i++) {
                Integer month = (Integer) beforeSix.get(index).get("month");
                //循环减1或加1
                targets[month] = isOver ? targets[month].subtract(BigDecimal.ONE) : targets[month].add(BigDecimal.ONE);
                log.info("月份" + month + ",值:" + targets[month] + ",余量:" + i);
                if (index == beforeSix.size() - 1) {
                    index = 0;
                } else {
                    index++;
                }
            }
        } else {
            if (surplus.compareTo(BigDecimal.ZERO) == 1) {
                //先给前六个月减掉
                for (Map<String, Object> before : beforeSix) {
                    Integer month = (Integer) before.get("month");
                    targets[month] = isOver ? targets[month].subtract(controlDecimal) : targets[month].add(controlDecimal);
                    log.info("月份" + month + ",值:" + targets[month]);
                }
                //已后六个月为起点 剩余值平均分配给12个月
                behindSix.addAll(beforeSix);
                int surplusInt = surplus.intValue();
                int index = 0;
                for (int i = surplusInt; i > 0; i--) {
                    Integer month = (Integer) behindSix.get(index).get("month");
                    targets[month] = isOver ? targets[month].subtract(BasTargetUtil.ONE) : targets[month].add(BasTargetUtil.ONE);
                    if (index == behindSix.size() - 1) {
                        index = 0;
                    } else {
                        index++;
                    }
                    log.info("月份" + month + ",值:" + targets[month] + ",余量:" + i);
                }
            } else {
                BigDecimal sumVal = BigDecimal.ZERO;
                //余量为负数  在高值月份少减
                for (Map<String, Object> before : beforeSix) {
                    Integer month = (Integer) before.get("month");
                    sumVal = sumVal.add(controlDecimal);
                    if (sumVal.compareTo(subtract) == 1) {
                        targets[month] = isOver ? targets[month].subtract(sumVal.divide(highValueControl)) : targets[month].add(sumVal.divide(highValueControl));
                        break;
                    } else {
                        targets[month] = isOver ? targets[month].subtract(controlDecimal) : targets[month].add(controlDecimal);
                    }
                    log.info("月份" + month + ",值:" + targets[month]);
                }
            }
        }

        return targets;
    }


    @Override
    public Map<String, BigDecimal[]> twoFactorTargets(int year, String regionCode, String factor, BigDecimal target) {
        Map<String, BigDecimal[]> map = new HashMap<>();
        BigDecimal[] actuals = monthListToArray(qEnvgasWqMonthMapper.selectAreaYearData(regionCode, year), factor);
        //实际值不包含本月
        actuals[DateUtil.getCurrentMonth() - 1] = null;
        BigDecimal[] targets = new BigDecimal[12];
        for (int i = 0; i < targets.length; i++) {
            targets[i] = actuals[i] == null ? target : actuals[i];
        }
        map.put("targets", targets);
        map.put("actuals", actuals);
        return map;
    }

    @Override
    public Map<String, BigDecimal[]> heavyDaysTargets(int year, String regionCode, String factor) {
        Map<String, BigDecimal[]> map = new HashMap<>();
        //查询今年已有的重污染天数
        List<MonthDataVo> yearHeavyDays = qEnvgasWqDayMapper.findYearHeavyDays(year, regionCode);
        //实际值
        BigDecimal[] actuals = monthListToArray(yearHeavyDays, factor);
        //实际值不包含当前月
        actuals[DateUtil.getCurrentMonth() - 1] = null;
        BigDecimal[] targets = new BigDecimal[12];
        //重污染天数目标值都为0,目标值不随实际值发生变化
        for (int i = 0; i < targets.length; i++) {
            targets[i] = BigDecimal.ZERO;
        }
        map.put("targets", targets);
        map.put("actuals", actuals);
        return map;
    }

    @Override
    public Map<String, BigDecimal[]> goodDaysTargets(int year, String regionCode, String factor, BigDecimal target) {
        //查询今年已有的优良天数
        List<MonthDataVo> goodDays = qEnvgasWqDayMapper.findYearGoodDays(year, regionCode);
        //实际值
        BigDecimal[] actuals = monthListToArray(goodDays, factor);
        //实际值不包含当前月
        actuals[DateUtil.getCurrentMonth() - 1] = null;
        //目标值
        BigDecimal[] targets = new BigDecimal[12];
        //实际值总和
        BigDecimal actualSumValue = AirDataConverseUtil.decimalSumValue(Arrays.asList(actuals).stream().filter(e -> e != null).collect(Collectors.toList()));
        if (actualSumValue == null) {
            actualSumValue = BigDecimal.ZERO;
        }
        //差值
        BigDecimal subtract = target.subtract(actualSumValue);
        BigDecimal surplus = BigDecimal.ZERO;
        BigDecimal actualSize = new BigDecimal(BasTargetUtil.INT_MONTH_LENGTH - goodDays.size());
        if (actualSize.compareTo(BigDecimal.ZERO) != 0) {
            surplus = subtract.divide(actualSize, 0, BigDecimal.ROUND_UP);
            //余量小于0时 剩余月份分配天数都为0
            if (surplus.compareTo(BigDecimal.ZERO) == -1) {
                surplus = BigDecimal.ZERO;
            }
        }
        return distribution(actuals, targets, surplus, year);
    }

    @Override
    public Map<String, BigDecimal[]> coOverDayTarget(int year, String regionCode, String factor, BigDecimal target) {
        //本年天数
        int yearDays = DateUtil.getYearDays(year);
        if (target == null) {
            //如果目标值为空,判断超标的目标值为去年的年均co数据
            AirParmaVo parmaVo = new AirParmaVo();
            parmaVo.setRegionCode(regionCode);
            parmaVo.setDatetime((year - 1) + "");
            List<AirQualityData> airQualityData = qEnvgasWqYearMapper.queryAreaYearData(parmaVo);
            if (airQualityData != null && airQualityData.size() > 0) {
                target = airQualityData.get(0).getCo();
            }
        }
        //查询实际值
        List<MonthDataVo> coOverDays = qEnvgasWqDayMapper.findYearCoOverDays(year, regionCode, target);
        BigDecimal[] actuals = monthListToArray(coOverDays, factor);
        //实际值不包含当前月
        actuals[DateUtil.getCurrentMonth() - 1] = null;
        BigDecimal[] targets = new BigDecimal[12];
        //实际值和
        BigDecimal actualSum = AirDataConverseUtil.decimalSumValue(Arrays.stream(actuals).filter(e -> e != null).collect(Collectors.toList()));
        //本年天数 * 0.95  标准超标天数
        BigDecimal standDays = new BigDecimal(DateUtil.getYearDays(year)).subtract(new BigDecimal(yearDays).multiply(BasTargetUtil.PERCENT_95).setScale(0, BigDecimal.ROUND_UP));
        //剩余天数
        BigDecimal surplus = standDays.subtract(actualSum);
        //每天剩余
        BigDecimal monthSurplus = surplus.divide(new BigDecimal(BasTargetUtil.INT_MONTH_LENGTH - coOverDays.size()), 0, BigDecimal.ROUND_UP);
        return distribution(actuals, targets, monthSurplus, year);
    }

    @Override
    public Map<String, BigDecimal[]> o3OverDayTarget(int year, String regionCode, String factor, BigDecimal target) {
        List<MonthDataVo> o38hOverDays = qEnvgasWqDayMapper.findYearO38hOverDays(year, regionCode, target);
        //实际值
        BigDecimal[] actuals = monthListToArray(o38hOverDays, factor);
        //实际值不包含当前月
        actuals[DateUtil.getCurrentMonth() - 1] = null;
        BigDecimal[] targets = new BigDecimal[12];
        //年超标天数标准值
        BigDecimal overStand = BasTargetUtil.O38HSTAND;
        //实际总和
        BigDecimal actualSum = AirDataConverseUtil.decimalSumValue(Arrays.stream(actuals).filter(e -> e != null).collect(Collectors.toList()));
        //总余量
        BigDecimal surplus = overStand.subtract(actualSum == null ? BigDecimal.ZERO : actualSum);
        //每月余量
        BigDecimal monthSurplus = surplus.divide(new BigDecimal(BasTargetUtil.INT_MONTH_LENGTH - o38hOverDays.size()), 0, BigDecimal.ROUND_UP);
        return distribution(actuals, targets, monthSurplus, year);
    }

    *//**
     * 分配余量
     *
     * @param actuals      实际值数组
     * @param targets      累计值数组
     * @param monthSurplus 月余量
     * @param year         年份
     * @return
     *//*
    public Map distribution(BigDecimal[] actuals, BigDecimal[] targets, BigDecimal monthSurplus, int year) {
        int[] days = BasTargetUtil.yearMonthDays(year);
        for (int i = 0; i < actuals.length; i++) {
            if (actuals[i] == null) {
                if (monthSurplus.compareTo(new BigDecimal(days[i])) == 1) {
                    //大于月份为本月天数
                    targets[i] = new BigDecimal(days[i]);
                } else {
                    targets[i] = monthSurplus;
                }
            } else {
                targets[i] = actuals[i];
            }
        }
        Map map = new HashMap();
        map.put("targets", targets);
        map.put("actuals", actuals);
        return map;
    }


    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = BussinessException.class)
    @Override
    public void saveYearTarget(int year, BigDecimal target, String regionCode, String factor) {
        QEnvgasAreaTarget qEnvgasAreaTarget = new QEnvgasAreaTarget();
        qEnvgasAreaTarget.setRegionCode(regionCode);
        //因子id
        qEnvgasAreaTarget.setFkFactorId(pCodeIndexPollutantMapper.findIdByColumn(factor));
        AirParmaVo airParmaVo = new AirParmaVo();
        airParmaVo.setDatetime(year + "");
        airParmaVo.setRegionCode(regionCode);
        List<AirQualityData> airQualityData = qEnvgasWqYearMapper.queryAreaYearDataNew(airParmaVo);
        //实际值
        if (!CollectionUtils.isEmpty(airQualityData)) {
            AirQualityData qualityData = airQualityData.get(0);
            if (Objects.nonNull(qualityData)) {
                qEnvgasAreaTarget.setActualValue(fieldCache.get(qualityData, factor) == null ? null : (BigDecimal) fieldCache.get(qualityData, factor));
            }
        }
        qEnvgasAreaTarget.setTimeType(3);
        qEnvgasAreaTarget.setTime(year + "");
        qEnvgasAreaTarget.setTargetValue(target);
        qEnvgasAreaTarget.setPkId(uuid());
        qEnvgasAreaTargetMapper.insert(qEnvgasAreaTarget);
    }

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = BussinessException.class)
    @Override
    public void saveMonthTarget(int year, BigDecimal[] target, BigDecimal[] actual, String regionCode, String factor) {
        List<String> monthList = yearMonthList(year);
        //绑定因子id
        Integer fkPollutantId = pCodeIndexPollutantMapper.findIdByColumn(factor);
        for (int i = 0; i < monthList.size(); i++) {
            QEnvgasAreaTarget qEnvgasAreaTarget = new QEnvgasAreaTarget();
            qEnvgasAreaTarget.setPkId(uuid());
            qEnvgasAreaTarget.setTime(monthList.get(i));
            //时间类型 2:月份
            qEnvgasAreaTarget.setTimeType(2);
            qEnvgasAreaTarget.setTargetValue(target[i]);
            qEnvgasAreaTarget.setActualValue(actual[i]);
            qEnvgasAreaTarget.setFkFactorId(fkPollutantId);
            qEnvgasAreaTarget.setRegionCode(regionCode);
            qEnvgasAreaTargetMapper.insert(qEnvgasAreaTarget);
        }
    }

    @Override
    public void saveAutumnWinterTarget(int year, BigDecimal target, int type, String regionCode, String factor) {
        QEnvgasAreaTarget qEnvgasAreaTarget = new QEnvgasAreaTarget();
        qEnvgasAreaTarget.setPkId(uuid());
        qEnvgasAreaTarget.setRegionCode(regionCode);
        qEnvgasAreaTarget.setFkFactorId(pCodeIndexPollutantMapper.findIdByColumn(factor));
        qEnvgasAreaTarget.setTargetValue(target);
        qEnvgasAreaTarget.setTime(year + "");
        qEnvgasAreaTarget.setTimeType(type);
        qEnvgasAreaTarget.setCreateTime(now());
        qEnvgasAreaTargetMapper.insert(qEnvgasAreaTarget);
    }

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    @Override
    public boolean saveAllTarget(BasTargetDto basTargetDto) {
        //删除历史目标
        qEnvgasAreaTargetMapper.deleteByRegionCode(basTargetDto.getUserRegionCode());
        //获取年份
        int year = getYear(new Date());
        Map<String, BigDecimal[]> targetMap;
        //计算PM2.5 并保存
        if (basTargetDto.getPm25Target() != null) {
            targetMap = fourFactorTargets(basTargetDto.getUserRegionCode(), BasTargetUtil.PM25, basTargetDto.getPm25Target());
            saveYearTarget(year, basTargetDto.getPm25Target(), basTargetDto.getUserRegionCode(), BasTargetUtil.PM25);
            saveMonthTarget(year, targetMap.get("targets"), targetMap.get("actuals"), basTargetDto.getUserRegionCode(), BasTargetUtil.PM25);
            //保存秋防目标
            saveAutumnWinterTarget(year, autumnWinterAvg(targetMap.get("targets")), BasTargetUtil.AUTUMN_TARGET, basTargetDto.getUserRegionCode(), BasTargetUtil.PM25);
        }
        //计算PM10 并保存
        if (basTargetDto.getPm10Target() != null) {
            targetMap = fourFactorTargets(basTargetDto.getUserRegionCode(), BasTargetUtil.PM10, basTargetDto.getPm10Target());
            saveYearTarget(year, basTargetDto.getPm10Target(), basTargetDto.getUserRegionCode(), BasTargetUtil.PM10);
            saveMonthTarget(year, targetMap.get("targets"), targetMap.get("actuals"), basTargetDto.getUserRegionCode(), BasTargetUtil.PM10);
            //保存秋防目标
            saveAutumnWinterTarget(year, autumnWinterAvg(targetMap.get("targets")), BasTargetUtil.AUTUMN_TARGET, basTargetDto.getUserRegionCode(), BasTargetUtil.PM10);
        }
        //计算SO2 并保存
        if (basTargetDto.getSo2Target() != null) {
            targetMap = fourFactorTargets(basTargetDto.getUserRegionCode(), BasTargetUtil.SO2, basTargetDto.getSo2Target());
            saveYearTarget(year, basTargetDto.getSo2Target(), basTargetDto.getUserRegionCode(), BasTargetUtil.SO2);
            saveMonthTarget(year, targetMap.get("targets"), targetMap.get("actuals"), basTargetDto.getUserRegionCode(), BasTargetUtil.SO2);
        }
        //计算NO2 并保存
        if (basTargetDto.getNo2Target() != null) {
            targetMap = fourFactorTargets(basTargetDto.getUserRegionCode(), BasTargetUtil.NO2, basTargetDto.getNo2Target());
            saveYearTarget(year, basTargetDto.getNo2Target(), basTargetDto.getUserRegionCode(), BasTargetUtil.NO2);
            saveMonthTarget(year, targetMap.get("targets"), targetMap.get("actuals"), basTargetDto.getUserRegionCode(), BasTargetUtil.NO2);
        }
        //CO
        if (basTargetDto.getCoTarget() != null) {
            targetMap = twoFactorTargets(year, basTargetDto.getUserRegionCode(), BasTargetUtil.CO, basTargetDto.getCoTarget());
            saveYearTarget(year, basTargetDto.getCoTarget(), basTargetDto.getUserRegionCode(), BasTargetUtil.CO);
            saveMonthTarget(year, targetMap.get("targets"), targetMap.get("actuals"), basTargetDto.getUserRegionCode(), BasTargetUtil.CO);
        }
        //o38h
        if (basTargetDto.getO38hTarget() != null) {
            targetMap = twoFactorTargets(year, basTargetDto.getUserRegionCode(), BasTargetUtil.O38H, basTargetDto.getO38hTarget());
            saveYearTarget(year, basTargetDto.getO38hTarget(), basTargetDto.getUserRegionCode(), BasTargetUtil.O38H);
            saveMonthTarget(year, targetMap.get("targets"), targetMap.get("actuals"), basTargetDto.getUserRegionCode(), BasTargetUtil.O38H);
        }
        //优良天
        if (basTargetDto.getGoodDaysTarget() != null) {
            targetMap = goodDaysTargets(year, basTargetDto.getUserRegionCode(), BasTargetUtil.GOODDYAS, basTargetDto.getGoodDaysTarget());
            saveYearTarget(year, basTargetDto.getGoodDaysTarget(), basTargetDto.getUserRegionCode(), BasTargetUtil.GOODDYAS);
            saveMonthTarget(year, targetMap.get("targets"), targetMap.get("actuals"), basTargetDto.getUserRegionCode(), BasTargetUtil.GOODDYAS);
            //保存秋防目标
            saveAutumnWinterTarget(year, autumnWinterSum(targetMap.get("targets")), BasTargetUtil.AUTUMN_TARGET, basTargetDto.getUserRegionCode(), BasTargetUtil.GOODDYAS);
        }
        //重污染天
        if (basTargetDto.getHeavyDaysTarget() != null) {
            targetMap = heavyDaysTargets(year, basTargetDto.getUserRegionCode(), BasTargetUtil.HEAVYDAYS);
            saveYearTarget(year, BigDecimal.ZERO, basTargetDto.getUserRegionCode(), BasTargetUtil.HEAVYDAYS);
            saveMonthTarget(year, targetMap.get("targets"), targetMap.get("actuals"), basTargetDto.getUserRegionCode(), BasTargetUtil.HEAVYDAYS);
            //保存秋防目标
            saveAutumnWinterTarget(year, autumnWinterSum(targetMap.get("targets")), BasTargetUtil.AUTUMN_TARGET, basTargetDto.getUserRegionCode(), BasTargetUtil.HEAVYDAYS);
        }
        ////o38h超标天数
        //if (basTargetDto.getO38hTarget() != null) {
        //    targetMap = o3OverDayTarget(year, userRegionCode, BasTargetUtil.O38HOVERDAYS, basTargetDto.getO38hTarget());
        //    //今年实际超标值
        //    BigDecimal sumValue = AirDataConverseUtil.decimalSumValue(Arrays.stream(targetMap.get("actuals")).filter(e -> e != null).collect(Collectors.toList()));
        //    saveYearTarget(year, basTargetDto.getO38hTarget(), userRegionCode, BasTargetUtil.O38HOVERDAYS);
        //    saveMonthTarget(year, targetMap.get("targets"), targetMap.get("actuals"), userRegionCode, BasTargetUtil.O38HOVERDAYS);
        //}
        ////计算co 超标天
        //targetMap = coOverDayTarget(year, userRegionCode, BasTargetUtil.COOVERDAYS, basTargetDto.getCoTarget());
        //saveYearTarget(year, basTargetDto.getCoTarget(), userRegionCode, BasTargetUtil.COOVERDAYS);
        //saveMonthTarget(year, targetMap.get("targets"), targetMap.get("actuals"), userRegionCode, BasTargetUtil.COOVERDAYS);
        return true;
    }

    @Override
    public BasYearTargetVo findYearTarget(String regionCode) {
        int year = getYear(new Date());
        //查询年度目标集合
        List<Map<String, Object>> targets = qEnvgasAreaTargetMapper.findTargets(regionCode, BasTargetUtil.YEAR_TARGET, year + "");
        BasYearTargetVo yearTargetVo = new BasYearTargetVo();
        //列转行
        targets.forEach(target -> {
            String field;
            BigDecimal value;
            if (target.get("field").equals(BasTargetUtil.CO)) {
                field = (String) target.get("field") + "Target";
                value = target.get("target") == null ? null : ((BigDecimal) target.get("target")).setScale(1, BigDecimal.ROUND_UP);
                fieldCache.set(yearTargetVo, field, value);
            } else {
                field = (String) target.get("field") + "Target";
                value = target.get("target") == null ? null : ((BigDecimal) target.get("target")).setScale(0, BigDecimal.ROUND_UP);
                fieldCache.set(yearTargetVo, field, value);
            }
        });
        return yearTargetVo;
    }


    @Override
    public Map findMonthTarget(String regionCode) {
        Map map = new HashMap();
        int year = getYear(new Date());
        //查询月度目标
        List<Map<String, Object>> monthTarget = qEnvgasAreaTargetMapper.findMonthTarget(regionCode, BasTargetUtil.MONTH_TARGET, year);
        //查询达标计算相关污染物
        List<PCodeIndexPollutant> pollutant = pCodeIndexPollutantMapper.findTargetPollutant();
        pollutant.forEach(e -> {
            //因子属性名
            String field = e.getField();
            List<Map<String, Object>> factorTarget = monthTarget.stream().filter(n -> n.get("field").equals(field)).collect(Collectors.toList());
            String[] target = new String[13];
            target[0] = "目标值";
            String[] actual = new String[13];
            actual[0] = "实际值";
            List<Map> factorTargetList = new ArrayList<>();
            factorTarget.forEach(factor -> {
                int month = Integer.parseInt((String) factor.get("month"));
                if (field.equals(BasTargetUtil.CO)) {
                    target[month] = factor.get("target") == null ? "--" : ((BigDecimal) factor.get("target")).setScale(1, BigDecimal.ROUND_UP) + "";
                    actual[month] = factor.get("actual") == null ? "--" : ((BigDecimal) factor.get("actual")).setScale(1, BigDecimal.ROUND_UP) + "";
                } else {
                    target[month] = factor.get("target") == null ? "--" : ((BigDecimal) factor.get("target")).intValue() + "";
                    actual[month] = factor.get("actual") == null ? "--" : ((BigDecimal) factor.get("actual")).intValue() + "";
                }
            });
            factorTargetList.add(tableColumn(target));
            factorTargetList.add(tableColumn(actual));
            map.put(field, factorTargetList);
        });
        return map;
    }

    @Override
    public List<Map<String,Object>> findAutumnWinterTarget(String regionCode) {
        int year = getYear(new Date());
        List<PCodeIndexPollutant> winterPollutant = pCodeIndexPollutantMapper.findWinterPollutant();
        Map autumnMap = initMap();
        autumnMap.put("title", "10月-12月");
        Map winterMap = initMap();
        winterMap.put("title", "次年1月-次年3月");
        Map totalMap = initMap();
        totalMap.put("title", "总目标");

        //秋防
        List<Map<String, Object>> autumn = qEnvgasAreaTargetMapper.findAutumTarget(regionCode, year, BasTargetUtil.AUTUMN_TARGET);
        autumnMap = groupByType(autumn, autumnMap);
        //冬防
        List<Map<String, Object>> winter = qEnvgasAreaTargetMapper.findAutumTarget(regionCode, year, BasTargetUtil.WINTER_TARGET);
        winterMap = groupByType(winter, winterMap);
        //总计
        List<Map<String, Object>> total = qEnvgasAreaTargetMapper.findAutumTarget(regionCode, year, BasTargetUtil.SUM_TARGET);
        totalMap = groupByType(total, totalMap);
        List<Map<String,Object>> table = new ArrayList<>();
        table.add(autumnMap);
        table.add(winterMap);
        table.add(totalMap);
        return table;
    }

    *//**
     * 根据 秋防、冬防、秋冬防总计分组
     *
     * @param dataMap 数据集合
     * @param map     初始化对象
     * @return
     *//*
    Map groupByType(List<Map<String, Object>> dataMap, Map map) {
        if (!CollectionUtils.isEmpty(dataMap)) {
            dataMap.forEach(e -> {
                if (e.get("field").equals(BasTargetUtil.PM25)) {
                    map.put(BasTargetUtil.PM25 + "Target", e.get("target"));
                    map.put(BasTargetUtil.PM25 + "Input", true);
                }
                if (e.get("field").equals(BasTargetUtil.PM10)) {
                    map.put(BasTargetUtil.PM10 + "Target", e.get("target"));
                    map.put(BasTargetUtil.PM10 + "Input", true);
                }
                if (e.get("field").equals(BasTargetUtil.GOODDYAS)) {
                    map.put(BasTargetUtil.GOODDYAS + "Target", e.get("target"));
                    map.put(BasTargetUtil.GOODDYAS + "Input", true);
                }
                if (e.get("field").equals(BasTargetUtil.HEAVYDAYS)) {
                    map.put(BasTargetUtil.HEAVYDAYS + "Target", e.get("target"));
                    map.put(BasTargetUtil.HEAVYDAYS + "Input", true);
                }
            });
        }
        return map;
    }


    *//**
     * 初始化秋冬防表格map
     *
     * @return
     *//*
    Map initMap() {
        Map map = new HashMap();
        map.put("title", null);
        map.put("pm25Target", null);
        map.put("pm10Target", null);
        map.put("goodDaysTarget", null);
        map.put("heavyDaysTarget", null);
        map.put("pm25Input", false);
        map.put("pm10Input", false);
        map.put("goodDaysInput", false);
        map.put("heavyDaysInput", false);
        return map;
    }

    *//**
     * 生成表格对象
     *
     * @param arr
     * @return
     *//*
    Map tableColumn(String[] arr) {
        Map map = new HashMap();
        for (int i = 0; i < arr.length; i++) {
            map.put("column" + i + 1, arr[i]);
        }
        return map;
    }


    @Override
    public Map regionTarget(String regionCode) {
        Map map = new HashMap();
        //年目标值
        map.put("year", findYearTarget(regionCode));
        map.put("month", findMonthTarget(regionCode));
        return map;
    }

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    @Override
    public void calcWinterTarget(String regionCode, BasTargetDto basTargetDto) {
        int year = getYear(new Date());
        BigDecimal winterTarget = null;
        String[] autumnArr = {year + "-10", year + "-11", year + "-12"};
        if (basTargetDto.getPm25Target() != null) {
            //删除历史数据
            qEnvgasAreaTargetMapper.deleteAutumnByRegionCode(regionCode, pCodeIndexPollutantMapper.findIdByColumn(BasTargetUtil.PM25));
            Map<String, Object> autumnTarget = qEnvgasAreaTargetMapper.findAutumnWinterTarget(regionCode, autumnArr, BasTargetUtil.MONTH_TARGET, BasTargetUtil.PM25);
            winterTarget = winterSubtraction(autumnTarget, BasTargetUtil.PM25, basTargetDto.getPm25Target());
            saveAutumnWinterTarget(year, winterTarget, BasTargetUtil.WINTER_TARGET, regionCode, BasTargetUtil.PM25);
            saveAutumnWinterTarget(year, basTargetDto.getPm25Target(), BasTargetUtil.SUM_TARGET, regionCode, BasTargetUtil.PM25);
        }
        if (basTargetDto.getPm10Target() != null) {
            //删除历史数据
            qEnvgasAreaTargetMapper.deleteAutumnByRegionCode(regionCode, pCodeIndexPollutantMapper.findIdByColumn(BasTargetUtil.PM10));
            Map<String, Object> autumnTarget = qEnvgasAreaTargetMapper.findAutumnWinterTarget(regionCode, autumnArr, BasTargetUtil.MONTH_TARGET, BasTargetUtil.PM10);
            winterTarget = winterSubtraction(autumnTarget, BasTargetUtil.PM10, basTargetDto.getPm10Target());
            saveAutumnWinterTarget(year, winterTarget, BasTargetUtil.WINTER_TARGET, regionCode, BasTargetUtil.PM10);
            saveAutumnWinterTarget(year, basTargetDto.getPm10Target(), BasTargetUtil.SUM_TARGET, regionCode, BasTargetUtil.PM10);
        }
        if (basTargetDto.getGoodDaysTarget() != null) {
            //删除历史数据
            qEnvgasAreaTargetMapper.deleteAutumnByRegionCode(regionCode, pCodeIndexPollutantMapper.findIdByColumn(BasTargetUtil.GOODDYAS));
            Map<String, Object> autumnTarget = qEnvgasAreaTargetMapper.findAutumnWinterTarget(regionCode, autumnArr, BasTargetUtil.MONTH_TARGET, BasTargetUtil.GOODDYAS);
            winterTarget = winterSubtraction(autumnTarget, BasTargetUtil.GOODDYAS, basTargetDto.getGoodDaysTarget());
            saveAutumnWinterTarget(year, winterTarget, BasTargetUtil.WINTER_TARGET, regionCode, BasTargetUtil.GOODDYAS);
            saveAutumnWinterTarget(year, basTargetDto.getGoodDaysTarget(), BasTargetUtil.SUM_TARGET, regionCode, BasTargetUtil.GOODDYAS);
        }
        if (basTargetDto.getHeavyDaysTarget() != null) {
            //删除历史数据
            qEnvgasAreaTargetMapper.deleteAutumnByRegionCode(regionCode, pCodeIndexPollutantMapper.findIdByColumn(BasTargetUtil.HEAVYDAYS));
            Map<String, Object> autumnTarget = qEnvgasAreaTargetMapper.findAutumnWinterTarget(regionCode, autumnArr, BasTargetUtil.MONTH_TARGET, BasTargetUtil.HEAVYDAYS);
            winterTarget = winterSubtraction(autumnTarget, BasTargetUtil.HEAVYDAYS, basTargetDto.getHeavyDaysTarget());
            saveAutumnWinterTarget(year, winterTarget, BasTargetUtil.WINTER_TARGET, regionCode, BasTargetUtil.HEAVYDAYS);
            saveAutumnWinterTarget(year, basTargetDto.getHeavyDaysTarget(), BasTargetUtil.SUM_TARGET, regionCode, BasTargetUtil.HEAVYDAYS);
        }
    }

    *//**
     * 次年1月到3月为，秋冬防总目标乘以六减去10、11、12月份的月度目标总和除以三
     *//*
    BigDecimal winterSubtraction(Map<String, Object> map, String factor, BigDecimal target) {
        BigDecimal value = null;
        String factorName = pCodeIndexPollutantMapper.findNameByColumn(factor);
        if (map != null) {
            BigDecimal autumn = map.get("target") == null ? BigDecimal.ZERO : (BigDecimal) map.get("target");
            BigDecimal subtract = target.multiply(BasTargetUtil.HALF_YEAR).subtract(autumn);
            if (factor.equals(BasTargetUtil.GOODDYAS) || factor.equals(BasTargetUtil.HEAVYDAYS)) {
                //优良天重污染都是总天数  直接减掉
                value = target.subtract(autumn);
                //优良天或重污染天为负数时判断为0
                value = value.compareTo(BigDecimal.ZERO) == 1 ? value : BigDecimal.ZERO;
            } else {
                value = subtract.divide(new BigDecimal(3), 0, BigDecimal.ROUND_HALF_EVEN);
            }
        } else {
            throw new BussinessException("请先设置" + factorName + "的年月目标");
        }
        return value;
    }


    *//**
     * 可达性分析  用
     *
     * @return
     *//*
    @Override
    public List<QEnvgasAreaTargetVo> findReachabilityAnalysis(ReachabilityDto reachabilityDto) {
        List<QEnvgasAreaTargetVo> list = new ArrayList<>();
        //获取时间参数
        getMonitorDate(reachabilityDto);

        PCodeRegion pCodeRegion = pCodeRegionMapper.
                selectOne(new QueryWrapper<PCodeRegion>().
                        eq("region_code", reachabilityDto.getUserRegionCode()).
                        eq("cast(delete_flag as varchar)", "0"));
        //2 本月累计 3 本年累计 5冬防阶段目标 6 秋冬防总目标
        Integer timeType = reachabilityDto.getTimeType();
        Map map = new HashMap<>();
        if ("2".equals(timeType.toString())) {
            //今天数据
            map = qEnvgasWqMonthMapper.findStandardMonitoringLastMonth(reachabilityDto.getUserRegionCode(), "1");
            getCarryData(map);
        } else if ("3".equals(timeType.toString())) {
            //今天数据
            map = qEnvgasWqYearMapper.findStandardMonitoringLastYear(reachabilityDto.getUserRegionCode(), "1");
            getCarryData(map);
        } else if ("5".equals(timeType.toString())) {
            //今天数据
            map = qEnvgasWqYearMapper.findAutumnWinter(reachabilityDto);
            getCarryData(map);
        } else if ("6".equals(timeType.toString())) {
            //今天数据
            map = qEnvgasWqYearMapper.findAutumnWinter(reachabilityDto);
            getCarryData(map);
        }

        //因子多选
        List<String> factorCodeList = setFactorCodeData(reachabilityDto);
        for (int i = 0; i < factorCodeList.size(); i++) {
            String factorCodeId = factorCodeList.get(i);
            reachabilityDto.setFactorCodeInt(Integer.parseInt(factorCodeId));
            QEnvgasAreaTargetVo data = qEnvgasWqYearMapper.findReachabilityAnalysis(reachabilityDto);
            if (Objects.nonNull(data)) {
                data.setRegionName(pCodeRegion.getRegionName());
                data.setRegionCode(pCodeRegion.getRegionCode());
                //5代表co 保留一位小数
                if ("5".equals(factorCodeId)) {
                    data.setActualValue(Objects.nonNull(data.getActualValue()) ? data.getActualValue().setScale(1, BigDecimal.ROUND_UP) : null);
                    data.setTargetValue(Objects.nonNull(data.getTargetValue()) ? data.getTargetValue().setScale(1, BigDecimal.ROUND_UP) : null);
                } else {
                    data.setActualValue(Objects.nonNull(data.getActualValue()) ? data.getActualValue().setScale(0, BigDecimal.ROUND_UP) : null);
                    data.setTargetValue(Objects.nonNull(data.getTargetValue()) ? data.getTargetValue().setScale(0, BigDecimal.ROUND_UP) : null);
                }
                reachabilityDto.setField(data.getField());
                //去年剩余天数的监测值总和
                BigDecimal count = qEnvgasWqYearMapper.findPeriodLastYear(reachabilityDto);
                //2 本月累计 3 本年累计 5冬防阶段目标 6 秋冬防总目标
                if ("2".equals(timeType)) {
                    if (Objects.nonNull(map) && Objects.nonNull(map.get(data.getField()))) {
                        data.setActualValue(new BigDecimal(map.get(data.getField()).toString()));
                    }

                    BigDecimal threshold = thresholdToData(data.getTargetValue(), data.getActualValue(), "2");
                    BigDecimal period = periodLastYear(count, "2");
                    setQualityData(threshold, period, reachabilityDto.getFactorCode(), data);
                } else if ("3".equals(timeType)) {
                    if (Objects.nonNull(map) && Objects.nonNull(map.get(data.getField()))) {
                        data.setActualValue(new BigDecimal(map.get(data.getField()).toString()));
                    }

                    BigDecimal threshold = thresholdToData(data.getTargetValue(), data.getActualValue(), "1");
                    BigDecimal period = periodLastYear(count, "1");
                    setQualityData(threshold, period, reachabilityDto.getFactorCode(), data);
                } else if ("5".equals(timeType)) {
                    BigDecimal threshold = thresholdToData(data.getTargetValue(), data.getActualValue(), "3");
                    BigDecimal period = periodLastYear(count, "3");
                    setQualityData(threshold, period, reachabilityDto.getFactorCode(), data);
                } else if ("6".equals(timeType)) {
//                    BigDecimal accumulative = qEnvgasWqYearMapper.findPrevention(reachabilityDto);
//                    if (Objects.nonNull(reachabilityDto)) {
//                        data.setActualValue(accumulative);
//                    }
                    if (Objects.nonNull(map) && Objects.nonNull(map.get(data.getField()))) {
                        data.setActualValue(new BigDecimal(map.get(data.getField()).toString()));
                    }

                    BigDecimal threshold = thresholdToData(data.getTargetValue(), data.getActualValue(), "5");
                    BigDecimal period = periodLastYear(count, "5");
                    setQualityData(threshold, period, reachabilityDto.getFactorCode(), data);
                }
                list.add(data);
            }
        }
        return list;
    }

    *//***
     * 达标监控
     * @param userRegionCode 用户区域code
     * @param type 1日 2 本月累计 3 本年累计
     * @return
     *//*
    @Override
    public List<QEnvgasAreaTargetVo> findStandardMonitoring(String userRegionCode, String type) {
        if (Objects.isNull(type)) {
            throw new BussinessException("类型不能为空");
        }
        List<QEnvgasAreaTargetVo> list = new ArrayList<>();
        String time = "3".equals(type) ? DateUtil.format(new Date(), DateUtil.YYYY) : DateUtil.format(new Date(), DateUtil.DATE_PATTERN_MONTH);
        List<QEnvgasAreaTargetVo> targetDay = qEnvgasWqDayMapper.findStandardTargetDay(userRegionCode, time, type);
        if ("1".equals(type)) {
//            Map monitoringThisDay = qEnvgasWqDayMapper.findStandardMonitoringDay(userRegionCode);     //数据库中当日数据未有值
//            Map monitoringLastDay = qEnvgasWqDayMapper.findStandardMonitoringLastDay(userRegionCode); //日数据数据

            AirQualityData airQualityData = reportManageService.cumulativeAirData(userRegionCode);      //计算24小时数据
            AirQualityData airQualityLastData = reportManageService.cumulativeAirLastData(userRegionCode); //去年24小时数据
            Map<String, Object> monitoringThisDay = BeanUtil.beanToMap(airQualityData);
            Map<String, Object> monitoringLastDay = BeanUtil.beanToMap(airQualityLastData);
            getMonitoringData(monitoringThisDay);
            getMonitoringData(monitoringLastDay);

            Map<String, BigDecimal> aqiMap = new HashMap<>();
            getTargetStandard(monitoringLastDay, targetDay, list, type, monitoringThisDay, aqiMap);
            //aqi计算数据
            getAqiTarget(monitoringThisDay, monitoringLastDay, aqiMap, list);
        } else if ("2".equals(type)) {
            //今天数据
            Map monitoringDay = qEnvgasWqMonthMapper.findStandardMonitoringLastMonth(userRegionCode, "1");
            List<Map> monitoringCoDay = qEnvgasWqMonthMapper.findStandardDivisorMonth(userRegionCode, "1");
            getDivisorData(monitoringCoDay, monitoringDay);

            //去年
            Map monitoringLastDay = qEnvgasWqMonthMapper.findStandardMonitoringLastMonth(userRegionCode, "2");
            List<Map> monitoringLastCoDay = qEnvgasWqMonthMapper.findStandardDivisorMonth(userRegionCode, "2");
            getDivisorData(monitoringLastCoDay, monitoringLastDay);

            getCarryData(monitoringDay);
            getCarryData(monitoringLastDay);
            //绑定今年数据
            getBindingActualValue(monitoringDay, targetDay);
            //遍历六因子
            getTargetStandard(monitoringLastDay, targetDay, list, type, null, null);
        } else if ("3".equals(type)) {
            //今天数据
            Map monitoringDay = qEnvgasWqYearMapper.findStandardMonitoringLastYear(userRegionCode, "1");
            List<Map> monitoringDivisorDay = qEnvgasWqYearMapper.findStandardDivisorLastYear(userRegionCode, "1");
            getDivisorData(monitoringDivisorDay, monitoringDay);
            //去年数据
            Map monitoringLastDay = qEnvgasWqYearMapper.findStandardMonitoringLastYear(userRegionCode, "2");
            List<Map> monitoringDivisorLastDay = qEnvgasWqYearMapper.findStandardDivisorLastYear(userRegionCode, "2");
            getDivisorData(monitoringDivisorLastDay, monitoringLastDay);

            getCarryData(monitoringDay);
            getCarryData(monitoringLastDay);
            //绑定今年数据
            getBindingActualValue(monitoringDay, targetDay);
            //遍历六因子
            getTargetStandard(monitoringLastDay, targetDay, list, type, null, null);
        }
        return list;
    }

    *//**
     * 封装数据
     *
     * @param monitoringCoDay
     * @param monitoringDay
     *//*
    private void getDivisorData(List<Map> monitoringCoDay, Map monitoringDay) {
        if (!CollectionUtils.isEmpty(monitoringCoDay) && Objects.nonNull(monitoringDay)) {
            List<BigDecimal> ccollectCo = monitoringCoDay.stream().filter(e -> e != null && Objects.nonNull(e.get("co"))).map(m -> new BigDecimal(m.get("co").toString())).collect(Collectors.toList());
            List<BigDecimal> collectO38H = monitoringCoDay.stream().filter(m -> m != null && Objects.nonNull(m.get("o38h"))).map(m -> new BigDecimal(m.get("o38h").toString())).collect(Collectors.toList());
            monitoringDay.put("co", BasTargetUtil.percentile(ccollectCo.toArray(new BigDecimal[ccollectCo.size()]), new BigDecimal(0.95)));
            monitoringDay.put("o38h", BasTargetUtil.percentile(collectO38H.toArray(new BigDecimal[collectO38H.size()]), new BigDecimal(0.9)));
        } else {
            if (Objects.nonNull(monitoringDay)) {
                monitoringDay.put("co", null);
                monitoringDay.put("o38h", null);
            }
        }
    }

    *//**
     * 数据设计累计值
     *
     * @param monitoringDay
     * @param list
     *//*
    private void getBindingActualValue(Map monitoringDay, List<QEnvgasAreaTargetVo> list) {
        if (!CollectionUtils.isEmpty(list)) {
            for (QEnvgasAreaTargetVo qEnvgasAreaTargetVo : list) {
                String field = qEnvgasAreaTargetVo.getField();
                if (Objects.nonNull(monitoringDay) && Objects.nonNull(monitoringDay.get(field))) {
                    qEnvgasAreaTargetVo.setActualValue(new BigDecimal(monitoringDay.get(field).toString()));
                }
            }
        }
    }

    *//**
     * 进行四舍六入五成双
     *
     * @param map
     *//*
    private void getCarryData(Map map) {
        if (Objects.nonNull(map)) {
            map.put("aqi", StringTools.sciCal(map.get("aqi"), 0));
            map.put("pm25", StringTools.sciCal(map.get("pm25"), 0));
            map.put("pm10", StringTools.sciCal(map.get("pm10"), 0));
            map.put("so2", StringTools.sciCal(map.get("so2"), 0));
            map.put("no2", StringTools.sciCal(map.get("no2"), 0));
            map.put("co", StringTools.sciCal(map.get("co"), 1));
            map.put("o3_8h", StringTools.sciCal(map.get("o3_8h"), 0));
            map.put("o3", StringTools.sciCal(map.get("o3"), 0));
            map.put("o38h", StringTools.sciCal(map.get("o38h"), 0));
        }
    }

    *//**
     * 小时o3
     *
     * @param monitoringThisDay
     *//*
    private void getMonitoringData(Map<String, Object> monitoringThisDay) {
        if (Objects.nonNull(monitoringThisDay) && Objects.nonNull(monitoringThisDay.get("o3"))) {
            monitoringThisDay.put("o38h", monitoringThisDay.get("o3"));
        }
    }


    *//**
     * 封装遍历数据
     *
     * @param type 1日 2 本月累计 3 本年累计
     *//*
    private void getTargetStandard(Map monitoringLastDay, List<QEnvgasAreaTargetVo> targetDay, List<QEnvgasAreaTargetVo> list, String type, Map monitoringThisDay, Map<String, BigDecimal> aqiMap) {
        if ("1".equals(type)) {
            //遍历六因子
            for (QEnvgasAreaTargetVo targetVo : targetDay) {
                aqiMap.put(targetVo.getField(), targetVo.getTargetValue());
                getFieldData(monitoringLastDay, list, monitoringThisDay, targetVo, targetVo.getField());
            }
        } else {
            //遍历八参数
            for (QEnvgasAreaTargetVo targetVo : targetDay) {
                //判断co 和 o38h 超标天数
                getOverProofDay(monitoringLastDay, targetVo, type);
                //污染天处理年
                getPollutionDay(targetVo, type);
                getFieldData(monitoringLastDay, list, monitoringThisDay, targetVo, targetVo.getField());
            }
        }
    }

    *//**
     * 封装年 优良天数和重污染天数
     * 优良天数	goodDays
     * 重污染天数	heavyDays
     *
     * @param targetVo
     * @param type     1日 2 本月累计 3 本年累计
     *//*
    private void getPollutionDay(QEnvgasAreaTargetVo targetVo, String type) {
        if ("3".equals(type)) {
            String field = targetVo.getField();
            if ("goodDays".equals(field)) {
                BigDecimal data = qEnvgasWqDayMapper.getPollutionDay(targetVo.getRegionCode(), "1");
                if (data.compareTo(BigDecimal.ZERO) == 0) {
                    data = null;
                }
                targetVo.setActualValue(Objects.nonNull(data) ? data : null);
            } else if ("heavyDays".equals(field)) {
                BigDecimal data = qEnvgasWqDayMapper.getPollutionDay(targetVo.getRegionCode(), "2");
                if (data.compareTo(BigDecimal.ZERO) == 0) {
                    data = null;
                }
                targetVo.setActualValue(Objects.nonNull(data) ? data : null);
            }
        }
    }

    *//**
     *
     *//*
    private void getOverProofDay(Map monitoringLastDay, QEnvgasAreaTargetVo targetVo, String type) {
        String field = targetVo.getField();
        BigDecimal targetValue = targetVo.getTargetValue();
        BigDecimal lastData = Objects.nonNull(monitoringLastDay) ? Objects.nonNull(monitoringLastDay.get(field)) ? new BigDecimal(monitoringLastDay.get(field).toString()) : null : null;
        //判断本年超标天数
        if ("3".equals(type)) {
            if ("co".equals(field)) {
                if (Objects.nonNull(targetValue)) {
                    BigDecimal decimal = qEnvgasWqDayMapper.selectByExceedDay(targetValue, targetVo.getRegionCode(), "co");
                    targetVo.setExceedanceDays(decimal);
                    targetVo.setControlDay(BasTargetUtil.thresholdToExceed(decimal, BasTargetUtil.CO, "1"));
                } else {
                    if (Objects.nonNull(lastData)) {
                        BigDecimal decimal = qEnvgasWqDayMapper.selectByExceedDay(lastData, targetVo.getRegionCode(), "co");
                        targetVo.setExceedanceDays(decimal);
                    }
                    targetVo.setControlDay(BasTargetUtil.thresholdToExceed(targetVo.getExceedanceDays(), BasTargetUtil.CO, "1"));
                }
            } else if ("o38h".equals(field)) {
                if (Objects.nonNull(targetValue)) {
                    BigDecimal decimal = qEnvgasWqDayMapper.selectByExceedDay(targetValue, targetVo.getRegionCode(), "o3_8h");
                    targetVo.setExceedanceDays(decimal);
                }
                targetVo.setControlDay(BasTargetUtil.thresholdToExceed(targetVo.getExceedanceDays(), BasTargetUtil.O38H, "1"));
            }
        }
    }


    *//**
     * 遍历封装查询
     *//*
    private void getFieldData(Map monitoringLastDay, List<QEnvgasAreaTargetVo> list, Map monitoringThisDay, QEnvgasAreaTargetVo targetVo, String field) {
        //用于判断1日 2 本月累计 3 本年累计
        BigDecimal thisData = null;
        if (Objects.nonNull(monitoringThisDay)) {
            thisData = Objects.nonNull(monitoringThisDay) ? Objects.nonNull(monitoringThisDay.get(field)) ? new BigDecimal(monitoringThisDay.get(field).toString()) : null : null;
        } else {
            thisData = targetVo.getActualValue();
        }
        BigDecimal lastData = Objects.nonNull(monitoringLastDay) ? Objects.nonNull(monitoringLastDay.get(field)) ? new BigDecimal(monitoringLastDay.get(field).toString()) : null : null;
        BigDecimal targetValue = targetVo.getTargetValue();
        //达标差距
        if (!"co".equals(field)) {
            BigDecimal standardData = BasTargetUtil.getStandardData(thisData, targetValue);
            if (Objects.nonNull(standardData)) {
                targetVo.setStandard(standardData.setScale(0, BigDecimal.ROUND_HALF_EVEN));
            }
        } else {
            targetVo.setStandard(BasTargetUtil.getStandardData(thisData, targetValue));
        }

        //同比改善率
        BigDecimal multiply = BasTargetUtil.comparedImprovement(thisData, lastData);
        multiply = Objects.nonNull(multiply) ? new BigDecimal(StringTools.sciCal(multiply, 1)) : null;
        targetVo.setImprovement(Objects.nonNull(multiply) ? multiply + "%" : null);
        //同比改善率 升降 1上升 2下降
        targetVo.setLifting(getLiftingData(multiply));
        if ("co".equals(field)) {
            targetVo.setActualValue(Objects.nonNull(thisData) ? thisData.setScale(1, BigDecimal.ROUND_UP) : null);
            targetVo.setTargetValue(Objects.nonNull(targetValue) ? targetValue.setScale(1, BigDecimal.ROUND_UP) : null);
        } else {
            targetVo.setActualValue(Objects.nonNull(thisData) ? thisData.setScale(0, BigDecimal.ROUND_UP) : null);
            targetVo.setTargetValue(Objects.nonNull(targetValue) ? targetValue.setScale(0, BigDecimal.ROUND_UP) : null);
        }
        list.add(targetVo);
    }


    *//**
     * 封装aqi储存数据
     *//*
    private void getAqiTarget(Map monitoringThisDay, Map monitoringLastDay, Map<String, BigDecimal> aqiMap, List<QEnvgasAreaTargetVo> list) {
        //日数据 处理 aqi
        QEnvgasAreaTargetVo aqiTargetVo = new QEnvgasAreaTargetVo();
        aqiTargetVo.setPollutantName("AQI");
        aqiTargetVo.setFkFactorId(StandardPollutantEnum.AQI.getPkId());
        BigDecimal target = null;
        //判断六参不为空
        if (Objects.nonNull(aqiMap.get("pm25")) && Objects.nonNull(aqiMap.get("pm10")) && Objects.nonNull(aqiMap.get("so2")) && Objects.nonNull(aqiMap.get("no2")) && Objects.nonNull(aqiMap.get("co")) && Objects.nonNull(aqiMap.get("o38h"))) {
            target = new BigDecimal(AirQualityConverter.concAqiBySixParamByCustomTime(aqiMap.get("pm25"), aqiMap.get("pm10"), aqiMap.get("so2"), aqiMap.get("no2"), aqiMap.get("co"), aqiMap.get("o38h")));
        }
        //目标值
        aqiTargetVo.setTargetValue(target);
        getFieldData(monitoringLastDay, list, monitoringThisDay, aqiTargetVo, "aqi");
    }


    *//**
     * 判断是否上升还是下降 同比改善率 升降 0不上升不下降 1上升 2下降
     *
     * @param multiply
     * @return
     *//*
    private String getLiftingData(BigDecimal multiply) {
        if (Objects.nonNull(multiply)) {
            if (multiply.compareTo(BigDecimal.ZERO) == 1) {
                return "1";
            } else if (multiply.compareTo(BigDecimal.ZERO) == 0) {
                return "0";
            } else {
                return "2";
            }
        }
        return null;
    }


    private List<String> setFactorCodeData(ReachabilityDto reachabilityDto) {
        //因子多选
        String factorCode = reachabilityDto.getFactorCode();
        List<String> factorCodeList = new ArrayList<>();
        if (StringUtils.isNotBlank(factorCode)) {
            if (factorCode.contains(",")) {
                factorCodeList.addAll(Arrays.asList(factorCode.split(",")));
            } else {
                factorCodeList.add(factorCode);
            }
        } else {
            throw new BussinessException("因子不能为空");
        }
        return factorCodeList;
    }


    *//**
     * 封装重复利用
     *
     * @param threshold
     * @param period
     * @param factorCode
     * @param data
     *//*
    private void setQualityData(BigDecimal threshold, BigDecimal period, String factorCode, QEnvgasAreaTargetVo data) {
        BigDecimal change = BasTargetUtil.comparedChange(data.getActualValue(), period);
        change = Objects.nonNull(change) ? new BigDecimal(StringTools.sciCal(change, 1)) : null;
        String gradient = BasTargetUtil.comparedGradient(getFactorCodeData(factorCode), change);
        data.setThreshold(threshold);
        data.setContemporary(period);
        data.setBasisChange(Objects.nonNull(change) ? change + "%" : null);
        data.setCalculation(gradient);
    }

    *//**
     * 获取因子类型字段
     *//*
    private String getFactorCodeData(String factorCode) {
        switch (factorCode) {
            case "1":
                factorCode = BasTargetUtil.PM25;
                break;
            case "2":
                factorCode = BasTargetUtil.PM10;
                break;
            case "3":
                factorCode = BasTargetUtil.SO2;
                break;
            case "4":
                factorCode = BasTargetUtil.NO2;
                break;
            case "5":
                factorCode = BasTargetUtil.CO;
                break;
            case "6":
                factorCode = BasTargetUtil.O38H;
                break;
        }
        return factorCode;
    }

    *//**
     * 获取时间赋值
     *
     * @param reachabilityDto
     *//*
    private void getMonitorDate(ReachabilityDto reachabilityDto) {
        Date date = new Date();
        Integer timeTypeInt = reachabilityDto.getTimeType();
        if (Objects.isNull(timeTypeInt) || Objects.isNull(reachabilityDto.getFactorCode())) {
            throw new BussinessException("必填不能为空");
        }
        Date dateTime = DateUtils.addDateYears(new Date(), -1);
        //2 本月累计 3 本年累计 5冬防阶段目标 6 秋冬防总目标
        if (timeTypeInt == 2) {
            reachabilityDto.setMonitorTime(DateUtil.format(date, DateUtil.DATE_PATTERN_MONTH));
            //过去天数
            Date dateLast = DateUtils.addDateYears(new Date(), -1);
            reachabilityDto.setStartTime(DateUtil.format(dateLast));

//            reachabilityDto.setStartTime(DateUtil.getFirstDay(dateTime));
            reachabilityDto.setEndTime(DateUtil.getLastOfMonthByDate(dateTime));

//            Date dateLast = DatesUtils.addDateYears(new Date(), -1);
//            reachabilityDto.setEndTime(DateUtil.format(dateLast));
        } else if (timeTypeInt == 3) {
            reachabilityDto.setMonitorTime(DateUtil.format(date, DateUtil.YYYY));

            Date dateLast = DateUtils.addDateYears(new Date(), -1);
            reachabilityDto.setStartTime(DateUtil.format(dateLast));

//            reachabilityDto.setStartTime(DateUtil.format(dateTime, DateUtil.DATE_PATTERN));
            reachabilityDto.setEndTime((getYear(date) - 1) + "-12-31");
        } else if (timeTypeInt == 5) {
            reachabilityDto.setMonitorTime(DateUtil.format(date, DateUtil.YYYY));

            //去年时间 01月-03月
            Date dateLast = DateUtils.addDateYears(new Date(), -1);
            String format = DateUtil.format(dateLast);
            String start = (getYear(date)) + "-01-01";
            reachabilityDto.setStartTime(start);

            Date dateFixed = DateUtil.stringToDate(start, DateUtil.DATE_PATTERN);
            //当前时间大于开始时间  字符串比较时间有误
            long timeLast = dateLast.getTime();
            long timeFixed = dateFixed.getTime();
            if (timeLast > timeFixed) {
                reachabilityDto.setStartTime(format);
            }


            reachabilityDto.setEndTime((getYear(date)) + "-03-31");
        } else if (timeTypeInt == 6) {
            reachabilityDto.setMonitorTime(DateUtil.format(date, DateUtil.YYYY));

//            2022-10-01 2023-03-31
            //去年时间 10月-03月
            Date dateLast = DateUtils.addDateYears(new Date(), -1);
            String format = DateUtil.format(dateLast);
            String start = (getYear(date) - 1) + "-10-01";
            reachabilityDto.setStartTime(start);

            Date dateFixed = DateUtil.stringToDate(start, DateUtil.DATE_PATTERN);
            //当前时间大于开始时间  字符串比较时间有误
            long timeLast = dateLast.getTime();
            long timeFixed = dateFixed.getTime();
            if (timeLast > timeFixed) {
                reachabilityDto.setStartTime(format);
            }


            reachabilityDto.setEndTime((getYear(date)) + "-03-31");
        }
    }


    *//**
     * 生成12个月份集合
     *
     * @param year 年份
     * @return
     *//*
    List<String> yearMonthList(int year) {
        List<String> months = new ArrayList<>();
        for (int i = 1; i <= 12; i++) {
            if (i < 10) {
                months.add(year + "-0" + i);
            } else {
                months.add(year + "-" + i);
            }
        }
        return months;
    }


    *//**
     * 月份数据集合转 decimal数组
     *
     * @param monthData 月份数据
     * @return
     *//*
    BigDecimal[] monthListToArray(List<MonthDataVo> monthData, String factor) {
        BigDecimal[] decimalArr = new BigDecimal[12];
        if (monthData != null && monthData.size() > 0) {
            monthData.forEach(data -> {
                int month = Integer.parseInt(data.getMonthNum());
                if (factor.equals(BasTargetUtil.CO)) {
                    //赋值
                    decimalArr[month - 1] = fieldCache.get(data, factor) == null ? null : ((BigDecimal) fieldCache.get(data, factor)).setScale(1, BigDecimal.ROUND_HALF_EVEN);
                } else {
                    //赋值
                    decimalArr[month - 1] = fieldCache.get(data, factor) == null ? null : ((BigDecimal) fieldCache.get(data, factor)).setScale(0, BigDecimal.ROUND_HALF_EVEN);
                }
            });
        }
        return decimalArr;
    }

    *//**
     * 月份目标值数组转map 并排序
     *
     * @param calcMap key:月份 value:推算值      map
     * @return
     *//*
    List<Map<String, Object>> arrayToSortList(List<Map<String, Object>> calcMap) {
        calcMap = calcMap
                .stream()
                .filter(e -> e.get("value") != null)
                .sorted(Comparator.comparing(e -> (BigDecimal) e.get("value")))
                .collect(Collectors.toList());
        //倒序排序
        Collections.reverse(calcMap);
        return calcMap;
    }

    String uuid() {
        return UUID.randomUUID().toString().replaceAll("-", "");
    }

    *//**
     * 秋冬防均值
     *
     * @param arr 目标数组
     * @return
     *//*
    BigDecimal autumnWinterAvg(BigDecimal[] arr) {
        List<BigDecimal> valueList = new ArrayList<>();
        valueList.add(arr[11]);
        valueList.add(arr[10]);
        valueList.add(arr[9]);
        valueList = valueList.stream().filter(e -> e != null).collect(Collectors.toList());
        return AirDataConverseUtil.decimalAvgValue(valueList);
    }

    *//**
     * 秋冬防优良天 重污染天总和
     *
     * @param arr 目标数值
     * @return
     *//*
    BigDecimal autumnWinterSum(BigDecimal[] arr) {
        List<BigDecimal> valueList = new ArrayList<>();
        valueList.add(arr[11]);
        valueList.add(arr[10]);
        valueList.add(arr[9]);
        valueList = valueList.stream().filter(e -> e != null).collect(Collectors.toList());
        return AirDataConverseUtil.decimalSumValue(valueList);
    }*/
}
