|  |  | 
 |  |  |  | 
 |  |  | import com.alibaba.fastjson.JSONObject; | 
 |  |  | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; | 
 |  |  | import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; | 
 |  |  | import com.moral.api.entity.CityAqiDaily; | 
 |  |  | import com.moral.api.entity.CityAqiMonthly; | 
 |  |  | import com.moral.api.mapper.CityAqiMonthlyMapper; | 
 |  |  | 
 |  |  |         //结束时间,本月1号 | 
 |  |  |         Date end = DateUtils.addMonths(start, 1); | 
 |  |  |  | 
 |  |  |         //如果是1号,先删除上月数据再统计 | 
 |  |  |         //不是1号,统计的是本月累计值,先删除本月数据 | 
 |  |  |         int day = DateUtils.getDay(new Date()); | 
 |  |  |         UpdateWrapper<CityAqiMonthly> cityAqiMonthlyUpdateWrapper = new UpdateWrapper<>(); | 
 |  |  |         if (day == 1) { | 
 |  |  |             cityAqiMonthlyUpdateWrapper.eq("time", start); | 
 |  |  |         } else { | 
 |  |  |             start = end; | 
 |  |  |             end = DateUtils.addMonths(start, 1); | 
 |  |  |             lastLastMonth = DateUtils.addMonths(start, -1); | 
 |  |  |             cityAqiMonthlyUpdateWrapper.eq("time", start); | 
 |  |  |         } | 
 |  |  |         cityAqiMonthlyMapper.delete(cityAqiMonthlyUpdateWrapper); | 
 |  |  |  | 
 |  |  |  | 
 |  |  |         //获取所有城市aqi小时数据 | 
 |  |  |         QueryWrapper<CityAqiDaily> wrapper = new QueryWrapper<>(); | 
 |  |  |         wrapper.select("city_code", "time", "value") | 
 |  |  |                 .ge("time", DateUtils.dateToDateString(start)) | 
 |  |  |                 .lt("time", DateUtils.dateToDateString(end)); | 
 |  |  |                 .ge("time", start) | 
 |  |  |                 .lt("time", end); | 
 |  |  |         List<Map<String, Object>> monthlyData = cityAqiDailyService.listMaps(wrapper); | 
 |  |  |  | 
 |  |  |         if (monthlyData.size() == 0) { | 
 |  |  |             return; | 
 |  |  |         } | 
 |  |  |         //按city_code分组 | 
 |  |  |         Map<String, List<Map<String, Object>>> data = monthlyData.parallelStream().collect(Collectors.groupingBy(o -> o.get("city_code").toString())); | 
 |  |  |         Map<Integer, List<Map<String, Object>>> data = monthlyData.stream() | 
 |  |  |                 .collect(Collectors.groupingBy(o ->Integer.parseInt(o.get("city_code").toString()) )); | 
 |  |  |  | 
 |  |  |         //获取上月数据,本月综指同上月对比 | 
 |  |  |         QueryWrapper<CityAqiMonthly> queryWrapper = new QueryWrapper<>(); | 
 |  |  |         queryWrapper.select("city_code", "value") | 
 |  |  |                 .eq("time", lastLastMonth); | 
 |  |  |         //获取上月数据 | 
 |  |  |         List<CityAqiMonthly> lastCityAqiMonthlyList = cityAqiMonthlyMapper.selectList(queryWrapper); | 
 |  |  |         Map<Integer, CityAqiMonthly> lastMonthData = new HashMap<>(); | 
 |  |  |         for (CityAqiMonthly cityAqiMonthly : lastCityAqiMonthlyList) { | 
 |  |  |             lastMonthData.put(cityAqiMonthly.getCityCode(), cityAqiMonthly); | 
 |  |  |         } | 
 |  |  |  | 
 |  |  |  | 
 |  |  |         //获取去年本月数据 | 
 |  |  |         Date thisMonthOfLastYear = DateUtils.addYears(start, -1); | 
 |  |  |         queryWrapper.clear(); | 
 |  |  |         queryWrapper.select("city_code", "value") | 
 |  |  |                 .eq("time", thisMonthOfLastYear); | 
 |  |  |         List<CityAqiMonthly> thisMonthOfLastYearList = cityAqiMonthlyMapper.selectList(queryWrapper); | 
 |  |  |         Map<Integer, CityAqiMonthly> thisMonthOfLastYearData = new HashMap<>(); | 
 |  |  |         for (CityAqiMonthly cityAqiMonthly : thisMonthOfLastYearList) { | 
 |  |  |             thisMonthOfLastYearData.put(cityAqiMonthly.getCityCode(), cityAqiMonthly); | 
 |  |  |         } | 
 |  |  |  | 
 |  |  |  | 
 |  |  |         List<CityAqiMonthly> cityAqiMonthlyList = new ArrayList<>(); | 
 |  |  |  | 
 |  |  |         Date finalStart = start; | 
 |  |  |         data.forEach((cityCode, value) -> { | 
 |  |  |             Map<String, Object> jsonMap = new HashMap<>(); | 
 |  |  |             CityAqiMonthly cityAqiMonthly = new CityAqiMonthly(); | 
 |  |  |             cityAqiMonthly.setCityCode(Integer.parseInt(cityCode)); | 
 |  |  |             cityAqiMonthly.setTime(start); | 
 |  |  |             Map<String, Object> jsonMap = new HashMap<>(); | 
 |  |  |             cityAqiMonthly.setCityCode(cityCode); | 
 |  |  |             cityAqiMonthly.setTime(finalStart); | 
 |  |  |  | 
 |  |  |             Map<String, Object> params = new HashMap<>(); | 
 |  |  |             List<Map<String, Object>> temp = new ArrayList<>(); | 
 |  |  | 
 |  |  |             } | 
 |  |  |  | 
 |  |  |             sensors.forEach(sensor -> { | 
 |  |  |                 OptionalDouble optionalDouble = value.parallelStream().flatMapToDouble(v -> { | 
 |  |  |                 OptionalDouble optionalDouble = value.stream().flatMapToDouble(v -> { | 
 |  |  |                     Map<String, Object> dataValue = JSONObject.parseObject((String) v.get("value"), Map.class); | 
 |  |  |                     double aDouble = Double.parseDouble(dataValue.get(sensor).toString()); | 
 |  |  |                     return DoubleStream.of(aDouble); | 
 |  |  | 
 |  |  |             Double compositeIndex = ComprehensiveIndexUtils.dailyData(jsonMap); | 
 |  |  |             jsonMap.put("compositeIndex", compositeIndex); | 
 |  |  |  | 
 |  |  |             //本月综指同上月对比 | 
 |  |  |             QueryWrapper<CityAqiMonthly> queryWrapper = new QueryWrapper<>(); | 
 |  |  |             queryWrapper.select("value") | 
 |  |  |                     .eq("city_code", cityCode) | 
 |  |  |                     .eq("time", DateUtils.dateToDateString(lastLastMonth)); | 
 |  |  |             //获取上上月数据 | 
 |  |  |             CityAqiMonthly lastCityAqiMonthly = cityAqiMonthlyMapper.selectOne(queryWrapper); | 
 |  |  |             //本月综指同上月对比(综合指数环比) | 
 |  |  |             CityAqiMonthly lastCityAqiMonthly = lastMonthData.get(cityCode); | 
 |  |  |             if (lastCityAqiMonthly != null) { | 
 |  |  |                 Map<String, Object> map = JSONObject.parseObject(lastCityAqiMonthly.getValue(), Map.class); | 
 |  |  |                 double lastCompositeIndex = Double.parseDouble(map.get("compositeIndex").toString()); | 
 |  |  | 
 |  |  |                 String format = decimalFormat.format((compositeIndex - lastCompositeIndex) / lastCompositeIndex); | 
 |  |  |                 jsonMap.put("monthContrast", format); | 
 |  |  |             } | 
 |  |  |  | 
 |  |  |             //获取去年本月数据,用于计算同比 | 
 |  |  |             CityAqiMonthly thisMonthOfLastYears = thisMonthOfLastYearData.get(cityCode); | 
 |  |  |  | 
 |  |  |             //各因子同比计算 | 
 |  |  |             Map<String, Object> yearOnYearValue = yearOnYearOfSensor(thisMonthOfLastYears, jsonMap); | 
 |  |  |             if (yearOnYearValue != null) { | 
 |  |  |                 jsonMap.putAll(yearOnYearValue); | 
 |  |  |             } | 
 |  |  |  | 
 |  |  |             cityAqiMonthly.setValue(JSONObject.toJSONString(jsonMap)); | 
 |  |  |             cityAqiMonthlyMapper.insert(cityAqiMonthly); | 
 |  |  |             cityAqiMonthlyList.add(cityAqiMonthly); | 
 |  |  |         }); | 
 |  |  |         cityAqiMonthlyMapper.insertCityAqiMonthly(cityAqiMonthlyList); | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * @param thisMonthOfLastYearData 去年本月数据 | 
 |  |  |      * @param currentData             当前月该数据 | 
 |  |  |      */ | 
 |  |  |     private Map<String, Object> yearOnYearOfSensor(CityAqiMonthly thisMonthOfLastYearData, Map<String, Object> currentData) { | 
 |  |  |         Map<String, Object> result = null; | 
 |  |  |         //需要计算同比的因子 | 
 |  |  |         List<String> sensors = Arrays.asList("PM2_5", "PM10", "SO2", "NO2", "CO", "O3", "compositeIndex"); | 
 |  |  |         if (thisMonthOfLastYearData != null) { | 
 |  |  |             result = new HashMap<>(); | 
 |  |  |             Map<String, Object> map = JSONObject.parseObject(thisMonthOfLastYearData.getValue(), Map.class); | 
 |  |  |             for (String sensor : sensors) { | 
 |  |  |                 //去年本月该因子值 | 
 |  |  |                 double thisMonthOfLeastYearValue = Double.parseDouble(map.get(sensor).toString()); | 
 |  |  |                 //当前该因子值 | 
 |  |  |                 double currentValue = Double.parseDouble(currentData.get(sensor).toString()); | 
 |  |  |                 DecimalFormat decimalFormat = new DecimalFormat("0.00%"); | 
 |  |  |                 String format = decimalFormat.format((currentValue - thisMonthOfLeastYearValue) / thisMonthOfLeastYearValue); | 
 |  |  |                 result.put(sensor + "_yearOnYear", format); | 
 |  |  |             } | 
 |  |  |         } | 
 |  |  |         return result; | 
 |  |  |     } | 
 |  |  | } |