|
|
|
|
@ -108,6 +108,8 @@ public class DeviceServiceImpl implements DeviceService {
|
|
|
|
|
@Resource
|
|
|
|
|
private DeviceOperationRecordMapper deviceOperationRecordMapper;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
|
|
public DeviceDO createDevice(DeviceSaveReqVO createReqVO) {
|
|
|
|
|
@ -689,78 +691,107 @@ public class DeviceServiceImpl implements DeviceService {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public List<Map<String, Object>> historyRecord(Long deviceId,String collectionStartTime, String collectionEndTime) {
|
|
|
|
|
|
|
|
|
|
public PageResult<Map<String, Object>> historyRecord(Long deviceId, String collectionStartTime, String collectionEndTime,Integer page,
|
|
|
|
|
Integer pageSize) {
|
|
|
|
|
List<Map<String, Object>> resultList = new ArrayList<>();
|
|
|
|
|
if (deviceId == null) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
// 1. 获取设备数据列表
|
|
|
|
|
List<Map<String, Object>> deviceDataList = tdengineService.getstDeviceDataOrderByTimeDesc(deviceId,collectionStartTime,collectionEndTime,null);
|
|
|
|
|
List<Map<String, Object>> deviceDataList = tdengineService.getstDeviceDataOrderByTimeDescPage(
|
|
|
|
|
deviceId, collectionStartTime, collectionEndTime, page, pageSize
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// 2. 获取属性类型映射
|
|
|
|
|
long total = tdengineService.queryDeviceDataTotal(deviceId, collectionStartTime, collectionEndTime);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (deviceDataList.isEmpty()) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 2. 获取属性类型映射 (ID -> Name) 并构建缓存,避免重复数据库查询
|
|
|
|
|
Map<Long, String> idToNameMap = deviceAttributeTypeMapper.selectList()
|
|
|
|
|
.stream()
|
|
|
|
|
.collect(Collectors.toMap(
|
|
|
|
|
DeviceAttributeTypeDO::getId,
|
|
|
|
|
DeviceAttributeTypeDO::getName
|
|
|
|
|
));
|
|
|
|
|
.collect(Collectors.toMap(DeviceAttributeTypeDO::getId, DeviceAttributeTypeDO::getName));
|
|
|
|
|
|
|
|
|
|
// 额外缓存:数字ID -> 名称,防止同一个ID多次查询数据库
|
|
|
|
|
Map<Long, String> attributeTypeCache = new HashMap<>();
|
|
|
|
|
|
|
|
|
|
// 3. 遍历每个时间点的数据
|
|
|
|
|
ObjectMapper objectMapper = new ObjectMapper();
|
|
|
|
|
|
|
|
|
|
// 3. 遍历每条设备数据
|
|
|
|
|
for (Map<String, Object> deviceData : deviceDataList) {
|
|
|
|
|
String queryDataJson = (String) deviceData.get("queryData");
|
|
|
|
|
Timestamp timestamp = (Timestamp) deviceData.get("timestamp");
|
|
|
|
|
|
|
|
|
|
if (StringUtils.isNotBlank(queryDataJson) && timestamp != null) {
|
|
|
|
|
List<Map<String, Object>> dataList = new ObjectMapper().readValue(
|
|
|
|
|
queryDataJson,
|
|
|
|
|
new TypeReference<List<Map<String, Object>>>() {}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// 按属性类型分组
|
|
|
|
|
Map<String, List<Map<String, Object>>> groupedData = new LinkedHashMap<>();
|
|
|
|
|
if (StringUtils.isBlank(queryDataJson) || timestamp == null) {
|
|
|
|
|
continue; // 跳过无效数据
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (Map<String, Object> data : dataList) {
|
|
|
|
|
String attributeTypeName = "其他";
|
|
|
|
|
String typeStr = (String) data.get("attributeType");
|
|
|
|
|
if (typeStr != null) {
|
|
|
|
|
try {
|
|
|
|
|
attributeTypeName = typeStr;
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
attributeTypeName = "未知";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
List<Map<String, Object>> dataList = objectMapper.readValue(
|
|
|
|
|
queryDataJson, new TypeReference<List<Map<String, Object>>>() {}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
Map<String, Object> simplifiedData = new HashMap<>();
|
|
|
|
|
simplifiedData.put("addressValue", data.get("addressValue"));
|
|
|
|
|
simplifiedData.put("attributeName", data.get("attributeName"));
|
|
|
|
|
// 4. 按属性类型分组
|
|
|
|
|
Map<String, List<Map<String, Object>>> groupedData = new LinkedHashMap<>();
|
|
|
|
|
|
|
|
|
|
groupedData
|
|
|
|
|
.computeIfAbsent(attributeTypeName, k -> new ArrayList<>())
|
|
|
|
|
.add(simplifiedData);
|
|
|
|
|
}
|
|
|
|
|
for (Map<String, Object> data : dataList) {
|
|
|
|
|
String attributeTypeName = "其他";
|
|
|
|
|
Object typeObj = data.get("attributeType");
|
|
|
|
|
|
|
|
|
|
// 创建当前时间点的Map
|
|
|
|
|
Map<String, Object> timePointData = new LinkedHashMap<>();
|
|
|
|
|
if (typeObj != null) {
|
|
|
|
|
String typeStr = typeObj.toString();
|
|
|
|
|
|
|
|
|
|
// 添加属性分组
|
|
|
|
|
for (Map.Entry<String, List<Map<String, Object>>> entry : groupedData.entrySet()) {
|
|
|
|
|
timePointData.put(entry.getKey(), entry.getValue());
|
|
|
|
|
try {
|
|
|
|
|
// 尝试当作数字 ID
|
|
|
|
|
Long typeId = Long.parseLong(typeStr);
|
|
|
|
|
|
|
|
|
|
// 先从缓存查
|
|
|
|
|
if (attributeTypeCache.containsKey(typeId)) {
|
|
|
|
|
attributeTypeName = attributeTypeCache.get(typeId);
|
|
|
|
|
} else {
|
|
|
|
|
// 查数据库
|
|
|
|
|
String nameFromDb = idToNameMap.get(typeId);
|
|
|
|
|
if (nameFromDb != null) {
|
|
|
|
|
attributeTypeName = nameFromDb;
|
|
|
|
|
} else {
|
|
|
|
|
attributeTypeName = typeStr; // 查不到就用原值
|
|
|
|
|
}
|
|
|
|
|
attributeTypeCache.put(typeId, attributeTypeName);
|
|
|
|
|
}
|
|
|
|
|
} catch (NumberFormatException e) {
|
|
|
|
|
// 不是数字,直接用原字符串
|
|
|
|
|
attributeTypeName = typeStr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 添加收集时间
|
|
|
|
|
timePointData.put("collectTime", timestamp.toString());
|
|
|
|
|
// 构建属性数据 Map
|
|
|
|
|
Map<String, Object> simplifiedData = new HashMap<>();
|
|
|
|
|
simplifiedData.put("addressValue", data.get("addressValue"));
|
|
|
|
|
simplifiedData.put("attributeName", data.get("attributeName"));
|
|
|
|
|
|
|
|
|
|
resultList.add(timePointData);
|
|
|
|
|
groupedData.computeIfAbsent(attributeTypeName, k -> new ArrayList<>())
|
|
|
|
|
.add(simplifiedData);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 5. 构建时间点 Map
|
|
|
|
|
Map<String, Object> timePointData = new LinkedHashMap<>(groupedData);
|
|
|
|
|
timePointData.put("collectTime", timestamp.toString());
|
|
|
|
|
|
|
|
|
|
resultList.add(timePointData);
|
|
|
|
|
}
|
|
|
|
|
return new PageResult<>(resultList, total);
|
|
|
|
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
System.out.println("处理设备数据时发生异常: " + e.getMessage());
|
|
|
|
|
log.error("处理设备数据时发生异常", e);
|
|
|
|
|
return PageResult.empty();
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return resultList;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void validateDeviceAttributeExists(Long id) {
|
|
|
|
|
|