feat:新增产能报表接口

main
HuangHuiKang 2 days ago
parent 5e99f8d3dc
commit f6aad2752e

@ -122,7 +122,7 @@ public class IotMqttRuntimeCache {
}
List<CachedPointRule> parsedRules = new ArrayList<>();
for (DevicePointRulesDO rule : rules) {
if (StringUtils.isBlank(rule.getFieldRule())) {
if (StringUtils.isBlank(rule.getAlarmLevel()) || StringUtils.isBlank(rule.getFieldRule())) {
continue;
}
try {

@ -398,7 +398,6 @@ public class MqttDataHandler extends SuperConsumer<String> {
attributeCode, processedValue,
JSON.toJSONString(pointRulesRespVO));
handleMatchedSuccessRule(cachedRule.getRule(), pointRulesRespVO, processedValue, device, attributeCode, point);
break;
} else {
log.debug("规则不匹配: modelId={}, value={}, rule={}",
attributeCode, processedValue,

@ -12,24 +12,31 @@ import cn.iocoder.yudao.module.iot.controller.admin.device.vo.DeviceProductionDa
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.DeviceProductionDailyReportRespVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.devicecontactmodel.DeviceContactModelDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.devicewarinningrecord.DeviceWarinningRecordDO;
import cn.iocoder.yudao.module.iot.dal.mysql.device.DeviceMapper;
import cn.iocoder.yudao.module.iot.dal.mysql.devicecontactmodel.DeviceContactModelMapper;
import cn.iocoder.yudao.module.mes.api.workteam.WorkTeamApi;
import cn.iocoder.yudao.module.mes.api.workteam.dto.WorkTeamRespDTO;
import cn.iocoder.yudao.module.system.api.dict.DictDataApi;
import cn.iocoder.yudao.module.system.api.dict.dto.DictDataRespDTO;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.ss.util.CellRangeAddress;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.math.BigDecimal;
@ -57,8 +64,10 @@ public class DeviceProductionDailyReportServiceImpl implements DeviceProductionD
private static final String TEMPLATE_PATH = "excel/templates/fully-automatic-molding-production-daily-report-template.xlsx";
private static final String REPORT_PATH_PREFIX = "iot/device/production-daily-report";
private static final String ALARM_LEVEL_DICT_TYPE = "alarm_registration";
private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm:ss");
@Resource
private DeviceMapper deviceMapper;
@ -69,6 +78,8 @@ public class DeviceProductionDailyReportServiceImpl implements DeviceProductionD
@Resource
private WorkTeamApi workTeamApi;
@Resource
private DictDataApi dictDataApi;
@Resource
private FileService fileService;
@Resource
private FileMapper fileMapper;
@ -96,15 +107,19 @@ public class DeviceProductionDailyReportServiceImpl implements DeviceProductionD
if (!endTime.isAfter(startTime)) {
endTime = endTime.plusDays(1);
}
log.info("[production-daily-report] generate request: reportDate={}, workTeamId={}, workTeamName={}, startTime={}, endTime={}, deviceIds={}",
reqVO.getReportDate(), reqVO.getWorkTeamId(), workTeam.getTeamName(), startTime, endTime, deviceIds);
List<DeviceProductionDailyReportRespVO.DeviceCapacityItem> items = buildCapacityItems(deviceIds, deviceMap, startTime, endTime);
byte[] excelContent = buildExcel(reqVO, workTeam, startTime, endTime, items);
byte[] excelContent = buildExcel(reqVO, workTeam, startTime, endTime, items, deviceIds);
String fileName = String.format("全自动成型机生产日报表_%s_%s_%s.xlsx",
reqVO.getReportDate().format(DateTimeFormatter.BASIC_ISO_DATE), reqVO.getWorkTeamId(), System.currentTimeMillis());
String filePath = String.format("%s/date=%s/workTeamId=%s/deviceIds=%s/deviceTags=%s/%s",
REPORT_PATH_PREFIX, reqVO.getReportDate(), reqVO.getWorkTeamId(), joinDeviceIds(deviceIds), buildDeviceTags(deviceIds), fileName);
Map<String, String> file = fileService.createFile(fileName, filePath, excelContent);
log.info("[production-daily-report] file created: fileName={}, filePath={}, fileUrl={}, contentLength={}",
file.get("fileName"), filePath, file.get("fileUrl"), excelContent.length);
DeviceProductionDailyReportRespVO respVO = buildBaseResp(reqVO.getReportDate(), workTeam, startTime, endTime, deviceIds);
respVO.setFileName(file.get("fileName"));
@ -141,7 +156,7 @@ public class DeviceProductionDailyReportServiceImpl implements DeviceProductionD
Map<Long, DeviceDO> deviceMap,
LocalDateTime startTime,
LocalDateTime endTime) {
Map<Long, List<DeviceContactModelDO>> capacityPointMap = queryCapacityPoints(deviceIds);
Map<Long, DeviceContactModelDO> capacityPointMap = queryCapacityPoints(deviceIds);
Map<Long, Map<String, Object>> firstRows = tDengineService.queryDevicesEarliestRow(deviceIds,
startTime.format(DATE_TIME_FORMATTER), endTime.format(DATE_TIME_FORMATTER));
Map<Long, Map<String, Object>> lastRows = tDengineService.queryDevicesLatestRow(deviceIds,
@ -150,31 +165,28 @@ public class DeviceProductionDailyReportServiceImpl implements DeviceProductionD
List<DeviceProductionDailyReportRespVO.DeviceCapacityItem> items = new ArrayList<>();
for (Long deviceId : deviceIds) {
DeviceDO device = deviceMap.get(deviceId);
List<DeviceContactModelDO> points = capacityPointMap.getOrDefault(deviceId, Collections.emptyList());
if (CollUtil.isEmpty(points)) {
DeviceContactModelDO point = capacityPointMap.get(deviceId);
if (point == null) {
items.add(buildEmptyCapacityItem(device));
continue;
}
Map<String, Object> firstRow = firstRows.get(deviceId);
Map<String, Object> lastRow = lastRows.get(deviceId);
for (DeviceContactModelDO point : points) {
items.add(buildCapacityItem(device, point, firstRow, lastRow));
}
items.add(buildCapacityItem(device, point, firstRow, lastRow));
}
return items;
}
private Map<Long, List<DeviceContactModelDO>> queryCapacityPoints(List<Long> deviceIds) {
private Map<Long, DeviceContactModelDO> queryCapacityPoints(List<Long> deviceIds) {
List<DeviceContactModelDO> points = deviceContactModelMapper.selectList(
Wrappers.<DeviceContactModelDO>lambdaQuery()
.in(DeviceContactModelDO::getDeviceId, deviceIds)
.and(wrapper -> wrapper.like(DeviceContactModelDO::getTypeName, "产能")
.or().like(DeviceContactModelDO::getAttributeType, "产能")
.or().like(DeviceContactModelDO::getAttributeName, "产能"))
.eq(DeviceContactModelDO::getTypeName, "产能")
.orderByAsc(DeviceContactModelDO::getDeviceId)
.orderByAsc(DeviceContactModelDO::getSort)
.orderByAsc(DeviceContactModelDO::getId));
return points.stream().collect(Collectors.groupingBy(DeviceContactModelDO::getDeviceId, LinkedHashMap::new, Collectors.toList()));
.orderByDesc(DeviceContactModelDO::getCreateTime)
.orderByDesc(DeviceContactModelDO::getId));
return points.stream().collect(Collectors.toMap(DeviceContactModelDO::getDeviceId, item -> item, (first, second) -> first,
LinkedHashMap::new));
}
private DeviceProductionDailyReportRespVO.DeviceCapacityItem buildEmptyCapacityItem(DeviceDO device) {
@ -212,36 +224,190 @@ public class DeviceProductionDailyReportServiceImpl implements DeviceProductionD
@SneakyThrows
private byte[] buildExcel(DeviceProductionDailyReportGenerateReqVO reqVO, WorkTeamRespDTO workTeam,
LocalDateTime startTime, LocalDateTime endTime,
List<DeviceProductionDailyReportRespVO.DeviceCapacityItem> items) {
List<DeviceProductionDailyReportRespVO.DeviceCapacityItem> items, List<Long> deviceIds) {
try (InputStream inputStream = new ClassPathResource(TEMPLATE_PATH).getInputStream();
Workbook workbook = WorkbookFactory.create(inputStream);
Workbook workbook = WorkbookFactory.create(inputStream);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
Sheet sheet = workbook.getSheetAt(0);
setCellValue(sheet, 2, 0, "日期:" + LocalDate.now().format(DATE_FORMATTER));
setCellValue(sheet, 2, 4, "班次:" + StrUtil.blankToDefault(workTeam.getTeamName(), ""));
setCellValue(sheet, 19, 9, "审核:");
int rowIndex = 5;
log.info("[production-daily-report] template loaded: path={}, sheetName={}, mergedRegions={}",
TEMPLATE_PATH, sheet.getSheetName(), sheet.getMergedRegions());
String dateText = "日期:" + reqVO.getReportDate().format(DATE_FORMATTER);
String shiftText = "班次:" + StrUtil.blankToDefault(workTeam.getTeamName(), "");
setHeaderValue(sheet, "日期:", dateText, 2, 0);
setHeaderValue(sheet, "班次:", shiftText, 2, 4);
log.info("[production-daily-report] header cells after write: A3={}, C3={}, E3={}",
getCellValue(sheet, 2, 0), getCellValue(sheet, 2, 2), getCellValue(sheet, 2, 4));
int rowIndex = 4;
int exceptionStartRowIndex = 5;
Row templateRow = sheet.getRow(rowIndex);
if (items.size() > 1) {
sheet.shiftRows(exceptionStartRowIndex, sheet.getLastRowNum(), items.size() - 1, true, false);
}
for (int index = 0; index < items.size(); index++) {
if (rowIndex + index > 9) {
sheet.shiftRows(10, sheet.getLastRowNum(), 1, true, false);
}
Row row = sheet.getRow(rowIndex + index);
if (row == null) {
row = sheet.createRow(rowIndex + index);
copyRowStyle(templateRow, row, 5);
}
DeviceProductionDailyReportRespVO.DeviceCapacityItem item = items.get(index);
setCellValue(row, 0, index + 1);
setCellValue(row, 1, StrUtil.blankToDefault(item.getDeviceCode(), item.getDeviceName()));
setCellValue(row, 4, item.getCapacityName());
setCellValue(row, 20, item.getCapacityDiff());
setCellValue(row, 21, toHour(startTime, endTime));
setCellValue(row, 22, startTime.toLocalTime() + "-" + endTime.toLocalTime());
setCellValue(row, 24, workTeam.getTeamName());
setCellValue(row, 2, buildCapacityPointText(item));
setCellValue(row, 3, item.getCapacityDiff());
setCellValue(row, 4, startTime.toLocalTime() + "-" + endTime.toLocalTime());
}
fillWarningDescription(sheet, rowIndex + items.size() + 2, deviceIds, startTime, endTime);
workbook.write(outputStream);
return outputStream.toByteArray();
byte[] bytes = outputStream.toByteArray();
logGeneratedHeader(bytes);
return bytes;
}
}
private void fillWarningDescription(Sheet sheet, int warningRowIndex, List<Long> deviceIds,
LocalDateTime startTime, LocalDateTime endTime) {
List<DeviceWarinningRecordDO> warningRecords = tDengineService.selectDeviceWarningList(deviceIds, startTime, endTime);
Map<Long, List<DeviceWarinningRecordDO>> warningMap = warningRecords.stream()
.collect(Collectors.groupingBy(DeviceWarinningRecordDO::getDeviceId, LinkedHashMap::new, Collectors.toList()));
Row templateRow = sheet.getRow(warningRowIndex);
for (int index = 0; index < deviceIds.size(); index++) {
Row row = sheet.getRow(warningRowIndex + index);
if (row == null) {
row = sheet.createRow(warningRowIndex + index);
copyRowStyle(templateRow, row, 5);
mergeCellsIfAbsent(sheet, warningRowIndex + index, 2, 4);
}
Long deviceId = deviceIds.get(index);
setCellValue(row, 0, index + 1);
setCellValue(row, 1, getDeviceText(deviceId));
String warningDescription = buildWarningDescription(warningMap.getOrDefault(deviceId, Collections.emptyList()));
setCellValue(row, 2, warningDescription);
setWrapText(row, 2);
row.setHeightInPoints(Math.max(row.getHeightInPoints(), 18F * Math.max(1, warningDescription.split("\n", -1).length)));
}
}
private String buildCapacityPointText(DeviceProductionDailyReportRespVO.DeviceCapacityItem item) {
String capacityName = item.getCapacityName();
String capacityCode = item.getCapacityCode();
if (StringUtils.isBlank(capacityName)) {
return StrUtil.blankToDefault(capacityCode, "");
}
if (StringUtils.isBlank(capacityCode) || StringUtils.equals(capacityName, capacityCode)) {
return capacityName;
}
return capacityName + "" + capacityCode + "";
}
private String getDeviceText(Long deviceId) {
DeviceDO device = deviceMapper.selectById(deviceId);
if (device == null) {
return "";
}
return StrUtil.blankToDefault(device.getDeviceCode(), device.getDeviceName());
}
private String buildWarningDescription(List<DeviceWarinningRecordDO> warningRecords) {
if (CollUtil.isEmpty(warningRecords)) {
return "";
}
return warningRecords.stream()
.collect(Collectors.groupingBy(this::getWarningPointName, LinkedHashMap::new, Collectors.toList()))
.entrySet().stream()
.map(entry -> entry.getKey() + "" + buildWarningPointSummary(entry.getValue()))
.collect(Collectors.joining("\n"));
}
private String buildWarningPointSummary(List<DeviceWarinningRecordDO> warningRecords) {
return warningRecords.stream()
.collect(Collectors.groupingBy(this::getWarningRuleKey, LinkedHashMap::new, Collectors.toList()))
.values().stream()
.map(this::buildWarningRuleSummary)
.collect(Collectors.joining(""));
}
private String getWarningRuleKey(DeviceWarinningRecordDO record) {
return getWarningName(record) + "|" + StrUtil.blankToDefault(record.getAlarmLevel(), "");
}
private String buildWarningRuleSummary(List<DeviceWarinningRecordDO> warningRecords) {
DeviceWarinningRecordDO firstRecord = warningRecords.get(0);
String levelText = buildAlarmLevelText(firstRecord.getAlarmLevel());
return getWarningName(firstRecord) + warningRecords.size() + "次"
+ buildWarningValueRangeText(warningRecords) + levelText + buildWarningTimeRangeText(warningRecords);
}
private String buildAlarmLevelText(String alarmLevel) {
if (StringUtils.isBlank(alarmLevel)) {
return "";
}
DictDataRespDTO dictData = dictDataApi.getDictData(ALARM_LEVEL_DICT_TYPE, alarmLevel);
return ",等级=" + (dictData != null && StringUtils.isNotBlank(dictData.getLabel()) ? dictData.getLabel() : alarmLevel);
}
private String getWarningPointName(DeviceWarinningRecordDO record) {
return StrUtil.blankToDefault(record.getModelName(),
StrUtil.blankToDefault(record.getRuleName(), StrUtil.blankToDefault(record.getRule(), "未知点位")));
}
private String getWarningName(DeviceWarinningRecordDO record) {
return StrUtil.blankToDefault(record.getRuleName(), StrUtil.blankToDefault(record.getRule(), "告警"));
}
private String buildWarningValueRangeText(List<DeviceWarinningRecordDO> warningRecords) {
List<Double> values = warningRecords.stream()
.map(this::parseWarningValue)
.filter(Objects::nonNull)
.collect(Collectors.toList());
if (CollUtil.isEmpty(values)) {
return "";
}
double minValue = values.stream().min(Double::compareTo).orElse(0D);
double maxValue = values.stream().max(Double::compareTo).orElse(0D);
if (BigDecimal.valueOf(minValue).compareTo(BigDecimal.valueOf(maxValue)) == 0) {
return ",值=" + formatNumber(minValue);
}
return ",值=" + formatNumber(minValue) + "~" + formatNumber(maxValue);
}
private Double parseWarningValue(DeviceWarinningRecordDO record) {
if (StringUtils.isBlank(record.getAddressValue())) {
return null;
}
try {
return Double.valueOf(record.getAddressValue());
} catch (NumberFormatException e) {
return null;
}
}
private String buildWarningTimeRangeText(List<DeviceWarinningRecordDO> warningRecords) {
List<LocalDateTime> times = warningRecords.stream()
.map(DeviceWarinningRecordDO::getCreateTime)
.filter(Objects::nonNull)
.sorted()
.collect(Collectors.toList());
if (CollUtil.isEmpty(times)) {
return "";
}
LocalDateTime startTime = times.get(0);
LocalDateTime endTime = times.get(times.size() - 1);
if (Objects.equals(startTime, endTime)) {
return ",时间=" + formatWarningTime(startTime, startTime);
}
return ",时间=" + formatWarningTime(startTime, endTime) + "~" + formatWarningTime(endTime, startTime);
}
private String formatWarningTime(LocalDateTime time, LocalDateTime compareTime) {
if (Objects.equals(time.toLocalDate(), compareTime.toLocalDate())) {
return time.format(TIME_FORMATTER);
}
return time.format(DATE_TIME_FORMATTER);
}
private String formatNumber(Double value) {
return BigDecimal.valueOf(value).stripTrailingZeros().toPlainString();
}
private DeviceProductionDailyReportRespVO convertFileToReport(FileDO file) {
@ -343,6 +509,11 @@ public class DeviceProductionDailyReportServiceImpl implements DeviceProductionD
}
private void setCellValue(Sheet sheet, int rowIndex, int columnIndex, Object value) {
CellRangeAddress mergedRegion = getMergedRegion(sheet, rowIndex, columnIndex);
if (mergedRegion != null) {
rowIndex = mergedRegion.getFirstRow();
columnIndex = mergedRegion.getFirstColumn();
}
Row row = sheet.getRow(rowIndex);
if (row == null) {
row = sheet.createRow(rowIndex);
@ -361,5 +532,148 @@ public class DeviceProductionDailyReportServiceImpl implements DeviceProductionD
cell.setCellValue(value == null ? "" : value.toString());
}
}
private void setWrapText(Row row, int columnIndex) {
Cell cell = row.getCell(columnIndex);
if (cell == null) {
return;
}
CellStyle cellStyle = row.getSheet().getWorkbook().createCellStyle();
cellStyle.cloneStyleFrom(cell.getCellStyle());
cellStyle.setWrapText(true);
cell.setCellStyle(cellStyle);
}
private void copyRowStyle(Row sourceRow, Row targetRow, int columnCount) {
if (sourceRow == null || targetRow == null) {
return;
}
targetRow.setHeight(sourceRow.getHeight());
for (int columnIndex = 0; columnIndex < columnCount; columnIndex++) {
Cell sourceCell = sourceRow.getCell(columnIndex);
if (sourceCell == null) {
continue;
}
Cell targetCell = targetRow.getCell(columnIndex);
if (targetCell == null) {
targetCell = targetRow.createCell(columnIndex);
}
targetCell.setCellStyle(sourceCell.getCellStyle());
}
}
private void mergeCellsIfAbsent(Sheet sheet, int rowIndex, int firstColumn, int lastColumn) {
CellRangeAddress newRegion = new CellRangeAddress(rowIndex, rowIndex, firstColumn, lastColumn);
for (CellRangeAddress mergedRegion : sheet.getMergedRegions()) {
if (mergedRegion.intersects(newRegion)) {
return;
}
}
sheet.addMergedRegion(newRegion);
}
private void setHeaderValue(Sheet sheet, String label, String value, int fallbackRowIndex, int fallbackColumnIndex) {
Cell labelCell = findCellByPrefix(sheet, label);
if (labelCell != null) {
CellRangeAddress mergedRegion = getMergedRegion(sheet, labelCell.getRowIndex(), labelCell.getColumnIndex());
log.info("[production-daily-report] set header by label: label={}, foundCell={}, rowIndex={}, columnIndex={}, mergedRegion={}, value={}",
label, labelCell.getAddress().formatAsString(), labelCell.getRowIndex(), labelCell.getColumnIndex(), mergedRegion, value);
setStringCellValueForce(sheet, labelCell.getRowIndex(), labelCell.getColumnIndex(), value);
return;
}
CellRangeAddress mergedRegion = getMergedRegion(sheet, fallbackRowIndex, fallbackColumnIndex);
log.info("[production-daily-report] set header by fallback: label={}, fallbackRowIndex={}, fallbackColumnIndex={}, mergedRegion={}, value={}",
label, fallbackRowIndex, fallbackColumnIndex, mergedRegion, value);
setStringCellValueForce(sheet, fallbackRowIndex, fallbackColumnIndex, value);
}
private void setStringCellValueForce(Sheet sheet, int rowIndex, int columnIndex, String value) {
CellRangeAddress mergedRegion = getMergedRegion(sheet, rowIndex, columnIndex);
int firstRowIndex = mergedRegion != null ? mergedRegion.getFirstRow() : rowIndex;
int firstColumnIndex = mergedRegion != null ? mergedRegion.getFirstColumn() : columnIndex;
Row row = sheet.getRow(firstRowIndex);
if (row == null) {
row = sheet.createRow(firstRowIndex);
}
Cell oldCell = row.getCell(firstColumnIndex);
org.apache.poi.ss.usermodel.CellStyle cellStyle = oldCell != null ? oldCell.getCellStyle() : null;
if (oldCell != null) {
row.removeCell(oldCell);
}
Cell newCell = row.createCell(firstColumnIndex, CellType.STRING);
if (cellStyle != null) {
newCell.setCellStyle(cellStyle);
}
newCell.setCellValue(value);
if (mergedRegion != null) {
for (int column = mergedRegion.getFirstColumn() + 1; column <= mergedRegion.getLastColumn(); column++) {
Cell mergedCell = row.getCell(column);
if (mergedCell != null) {
mergedCell.setCellValue("");
}
}
}
log.info("[production-daily-report] force set header cell: targetRowIndex={}, targetColumnIndex={}, mergedRegion={}, value={}, actualValue={}",
firstRowIndex, firstColumnIndex, mergedRegion, value, getCellValue(sheet, firstRowIndex, firstColumnIndex));
}
@SneakyThrows
private void logGeneratedHeader(byte[] bytes) {
try (Workbook workbook = WorkbookFactory.create(new ByteArrayInputStream(bytes))) {
Sheet sheet = workbook.getSheetAt(0);
log.info("[production-daily-report] generated bytes header check: A3={}, C3={}, E3={}, mergedRegions={}",
getCellValue(sheet, 2, 0), getCellValue(sheet, 2, 2), getCellValue(sheet, 2, 4), sheet.getMergedRegions());
}
}
private String getCellValue(Sheet sheet, int rowIndex, int columnIndex) {
Row row = sheet.getRow(rowIndex);
Cell cell = row != null ? row.getCell(columnIndex) : null;
if (cell == null) {
CellRangeAddress mergedRegion = getMergedRegion(sheet, rowIndex, columnIndex);
if (mergedRegion != null) {
row = sheet.getRow(mergedRegion.getFirstRow());
cell = row != null ? row.getCell(mergedRegion.getFirstColumn()) : null;
}
}
if (row == null) {
return null;
}
if (cell == null) {
return null;
}
if (cell.getCellType() == CellType.STRING) {
return cell.getStringCellValue();
}
if (cell.getCellType() == CellType.NUMERIC) {
return String.valueOf(cell.getNumericCellValue());
}
if (cell.getCellType() == CellType.BOOLEAN) {
return String.valueOf(cell.getBooleanCellValue());
}
return cell.toString();
}
private Cell findCellByPrefix(Sheet sheet, String label) {
for (Row row : sheet) {
for (Cell cell : row) {
if (cell.getCellType() == CellType.STRING && StringUtils.startsWith(cell.getStringCellValue(), label)) {
return cell;
}
}
}
return null;
}
private CellRangeAddress getMergedRegion(Sheet sheet, int rowIndex, int columnIndex) {
for (CellRangeAddress mergedRegion : sheet.getMergedRegions()) {
if (mergedRegion.isInRange(rowIndex, columnIndex)) {
return mergedRegion;
}
}
return null;
}
}

@ -2662,6 +2662,40 @@ public class TDengineService {
}
}
/**
*
*/
@DS("tdengine")
public List<DeviceWarinningRecordDO> selectDeviceWarningList(List<Long> deviceIds, LocalDateTime startTime, LocalDateTime endTime) {
if (CollectionUtils.isEmpty(deviceIds)) {
return Collections.emptyList();
}
String placeholders = deviceIds.stream().map(item -> "?").collect(Collectors.joining(","));
StringBuilder sql = new StringBuilder();
List<Object> params = new ArrayList<>();
sql.append("SELECT * FROM ").append(tdengineTable("iot_device_warning_record")).append(" ")
.append("WHERE deleted = 0 ")
.append("AND device_id IN (").append(placeholders).append(") ");
params.addAll(deviceIds);
if (startTime != null) {
sql.append("AND create_time >= ? ");
params.add(Timestamp.valueOf(startTime));
}
if (endTime != null) {
sql.append("AND create_time <= ? ");
params.add(Timestamp.valueOf(endTime));
}
sql.append("ORDER BY device_id ASC, create_time ASC");
try {
return jdbcTemplate.query(sql.toString(), params.toArray(), (rs, rowNum) -> mapRowToWarningRecordDO(rs));
} catch (Exception e) {
log.error("查询设备时间段告警记录失败: deviceIds={}, startTime={}, endTime={}", deviceIds, startTime, endTime, e);
return Collections.emptyList();
}
}
/**
*
*/

Loading…
Cancel
Save