【功能优化】Bpm:完善最新数据的接口

This commit is contained in:
YunaiV 2025-01-28 09:23:28 +08:00
parent 6071afeae8
commit 8c90448670
16 changed files with 122 additions and 140 deletions

View File

@ -1,50 +0,0 @@
package cn.iocoder.yudao.module.iot.controller.admin.device;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataPageReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataRespVO;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotTimeDataRespVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDevicePropertyDO;
import cn.iocoder.yudao.module.iot.service.device.data.IotDevicePropertyService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
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 java.util.List;
import java.util.Map;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@Tag(name = "管理后台 - IoT 设备数据")
@RestController
@RequestMapping("/iot/device/data")
@Validated
public class IotDeviceDataController {
@Resource
private IotDevicePropertyService deviceDataService;
// TODO @浩浩这里的 /latest-list包括方法名
@GetMapping("/latest")
@Operation(summary = "获取设备属性最新数据")
public CommonResult<List<IotDeviceDataRespVO>> getLatestDeviceProperties(@Valid IotDeviceDataPageReqVO deviceDataReqVO) {
List<IotDevicePropertyDO> list = deviceDataService.getLatestDeviceProperties(deviceDataReqVO);
return success(BeanUtils.toBean(list, IotDeviceDataRespVO.class));
}
// TODO @浩浩这里的 /history-page 包括方法名
@GetMapping("/history")
@Operation(summary = "获取设备属性历史数据")
public CommonResult<PageResult<IotTimeDataRespVO>> getHistoryDeviceProperties(@Valid IotDeviceDataPageReqVO deviceDataReqVO) {
PageResult<Map<String, Object>> list = deviceDataService.getHistoryDeviceProperties(deviceDataReqVO);
return success(BeanUtils.toBean(list, IotTimeDataRespVO.class));
}
}

View File

@ -3,8 +3,8 @@ package cn.iocoder.yudao.module.iot.controller.admin.device;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceLogPageReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceLogRespVO;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDeviceLogPageReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDeviceLogRespVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceLogDO;
import cn.iocoder.yudao.module.iot.service.device.data.IotDeviceLogService;
import io.swagger.v3.oas.annotations.Operation;

View File

@ -0,0 +1,75 @@
package cn.iocoder.yudao.module.iot.controller.admin.device;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDeviceDataPageReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDeviceDataRespVO;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotTimeDataRespVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDevicePropertyDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO;
import cn.iocoder.yudao.module.iot.service.device.IotDeviceService;
import cn.iocoder.yudao.module.iot.service.device.data.IotDevicePropertyService;
import cn.iocoder.yudao.module.iot.service.thingmodel.IotThingModelService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
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 java.util.List;
import java.util.Map;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
@Tag(name = "管理后台 - IoT 设备属性")
@RestController
@RequestMapping("/iot/device/property")
@Validated
public class IotDevicePropertyController {
@Resource
private IotDevicePropertyService devicePropertyService;
@Resource
private IotThingModelService thingModelService;
@Resource
private IotDeviceService deviceService;
@GetMapping("/latest")
@Operation(summary = "获取设备属性最新属性")
public CommonResult<List<IotDeviceDataRespVO>> getLatestDeviceProperties(@Valid IotDeviceDataPageReqVO pageReqVO) {
Map<String, IotDevicePropertyDO> properties = devicePropertyService.getLatestDeviceProperties(pageReqVO);
// 拼接数据
IotDeviceDO device = deviceService.getDevice(pageReqVO.getDeviceId());
Assert.notNull(device, "设备不存在");
List<IotThingModelDO> thingModels = thingModelService.getThingModelListByProductId(device.getProductId());
return success(convertList(properties.entrySet(), entry -> {
IotThingModelDO thingModel = CollUtil.findOne(thingModels,
item -> item.getIdentifier().equals(entry.getKey()));
if (thingModel == null || thingModel.getProperty() == null) {
return null;
}
IotDevicePropertyDO property = entry.getValue();
return BeanUtils.toBean(thingModel, IotDeviceDataRespVO.class)
.setDataType(thingModel.getProperty().getDataType())
.setValue(property.getValue()).setUpdateTime(property.getUpdateTime());
}));
}
// TODO @浩浩这里的 /history-page 包括方法名
@GetMapping("/history")
@Operation(summary = "获取设备属性历史数据")
public CommonResult<PageResult<IotTimeDataRespVO>> getHistoryDeviceProperties(@Valid IotDeviceDataPageReqVO pageReqVO) {
PageResult<Map<String, Object>> list = devicePropertyService.getHistoryDeviceProperties(pageReqVO);
return success(BeanUtils.toBean(list, IotTimeDataRespVO.class));
}
}

View File

@ -1,20 +1,16 @@
package cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData;
package cn.iocoder.yudao.module.iot.controller.admin.device.vo.data;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Size;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - IoT 设备数据 Request VO")
@Data
public class IotDeviceDataPageReqVO extends PageParam {
@Schema(description = "设备编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "177")
@NotNull(message = "设备编号不能为空")
private Long deviceId;
@Schema(description = "属性标识符", requiredMode = Schema.RequiredMode.REQUIRED)
@ -23,9 +19,4 @@ public class IotDeviceDataPageReqVO extends PageParam {
@Schema(description = "属性名称", requiredMode = Schema.RequiredMode.REQUIRED)
private String name;
@Schema(description = "时间范围", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@Size(min = 2, max = 2, message = "请选择时间范围")
private LocalDateTime[] times;
}

View File

@ -1,39 +1,32 @@
package cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData;
package cn.iocoder.yudao.module.iot.controller.admin.device.vo.data;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - IoT 设备数据 Response VO")
@Schema(description = "管理后台 - IoT 设备属性 Response VO")
@Data
public class IotDeviceDataRespVO {
@Schema(description = "设备编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "177")
private Long deviceId;
@Schema(description = "物模型编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "21816")
private Long thingModelId;
@Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED)
private String productKey;
@Schema(description = "设备名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五")
private String deviceName;
@Schema(description = "属性标识符", requiredMode = Schema.RequiredMode.REQUIRED)
private String identifier;
@Schema(description = "最新值", requiredMode = Schema.RequiredMode.REQUIRED)
private Object value;
@Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime updateTime;
// ========== 基于 ThingModel 查询 ==========
// @Schema(description = "物模型编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "21816")
// private Long thingModelId;
@Schema(description = "属性名称", requiredMode = Schema.RequiredMode.REQUIRED)
private String name;
@Schema(description = "数据类型", requiredMode = Schema.RequiredMode.REQUIRED)
private String dataType;
@Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime updateTime;
@Schema(description = "最新值", requiredMode = Schema.RequiredMode.REQUIRED)
private String value;
}

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData;
package cn.iocoder.yudao.module.iot.controller.admin.device.vo.data;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData;
package cn.iocoder.yudao.module.iot.controller.admin.device.vo.data;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@ -22,7 +22,7 @@ public class IotDeviceLogRespVO {
private String type;
@Schema(description = "标识符", requiredMode = Schema.RequiredMode.REQUIRED, example = "temperature")
private String subType;
private String identifier;
@Schema(description = "日志内容", requiredMode = Schema.RequiredMode.REQUIRED)
private String content;

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData;
package cn.iocoder.yudao.module.iot.controller.admin.device.vo.data;
import lombok.AllArgsConstructor;
import lombok.Data;

View File

@ -28,8 +28,9 @@ public class DevicePropertyRedisDAO {
if (CollUtil.isEmpty(entries)) {
return Collections.emptyMap();
}
return convertMap(entries.values(), key -> (String) key,
value -> JsonUtils.parseObject((String) value, IotDevicePropertyDO.class));
return convertMap(entries.entrySet(),
entry -> (String) entry.getKey(),
entry -> JsonUtils.parseObject((String) entry.getValue(), IotDevicePropertyDO.class));
}
public void set(String deviceKey, Map<String, IotDevicePropertyDO> properties) {

View File

@ -1,6 +1,6 @@
package cn.iocoder.yudao.module.iot.dal.tdengine;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceLogPageReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDeviceLogPageReqVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceLogDO;
import cn.iocoder.yudao.module.iot.framework.tdengine.core.annotation.TDengineDS;
import com.baomidou.mybatisplus.annotation.InterceptorIgnore;

View File

@ -59,6 +59,14 @@ public interface IotDeviceService {
*/
void deleteDeviceList(Collection<Long> ids);
/**
* 校验设备是否存在
*
* @param id 设备 ID
* @return 设备对象
*/
IotDeviceDO validateDeviceExists(Long id);
/**
* 获得设备
*
@ -67,7 +75,6 @@ public interface IotDeviceService {
*/
IotDeviceDO getDevice(Long id);
/**
* 根据设备 key 获得设备
*

View File

@ -187,13 +187,8 @@ public class IotDeviceServiceImpl implements IotDeviceService {
deleteDeviceCache(devices);
}
/**
* 校验设备是否存在
*
* @param id 设备 ID
* @return 设备对象
*/
private IotDeviceDO validateDeviceExists(Long id) {
@Override
public IotDeviceDO validateDeviceExists(Long id) {
IotDeviceDO device = deviceMapper.selectById(id);
if (device == null) {
throw exception(DEVICE_NOT_EXISTS);

View File

@ -1,7 +1,7 @@
package cn.iocoder.yudao.module.iot.service.device.data;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceLogPageReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDeviceLogPageReqVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceLogDO;
import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage;

View File

@ -5,7 +5,7 @@ import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceLogPageReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDeviceLogPageReqVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceLogDO;
import cn.iocoder.yudao.module.iot.dal.tdengine.IotDeviceLogMapper;
import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage;

View File

@ -1,12 +1,11 @@
package cn.iocoder.yudao.module.iot.service.device.data;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataPageReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDeviceDataPageReqVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDevicePropertyDO;
import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage;
import jakarta.validation.Valid;
import java.util.List;
import java.util.Map;
/**
@ -36,7 +35,7 @@ public interface IotDevicePropertyService {
* @param deviceId 设备编号
* @return 设备属性最新数据
*/
List<IotDevicePropertyDO> getLatestDeviceProperties(@Valid IotDeviceDataPageReqVO deviceId);
Map<String, IotDevicePropertyDO> getLatestDeviceProperties(@Valid IotDeviceDataPageReqVO deviceId);
/**
* 获得设备属性历史数据

View File

@ -6,7 +6,7 @@ import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataPageReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDeviceDataPageReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType.ThingModelDateOrTextDataSpecs;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDevicePropertyDO;
@ -151,41 +151,12 @@ public class IotDevicePropertyServiceImpl implements IotDevicePropertyService {
}
@Override
public List<IotDevicePropertyDO> getLatestDeviceProperties(@Valid IotDeviceDataPageReqVO deviceDataReqVO) {
// List<IotDevicePropertyDO> list = new ArrayList<>();
// // 1. 获取设备信息
// IotDeviceDO device = deviceService.getDevice(deviceDataReqVO.getDeviceId());
// // 2. 获取设备属性最新数据
// List<IotThingModelDO> thingModelList = thingModelService.getProductThingModelListByProductKey(device.getProductKey());
// thingModelList = filterList(thingModelList, thingModel -> IotThingModelTypeEnum.PROPERTY.getType()
// .equals(thingModel.getType()));
//
// // 3. 过滤标识符和属性名称
// if (deviceDataReqVO.getIdentifier() != null) {
// thingModelList = filterList(thingModelList, thingModel -> thingModel.getIdentifier()
// .toLowerCase().contains(deviceDataReqVO.getIdentifier().toLowerCase()));
// }
// if (deviceDataReqVO.getName() != null) {
// thingModelList = filterList(thingModelList, thingModel -> thingModel.getName()
// .toLowerCase().contains(deviceDataReqVO.getName().toLowerCase()));
// }
// // 4. 获取设备属性最新数据
// thingModelList.forEach(thingModel -> {
// IotDevicePropertyDO deviceData = deviceDataRedisDAO.get(device.getProductKey(), device.getDeviceName(), thingModel.getIdentifier());
// if (deviceData == null) {
// deviceData = new IotDevicePropertyDO();
// deviceData.setProductKey(device.getProductKey());
// deviceData.setDeviceName(device.getDeviceName());
// deviceData.setIdentifier(thingModel.getIdentifier());
// deviceData.setDeviceId(deviceDataReqVO.getDeviceId());
// deviceData.setThingModelId(thingModel.getId());
// deviceData.setName(thingModel.getName());
// deviceData.setDataType(thingModel.getProperty().getDataType());
// }
// list.add(deviceData);
// });
// return list;
return null; // TODO 芋艿晚点实现
public Map<String, IotDevicePropertyDO> getLatestDeviceProperties(@Valid IotDeviceDataPageReqVO pageReqVO) {
// 获取设备信息
IotDeviceDO device = deviceService.validateDeviceExists(pageReqVO.getDeviceId());
// 获得设备属性
return deviceDataRedisDAO.get(device.getDeviceKey());
}
@Override