feat:添加设备运行报表时间字段,新增首页设备运行状态接口

plp
HuangHuiKang 2 weeks ago
parent 27778698a2
commit 41f35456ec

@ -172,6 +172,16 @@ public class DeviceController {
}
@GetMapping("/getDeviceOperationalStatus")
@Operation(summary = "获取首页设备运行状态")
@PreAuthorize("@ss.hasPermission('iot:device:query')")
public CommonResult<DeviceOperationStatusRespVO> getDeviceOperationalStatus() throws JsonProcessingException {
DeviceOperationStatusRespVO deviceOperationalStatus=deviceService.getDeviceOperationalStatus();
return success(deviceOperationalStatus);
}
// ==================== 子表(设备属性) ====================
@GetMapping("/device-attribute/page")

@ -0,0 +1,36 @@
package cn.iocoder.yudao.module.iot.controller.admin.device.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.ToString;
@Schema(description = "管理后台 - 设备运行状态 Resp VO")
@Data
@ToString(callSuper = true)
public class DeviceOperationStatusRespVO {
@Schema(description = "总设备数")
private int totalDevices;
@Schema(description = "运行")
private int runningCount;
@Schema(description = "待机中(不运行、没故障)")
private int standbyCount;
@Schema(description = "故障中(故障且待机)")
private int faultCount;
@Schema(description = "报警中(故障且运行)")
private int warningCount;
@Schema(description = "利用率")
private String utilizationRate;
@Schema(description = "故障率")
private String faultRate;
}

@ -119,6 +119,6 @@ public class DeviceOperationRecordController {
// 导出Excel
String fileName = String.format("设备运行报表记录_%s.xls", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
// 导出 Excel
ExcelUtils.write(response, "设备运行报表记录.xls", "数据", DeviceTotalTimeRecordRespVO.class,pageResult.getList());
ExcelUtils.write(response, fileName, "数据", DeviceTotalTimeRecordRespVO.class,pageResult.getList());
}
}

@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.iot.controller.admin.deviceoperationrecord.vo;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@ -10,8 +11,8 @@ import lombok.Data;
@ExcelIgnoreUnannotated
public class DeviceTotalTimeRecordRespVO {
@Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "4283")
private Long id;
// @Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "4283")
// private Long id;
@Schema(description = "设备编码")
@ExcelProperty("设备编码")
@ -40,4 +41,14 @@ public class DeviceTotalTimeRecordRespVO {
@Schema(description = "稼动率")
@ExcelProperty("稼动率")
private String utilizationRate;
@Schema(description = "开始时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ExcelProperty("开始时间")
private String startTime;
@Schema(description = "结束时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ExcelProperty("结束时间")
private String endTime;
}

@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.DeviceOperationStatusRespVO;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.DevicePageReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.LineDeviceRequestVO;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.LineDeviceRespVO;
@ -96,4 +97,5 @@ public interface DeviceMapper extends BaseMapperX<DeviceDO> {
IPage<LineDeviceRespVO> lineDevicePage(Page<LineDeviceRespVO> page, @Param("pageReqVO") LineDeviceRequestVO pageReqVO);
DeviceOperationStatusRespVO getDeviceOperationalStatus();
}

@ -131,4 +131,5 @@ public interface DeviceService {
Boolean scheduledStop(Long id);
DeviceOperationStatusRespVO getDeviceOperationalStatus();
}

@ -788,4 +788,52 @@ public class DeviceServiceImpl implements DeviceService {
}
}
@Override
public DeviceOperationStatusRespVO getDeviceOperationalStatus() {
DeviceOperationStatusRespVO deviceOperationalStatus= deviceMapper.getDeviceOperationalStatus();
// 计算利用率
calculateUtilizationRate(deviceOperationalStatus);
// 计算故障率
calculateFaultRate(deviceOperationalStatus);
return deviceOperationalStatus;
}
/**
*
* = / * 100%
*/
private void calculateUtilizationRate(DeviceOperationStatusRespVO statusVO) {
int totalDevices = statusVO.getTotalDevices();
int runningCount = statusVO.getRunningCount();
double utilizationRate = 0.0;
if (totalDevices > 0) {
utilizationRate = (double) runningCount / totalDevices * 100;
}
// 格式化百分比保留2位小数
String formattedRate = String.format("%.2f%%", utilizationRate);
statusVO.setUtilizationRate(formattedRate);
}
/**
*
* = / * 100%
*/
private void calculateFaultRate(DeviceOperationStatusRespVO statusVO) {
int totalDevices = statusVO.getTotalDevices();
int faultCount = statusVO.getFaultCount();
double faultRate = 0.0;
if (totalDevices > 0) {
faultRate = (double) faultCount / totalDevices * 100;
}
// 格式化百分比保留2位小数
String formattedRate = String.format("%.2f%%", faultRate);
statusVO.setFaultRate(formattedRate);
}
}

@ -4,6 +4,7 @@ import cn.iocoder.yudao.module.iot.controller.admin.deviceoperationrecord.utils.
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
@ -83,7 +84,7 @@ public class DeviceOperationRecordServiceImpl implements DeviceOperationRecordSe
IPage<DeviceTotalTimeRecordRespVO> deviceOperationRecordRespVOIPage = deviceOperationRecordMapper.deviceOperationPage(page,pageReqVO);
// 计算和转换
if (deviceOperationRecordRespVOIPage != null && !deviceOperationRecordRespVOIPage.getRecords().isEmpty()) {
calculateAndSetConvertedValues(deviceOperationRecordRespVOIPage.getRecords());
calculateAndSetConvertedValues(deviceOperationRecordRespVOIPage.getRecords(),pageReqVO);
}
@ -91,9 +92,17 @@ public class DeviceOperationRecordServiceImpl implements DeviceOperationRecordSe
}
private void calculateAndSetConvertedValues(List<DeviceTotalTimeRecordRespVO> records) {
private void calculateAndSetConvertedValues(List<DeviceTotalTimeRecordRespVO> records,DeviceTotalTimeRecordReqVO deviceTotalTimeRecordReqVO) {
for (DeviceTotalTimeRecordRespVO record : records) {
try {
//添加时间字段
if (StringUtils.isNotBlank(deviceTotalTimeRecordReqVO.getStartTime())){
record.setStartTime(deviceTotalTimeRecordReqVO.getStartTime());
}
if (StringUtils.isNotBlank(deviceTotalTimeRecordReqVO.getEndTime())){
record.setEndTime(deviceTotalTimeRecordReqVO.getEndTime());
}
// 获取原始秒数
double runningTimeSec = record.getTotalRunningTime();
double standbyTimeSec = record.getTotalStandbyTime();

@ -45,4 +45,31 @@
order by mo.create_time desc
</select>
<select id="getDeviceOperationalStatus"
resultType="cn.iocoder.yudao.module.iot.controller.admin.device.vo.DeviceOperationStatusRespVO">
SELECT
-- 设备总数
COUNT(DISTINCT ide.id) AS totalDevices,
-- 各状态设备数量
SUM(CASE WHEN latest_status.rule = '1' THEN 1 ELSE 0 END) AS runningCount,
SUM(CASE WHEN latest_status.rule = '2' THEN 1 ELSE 0 END) AS standbyCount,
SUM(CASE WHEN latest_status.rule = '3' THEN 1 ELSE 0 END) AS faultCount,
SUM(CASE WHEN latest_status.rule = '4' THEN 1 ELSE 0 END) AS warningCount
FROM besure.iot_device ide
LEFT JOIN (
-- 获取每个设备的最新状态
SELECT
device_id,
rule,
ROW_NUMBER() OVER (PARTITION BY device_id ORDER BY create_time DESC) AS rn
FROM besure.iot_device_operation_record
WHERE rule IN ('1', '2', '3', '4')
AND deleted = 0
) latest_status ON ide.id = latest_status.device_id AND latest_status.rn = 1
WHERE ide.deleted = 0
</select>
</mapper>
Loading…
Cancel
Save