package com.moral.api.service.impl; 
 | 
  
 | 
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.CityAqiYearly; 
 | 
import com.moral.api.mapper.CityAqiYearlyMapper; 
 | 
import com.moral.api.service.CityAqiDailyService; 
 | 
import com.moral.api.service.CityAqiYearlyService; 
 | 
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 
 | 
import com.moral.util.AmendUtils; 
 | 
import com.moral.util.ComprehensiveIndexUtils; 
 | 
import com.moral.util.DateUtils; 
 | 
  
 | 
import org.springframework.beans.factory.annotation.Autowired; 
 | 
import org.springframework.stereotype.Service; 
 | 
import org.springframework.util.ObjectUtils; 
 | 
  
 | 
import java.text.DecimalFormat; 
 | 
import java.util.ArrayList; 
 | 
import java.util.Date; 
 | 
import java.util.HashMap; 
 | 
import java.util.List; 
 | 
import java.util.Map; 
 | 
import java.util.stream.Collectors; 
 | 
  
 | 
/** 
 | 
 * <p> 
 | 
 * 城市aqi年数据表 服务实现类 
 | 
 * </p> 
 | 
 * 
 | 
 * @author moral 
 | 
 * @since 2021-11-04 
 | 
 */ 
 | 
@Service 
 | 
public class CityAqiYearlyServiceImpl extends ServiceImpl<CityAqiYearlyMapper, CityAqiYearly> implements CityAqiYearlyService { 
 | 
  
 | 
    @Autowired 
 | 
    private CityAqiDailyService cityAqiDailyService; 
 | 
  
 | 
    @Autowired 
 | 
    private CityAqiYearlyMapper cityAqiYearlyMapper; 
 | 
  
 | 
  
 | 
    @Override 
 | 
    public void insertCityAqiYearly() { 
 | 
        /* 
 | 
         * 年均值算法 
 | 
         * PM2.5,PM10,CO,日均值95百分位 
 | 
         * SO2,NO2,日均值98百分位 
 | 
         * O3,日最大值90百分位 
 | 
         * */ 
 | 
  
 | 
        //开始时间,去年1号 
 | 
        Date start = DateUtils.getFirstDayOfLastYear(); 
 | 
        //上上年 
 | 
        Date lastLastYear = DateUtils.getDate(DateUtils.getDateAddYear(DateUtils.dateToDateString(start, DateUtils.yyyy), -1), DateUtils.yyyy); 
 | 
        //结束时间,本年1号 
 | 
        Date end = DateUtils.getDate(DateUtils.getDateAddYear(DateUtils.dateToDateString(start, DateUtils.yyyy), 1), DateUtils.yyyy); 
 | 
  
 | 
        //如果是1月1号,先删除去年数据 
 | 
        //不是1月1号,统计的是本年累计值,先删除本年数据 
 | 
        String monthAndDay = DateUtils.dateToDateString(new Date(), DateUtils.MM_dd_EN); 
 | 
        UpdateWrapper<CityAqiYearly> cityAqiYearlyUpdateWrapper = new UpdateWrapper<>(); 
 | 
        if ("01-01".equals(monthAndDay)) { 
 | 
            cityAqiYearlyUpdateWrapper.eq("time", start); 
 | 
        } else { 
 | 
            start = end; 
 | 
            end = DateUtils.getDate(DateUtils.getDateAddYear(DateUtils.dateToDateString(start, DateUtils.yyyy), 1), DateUtils.yyyy); 
 | 
            lastLastYear = DateUtils.getDate(DateUtils.getDateAddYear(DateUtils.dateToDateString(start, DateUtils.yyyy), -1), DateUtils.yyyy); 
 | 
            cityAqiYearlyUpdateWrapper.eq("time", start); 
 | 
        } 
 | 
        cityAqiYearlyMapper.delete(cityAqiYearlyUpdateWrapper); 
 | 
  
 | 
  
 | 
        //获取所有城市aqi日数据 
 | 
        QueryWrapper<CityAqiDaily> wrapper = new QueryWrapper<>(); 
 | 
        wrapper.select("city_code", "time", "value") 
 | 
                .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.stream() 
 | 
                .collect(Collectors.groupingBy(o -> o.get("city_code").toString())); 
 | 
  
 | 
        //上年数据 
 | 
        QueryWrapper<CityAqiYearly> queryWrapper = new QueryWrapper<>(); 
 | 
        queryWrapper.select("city_code", "value") 
 | 
                .eq("time", lastLastYear); 
 | 
        //获取上年数据 
 | 
        List<CityAqiYearly> lastCityAqiYearlyList = cityAqiYearlyMapper.selectList(queryWrapper); 
 | 
        Map<Integer, CityAqiYearly> lastYearData = new HashMap<>(); 
 | 
        for (CityAqiYearly cityAqiYearly : lastCityAqiYearlyList) { 
 | 
            lastYearData.put(cityAqiYearly.getCityCode(), cityAqiYearly); 
 | 
        } 
 | 
  
 | 
  
 | 
        List<CityAqiYearly> cityAqiYearlyList = new ArrayList<>(); 
 | 
  
 | 
        Date finalStart = start; 
 | 
        data.forEach((cityCode, value) -> { 
 | 
            CityAqiYearly cityAqiYearly = new CityAqiYearly(); 
 | 
            Map<String, Object> jsonMap = new HashMap<>(); 
 | 
            cityAqiYearly.setCityCode(Integer.parseInt(cityCode)); 
 | 
            cityAqiYearly.setTime(finalStart); 
 | 
  
 | 
            //PM2.5 
 | 
            Double pm25Avg = AmendUtils.getAvgOfYear(value, "PM2_5"); 
 | 
            jsonMap.put("PM2_5", pm25Avg); 
 | 
  
 | 
            //PM10 
 | 
            Double pm10Avg = AmendUtils.getAvgOfYear(value, "PM10"); 
 | 
            jsonMap.put("PM10", pm10Avg); 
 | 
  
 | 
            //SO2 
 | 
            Double so2Avg = AmendUtils.getAvgOfYear(value, "SO2"); 
 | 
            jsonMap.put("SO2", so2Avg); 
 | 
  
 | 
            //NO2 
 | 
            Double no2Avg = AmendUtils.getAvgOfYear(value, "NO2"); 
 | 
            jsonMap.put("NO2", no2Avg); 
 | 
  
 | 
            //CO 
 | 
            Double coAvg = AmendUtils.getAvgOfYear(value, "CO"); 
 | 
            jsonMap.put("CO", coAvg); 
 | 
  
 | 
            //O3 
 | 
            Double o3Avg = AmendUtils.getAvgOfYear(value, "O3"); 
 | 
            jsonMap.put("O3", o3Avg); 
 | 
  
 | 
            //本月月综指计算 
 | 
            Double compositeIndex = ComprehensiveIndexUtils.dailyData(jsonMap); 
 | 
            jsonMap.put("compositeIndex", compositeIndex); 
 | 
  
 | 
            //上年数据同本年对比 
 | 
            CityAqiYearly lastCityAqiYearly = lastYearData.get(Integer.parseInt(cityCode)); 
 | 
            if (lastCityAqiYearly != null) { 
 | 
                Map<String, Object> map = JSONObject.parseObject(lastCityAqiYearly.getValue(), Map.class); 
 | 
                double lastCompositeIndex = Double.parseDouble(map.get("compositeIndex").toString()); 
 | 
                DecimalFormat decimalFormat = new DecimalFormat("0.00%"); 
 | 
                String format = decimalFormat.format((compositeIndex - lastCompositeIndex) / lastCompositeIndex); 
 | 
                jsonMap.put("yearContrast", format); 
 | 
            } 
 | 
            cityAqiYearly.setValue(JSONObject.toJSONString(jsonMap)); 
 | 
            cityAqiYearlyList.add(cityAqiYearly); 
 | 
        }); 
 | 
        cityAqiYearlyMapper.insertCityAqiYearly(cityAqiYearlyList); 
 | 
    } 
 | 
} 
 |