Compare commits
3 Commits
63c1ff4a7c
...
86e4fdad3b
Author | SHA1 | Date |
---|---|---|
xiepufeng | 86e4fdad3b | 7 months ago |
xiepufeng | 19403c9a17 | 7 months ago |
xiepufeng | f9de44862b | 8 months ago |
14 changed files with 362 additions and 12 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