package com.zc.business.controller; import cn.hutool.core.date.DateUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.redis.RedisCache; import com.zc.business.enums.UniversalEnum; import com.zc.business.request.DcMessageAccessCountRequest; import com.zc.business.service.IDcMetricsService; import com.zc.common.core.httpclient.OkHttp; import com.zc.common.core.httpclient.exception.HttpException; import com.zc.common.core.httpclient.request.RequestParams; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import okhttp3.Response; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; import static com.zc.business.constant.RedisKeyConstants.MONITOR_IOT_SERVER; /** * 指标数据 * @author xiepufeng */ @Api(tags = "指标数据") @RestController @RequestMapping("/business/metrics") public class DcMetricsController { protected final Logger logger = LoggerFactory.getLogger(this.getClass()); @Resource private IDcMetricsService dcMetricsService; @Value("${iot.address}") private String iotAddress; @Resource private RedisCache redisCache; /** * 设备总数 */ @ApiOperation("设备总数") @GetMapping("/device/count") public AjaxResult deviceCount(){ return AjaxResult.success(dcMetricsService.deviceCount()); } /** * 产品总数 */ @ApiOperation("产品总数") @GetMapping("/product/count") public AjaxResult productCount(){ return AjaxResult.success(dcMetricsService.productCount()); } /** * 异常设备总数 */ @ApiOperation("异常设备总数") @GetMapping("/device-abnormal/count") public AjaxResult deviceAbnormalCount(){ return AjaxResult.success(dcMetricsService.deviceAbnormalCount()); } /** * 获取消息接入总数 * * @param request 请求参数对象,包含消息接入的相关条件 * @return 返回AjaxResult对象,其中包含消息接入总数 * @throws HttpException 当HTTP请求发生错误时抛出 * @throws IOException 当进行网络读写操作发生错误时抛出 */ @ApiOperation("接入数据总数") @GetMapping("/message-access/count") public AjaxResult messageAccessCount(@Validated DcMessageAccessCountRequest request) throws HttpException, IOException { // 初始化OkHttp客户端 OkHttp okHttp = new OkHttp(); // 将请求对象转换为JSON字符串 String string = JSON.toJSONString(request); JSONObject jsonObject = JSON.parseObject(string); jsonObject.put("direction", UniversalEnum.RECEIVED_MESSAGE.getValue()); // 将JSON对象转换为请求参数 RequestParams requestParams = new RequestParams(jsonObject); // 默认请求URL String url = iotAddress + UniversalEnum.DC_METRICS_DEVICE_GATEWAY_URI.getValue(); // 如果请求中包含产品ID,则修改请求URL if (request.getProductId() != null) { url = iotAddress + UniversalEnum.DC_METRICS_DEVICE_URI.getValue(); } // 发起HTTP GET请求并获取响应 Response response // 请求响应 = okHttp .url(url) // 设置请求地址 .data(requestParams) // 设置请求参数 .get(); // 执行GET请求 // 将响应内容解析为AjaxResult对象并返回 return JSON.parseObject(response.body().string(), AjaxResult.class); } @ApiOperation("物联系统监控") @GetMapping("/iot-server/monitor") public AjaxResult iotServerMonitor() throws HttpException, IOException { OkHttp okHttp = new OkHttp(); String url = iotAddress + UniversalEnum.IOT_SYSTEMS_MONITOR_URL.getValue(); Response response // 请求响应 = okHttp .url(url) // 请求地址 .get(); // 请求方法 return JSON.parseObject(response.body().string(), AjaxResult.class); } /** * 物联系统监控指标前天昨天数据查询 * 该接口不接受任何参数,返回前天和昨天的物联系统监控指标数据。 * * @return AjaxResult 返回一个包含前天和昨天监控指标数据的列表,如果数据不存在,则返回错误信息。 */ @ApiOperation("物联系统监控指标前天昨天数据") @GetMapping("/iot-server/monitor-previous") public AjaxResult iotServerChain() { // 从Redis缓存中获取昨天和前天的监控数据 JSONObject yesterdayData = redisCache.getCacheObject(MONITOR_IOT_SERVER + DateUtil.formatDate(DateUtil.yesterday())); JSONObject beforeYesterdayData = redisCache.getCacheObject(MONITOR_IOT_SERVER + DateUtil.formatDate(DateUtil.offsetDay(DateUtil.date(), UniversalEnum.MINUS_TWO.getNumber()))); // 如果昨天或前天的数据为空,则返回错误信息 if (yesterdayData == null || beforeYesterdayData == null) { return AjaxResult.success(null); } // 将数据放入列表并返回 List dataList = new ArrayList<>(); dataList.add(beforeYesterdayData); dataList.add(yesterdayData); return AjaxResult.success(dataList); } /** * 定时缓存物联系统监控数据。 * 该方法使用CRON表达式“0 0 0 * * ?”定时在每天的0点执行。 * 方法不接受参数,也不返回任何值。 * 主要步骤包括: * 1. 构造缓存键值,基于监控数据和前一天的日期。 * 2. 获取物联系统监控的详细数据。 * 3. 设定缓存过期时间为3天。 * 4. 将监控数据缓存起来。 * 如果在执行过程中遇到HttpException或IOException,会记录错误日志。 */ @Scheduled(cron = "0 0 0 * * ?") public void cacheIotServerMonitor() { try { // 构造缓存键,使用MONITOR_IOT_SERVER常量和前一天的日期 String cacheKey = MONITOR_IOT_SERVER + DateUtil.formatDate(DateUtil.yesterday()); // 获取监控数据中的"data"部分 Object cacheValue = this.iotServerMonitor().get("data"); // 设定缓存过期时间为3天 Integer expireTime = UniversalEnum.THREE.getNumber(); // 将监控数据缓存到Redis中,设定过期时间 redisCache.setCacheObject(cacheKey, cacheValue, expireTime, TimeUnit.DAYS); } catch (HttpException | IOException e) { // 记录缓存失败的错误日志 logger.error(UniversalEnum.FAILED_TO_CACHE_IOT_SYSTEM_MONITORING_DATA.getValue(), e); } } }