feat:完成设备运行报表页面,新增采集设备页面运行状态、采集时间字段

plp
HuangHuiKang 2 months ago
parent 876dcdd7ca
commit 27778698a2

@ -96,8 +96,8 @@ public class DeviceController {
@Operation(summary = "获得物联设备分页") @Operation(summary = "获得物联设备分页")
@PreAuthorize("@ss.hasPermission('iot:device:query')") @PreAuthorize("@ss.hasPermission('iot:device:query')")
public CommonResult<PageResult<DeviceRespVO>> getDevicePage(@Valid DevicePageReqVO pageReqVO) { public CommonResult<PageResult<DeviceRespVO>> getDevicePage(@Valid DevicePageReqVO pageReqVO) {
PageResult<DeviceDO> pageResult = deviceService.getDevicePage(pageReqVO); PageResult<DeviceRespVO> pageResult = deviceService.getDevicePage(pageReqVO);
return success(BeanUtils.toBean(pageResult, DeviceRespVO.class)); return success(pageResult);
} }
@GetMapping("/export-excel") @GetMapping("/export-excel")
@ -107,17 +107,16 @@ public class DeviceController {
public void exportDeviceExcel(@Valid DevicePageReqVO pageReqVO, public void exportDeviceExcel(@Valid DevicePageReqVO pageReqVO,
HttpServletResponse response) throws IOException { HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<DeviceDO> list = deviceService.getDevicePage(pageReqVO).getList(); List<DeviceRespVO> list = deviceService.getDevicePage(pageReqVO).getList();
// 导出 Excel // 导出 Excel
ExcelUtils.write(response, "物联设备.xls", "数据", DeviceRespVO.class, ExcelUtils.write(response, "物联设备.xls", "数据", DeviceRespVO.class,list);
BeanUtils.toBean(list, DeviceRespVO.class));
} }
@GetMapping("/deviceList") @GetMapping("/deviceList")
@PreAuthorize("@ss.hasPermission('iot:device:query')") @PreAuthorize("@ss.hasPermission('iot:device:query')")
public CommonResult<List<DeviceDO>> deviceList(@Valid DevicePageReqVO pageReqVO) { public CommonResult<List<DeviceRespVO>> deviceList(@Valid DevicePageReqVO pageReqVO) {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<DeviceDO> list = deviceService.getDevicePage(pageReqVO).getList(); List<DeviceRespVO> list = deviceService.getDevicePage(pageReqVO).getList();
return success(BeanUtils.toBean(list, DeviceDO.class)); return success(list);
} }
@PostMapping("/connect") @PostMapping("/connect")

@ -53,7 +53,7 @@ public enum DeviceStatusEnum {
/** /**
* *
*/ */
public static DeviceStatusEnum getByCode(Integer code) { public static DeviceStatusEnum getByCode(String code) {
if (code == null) { if (code == null) {
return null; return null;
} }

@ -417,36 +417,36 @@ public class DeviceTask implements Task {
return; return;
} }
DeviceOperationRecordDO lastRecord = deviceOperationRecordMapper.selectOne( // DeviceOperationRecordDO lastRecord = deviceOperationRecordMapper.selectOne(
Wrappers.<DeviceOperationRecordDO>lambdaQuery() // Wrappers.<DeviceOperationRecordDO>lambdaQuery()
.eq(DeviceOperationRecordDO::getRule, ruleCode) // .eq(DeviceOperationRecordDO::getRule, ruleCode)
.orderByDesc(DeviceOperationRecordDO::getCreateTime) // .orderByDesc(DeviceOperationRecordDO::getCreateTime)
.last("LIMIT 1") // .last("LIMIT 1")
); // );
if (ruleCode.equals(DeviceStatusEnum.RUNNING.getCode())) { if (ruleCode.equals(DeviceStatusEnum.RUNNING.getCode())) {
Double totalTime = (lastRecord != null && lastRecord.getTotalRunningTime() != null) // Double totalTime = (lastRecord != null && lastRecord.getTotalRunningTime() != null)
? lastRecord.getTotalRunningTime() + sampleCycle // ? lastRecord.getTotalRunningTime() + sampleCycle
: sampleCycle; // : sampleCycle;
record.setTotalRunningTime(totalTime); record.setTotalRunningTime(sampleCycle);
} else if (ruleCode.equals(DeviceStatusEnum.STANDBY.getCode())) { } else if (ruleCode.equals(DeviceStatusEnum.STANDBY.getCode())) {
Double totalTime = (lastRecord != null && lastRecord.getTotalStandbyTime() != null) // Double totalTime = (lastRecord != null && lastRecord.getTotalStandbyTime() != null)
? lastRecord.getTotalStandbyTime() + sampleCycle // ? lastRecord.getTotalStandbyTime() + sampleCycle
: sampleCycle; // : sampleCycle;
record.setTotalStandbyTime(totalTime); record.setTotalStandbyTime(sampleCycle);
} else if (ruleCode.equals(DeviceStatusEnum.FAULT_STANDBY.getCode())) { } else if (ruleCode.equals(DeviceStatusEnum.FAULT_STANDBY.getCode())) {
Double totalTime = (lastRecord != null && lastRecord.getTotalFaultTime() != null) // Double totalTime = (lastRecord != null && lastRecord.getTotalFaultTime() != null)
? lastRecord.getTotalFaultTime() + sampleCycle // ? lastRecord.getTotalFaultTime() + sampleCycle
: sampleCycle; // : sampleCycle;
record.setTotalFaultTime(totalTime); record.setTotalFaultTime(sampleCycle);
} else if (ruleCode.equals(DeviceStatusEnum.ALARM_RUNNING.getCode())) { } else if (ruleCode.equals(DeviceStatusEnum.ALARM_RUNNING.getCode())) {
Double totalTime = (lastRecord != null && lastRecord.getTotalWarningTime() != null) // Double totalTime = (lastRecord != null && lastRecord.getTotalWarningTime() != null)
? lastRecord.getTotalWarningTime() + sampleCycle // ? lastRecord.getTotalWarningTime() + sampleCycle
: sampleCycle; // : sampleCycle;
record.setTotalWarningTime(totalTime); record.setTotalWarningTime(sampleCycle);
} }
} }

@ -3,6 +3,11 @@ package cn.iocoder.yudao.module.iot.controller.admin.device.vo;
import cn.iocoder.yudao.module.iot.controller.admin.devicemodelrules.vo.PointRulesRespVO; import cn.iocoder.yudao.module.iot.controller.admin.devicemodelrules.vo.PointRulesRespVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.devicepointrules.DevicePointRulesDO; import cn.iocoder.yudao.module.iot.dal.dataobject.devicepointrules.DevicePointRulesDO;
import com.alibaba.excel.annotation.write.style.ColumnWidth; import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*; import lombok.*;
import java.util.*; import java.util.*;
@ -102,6 +107,16 @@ public class DeviceRespVO {
@ExcelProperty("密码") @ExcelProperty("密码")
private String password; private String password;
@Schema(description = "点位规则") @Schema(description = "运行状态")
private List<DevicePointRulesDO> pointRulesVOList; @ExcelProperty("运行状态")
private String operatingStatus;
@Schema(description = "采集时间")
@ExcelProperty("采集时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
private LocalDateTime collectionTime;
} }

@ -11,6 +11,9 @@ import io.swagger.v3.oas.annotations.Operation;
import javax.validation.constraints.*; import javax.validation.constraints.*;
import javax.validation.*; import javax.validation.*;
import javax.servlet.http.*; import javax.servlet.http.*;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*; import java.util.*;
import java.io.IOException; import java.io.IOException;
@ -92,4 +95,30 @@ public class DeviceOperationRecordController {
BeanUtils.toBean(list, DeviceOperationRecordRespVO.class)); BeanUtils.toBean(list, DeviceOperationRecordRespVO.class));
} }
@GetMapping("/deviceOperationPage")
@Operation(summary = "设备运行报表")
@PreAuthorize("@ss.hasPermission('mes:repair-tems:query')")
public CommonResult<PageResult<DeviceTotalTimeRecordRespVO>> deviceOperationPage(@Valid DeviceTotalTimeRecordReqVO pageReqVO) {
PageResult<DeviceTotalTimeRecordRespVO> pageResult = deviceOperationRecordService.deviceOperationPage(pageReqVO);
return success(pageResult);
}
@GetMapping("/export-device-operation-report")
@Operation(summary = "导出设备运行报表记录 Excel")
@PreAuthorize("@ss.hasPermission('iot:device-operation-record:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportDeviceOperationReport(@Valid DeviceTotalTimeRecordReqVO pageReqVO,
HttpServletResponse response) throws IOException {
PageResult<DeviceTotalTimeRecordRespVO> pageResult = deviceOperationRecordService.deviceOperationPage(pageReqVO);
// 设置响应头
response.setContentType("application/vnd.ms-excel;charset=UTF-8");
response.setHeader("Content-Disposition",
"attachment;filename=" + URLEncoder.encode("设备运行报表记录.xls", "UTF-8"));
response.setHeader("Content-Encoding", "identity");
// 导出Excel
String fileName = String.format("设备运行报表记录_%s.xls", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
// 导出 Excel
ExcelUtils.write(response, "设备运行报表记录.xls", "数据", DeviceTotalTimeRecordRespVO.class,pageResult.getList());
}
} }

@ -0,0 +1,63 @@
package cn.iocoder.yudao.module.iot.controller.admin.deviceoperationrecord.utils;
import org.springframework.stereotype.Component;
@Component
public class TimeConverterUtil {
private static final int SECONDS_PER_HOUR = 3600;
/**
* 2
*/
public static double secondsToHours(double seconds) {
if (seconds <= 0) {
return 0.0;
}
double hours = seconds / SECONDS_PER_HOUR;
return formatDouble(hours, 2);
}
/**
*
*/
public static double secondsToHours(double seconds, int scale) {
if (seconds <= 0) {
return 0.0;
}
double hours = seconds / SECONDS_PER_HOUR;
return formatDouble(hours, scale);
}
/**
*
* = / ( + + + ) * 100%
*/
public static double calculateUtilizationRate(double runningTime, double standbyTime,
double faultTime, double warningTime) {
double totalTime = runningTime + standbyTime + faultTime + warningTime;
if (totalTime <= 0) {
return 0.0;
}
double rate = runningTime / totalTime * 100;
return formatDouble(rate, 2);
}
/**
*
*/
public static double formatDouble(double value, int scale) {
if (scale < 0) {
scale = 2;
}
double factor = Math.pow(10, scale);
return Math.round(value * factor) / factor;
}
/**
*
*/
public static String getPercentString(double value) {
return formatDouble(value, 2) + "%";
}
}

@ -0,0 +1,32 @@
package cn.iocoder.yudao.module.iot.controller.admin.deviceoperationrecord.vo;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
@Schema(description = "管理后台 - 运行记录分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class DeviceTotalTimeRecordReqVO extends PageParam{
@Schema(description = "设备编码")
private String deviceCode;
@Schema(description = "设备名称")
private String deviceName;
@Schema(description = "开始时间")
private String startTime;
@Schema(description = "结束时间")
private String endTime;
@Schema(description = "ids导出集合用")
private String ids;
}

@ -0,0 +1,43 @@
package cn.iocoder.yudao.module.iot.controller.admin.deviceoperationrecord.vo;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "管理后台 - 运行设备报表时间记录 Request VO")
@Data
@ExcelIgnoreUnannotated
public class DeviceTotalTimeRecordRespVO {
@Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "4283")
private Long id;
@Schema(description = "设备编码")
@ExcelProperty("设备编码")
private String deviceCode;
@Schema(description = "设备名称")
@ExcelProperty("设备名称")
private String deviceName;
@Schema(description = "运行时间(小时)")
@ExcelProperty("运行时间(小时)")
private double totalRunningTime;
@Schema(description = "待机时间(小时)")
@ExcelProperty("待机时间(小时)")
private double totalStandbyTime;
@Schema(description = "故障时间(小时)")
@ExcelProperty("故障时间(小时)")
private double totalFaultTime;
@Schema(description = "警告时间(小时)")
@ExcelProperty("警告时间(小时)")
private double totalWarningTime;
@Schema(description = "稼动率")
@ExcelProperty("稼动率")
private String utilizationRate;
}

@ -6,8 +6,11 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.iot.dal.dataobject.deviceoperationrecord.DeviceOperationRecordDO; import cn.iocoder.yudao.module.iot.dal.dataobject.deviceoperationrecord.DeviceOperationRecordDO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import cn.iocoder.yudao.module.iot.controller.admin.deviceoperationrecord.vo.*; import cn.iocoder.yudao.module.iot.controller.admin.deviceoperationrecord.vo.*;
import org.apache.ibatis.annotations.Param;
/** /**
* Mapper * Mapper
@ -28,4 +31,6 @@ public interface DeviceOperationRecordMapper extends BaseMapperX<DeviceOperation
.orderByDesc(DeviceOperationRecordDO::getId)); .orderByDesc(DeviceOperationRecordDO::getId));
} }
IPage<DeviceTotalTimeRecordRespVO> deviceOperationPage(Page<DeviceTotalTimeRecordRespVO> page,@Param("pageReqVO") DeviceTotalTimeRecordReqVO pageReqVO);
} }

@ -69,7 +69,7 @@ public interface DeviceService {
* @param pageReqVO * @param pageReqVO
* @return * @return
*/ */
PageResult<DeviceDO> getDevicePage(DevicePageReqVO pageReqVO); PageResult<DeviceRespVO> getDevicePage(DevicePageReqVO pageReqVO);
List<DeviceDO> selectList(DevicePageReqVO reqVO); List<DeviceDO> selectList(DevicePageReqVO reqVO);
// ==================== 子表(设备属性) ==================== // ==================== 子表(设备属性) ====================

@ -6,6 +6,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.common.util.opc.OpcUtils; import cn.iocoder.yudao.framework.common.util.opc.OpcUtils;
import cn.iocoder.yudao.module.iot.controller.admin.device.enums.DeviceStatusEnum;
import cn.iocoder.yudao.module.iot.controller.admin.device.scheduled.utils.CronExpressionUtils; import cn.iocoder.yudao.module.iot.controller.admin.device.scheduled.utils.CronExpressionUtils;
import cn.iocoder.yudao.module.iot.controller.admin.device.scheduled.scheduler.TaskSchedulerManager; import cn.iocoder.yudao.module.iot.controller.admin.device.scheduled.scheduler.TaskSchedulerManager;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.*; import cn.iocoder.yudao.module.iot.controller.admin.device.vo.*;
@ -16,6 +17,7 @@ import cn.iocoder.yudao.module.iot.dal.dataobject.deviceattributetype.DeviceAttr
import cn.iocoder.yudao.module.iot.dal.dataobject.devicemodel.DeviceModelDO; import cn.iocoder.yudao.module.iot.dal.dataobject.devicemodel.DeviceModelDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.devicemodelattribute.DeviceModelAttributeDO; import cn.iocoder.yudao.module.iot.dal.dataobject.devicemodelattribute.DeviceModelAttributeDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.devicemodelrules.DeviceModelRulesDO; import cn.iocoder.yudao.module.iot.dal.dataobject.devicemodelrules.DeviceModelRulesDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.deviceoperationrecord.DeviceOperationRecordDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.devicepointrules.DevicePointRulesDO; import cn.iocoder.yudao.module.iot.dal.dataobject.devicepointrules.DevicePointRulesDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.mqttdatarecord.MqttDataRecordDO; import cn.iocoder.yudao.module.iot.dal.dataobject.mqttdatarecord.MqttDataRecordDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.devicecontactmodel.DeviceContactModelDO; import cn.iocoder.yudao.module.iot.dal.dataobject.devicecontactmodel.DeviceContactModelDO;
@ -25,6 +27,7 @@ import cn.iocoder.yudao.module.iot.dal.mysql.devicecontactmodel.DeviceContactMod
import cn.iocoder.yudao.module.iot.dal.mysql.devicemodel.DeviceModelMapper; import cn.iocoder.yudao.module.iot.dal.mysql.devicemodel.DeviceModelMapper;
import cn.iocoder.yudao.module.iot.dal.mysql.devicemodelattribute.DeviceModelAttributeMapper; import cn.iocoder.yudao.module.iot.dal.mysql.devicemodelattribute.DeviceModelAttributeMapper;
import cn.iocoder.yudao.module.iot.dal.mysql.devicemodelrules.DeviceModelRulesMapper; import cn.iocoder.yudao.module.iot.dal.mysql.devicemodelrules.DeviceModelRulesMapper;
import cn.iocoder.yudao.module.iot.dal.mysql.deviceoperationrecord.DeviceOperationRecordMapper;
import cn.iocoder.yudao.module.iot.dal.mysql.devicepointrules.DevicePointRulesMapper; import cn.iocoder.yudao.module.iot.dal.mysql.devicepointrules.DevicePointRulesMapper;
import cn.iocoder.yudao.module.iot.dal.mysql.mqttdatarecord.MqttDataRecordMapper; import cn.iocoder.yudao.module.iot.dal.mysql.mqttdatarecord.MqttDataRecordMapper;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceAttributeDO; import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceAttributeDO;
@ -102,6 +105,9 @@ public class DeviceServiceImpl implements DeviceService {
@Resource @Resource
private DevicePointRulesMapper devicePointRulesMapper; private DevicePointRulesMapper devicePointRulesMapper;
@Resource
private DeviceOperationRecordMapper deviceOperationRecordMapper;
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@ -231,12 +237,12 @@ public class DeviceServiceImpl implements DeviceService {
DeviceRespVO deviceRespVO = BeanUtils.toBean(deviceDO, DeviceRespVO.class); DeviceRespVO deviceRespVO = BeanUtils.toBean(deviceDO, DeviceRespVO.class);
List<DevicePointRulesDO> devicePointRulesDOList = devicePointRulesMapper.selectList(Wrappers.<DevicePointRulesDO>lambdaQuery() List<DevicePointRulesDO> devicePointRulesDOList = devicePointRulesMapper.selectList(Wrappers.<DevicePointRulesDO>lambdaQuery()
.eq(DevicePointRulesDO::getDeviceId, id)); .eq(DevicePointRulesDO::getDeviceId, id));
//
//设置点位规则 // //设置点位规则
if (!devicePointRulesDOList.isEmpty()){ // if (!devicePointRulesDOList.isEmpty()){
//
deviceRespVO.setPointRulesVOList(devicePointRulesDOList); // deviceRespVO.setPointRulesVOList(devicePointRulesDOList);
} // }
return deviceRespVO; return deviceRespVO;
@ -250,8 +256,31 @@ public class DeviceServiceImpl implements DeviceService {
return deviceMapper.selectByTopic(topic); return deviceMapper.selectByTopic(topic);
} }
@Override @Override
public PageResult<DeviceDO> getDevicePage(DevicePageReqVO pageReqVO) { public PageResult<DeviceRespVO> getDevicePage(DevicePageReqVO pageReqVO) {
return deviceMapper.selectPage(pageReqVO);
PageResult<DeviceDO> deviceDOPageResult = deviceMapper.selectPage(pageReqVO);
PageResult<DeviceRespVO> deviceRespVOPageResult = BeanUtils.toBean(deviceDOPageResult, DeviceRespVO.class);
List<String> ruleCodes = Arrays.stream(DeviceStatusEnum.values())
.map(DeviceStatusEnum::getCode)
.collect(Collectors.toList());
for (DeviceRespVO deviceRespVO : deviceRespVOPageResult.getList()) {
DeviceOperationRecordDO deviceOperationRecordDO = deviceOperationRecordMapper.selectOne(Wrappers.<DeviceOperationRecordDO>lambdaQuery()
.eq(DeviceOperationRecordDO::getDeviceId, deviceRespVO.getId())
.in(DeviceOperationRecordDO::getRule, ruleCodes)
.orderByDesc(DeviceOperationRecordDO::getCreateTime)
.last("LIMIT 1"));
if(deviceOperationRecordDO !=null){
deviceRespVO.setOperatingStatus(DeviceStatusEnum.getByCode(deviceOperationRecordDO.getRule()).getName());
deviceRespVO.setCollectionTime(deviceOperationRecordDO.getCreateTime());
}
}
return deviceRespVOPageResult;
} }
@Override @Override

@ -52,4 +52,6 @@ public interface DeviceOperationRecordService {
*/ */
PageResult<DeviceOperationRecordDO> getDeviceOperationRecordPage(DeviceOperationRecordPageReqVO pageReqVO); PageResult<DeviceOperationRecordDO> getDeviceOperationRecordPage(DeviceOperationRecordPageReqVO pageReqVO);
PageResult<DeviceTotalTimeRecordRespVO> deviceOperationPage(@Valid DeviceTotalTimeRecordReqVO pageReqVO);
} }

@ -1,5 +1,9 @@
package cn.iocoder.yudao.module.iot.service.deviceoperationrecord; package cn.iocoder.yudao.module.iot.service.deviceoperationrecord;
import cn.iocoder.yudao.module.iot.controller.admin.deviceoperationrecord.utils.TimeConverterUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
@ -24,6 +28,7 @@ import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*;
*/ */
@Service @Service
@Validated @Validated
@Slf4j
public class DeviceOperationRecordServiceImpl implements DeviceOperationRecordService { public class DeviceOperationRecordServiceImpl implements DeviceOperationRecordService {
@Resource @Resource
@ -71,4 +76,62 @@ public class DeviceOperationRecordServiceImpl implements DeviceOperationRecordSe
return deviceOperationRecordMapper.selectPage(pageReqVO); return deviceOperationRecordMapper.selectPage(pageReqVO);
} }
@Override
public PageResult<DeviceTotalTimeRecordRespVO> deviceOperationPage(DeviceTotalTimeRecordReqVO pageReqVO) {
Page<DeviceTotalTimeRecordRespVO> page = new Page<>(pageReqVO.getPageNo(), pageReqVO.getPageSize());
IPage<DeviceTotalTimeRecordRespVO> deviceOperationRecordRespVOIPage = deviceOperationRecordMapper.deviceOperationPage(page,pageReqVO);
// 计算和转换
if (deviceOperationRecordRespVOIPage != null && !deviceOperationRecordRespVOIPage.getRecords().isEmpty()) {
calculateAndSetConvertedValues(deviceOperationRecordRespVOIPage.getRecords());
}
return new PageResult<>(deviceOperationRecordRespVOIPage.getRecords(), deviceOperationRecordRespVOIPage.getTotal());
}
private void calculateAndSetConvertedValues(List<DeviceTotalTimeRecordRespVO> records) {
for (DeviceTotalTimeRecordRespVO record : records) {
try {
// 获取原始秒数
double runningTimeSec = record.getTotalRunningTime();
double standbyTimeSec = record.getTotalStandbyTime();
double faultTimeSec = record.getTotalFaultTime();
double warningTimeSec = record.getTotalWarningTime();
// 1. 转换为小时
double runningHours = TimeConverterUtil.secondsToHours(runningTimeSec, 2);
double standbyHours = TimeConverterUtil.secondsToHours(standbyTimeSec, 2);
double faultHours = TimeConverterUtil.secondsToHours(faultTimeSec, 2);
double warningHours = TimeConverterUtil.secondsToHours(warningTimeSec, 2);
// 2. 计算稼动率
double utilizationRate = TimeConverterUtil.calculateUtilizationRate(
runningTimeSec, standbyTimeSec, faultTimeSec, warningTimeSec
);
// 3. 设置转换后的值(将原来的秒数值覆盖为小时值)
record.setTotalRunningTime(runningHours);
record.setTotalStandbyTime(standbyHours);
record.setTotalFaultTime(faultHours);
record.setTotalWarningTime(warningHours);
record.setUtilizationRate(TimeConverterUtil.getPercentString(utilizationRate));
} catch (Exception e) {
log.error("计算设备{}时间转换时出错: {}", record.getDeviceCode(), e.getMessage());
// 设置默认值
setDefaultValues(record);
}
}
}
private void setDefaultValues(DeviceTotalTimeRecordRespVO record) {
record.setTotalRunningTime(0.0);
record.setTotalStandbyTime(0.0);
record.setTotalFaultTime(0.0);
record.setTotalWarningTime(0.0);
record.setUtilizationRate("0%");
}
} }

@ -9,4 +9,35 @@
文档可见https://www.iocoder.cn/MyBatis/x-plugins/ 文档可见https://www.iocoder.cn/MyBatis/x-plugins/
--> -->
<select id="deviceOperationPage"
resultType="cn.iocoder.yudao.module.iot.controller.admin.deviceoperationrecord.vo.DeviceTotalTimeRecordRespVO">
SELECT
ide.device_code as deviceCode,
ide.device_name as deviceName,
SUM(CASE WHEN idor.rule = '1' THEN idor.total_running_time ELSE 0 END) AS totalRunningTime,
SUM(CASE WHEN idor.rule = '2' THEN idor.total_standby_time ELSE 0 END) AS totalStandbyTime,
SUM(CASE WHEN idor.rule = '3' THEN idor.total_fault_time ELSE 0 END) AS totalFaultTime,
SUM(CASE WHEN idor.rule = '4' THEN idor.total_warning_time ELSE 0 END) AS totalWarningTime
FROM besure.iot_device_operation_record idor
LEFT JOIN besure.iot_device ide ON idor.device_id = ide.id
WHERE idor.rule IN ('1', '2', '3', '4')
AND idor.deleted = 0
<!-- 时间筛选条件 -->
<if test="pageReqVO.startTime != null">
AND idor.create_time &gt;= #{pageReqVO.startTime}
</if>
<if test="pageReqVO.endTime != null">
AND idor.create_time &lt;= #{pageReqVO.endTime}
</if>
<!-- 设备编码筛选条件 -->
<if test="pageReqVO.deviceCode != null and pageReqVO.deviceCode != ''">
AND ide.device_code LIKE CONCAT('%', #{pageReqVO.deviceCode}, '%')
</if>
<!-- 设备名称筛选条件 -->
<if test="pageReqVO.deviceName != null and pageReqVO.deviceName != ''">
AND ide.device_name LIKE CONCAT('%', #{pageReqVO.deviceName}, '%')
</if>
GROUP BY ide.id, ide.device_code, ide.device_name
ORDER BY ide.device_code
</select>
</mapper> </mapper>
Loading…
Cancel
Save