package com.moral.api.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.moral.api.config.properties.AnnouncementProperties;
import com.moral.api.config.properties.SpecialCitiesProperties;
import com.moral.api.entity.CityAqiDaily;
import com.moral.api.entity.CityAqiMonthly;
import com.moral.api.entity.SysArea;
import com.moral.api.mapper.CityAqiMonthlyMapper;
import com.moral.api.service.CityAqiDailyService;
import com.moral.api.service.CityAqiMonthlyService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.moral.api.service.SysAreaService;
import com.moral.constant.Constants;
import com.moral.constant.RedisConstants;
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.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import java.text.DecimalFormat;
import java.time.Duration;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.DoubleStream;
/**
*
* 城市aqi月数据表 服务实现类
*
*
* @author moral
* @since 2021-11-05
*/
@Service
public class CityAqiMonthlyServiceImpl extends ServiceImpl implements CityAqiMonthlyService {
@Autowired
private CityAqiMonthlyMapper cityAqiMonthlyMapper;
@Autowired
private SpecialCitiesProperties specialCitiesProperties;
@Autowired
private SysAreaService sysAreaService;
@Autowired
private CityAqiDailyService cityAqiDailyService;
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private AnnouncementProperties announcementProperties;
@Override
public List getCityAqiMonthByRegionCodeAndTime(Integer regionCode, Date startDate, Date endDate) {
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.eq("city_code", regionCode);
queryWrapper.between("time", startDate, endDate);
return cityAqiMonthlyMapper.selectList(queryWrapper);
}
@Override
public CityAqiMonthly getCityAqiMonthByRegionCodeAndTime(Integer regionCode, Date time) {
time = DateUtils.getFirstDayOfMonth(time);
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.eq("city_code", regionCode);
queryWrapper.eq("time", time);
return cityAqiMonthlyMapper.selectOne(queryWrapper);
}
@Override
public Map airQualityRankingAnnouncement(Integer regionCode, Date time) {
Map result = new LinkedHashMap<>();
String month = DateUtils.getMonth(time) + "";
int yearMonthOfSelect = Integer.parseInt(DateUtils.dateToDateString(time, DateUtils.yyyyMM_EN));
int nowYearMonthOfSelect = Integer.parseInt(DateUtils.getCurDate(DateUtils.yyyyMM_EN));
if (yearMonthOfSelect > nowYearMonthOfSelect) {
return result;
}
//先根据时间和地区code从redis中获取,没有再计算后存入redis
result = (Map) redisTemplate.opsForValue().get(RedisConstants.AQI_ANNOUNCEMENT + "_" + regionCode + "_" + DateUtils.dateToDateString(time, DateUtils.yyyyMM_EN));
if (result != null) {
return result;
}
result = new LinkedHashMap<>();
//获取xx市和所有县市区名字信息
QueryWrapper sysAreaQueryWrapper = new QueryWrapper<>();
sysAreaQueryWrapper.select("area_code", "area_name")
.eq("parent_code", regionCode).or()
.eq("area_code", regionCode);
List sysAreas = sysAreaService.list(sysAreaQueryWrapper);
Map areasMap = new HashMap<>();
for (SysArea sysArea : sysAreas) {
areasMap.put(sysArea.getAreaCode(), sysArea.getAreaName());
}
String cityName = areasMap.remove(regionCode);
result.put("cityName", cityName);
result.put("areaSize", areasMap.size());
//一、空气质量排名
//1.本月xx市空气质量排名
Map currentRankingResult = new HashMap<>();
//获取本月xx市空气质量数据
QueryWrapper cityAqiMonthlyQueryWrapper = new QueryWrapper<>();
cityAqiMonthlyQueryWrapper.select("value")
.eq("city_code", regionCode)
.eq("time", time);
CityAqiMonthly cityAqiMonthly = cityAqiMonthlyMapper.selectOne(cityAqiMonthlyQueryWrapper);
Double compositeIndex = null;
String compositeIndexYearOnYear = null;
Double pm25 = null;
String pm25YearOnYear = null;
if (cityAqiMonthly != null) {
Map aqiMap = JSONObject.parseObject(cityAqiMonthly.getValue(), Map.class);
//1.综指
if (aqiMap.get("compositeIndex") != null) {
compositeIndex = Double.parseDouble(aqiMap.get("compositeIndex").toString());
}
currentRankingResult.put("compositeIndex", compositeIndex);
//2.综指同比
if (aqiMap.get("compositeIndex_yearOnYear") != null) {
compositeIndexYearOnYear = aqiMap.get("compositeIndex_yearOnYear").toString();
}
currentRankingResult.put("compositeIndex_yearOnYear", compositeIndexYearOnYear);
//3.PM2.5浓度
if (aqiMap.get("PM2_5") != null) {
pm25 = Objects.nonNull(aqiMap.get("PM2_5"))?Double.parseDouble(aqiMap.get("PM2_5").toString()):0d;
}
currentRankingResult.put("PM2_5", pm25 + "ug/m³");
//4.PM.5浓度同比
if (aqiMap.get("PM2_5_yearOnYear") != null) {
pm25YearOnYear = aqiMap.get("PM2_5_yearOnYear").toString();
}
currentRankingResult.put("PM2_5_yearOnYear", pm25YearOnYear);
//5.168城市排名,包括综指,综指同比,pm2.5,pm2.5同比
Map ranking168 = getOneSixEightCitiesRanking(regionCode, time);
currentRankingResult.putAll(ranking168);
//6.2+26城市排名,包括综指,综指同比,pm2.5,pm2.5同比
Map ranking28 = getTwentyEightCitiesRanking(regionCode, time);
currentRankingResult.putAll(ranking28);
//7.河北八通道城市排名,包括综指,综指同比,pm2.5,pm2.5同比
Map ranking8Channels = getHeBeiEightCitiesRanking(regionCode, time);
currentRankingResult.putAll(ranking8Channels);
}
String start = DateUtils.dateToDateString(time, DateUtils.yyyy_MM_dd_CN);
//本月最后一日
String end = DateUtils.dateToDateString(DateUtils.getLastDayOfMonth(time), DateUtils.yyyy_MM_dd_CN);
result.put("currentRanking", aqiQualityRankingResponse(start + "-" + end, cityName, currentRankingResult));
//2.1-x月xx市空气质量排名
//所有县市区codes
List areaCodes = new ArrayList<>(areasMap.keySet());
//地级市code
areaCodes.add(regionCode);
Map> monthlyCumulativeResult = null;
Double cityCompositeIndex = null;
String cityCompositeIndexYearOnYear = null;
Double cityPM25 = null;
String cityPM25YearOnYear = null;
if (!"1".equals(month)) {
Map cumulativeRankingResult = new HashMap<>();
//获取xx市和下属所有县市区1-xx月数据
monthlyCumulativeResult = getMonthlyCumulativeResult(time, areaCodes);
//xx市数据
if (monthlyCumulativeResult != null) {
Map cityMap = monthlyCumulativeResult.remove(regionCode);
if (cityMap != null) {
//地级市综指
cityCompositeIndex = Double.parseDouble(cityMap.get("compositeIndex").toString());
if (cityMap.get("compositeIndex_yearOnYear") != null) {
cityCompositeIndexYearOnYear = cityMap.get("compositeIndex_yearOnYear").toString();
}
//地级市PM2.5
cityPM25 = Double.parseDouble(cityMap.get("PM2_5").toString());
if (cityMap.get("PM2_5_yearOnYear") != null) {
cityPM25YearOnYear = cityMap.get("PM2_5_yearOnYear").toString();
}
}
}
cumulativeRankingResult.put("compositeIndex", cityCompositeIndex);
cumulativeRankingResult.put("compositeIndex_yearOnYear", cityCompositeIndexYearOnYear);
cumulativeRankingResult.put("PM2_5", cityPM25);
if (cityPM25 != null) {
cumulativeRankingResult.put("PM2_5", cityPM25 + "ug/m³");
}
cumulativeRankingResult.put("PM2_5_yearOnYear", cityPM25YearOnYear);
//5.168城市排名,包括综指,综指同比,pm2.5,pm2.5同比
Map ranking168 = getOneSixEightCitiesRankingOfCumulative(regionCode, time);
cumulativeRankingResult.putAll(ranking168);
//6.2+26城市排名,包括综指,综指同比,pm2.5,pm2.5同比
Map ranking28 = getTwentyEightCitiesRankingOfCumulative(regionCode, time);
cumulativeRankingResult.putAll(ranking28);
//7.河北八通道城市排名,包括综指,综指同比,pm2.5,pm2.5同比
Map ranking8Channels = getHeBeiEightCitiesRankingOfCumulative(regionCode, time);
cumulativeRankingResult.putAll(ranking8Channels);
//开始时间,当年1月1日
start = DateUtils.dateToDateString(DateUtils.getFirstDayOfYear(time), DateUtils.yyyy_MM_dd_CN);
//结束时间,当月最后一天
end = DateUtils.dateToDateString(DateUtils.getLastDayOfMonth(time), DateUtils.yyyy_MM_dd_CN);
result.put("cumulativeRanking", aqiQualityRankingResponse(start + "-" + end, cityName, cumulativeRankingResult));
}
//二、各县市区空气质量情况结果集
//获取本期xx市下所有县市区数据
cityAqiMonthlyQueryWrapper.clear();
areaCodes.remove(regionCode);
cityAqiMonthlyQueryWrapper.select("city_code", "value")
.eq("time", time)
.in("city_code", areaCodes);
List areaData = cityAqiMonthlyMapper.selectList(cityAqiMonthlyQueryWrapper);
//获取本期所有县市区与中心城区(地级市)因子对比情况
Map areaCurrentMonthResult = getAreaCurrentMonthResult(areasMap, areaData, compositeIndex, compositeIndexYearOnYear, pm25, pm25YearOnYear);
//本月县市区综指与中心城区对比
result.put("currentCompositeIndexContrast", compositeIndexContrastResponse(month, cityName, areaCodes.size(), areaCurrentMonthResult));
//本月县市区综指同比与中心城区对比
result.put("currentCompositeIndexYearOnYearContrast", compositeIndexYearOnYearContrastResponse(month, cityName, areaCodes.size(), areaCurrentMonthResult));
//本月县市区PM2.5与中心城区对比
result.put("currentPM25Contrast", pm25tContrastResponse(month, cityName, areaCodes.size(), areaCurrentMonthResult));
//本月县市区Pm2.5同比与中心城区对比
result.put("currentPM25YearOnYearContrast", pm25YearOnYearContrastResponse(month, cityName, areaCodes.size(), areaCurrentMonthResult));
//三、1-x月累计结果
List cumulativeList = null;
if (!"1".equals(month)) {
cumulativeList = new ArrayList<>();
if (monthlyCumulativeResult != null) {
for (Map.Entry> entry : monthlyCumulativeResult.entrySet()) {
CityAqiMonthly cityAqiMonthly1 = new CityAqiMonthly();
cityAqiMonthly1.setCityCode(entry.getKey());
cityAqiMonthly1.setValue(JSONObject.toJSONString(entry.getValue()));
cumulativeList.add(cityAqiMonthly1);
}
}
month = "1-" + DateUtils.getMonth(time);
//获取1-x月所有县市区与地级市数据对比情况
Map monthlyCumulativeListResultMap = getAreaCurrentMonthResult(areasMap, cumulativeList, cityCompositeIndex, cityCompositeIndexYearOnYear, cityPM25, cityPM25YearOnYear);
//1-xx月份县市区综指与中心城区对比
result.put("cumulativeCompositeIndexContrast", compositeIndexContrastResponse(month, cityName, areaCodes.size(), monthlyCumulativeListResultMap));
//1-xx月份县市区综指同比与中心城区对比
result.put("cumulativeCompositeIndexYearOnYearContrast", compositeIndexYearOnYearContrastResponse(month, cityName, areaCodes.size(), monthlyCumulativeListResultMap));
//1-xx月份县市区PM2.5与中心城区对比
result.put("cumulativePM25Contrast", pm25tContrastResponse(month, cityName, areaCodes.size(), monthlyCumulativeListResultMap));
//1-xx月份县市区Pm2.5同比与中心城区对比
result.put("cumulativePM25YearOnYearContrast", pm25YearOnYearContrastResponse(month, cityName, areaCodes.size(), monthlyCumulativeListResultMap));
}
//四、附件
//1.本期综指和pm2.5考核排名报表
List