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; /** *

* 行业贡献率相关接口 *

* * @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 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> getProfessionsByOrganizationId(Integer organizationId) { //获取该组织下所有设备 List> devices = deviceService.getDevicesByOrganizationId(organizationId); Set> result = new HashSet<>(); for (Map device : devices) { List> professions = (List>) device.get("professions"); result.addAll(professions); } return result; } @Override public Set> getSensorByProfessionsAndOrganizationId(Map params) { Set> result = new HashSet<>(); //获取属于该行业所有设备 Integer orgId = Integer.parseInt(params.get("organizationId").toString()); List professions = Arrays.asList(params.get("professions").toString().split(",")); List devices = getDevicesOfProfessions(orgId, professions); //从redis获取设备详细信息 for (Device device : devices) { device = (Device) redisTemplate.opsForHash().get(RedisConstants.DEVICE_INFO, device.getMac()); List sensors = device.getVersion().getSensors(); for (Sensor sensor : sensors) { Map sensorMap = new HashMap<>(); sensorMap.put("sensorCode", sensor.getCode()); sensorMap.put("sensorName", sensor.getName()); result.add(sensorMap); } } return result; } private List getDevicesOfProfessions(Integer orgId, List professions) { QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.select("mac", "profession") .eq("organization_id", orgId) .eq("is_delete", Constants.NOT_DELETE); List 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> professionContribution(Map params) { int orgId = Integer.parseInt(params.get("organizationId").toString()); List 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> 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> professionContributionOfYear(Integer orgId, List professions, String time, String sensorCode) { List> result = new ArrayList<>(); //该组织所有设备信息 List allMacs = getMacsByOrgId(orgId); List timeLag = DateUtils.getTimeLag(time); for (String yearMonth : timeLag) { Map resultMap = new HashMap<>(); resultMap.put("time", yearMonth.split("-")[1]); yearMonth = yearMonth + "-01 00:00:00"; //所有设备该因子累加值 Double allDeviceSum = null; QueryWrapper historyMonthlyQueryWrapper = new QueryWrapper<>(); historyMonthlyQueryWrapper.select("SUM(`value`->'$." + sensorCode + "') AS result") .eq("time", yearMonth) .in("mac", allMacs); Map allDeviceSumMap = historyMonthlyService.getMap(historyMonthlyQueryWrapper); if (!ObjectUtils.isEmpty(allDeviceSumMap)) { allDeviceSum = (Double) allDeviceSumMap.get("result"); } //本市数据 Double cityValue = null; //根据组织获取区域定位 Integer locationLevelCode = organizationService.getById(orgId).getLocationLevelCode(); QueryWrapper cityAqiMonthlyQueryWrapper = new QueryWrapper<>(); cityAqiMonthlyQueryWrapper.select("`value`->'$." + sensorCode + "' AS result") .eq("city_code", locationLevelCode) .eq("time", yearMonth); Map cityValueMap = cityAqiMonthlyService.getMap(cityAqiMonthlyQueryWrapper); if (!ObjectUtils.isEmpty(cityValueMap)) { cityValue = (Double) cityValueMap.get("result"); } resultMap.put("cityValue", cityValue); for (String profession : professions) { Map professionMap = new HashMap<>(); //获取该行业设备 List devices = getDevicesOfProfessions(orgId, Collections.singletonList(profession)); List 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 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 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> professionContributionOfMonth(Integer orgId, List professions, String time, String sensorCode) { List> result = new ArrayList<>(); //该组织所有设备信息 List allMacs = getMacsByOrgId(orgId); List timeLag = DateUtils.getTimeLag(time); for (String yearMonthDay : timeLag) { Map resultMap = new HashMap<>(); resultMap.put("time", yearMonthDay.split("-")[2]); yearMonthDay = yearMonthDay + " 00:00:00"; //所有设备该因子累加值 Double allDeviceSum = null; QueryWrapper historyDailyQueryWrapper = new QueryWrapper<>(); historyDailyQueryWrapper.select("SUM(`value`->'$." + sensorCode + "') AS result") .eq("time", yearMonthDay) .in("mac", allMacs); Map allDeviceSumMap = historyDailyService.getMap(historyDailyQueryWrapper); if (!ObjectUtils.isEmpty(allDeviceSumMap)) { allDeviceSum = (Double) allDeviceSumMap.get("result"); } //本市数据 Double cityValue = null; //根据组织获取区域定位 Integer locationLevelCode = organizationService.getById(orgId).getLocationLevelCode(); QueryWrapper cityAqiDailyQueryWrapper = new QueryWrapper<>(); cityAqiDailyQueryWrapper.select("`value`->'$." + sensorCode + "' AS result") .eq("city_code", locationLevelCode) .eq("time", yearMonthDay); Map cityValueMap = cityAqiDailyService.getMap(cityAqiDailyQueryWrapper); if (!ObjectUtils.isEmpty(cityValueMap)) { cityValue = (Double) cityValueMap.get("result"); } resultMap.put("cityValue", cityValue); for (String profession : professions) { Map professionMap = new HashMap<>(); //获取该行业设备 List devices = getDevicesOfProfessions(orgId, Collections.singletonList(profession)); List 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 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 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> professionContributionOfDay(Integer orgId, List professions, String time, String sensorCode) { List> result = new ArrayList<>(); //该组织所有设备信息 List allMacs = getMacsByOrgId(orgId); List timeLag = DateUtils.getTimeLag(time); for (String yearMonthDayHour : timeLag) { Map 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 cityAqiQueryWrapper = new QueryWrapper<>(); cityAqiQueryWrapper.select("`value`->'$." + sensorCode + "' AS result") .eq("city_code", locationLevelCode) .eq("time", yearMonthDayHour); Map cityValueMap = cityAqiService.getMap(cityAqiQueryWrapper); if (!ObjectUtils.isEmpty(cityValueMap)) { cityValue = (Double) cityValueMap.get("result"); } resultMap.put("cityValue", cityValue); for (String profession : professions) { Map professionMap = new HashMap<>(); //获取该行业设备 List devices = getDevicesOfProfessions(orgId, Collections.singletonList(profession)); List 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 deviceQueryWrapper = new QueryWrapper<>(); deviceQueryWrapper.select("mac") .eq("organization_id", orgId) .eq("is_delete", Constants.NOT_DELETE); return deviceService.listObjs(deviceQueryWrapper); } }