package com.zc.business.controller; import cn.hutool.core.date.DateUtil; import cn.hutool.core.lang.tree.Tree; import com.alibaba.excel.util.DateUtils; import com.github.pagehelper.util.StringUtil; import com.ruoyi.common.annotation.Log; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.poi.ExcelMultipleSheetsUtil; import com.ruoyi.common.utils.poi.ExcelUtil; import com.zc.business.constant.RedisKeyConstants; import com.zc.business.controller.queryParams.OnlineQueryParams; import com.zc.business.domain.*; import com.zc.business.enums.UniversalEnum; import com.zc.business.service.IDcRoadSectionService; import com.zc.business.service.IOnlineLogService; import com.zc.business.service.IOnlineSumService; import com.zc.business.service.impl.DcDeviceServiceImpl; import com.zc.business.utils.MathUtil; import eu.bitwalker.useragentutils.DeviceType; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.checkerframework.checker.units.qual.A; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.format.annotation.DateTimeFormat; import org.springframework.util.ObjectUtils; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.math.BigDecimal; import java.math.RoundingMode; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; import java.util.*; import java.util.stream.Collectors; @Api(tags = "设备在线监测") @RestController @RequestMapping("/system/status") public class DcDeviceOnlineController extends BaseController { @Autowired private DcDeviceServiceImpl dcDeviceService; @Resource private RedisCache redisCache; @Resource private IDcRoadSectionService dcRoadSectionService; @Resource private IOnlineSumService onlineSumService; @Resource private IOnlineLogService onlineLogService; private static final String ORDERRULE = "orderRule";//排序策略key @ApiOperation("设备状态导出") @Log(title = "【设备状态导出】", businessType = BusinessType.EXPORT) @PostMapping("/export") public void export(HttpServletResponse response, OnlineQueryParams params) { if (ObjectUtils.isEmpty(params.getType())) { return; } if (StringUtil.isEmpty(params.getOrderByField()) || "time".equals(params.getOrderByField())) { params.setOrderByField("online_rate"); } String stakeMark = params.getStakeMark(); if (stakeMark!=null) { params.setStakeMark(stakeMark.replace(UniversalEnum.BLANK_SPACE.getValue(), UniversalEnum.PLUS_SIGN.getValue())); } List sums = onlineSumService.queryByDeviceTypesOfToday(params); if (params.getExportType() != null && params.getExportType().equals(UniversalEnum.ONE.getValue())) { sums = sums.stream() .filter(OnlineSum::isLossRatePositive) .sorted(Comparator.comparing(OnlineSum::getLossRate).reversed()) .collect(Collectors.toList()); } Map> sumsMap = sums.stream().collect(Collectors.groupingBy(OnlineSum::getDeviceType)); LinkedHashMap map = new LinkedHashMap<>(); for (String deviceType : params.getType()) { List list = sumsMap.getOrDefault(deviceType, new ArrayList<>()); String typeName = DeviceType.getDescriptionByValue(deviceType); if (StringUtil.isNotEmpty(typeName)) { map.put(DeviceType.getDescriptionByValue(deviceType), list); } } ExcelMultipleSheetsUtil multipleSheetsUtil = new ExcelMultipleSheetsUtil(); multipleSheetsUtil.excelMultipleSheets(map, UniversalEnum.DEVICE_STATUS_LIST.getValue() + DateUtil.format(new Date(), "yyyyMMddHHmmss"), "xlsx", response); } @ApiOperation("设备状态列表按时间和类型") @GetMapping("/tablist") public TableDataInfo getTabList(OnlineQueryParams params) { if (ObjectUtils.isEmpty(params.getType())) { return getDataTable(new ArrayList<>()); } if (StringUtil.isEmpty(params.getOrderByField()) || "time".equals(params.getOrderByField())) { params.setOrderByField("online_rate"); } startPage(); String stakeMark = params.getStakeMark(); if (stakeMark != null) { params.setStakeMark(stakeMark.replace(UniversalEnum.BLANK_SPACE.getValue(), UniversalEnum.PLUS_SIGN.getValue())); } List sums = onlineSumService.queryByDeviceTypesOfToday(params); /*Map onlineSumMap = redisCache.getCacheMap(RedisKeyConstants.DEVICE_ONLINE); String date = LocalDate.now().toString();*/ /*for (OnlineSum sum : sums) { String deviceId = sum.getDeviceId().toString(); String hKey = date+":"+deviceId; OnlineSum online = onlineSumMap.get(hKey); if(ObjectUtils.isEmpty(online)) { continue; } sum.setLastOnlineTime(onlineSumMap.get(hKey).getLastOnlineTime()); sum.setDeviceStatus(onlineSumMap.get(hKey).getDeviceStatus()); }*/ return getDataTable(sums); } //按时间划分设备柱状图 @ApiOperation("设备状态柱状图按时间和类型") @GetMapping("/list") public AjaxResult getStatusList( @RequestParam("startTime") String startTime, @RequestParam("time") String endTime, @RequestParam("type") String[] types, @RequestParam(value = "direction", required = false) String direction) { Map> maps = new HashMap<>(); LocalDateTime start = LocalDateTime.parse(startTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); LocalDateTime end = LocalDateTime.parse(endTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); List onlineSums = onlineSumService.queryByDeviceTypeAndDate(types, start.toLocalDate(), end.toLocalDate(), direction); Map> stringListMap = onlineSums.stream().collect(Collectors.groupingBy(OnlineSum::getDeviceType)); for (String type : types) { Map map = new HashMap<>(); List listOfType = stringListMap.getOrDefault(type, new ArrayList<>()); Map> localDateListMap = listOfType.stream().collect(Collectors.groupingBy(OnlineSum::getStatisticalDate)); for (LocalDate date = start.toLocalDate(); date.isBefore(end.toLocalDate().plusDays(1)); date = date.plusDays(1)) { List dayList = localDateListMap.getOrDefault(date, new ArrayList<>()); map.put(date.toString(), MathUtil.doubleTwoDecimalStr(dayList.stream().mapToDouble(OnlineSum::getOnlineRate).average().orElse(0.0)) + "%"); } maps.put(type, new TreeMap<>(map)); } return AjaxResult.success(maps); } /** * 查询设备在线率 * * @param deviceId * @return */ @ApiOperation("根据设备Id查询折线图数据") @GetMapping("/deviceStatusList/{deviceId}") public AjaxResult getDeviceStatusList(@PathVariable Long deviceId) { LocalDate startDate = LocalDate.now().minusDays(30); LocalDate endDate = LocalDate.now(); List onlineSums = onlineSumService.queryByDateRangeOfDevice(deviceId, startDate, endDate); if (onlineSums.isEmpty()) { return AjaxResult.success(UniversalEnum.NO_DATA_AVAILABLE.getValue()); } Map map = new HashMap<>(); for (OnlineSum onlineSum : onlineSums) { map.put(onlineSum.getStatisticalDate().toString(), onlineSum.getOnlineRate()); } return AjaxResult.success(new TreeMap<>(map)); } /** * 缓存类型卡片排序规则 * * @param rule 排序规则 * @return AjaxResult */ @ApiOperation("缓存类型卡片排序规则") @GetMapping("/rule") public AjaxResult setRule(String rule) { redisCache.setCacheObject(ORDERRULE, rule); return AjaxResult.success(); } /** * 设备分类当日在线率 */ @ApiOperation("设备分类当日在线率") @GetMapping("/type") public AjaxResult getTypeList() { String LOST_RATE = "lostRate";//丢包率 String SUCESS_RATE = "sucessRate";//在线率 String FAIL_RATE = "failRate";//离线率 String SUM_USE_STATE = "sumUseState";//在用数 String SUM = "sum";//总数 String RULE = "rule"; String All_TYPE = "全部设备"; String SORT_RULE = "排序规则"; Map returnMap = new HashMap<>(); List onlineSums = onlineSumService.queryByDateOfDeviceType(LocalDate.now()); List dcDeviceList = dcDeviceService.list(); List useDeviceList = dcDeviceList.stream().filter(device -> device.getUseState() != null && device.getUseState() == 1).collect(Collectors.toList()); //分类总数 Map totalCounts = dcDeviceList.stream() .collect(Collectors.groupingBy(DcDevice::getRealType, Collectors.counting())); //分类在用数 Map useCounts = useDeviceList.stream() .collect(Collectors.groupingBy(DcDevice::getRealType, Collectors.counting())); Map> typeSumGroup = onlineSums.stream().collect(Collectors.groupingBy(OnlineSum::getDeviceType)); DeviceType.toMap().forEach((k, v) -> { Map itemMap = new HashMap<>(); itemMap.put(SUM, totalCounts.getOrDefault(k, 0L).toString());//总数 itemMap.put(SUM_USE_STATE, useCounts.getOrDefault(k, 0L).toString());//在用数 List onlineSumsOfType = typeSumGroup.getOrDefault(k, new ArrayList<>()); itemMap.put(LOST_RATE, MathUtil.doubleTwoDecimalStr(onlineSumsOfType.stream().mapToDouble(OnlineSum::getLossRate).average().orElse(0.0)) + "%"); itemMap.put(SUCESS_RATE, MathUtil.doubleTwoDecimalStr(onlineSumsOfType.stream().mapToDouble(OnlineSum::getOnlineRate).average().orElse(0.0)) + "%"); itemMap.put(FAIL_RATE, MathUtil.doubleTwoDecimalStr(onlineSumsOfType.stream().mapToDouble(OnlineSum::getOfflineRate).average().orElse(0.0)) + "%"); returnMap.put(v, itemMap); }); Map allMap = new HashMap<>(); allMap.put(SUM, dcDeviceList.size() + "");//总数 allMap.put(SUM_USE_STATE, useDeviceList.size() + "");//在用数 allMap.put(LOST_RATE, MathUtil.doubleTwoDecimalStr(onlineSums.stream().mapToDouble(OnlineSum::getLossRate).average().orElse(0.0)) + "%"); allMap.put(SUCESS_RATE, MathUtil.doubleTwoDecimalStr(onlineSums.stream().mapToDouble(OnlineSum::getOnlineRate).average().orElse(0.0)) + "%"); allMap.put(FAIL_RATE, MathUtil.doubleTwoDecimalStr(onlineSums.stream().mapToDouble(OnlineSum::getOfflineRate).average().orElse(0.0)) + "%"); returnMap.put(All_TYPE, allMap); Map sortMap = new TreeMap<>(); String orderRule = redisCache.getCacheObject(ORDERRULE); if (StringUtil.isNotEmpty(orderRule)) { sortMap.put(RULE, orderRule); } else { sortMap.put(RULE, DeviceType.defaultSortRule()); } returnMap.put(SORT_RULE, sortMap); return AjaxResult.success(returnMap); } //按路段统计设备在线率 @ApiOperation("设备状态列表按路段") @GetMapping("/section") public AjaxResult getSectionList() { String LOST_RATE = "lostRate";//丢包率 String SUCESS_RATE = "sucessRate";//在线率 String FAIL_RATE = "failRate";//离线率 String SUM_USE_STATE = "sumUseState";//在用数 String SUM = "sum";//总数 Map returnMap = new HashMap<>(); List> deviceOfRoad = dcDeviceService.selectDeviceOfRoad(); List dcRoadSections = dcRoadSectionService.selectDcRoadSectionList(new DcRoadSection()); List onlineSums = onlineSumService.queryByDateOfRoad(LocalDate.now()); Map totalRoadCounts = deviceOfRoad.stream() .collect(Collectors.groupingBy(m -> m.get("roadId").toString(), Collectors.counting())); Map useRoadCounts = deviceOfRoad.stream().filter(dr -> dr.get("useStata") != null && dr.get("useStata").toString().equals("1")) .collect(Collectors.groupingBy(m -> m.get("roadId").toString(), Collectors.counting())); Map> onLineSumMap = onlineSums.stream().filter(onlineSum -> onlineSum.getRoadId() != null).collect(Collectors.groupingBy(OnlineSum::getRoadId)); for (DcRoadSection dcRoadSection : dcRoadSections) { Map itemMap = new HashMap<>(); itemMap.put(SUM, totalRoadCounts.getOrDefault(dcRoadSection.getId().toString(), 0L).toString());//总数 itemMap.put(SUM_USE_STATE, useRoadCounts.getOrDefault(dcRoadSection.getId().toString(), 0L).toString());//在用数 List onlineSumsByRoad = onLineSumMap.getOrDefault(dcRoadSection.getId(), new ArrayList<>()); itemMap.put(LOST_RATE, MathUtil.doubleTwoDecimalStr(onlineSumsByRoad.stream().mapToDouble(OnlineSum::getLossRate).average().orElse(0.0)) + "%"); itemMap.put(SUCESS_RATE, MathUtil.doubleTwoDecimalStr(onlineSumsByRoad.stream().mapToDouble(OnlineSum::getOnlineRate).average().orElse(0.0)) + "%"); itemMap.put(FAIL_RATE, MathUtil.doubleTwoDecimalStr(onlineSumsByRoad.stream().mapToDouble(OnlineSum::getOfflineRate).average().orElse(0.0)) + "%"); returnMap.put(dcRoadSection.getSectionName(), itemMap); } return AjaxResult.success(returnMap); } @ApiOperation("查询设备网络日志") @GetMapping("/networkLogTable") public TableDataInfo networkLogTable( @RequestParam("deviceId") Long deviceId, @RequestParam("queryDate") String queryDate) { LocalDateTime start = LocalDateTime.parse(queryDate + " 00:00:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); LocalDateTime end = LocalDateTime.parse(queryDate + " 23:59:59", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); //startPage(); List onlineLogs = onlineLogService.queryByDateAndDevice(start, end, deviceId); return getDataTable(onlineLogs); } @ApiOperation("查询设备网络日志") @GetMapping("/networkLogEcharts") public AjaxResult networkLogEcharts( @RequestParam("deviceId") Long deviceId, @RequestParam("queryDate") String queryDate) { String LOST_RATE = "lostRate";//丢包率 String RTT_AVG = "rttAvg";//平均往返时延 String MONITOR_TIME = "time";//监控时间 LocalDateTime start = LocalDateTime.parse(queryDate + " 00:00:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); LocalDateTime end = LocalDateTime.parse(queryDate + " 23:59:59", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); List onlineLogs = onlineLogService.queryByDateAndDevice(start, end, deviceId); Map returnMap = new HashMap<>(); List xAxis = new ArrayList<>(); List lossRate = new ArrayList<>(); List rttAvg = new ArrayList<>(); onlineLogs.stream().sorted(Comparator.comparing(OnlineLog::getMonitorTime)).forEach(onlineLog -> { xAxis.add(onlineLog.getMonitorTime().format(DateTimeFormatter.ofPattern("HH:mm"))); lossRate.add(onlineLog.getLossRate()); rttAvg.add(onlineLog.getRttAvg()); }); returnMap.put(LOST_RATE, lossRate); returnMap.put(RTT_AVG, rttAvg); returnMap.put(MONITOR_TIME, xAxis); return AjaxResult.success(new TreeMap<>(returnMap)); } enum DeviceType { GUN_CAMERA("1-1", "高清网络枪型固定摄像机"), SPHERICAL_CAMERA("1-2", "高清网络球形摄像机"), SPHERICAL_CAMERA_BRIDGE("1-3", "桥下高清网络球形摄像机"), PANORAMIC_CAMERA_360("1-4", "360°全景摄像机"), PANORAMIC_CAMERA_180("1-5", "180°全景摄像机"), GANTRY_VMS("2-1", "门架式可变信息标志"), STATION_FRONT_VMS("2-2", "站前可变信息标志"), AWNING_VMS("2-3", "雨棚可变信息标志"), //站前悬臂式可变信息标志2-4 MET_DET("3", "气象检测器"), //出口诱导灯4 VOICE_BROADCAST("5", "路段语音广播系统"), GUARDRAIL_COLLISION("6", "护栏碰撞预警系统"), MMW_RADAR("7", "毫米波雷达"), CA_EARLY("8", "合流区预警系统"), //智慧锥桶9 LASER_FATIGUE_AWAKENING("10", "激光疲劳唤醒"), TRAFFIC_SURVEY_STATION("11", "一类交通量调查站"), DRIVING_GUIDANCE("12", "智能行车诱导系统"), DEVICE_BOX("13", "智能设备箱"), //光纤在线监测14 SOLAR_PANEL("15", "太阳能板"), REMOTE_COMPUTER("16", "远端机"); private final String value; private final String description; public String getValue() { return value; } public String getDescription() { return description; } DeviceType(String value, String description) { this.value = value; this.description = description; } /** * map转换{value,description} * * @return 转换后的map */ static Map toMap() { Map map = new HashMap<>(); for (DeviceType deviceType : DeviceType.values()) { map.put(deviceType.getValue(), deviceType.getDescription()); } return map; } /** * 默认排序规则 * * @return 排序规则 */ static String defaultSortRule() { StringBuilder stringBuilder = new StringBuilder(); String ALL_TYPE = "全部设备"; stringBuilder.append(ALL_TYPE); for (DeviceType deviceType : DeviceType.values()) { stringBuilder.append(",").append(deviceType.getDescription()); } return stringBuilder.toString(); } static String getDescriptionByValue(String value) { for (DeviceType type : DeviceType.values()) { if (type.value.equals(value)) { return type.description; } } return ""; } } }