xiepufeng
8 months ago
7 changed files with 347 additions and 1 deletions
@ -0,0 +1,192 @@ |
|||||
|
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.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", "received_message"); |
||||
|
|
||||
|
// 将JSON对象转换为请求参数
|
||||
|
RequestParams requestParams = new RequestParams(jsonObject); |
||||
|
|
||||
|
// 默认请求URL
|
||||
|
String url = iotAddress + "/api/iot/metrics/device-gateway/message/count"; |
||||
|
|
||||
|
// 如果请求中包含产品ID,则修改请求URL
|
||||
|
if (request.getProductId() != null) { |
||||
|
url = iotAddress + "/api/iot/metrics/device/message/count"; |
||||
|
} |
||||
|
|
||||
|
// 发起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 + "/monitor/server"; |
||||
|
|
||||
|
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(), -2))); |
||||
|
|
||||
|
// 如果昨天或前天的数据为空,则返回错误信息
|
||||
|
if (yesterdayData == null || beforeYesterdayData == null) { |
||||
|
return AjaxResult.error("暂无数据"); |
||||
|
} |
||||
|
|
||||
|
// 将数据放入列表并返回
|
||||
|
List<JSONObject> 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 = 3; |
||||
|
|
||||
|
// 将监控数据缓存到Redis中,设定过期时间
|
||||
|
redisCache.setCacheObject(cacheKey, cacheValue, expireTime, TimeUnit.DAYS); |
||||
|
} catch (HttpException | IOException e) { |
||||
|
// 记录缓存失败的错误日志
|
||||
|
logger.error("缓存物联系统监控数据失败", e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
@ -0,0 +1,58 @@ |
|||||
|
package com.zc.business.request; |
||||
|
|
||||
|
import lombok.Data; |
||||
|
import org.springframework.format.annotation.DateTimeFormat; |
||||
|
|
||||
|
import javax.validation.constraints.NotNull; |
||||
|
import java.util.Date; |
||||
|
|
||||
|
@Data |
||||
|
public class DcMessageAccessCountRequest { |
||||
|
|
||||
|
// 年、月、日、小时,用于定义时间周期类型
|
||||
|
public static final String YEAR = "year"; |
||||
|
public static final String MONTH = "month"; |
||||
|
public static final String DAY = "day"; |
||||
|
public static final String HOUR = "hour"; |
||||
|
|
||||
|
@NotNull(message = "开始时间不能为空") |
||||
|
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
||||
|
private String startTime; |
||||
|
|
||||
|
// 查询结束时间
|
||||
|
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
||||
|
@NotNull(message = "结束时间不能为空") |
||||
|
private String endTime; |
||||
|
|
||||
|
// 时间周期类型(年、月、日、小时)
|
||||
|
private String periodType; |
||||
|
|
||||
|
private String productId; |
||||
|
|
||||
|
/** |
||||
|
* 根据给定的周期类型字符串,将其转换为简写的字符串表示。 |
||||
|
* @return 对应的简写字符串,比如"1y"、"1m"等。 |
||||
|
* @throws IllegalArgumentException 如果传入的periodType不是预期的值或为null。 |
||||
|
*/ |
||||
|
public String convertPeriodType() throws IllegalArgumentException { |
||||
|
// 检查输入参数是否为null或空字符串
|
||||
|
if (periodType == null || periodType.isEmpty()) { |
||||
|
throw new IllegalArgumentException("periodType不能为null或空"); |
||||
|
} |
||||
|
|
||||
|
// 使用switch语句处理不同的周期类型
|
||||
|
switch (periodType) { |
||||
|
case YEAR: |
||||
|
return "1y"; |
||||
|
case MONTH: |
||||
|
return "1M"; |
||||
|
case DAY: |
||||
|
return "1d"; |
||||
|
case HOUR: |
||||
|
return "1h"; |
||||
|
default: |
||||
|
// 对于未预期的输入值,抛出异常
|
||||
|
throw new IllegalArgumentException("不受支持的 periodType: " + periodType); |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,32 @@ |
|||||
|
package com.zc.business.service; |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* DcMetricsService 接口定义了与指标相关的服务操作。 |
||||
|
*/ |
||||
|
public interface IDcMetricsService { |
||||
|
|
||||
|
/** |
||||
|
* 获取设备数量。 |
||||
|
* |
||||
|
* @return 设备数量,返回类型为整数。 |
||||
|
*/ |
||||
|
int deviceCount(); |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 获取产品数量。 |
||||
|
* 该方法用于统计当前系统中的产品总数,不需要传入任何参数。 |
||||
|
* |
||||
|
* @return 产品数量,返回类型为整数。 |
||||
|
*/ |
||||
|
int productCount(); |
||||
|
|
||||
|
/** |
||||
|
* 获取设备异常数量 |
||||
|
* 该方法用于统计当前系统中的异常设备总数,不需要传入任何参数。 |
||||
|
* |
||||
|
* @return 返回设备异常数量,类型为int。 |
||||
|
*/ |
||||
|
int deviceAbnormalCount(); |
||||
|
} |
@ -0,0 +1,55 @@ |
|||||
|
package com.zc.business.service.impl; |
||||
|
|
||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
||||
|
import com.zc.business.domain.DcDevice; |
||||
|
import com.zc.business.service.IDcMetricsService; |
||||
|
import com.zc.business.service.IDcDeviceService; |
||||
|
import com.zc.business.service.IDcProductService; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
|
||||
|
import javax.annotation.Resource; |
||||
|
|
||||
|
@Service |
||||
|
public class DcMetricsServiceImpl implements IDcMetricsService { |
||||
|
|
||||
|
@Resource |
||||
|
private IDcDeviceService dcDeviceService; |
||||
|
|
||||
|
@Resource |
||||
|
private IDcProductService dcProductService; |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 获取设备数量。 |
||||
|
* |
||||
|
* @return 设备数量,返回类型为整数。 |
||||
|
*/ |
||||
|
@Override |
||||
|
public int deviceCount() { |
||||
|
return dcDeviceService.count(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取产品数量。 |
||||
|
* 该方法用于统计当前系统中的产品总数,不需要传入任何参数。 |
||||
|
* |
||||
|
* @return 产品数量,返回类型为整数。 |
||||
|
*/ |
||||
|
@Override |
||||
|
public int productCount() { |
||||
|
return dcProductService.count(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取设备异常数量 |
||||
|
* 该方法用于统计当前系统中的异常设备总数,不需要传入任何参数。 |
||||
|
* |
||||
|
* @return 返回设备异常数量,类型为int。 |
||||
|
*/ |
||||
|
@Override |
||||
|
public int deviceAbnormalCount() { |
||||
|
LambdaQueryWrapper<DcDevice> queryWrapper = new LambdaQueryWrapper<>(); |
||||
|
queryWrapper.eq(DcDevice::getDeviceState, DcDevice.ABNORMAL); |
||||
|
return dcDeviceService.count(queryWrapper); |
||||
|
} |
||||
|
} |
Loading…
Reference in new issue