package com.moral.api.service.impl;
|
|
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.NumberFormat;
|
import java.util.ArrayList;
|
import java.util.Arrays;
|
import java.util.Collections;
|
import java.util.HashMap;
|
import java.util.HashSet;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.Set;
|
import java.util.stream.Collectors;
|
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.moral.api.entity.CityAqi;
|
import com.moral.api.entity.CityAqiDaily;
|
import com.moral.api.entity.CityAqiMonthly;
|
import com.moral.api.entity.Device;
|
import com.moral.api.entity.HistoryDaily;
|
import com.moral.api.entity.HistoryMonthly;
|
import com.moral.api.entity.Sensor;
|
import com.moral.api.service.CityAqiDailyService;
|
import com.moral.api.service.CityAqiMonthlyService;
|
import com.moral.api.service.CityAqiService;
|
import com.moral.api.service.DeviceService;
|
import com.moral.api.service.HistoryDailyService;
|
import com.moral.api.service.HistoryHourlyService;
|
import com.moral.api.service.HistoryMonthlyService;
|
import com.moral.api.service.OrganizationService;
|
import com.moral.api.service.ProfessionService;
|
|
import com.moral.constant.Constants;
|
import com.moral.constant.RedisConstants;
|
|
import com.moral.util.AmendUtils;
|
import com.moral.util.DateUtils;
|
|
/**
|
* <p>
|
* 行业贡献率相关接口
|
* </p>
|
*
|
* @author moral
|
* @since 2021-12-23
|
*/
|
@Service
|
public class ProfessionServiceImpl implements ProfessionService {
|
|
@Autowired
|
private DeviceService deviceService;
|
|
@Autowired
|
private RedisTemplate redisTemplate;
|
|
@Autowired
|
private HistoryMonthlyService historyMonthlyService;
|
|
@Autowired
|
private HistoryDailyService historyDailyService;
|
|
@Autowired
|
private HistoryHourlyService historyHourlyService;
|
|
@Autowired
|
private CityAqiMonthlyService cityAqiMonthlyService;
|
|
@Autowired
|
private CityAqiDailyService cityAqiDailyService;
|
|
@Autowired
|
private CityAqiService cityAqiService;
|
|
@Autowired
|
private OrganizationService organizationService;
|
|
private static Map<String, String> senorMap = new HashMap<>();
|
|
static {
|
senorMap.put(Constants.SENSOR_CODE_PM25, "PM2_5");
|
senorMap.put(Constants.SENSOR_CODE_PM10, "PM10");
|
senorMap.put(Constants.SENSOR_CODE_SO2, "SO2");
|
senorMap.put(Constants.SENSOR_CODE_NO2, "NO2");
|
senorMap.put(Constants.SENSOR_CODE_CO, "CO");
|
senorMap.put(Constants.SENSOR_CODE_O3, "O3");
|
}
|
|
@Override
|
public Set<Map<String, Object>> getProfessionsByOrganizationId(Integer organizationId) {
|
//获取该组织下所有设备
|
List<Map<String, Object>> devices = deviceService.getDevicesByOrganizationId(organizationId);
|
Set<Map<String, Object>> result = new HashSet<>();
|
for (Map<String, Object> device : devices) {
|
List<Map<String, Object>> professions = (List<Map<String, Object>>) device.get("professions");
|
result.addAll(professions);
|
}
|
return result;
|
}
|
|
@Override
|
public Set<Map<String, Object>> getSensorByProfessionsAndOrganizationId(Map<String, Object> params) {
|
Set<Map<String, Object>> result = new HashSet<>();
|
//获取属于该行业所有设备
|
Integer orgId = Integer.parseInt(params.get("organizationId").toString());
|
List<String> professions = Arrays.asList(params.get("professions").toString().split(","));
|
List<Device> devices = getDevicesOfProfessions(orgId, professions);
|
//从redis获取设备详细信息
|
for (Device device : devices) {
|
device = (Device) redisTemplate.opsForHash().get(RedisConstants.DEVICE_INFO, device.getMac());
|
List<Sensor> sensors = device.getVersion().getSensors();
|
for (Sensor sensor : sensors) {
|
Map<String, Object> sensorMap = new HashMap<>();
|
sensorMap.put("sensorCode", sensor.getCode());
|
sensorMap.put("sensorName", sensor.getName());
|
result.add(sensorMap);
|
}
|
}
|
return result;
|
}
|
|
private List<Device> getDevicesOfProfessions(Integer orgId, List<String> professions) {
|
QueryWrapper<Device> queryWrapper = new QueryWrapper<>();
|
queryWrapper.select("mac", "profession")
|
.eq("organization_id", orgId)
|
.eq("is_delete", Constants.NOT_DELETE);
|
List<Device> devices = deviceService.list(queryWrapper);
|
devices = devices.stream().filter(device -> {
|
String[] list = device.getProfession().split(",");
|
for (String s : list) {
|
if (professions.contains(s)) {
|
return true;
|
}
|
}
|
return false;
|
}).collect(Collectors.toList());
|
return devices;
|
}
|
|
@Override
|
public List<Map<String, Object>> professionContribution(Map<String, Object> params) {
|
int orgId = Integer.parseInt(params.get("organizationId").toString());
|
List<String> professions = Arrays.asList(params.get("professions").toString().split(","));
|
String type = params.get("type").toString();
|
String time = params.get("time").toString();
|
String sensorCode = params.get("sensorCode").toString();
|
List<Map<String, Object>> result = new ArrayList<>();
|
|
switch (type) {
|
case "year":
|
result = professionContributionOfYear(orgId, professions, time, sensorCode);
|
break;
|
case "month":
|
result = professionContributionOfMonth(orgId, professions, time, sensorCode);
|
break;
|
case "day":
|
result = professionContributionOfDay(orgId, professions, time, sensorCode);
|
break;
|
default:
|
break;
|
}
|
return result;
|
}
|
|
//贡献率,年
|
private List<Map<String, Object>> professionContributionOfYear(Integer orgId, List<String> professions, String time, String sensorCode) {
|
List<Map<String, Object>> result = new ArrayList<>();
|
|
//该组织所有设备信息
|
List allMacs = getMacsByOrgId(orgId);
|
|
List<String> timeLag = DateUtils.getTimeLag(time);
|
for (String yearMonth : timeLag) {
|
Map<String, Object> resultMap = new HashMap<>();
|
resultMap.put("time", yearMonth.split("-")[1]);
|
yearMonth = yearMonth + "-01 00:00:00";
|
|
|
//所有设备该因子累加值
|
Double allDeviceSum = null;
|
QueryWrapper<HistoryMonthly> historyMonthlyQueryWrapper = new QueryWrapper<>();
|
historyMonthlyQueryWrapper.select("SUM(`value`->'$." + sensorCode + "') AS result")
|
.eq("time", yearMonth)
|
.in("mac", allMacs);
|
Map<String, Object> allDeviceSumMap = historyMonthlyService.getMap(historyMonthlyQueryWrapper);
|
if (!ObjectUtils.isEmpty(allDeviceSumMap)) {
|
allDeviceSum = (Double) allDeviceSumMap.get("result");
|
}
|
|
|
//本市数据
|
Double cityValue = null;
|
//根据组织获取区域定位
|
Integer locationLevelCode = organizationService.getById(orgId).getLocationLevelCode();
|
QueryWrapper<CityAqiMonthly> cityAqiMonthlyQueryWrapper = new QueryWrapper<>();
|
cityAqiMonthlyQueryWrapper.select("`value`->'$." + sensorCode + "' AS result")
|
.eq("city_code", locationLevelCode)
|
.eq("time", yearMonth);
|
Map<String, Object> cityValueMap = cityAqiMonthlyService.getMap(cityAqiMonthlyQueryWrapper);
|
if (!ObjectUtils.isEmpty(cityValueMap)) {
|
cityValue = (Double) cityValueMap.get("result");
|
}
|
resultMap.put("cityValue", cityValue);
|
|
|
for (String profession : professions) {
|
Map<String, Object> professionMap = new HashMap<>();
|
|
//获取该行业设备
|
List<Device> devices = getDevicesOfProfessions(orgId, Collections.singletonList(profession));
|
List<String> professionMacs = devices.stream().map(Device::getMac).collect(Collectors.toList());
|
|
|
//该行业累加值
|
Double professionSum = null;
|
historyMonthlyQueryWrapper.clear();
|
historyMonthlyQueryWrapper.select("SUM(`value`->'$." + sensorCode + "') AS result")
|
.eq("time", yearMonth)
|
.in("mac", professionMacs);
|
Map<String, Object> professionSumMap = historyMonthlyService.getMap(historyMonthlyQueryWrapper);
|
if (!ObjectUtils.isEmpty(professionSumMap)) {
|
professionSum = (Double) professionSumMap.get("result");
|
}
|
|
|
//该行业平均值
|
Double professionAvg = null;
|
historyMonthlyQueryWrapper.clear();
|
historyMonthlyQueryWrapper.select("AVG(`value`->'$." + sensorCode + "') AS result")
|
.eq("time", yearMonth)
|
.in("mac", professionMacs);
|
Map<String, Object> professionAvgMap = historyMonthlyService.getMap(historyMonthlyQueryWrapper);
|
if (!ObjectUtils.isEmpty(professionAvgMap)) {
|
professionAvg = (Double) professionAvgMap.get("result");
|
}
|
|
//行业贡献率计算
|
String contributionRate = null;
|
NumberFormat numberFormat = NumberFormat.getInstance();
|
numberFormat.setMaximumFractionDigits(2);
|
if (professionSum != null && allDeviceSum != null) {
|
contributionRate = numberFormat.format(professionSum / allDeviceSum * 100) + "%";
|
}
|
|
//行业均值
|
professionMap.put("value", professionAvg == null ? null : AmendUtils.sciCal(professionAvg, 0));
|
//行业贡献率
|
professionMap.put("contributionRate", contributionRate);
|
|
resultMap.put(profession, professionMap);
|
}
|
result.add(resultMap);
|
}
|
return result;
|
}
|
|
//贡献率,月
|
private List<Map<String, Object>> professionContributionOfMonth(Integer orgId, List<String> professions, String time, String sensorCode) {
|
List<Map<String, Object>> result = new ArrayList<>();
|
|
//该组织所有设备信息
|
List allMacs = getMacsByOrgId(orgId);
|
|
List<String> timeLag = DateUtils.getTimeLag(time);
|
for (String yearMonthDay : timeLag) {
|
Map<String, Object> resultMap = new HashMap<>();
|
resultMap.put("time", yearMonthDay.split("-")[2]);
|
yearMonthDay = yearMonthDay + " 00:00:00";
|
|
|
//所有设备该因子累加值
|
Double allDeviceSum = null;
|
QueryWrapper<HistoryDaily> historyDailyQueryWrapper = new QueryWrapper<>();
|
historyDailyQueryWrapper.select("SUM(`value`->'$." + sensorCode + "') AS result")
|
.eq("time", yearMonthDay)
|
.in("mac", allMacs);
|
Map<String, Object> allDeviceSumMap = historyDailyService.getMap(historyDailyQueryWrapper);
|
if (!ObjectUtils.isEmpty(allDeviceSumMap)) {
|
allDeviceSum = (Double) allDeviceSumMap.get("result");
|
}
|
|
|
//本市数据
|
Double cityValue = null;
|
//根据组织获取区域定位
|
Integer locationLevelCode = organizationService.getById(orgId).getLocationLevelCode();
|
QueryWrapper<CityAqiDaily> cityAqiDailyQueryWrapper = new QueryWrapper<>();
|
cityAqiDailyQueryWrapper.select("`value`->'$." + sensorCode + "' AS result")
|
.eq("city_code", locationLevelCode)
|
.eq("time", yearMonthDay);
|
Map<String, Object> cityValueMap = cityAqiDailyService.getMap(cityAqiDailyQueryWrapper);
|
if (!ObjectUtils.isEmpty(cityValueMap)) {
|
cityValue = (Double) cityValueMap.get("result");
|
}
|
resultMap.put("cityValue", cityValue);
|
|
|
|
for (String profession : professions) {
|
Map<String, Object> professionMap = new HashMap<>();
|
|
//获取该行业设备
|
List<Device> devices = getDevicesOfProfessions(orgId, Collections.singletonList(profession));
|
List<String> professionMacs = devices.stream().map(Device::getMac).collect(Collectors.toList());
|
|
|
//该行业累加值
|
Double professionSum = null;
|
historyDailyQueryWrapper.clear();
|
historyDailyQueryWrapper.select("SUM(`value`->'$." + sensorCode + "') AS result")
|
.eq("time", yearMonthDay)
|
.in("mac", professionMacs);
|
Map<String, Object> professionSumMap = historyDailyService.getMap(historyDailyQueryWrapper);
|
if (!ObjectUtils.isEmpty(professionSumMap)) {
|
professionSum = (Double) professionSumMap.get("result");
|
}
|
|
|
//该行业平均值
|
Double professionAvg = null;
|
historyDailyQueryWrapper.clear();
|
historyDailyQueryWrapper.select("AVG(`value`->'$." + sensorCode + "') AS result")
|
.eq("time", yearMonthDay)
|
.in("mac", professionMacs);
|
Map<String, Object> professionAvgMap = historyDailyService.getMap(historyDailyQueryWrapper);
|
if (!ObjectUtils.isEmpty(professionAvgMap)) {
|
professionAvg = (Double) professionAvgMap.get("result");
|
}
|
|
|
//行业贡献率计算
|
String contributionRate = null;
|
NumberFormat numberFormat = NumberFormat.getInstance();
|
numberFormat.setMaximumFractionDigits(2);
|
if (professionSum != null && allDeviceSum != null) {
|
contributionRate = numberFormat.format(professionSum / allDeviceSum * 100) + "%";
|
}
|
|
//行业均值
|
professionMap.put("value", professionAvg == null ? null : AmendUtils.sciCal(professionAvg, 0));
|
//行业贡献率
|
professionMap.put("contributionRate", contributionRate);
|
|
resultMap.put(profession, professionMap);
|
}
|
result.add(resultMap);
|
}
|
return result;
|
}
|
|
private List<Map<String, Object>> professionContributionOfDay(Integer orgId, List<String> professions, String time, String sensorCode) {
|
List<Map<String, Object>> result = new ArrayList<>();
|
|
//该组织所有设备信息
|
List allMacs = getMacsByOrgId(orgId);
|
|
List<String> timeLag = DateUtils.getTimeLag(time);
|
for (String yearMonthDayHour : timeLag) {
|
Map<String, Object> resultMap = new HashMap<>();
|
resultMap.put("time", yearMonthDayHour.split(" ")[1]);
|
yearMonthDayHour = yearMonthDayHour + ":00:00";
|
|
|
//所有设备该因子累加值
|
Double allDeviceSum = historyHourlyService.getSensorSumByMacs(sensorCode, allMacs, yearMonthDayHour);
|
|
|
//本市数据
|
Double cityValue = null;
|
//根据组织获取区域定位
|
Integer locationLevelCode = organizationService.getById(orgId).getLocationLevelCode();
|
QueryWrapper<CityAqi> cityAqiQueryWrapper = new QueryWrapper<>();
|
cityAqiQueryWrapper.select("`value`->'$." + sensorCode + "' AS result")
|
.eq("city_code", locationLevelCode)
|
.eq("time", yearMonthDayHour);
|
Map<String, Object> cityValueMap = cityAqiService.getMap(cityAqiQueryWrapper);
|
if (!ObjectUtils.isEmpty(cityValueMap)) {
|
cityValue = (Double) cityValueMap.get("result");
|
}
|
resultMap.put("cityValue", cityValue);
|
|
|
for (String profession : professions) {
|
Map<String, Object> professionMap = new HashMap<>();
|
|
//获取该行业设备
|
List<Device> devices = getDevicesOfProfessions(orgId, Collections.singletonList(profession));
|
List<String> professionMacs = devices.stream().map(Device::getMac).collect(Collectors.toList());
|
|
//获取该行业设备数据,累加值,平均值
|
Double professionAvg = historyHourlyService.getSensorAvgByMacs(sensorCode, professionMacs, yearMonthDayHour);
|
Double professionSum = historyHourlyService.getSensorSumByMacs(sensorCode, professionMacs, yearMonthDayHour);
|
|
//行业贡献率计算
|
String contributionRate = null;
|
NumberFormat numberFormat = NumberFormat.getInstance();
|
numberFormat.setMaximumFractionDigits(2);
|
if (professionSum != null && allDeviceSum != null) {
|
contributionRate = numberFormat.format(professionSum / allDeviceSum * 100) + "%";
|
}
|
|
//行业均值
|
professionMap.put("value", professionAvg == null ? null : AmendUtils.sciCal(professionAvg, 0));
|
//行业贡献率
|
professionMap.put("contributionRate", contributionRate);
|
|
resultMap.put(profession, professionMap);
|
}
|
result.add(resultMap);
|
}
|
return result;
|
}
|
|
//根据组织id获取设备macs
|
private List getMacsByOrgId(Integer orgId) {
|
//该组织所有设备信息
|
QueryWrapper<Device> deviceQueryWrapper = new QueryWrapper<>();
|
deviceQueryWrapper.select("mac")
|
.eq("organization_id", orgId)
|
.eq("is_delete", Constants.NOT_DELETE);
|
return deviceService.listObjs(deviceQueryWrapper);
|
}
|
|
|
}
|