Initial commit with remote deployment configuration
Some checks failed
aagro-ui-admin CI / build (14.x) (push) Has been cancelled
aagro-ui-admin CI / build (16.x) (push) Has been cancelled
Java CI with Maven / build (11) (push) Has been cancelled
Java CI with Maven / build (17) (push) Has been cancelled
Java CI with Maven / build (8) (push) Has been cancelled
Some checks failed
aagro-ui-admin CI / build (14.x) (push) Has been cancelled
aagro-ui-admin CI / build (16.x) (push) Has been cancelled
Java CI with Maven / build (11) (push) Has been cancelled
Java CI with Maven / build (17) (push) Has been cancelled
Java CI with Maven / build (8) (push) Has been cancelled
This commit is contained in:
107
aagro-module-iot/aagro-module-iot-biz/pom.xml
Normal file
107
aagro-module-iot/aagro-module-iot-biz/pom.xml
Normal file
@@ -0,0 +1,107 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>aagro-module-iot</artifactId>
|
||||
<groupId>cn.aagro.gg</groupId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<artifactId>aagro-module-iot-biz</artifactId>
|
||||
|
||||
<name>${project.artifactId}</name>
|
||||
<description>
|
||||
物联网 模块,主要实现 产品管理、设备管理、协议管理等功能。
|
||||
<!-- TODO 芋艿:后续补充下 -->
|
||||
</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>cn.aagro.gg</groupId>
|
||||
<artifactId>aagro-module-system</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.aagro.gg</groupId>
|
||||
<artifactId>aagro-module-iot-core</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.aagro.gg</groupId>
|
||||
<artifactId>aagro-spring-boot-starter-biz-tenant</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Web 相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.aagro.gg</groupId>
|
||||
<artifactId>aagro-spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.aagro.gg</groupId>
|
||||
<artifactId>aagro-spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- DB 相关 -->
|
||||
<dependency>
|
||||
<groupId>com.taosdata.jdbc</groupId>
|
||||
<artifactId>taos-jdbcdriver</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.aagro.gg</groupId>
|
||||
<artifactId>aagro-spring-boot-starter-mybatis</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.aagro.gg</groupId>
|
||||
<artifactId>aagro-spring-boot-starter-redis</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Test 测试相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.aagro.gg</groupId>
|
||||
<artifactId>aagro-spring-boot-starter-test</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 工具类相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.aagro.gg</groupId>
|
||||
<artifactId>aagro-spring-boot-starter-excel</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 消息队列相关 -->
|
||||
<!-- TODO @芋艿:临时打开 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.rocketmq</groupId>
|
||||
<artifactId>rocketmq-spring-boot-starter</artifactId>
|
||||
<!-- <optional>true</optional>-->
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.kafka</groupId>
|
||||
<artifactId>spring-kafka</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-amqp</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- IoT 网络组件:接收来自设备的上行数据 -->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>cn.aagro.gg</groupId>-->
|
||||
<!-- <artifactId>aagro-module-iot-net-component-http</artifactId>-->
|
||||
<!-- <version>${revision}</version>-->
|
||||
<!-- </dependency>-->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>cn.aagro.gg</groupId>-->
|
||||
<!-- <artifactId>aagro-module-iot-net-component-emqx</artifactId>-->
|
||||
<!-- <version>${revision}</version>-->
|
||||
<!-- </dependency>-->
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,61 @@
|
||||
package cn.aagro.pp.module.iot.api.device;
|
||||
|
||||
import cn.aagro.pp.framework.common.enums.RpcConstants;
|
||||
import cn.aagro.pp.framework.common.pojo.CommonResult;
|
||||
import cn.aagro.pp.framework.common.util.object.BeanUtils;
|
||||
import cn.aagro.pp.module.iot.core.biz.IotDeviceCommonApi;
|
||||
import cn.aagro.pp.module.iot.core.biz.dto.IotDeviceAuthReqDTO;
|
||||
import cn.aagro.pp.module.iot.core.biz.dto.IotDeviceGetReqDTO;
|
||||
import cn.aagro.pp.module.iot.core.biz.dto.IotDeviceRespDTO;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.device.IotDeviceDO;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.product.IotProductDO;
|
||||
import cn.aagro.pp.module.iot.service.device.IotDeviceService;
|
||||
import cn.aagro.pp.module.iot.service.product.IotProductService;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.annotation.security.PermitAll;
|
||||
|
||||
import static cn.aagro.pp.framework.common.pojo.CommonResult.success;
|
||||
|
||||
/**
|
||||
* IoT 设备 API 实现类
|
||||
*
|
||||
* @author haohao
|
||||
*/
|
||||
@RestController
|
||||
@Validated
|
||||
@Primary // 保证优先匹配,因为 aagro-iot-gateway 也有 IotDeviceCommonApi 的实现,并且也可能会被 biz 引入
|
||||
public class IoTDeviceApiImpl implements IotDeviceCommonApi {
|
||||
|
||||
@Resource
|
||||
private IotDeviceService deviceService;
|
||||
@Resource
|
||||
private IotProductService productService;
|
||||
|
||||
@Override
|
||||
@PostMapping(RpcConstants.RPC_API_PREFIX + "/iot/device/auth")
|
||||
@PermitAll
|
||||
public CommonResult<Boolean> authDevice(@RequestBody IotDeviceAuthReqDTO authReqDTO) {
|
||||
return success(deviceService.authDevice(authReqDTO));
|
||||
}
|
||||
|
||||
@Override
|
||||
@PostMapping(RpcConstants.RPC_API_PREFIX + "/iot/device/get") // 特殊:方便调用,暂时使用 POST,实际更推荐 GET
|
||||
@PermitAll
|
||||
public CommonResult<IotDeviceRespDTO> getDevice(@RequestBody IotDeviceGetReqDTO getReqDTO) {
|
||||
IotDeviceDO device = getReqDTO.getId() != null ? deviceService.getDeviceFromCache(getReqDTO.getId())
|
||||
: deviceService.getDeviceFromCache(getReqDTO.getProductKey(), getReqDTO.getDeviceName());
|
||||
return success(BeanUtils.toBean(device, IotDeviceRespDTO.class, deviceDTO -> {
|
||||
IotProductDO product = productService.getProductFromCache(deviceDTO.getProductId());
|
||||
if (product != null) {
|
||||
deviceDTO.setCodecType(product.getCodecType());
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* iot API 包,定义并实现提供给其它模块的 API
|
||||
*/
|
||||
package cn.aagro.pp.module.iot.api;
|
||||
@@ -0,0 +1,104 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.alert;
|
||||
|
||||
import cn.aagro.pp.framework.common.enums.CommonStatusEnum;
|
||||
import cn.aagro.pp.framework.common.pojo.CommonResult;
|
||||
import cn.aagro.pp.framework.common.pojo.PageResult;
|
||||
import cn.aagro.pp.framework.common.util.object.BeanUtils;
|
||||
import cn.aagro.pp.module.iot.controller.admin.alert.vo.config.IotAlertConfigPageReqVO;
|
||||
import cn.aagro.pp.module.iot.controller.admin.alert.vo.config.IotAlertConfigRespVO;
|
||||
import cn.aagro.pp.module.iot.controller.admin.alert.vo.config.IotAlertConfigSaveReqVO;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.alert.IotAlertConfigDO;
|
||||
import cn.aagro.pp.module.iot.service.alert.IotAlertConfigService;
|
||||
import cn.aagro.pp.module.system.api.user.AdminUserApi;
|
||||
import cn.aagro.pp.module.system.api.user.dto.AdminUserRespDTO;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.aagro.pp.framework.common.pojo.CommonResult.success;
|
||||
import static cn.aagro.pp.framework.common.util.collection.CollectionUtils.convertList;
|
||||
import static cn.aagro.pp.framework.common.util.collection.CollectionUtils.convertSetByFlatMap;
|
||||
|
||||
@Tag(name = "管理后台 - IoT 告警配置")
|
||||
@RestController
|
||||
@RequestMapping("/iot/alert-config")
|
||||
@Validated
|
||||
public class IotAlertConfigController {
|
||||
|
||||
@Resource
|
||||
private IotAlertConfigService alertConfigService;
|
||||
|
||||
@Resource
|
||||
private AdminUserApi adminUserApi;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建告警配置")
|
||||
@PreAuthorize("@ss.hasPermission('iot:alert-config:create')")
|
||||
public CommonResult<Long> createAlertConfig(@Valid @RequestBody IotAlertConfigSaveReqVO createReqVO) {
|
||||
return success(alertConfigService.createAlertConfig(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新告警配置")
|
||||
@PreAuthorize("@ss.hasPermission('iot:alert-config:update')")
|
||||
public CommonResult<Boolean> updateAlertConfig(@Valid @RequestBody IotAlertConfigSaveReqVO updateReqVO) {
|
||||
alertConfigService.updateAlertConfig(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除告警配置")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('iot:alert-config:delete')")
|
||||
public CommonResult<Boolean> deleteAlertConfig(@RequestParam("id") Long id) {
|
||||
alertConfigService.deleteAlertConfig(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得告警配置")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('iot:alert-config:query')")
|
||||
public CommonResult<IotAlertConfigRespVO> getAlertConfig(@RequestParam("id") Long id) {
|
||||
IotAlertConfigDO alertConfig = alertConfigService.getAlertConfig(id);
|
||||
return success(BeanUtils.toBean(alertConfig, IotAlertConfigRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得告警配置分页")
|
||||
@PreAuthorize("@ss.hasPermission('iot:alert-config:query')")
|
||||
public CommonResult<PageResult<IotAlertConfigRespVO>> getAlertConfigPage(@Valid IotAlertConfigPageReqVO pageReqVO) {
|
||||
PageResult<IotAlertConfigDO> pageResult = alertConfigService.getAlertConfigPage(pageReqVO);
|
||||
|
||||
// 转换返回
|
||||
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
|
||||
convertSetByFlatMap(pageResult.getList(), config -> config.getReceiveUserIds().stream()));
|
||||
return success(BeanUtils.toBean(pageResult, IotAlertConfigRespVO.class, vo -> {
|
||||
vo.setReceiveUserNames(vo.getReceiveUserIds().stream()
|
||||
.map(userMap::get)
|
||||
.filter(Objects::nonNull)
|
||||
.map(AdminUserRespDTO::getNickname)
|
||||
.collect(Collectors.toList()));
|
||||
}));
|
||||
}
|
||||
|
||||
@GetMapping("/simple-list")
|
||||
@Operation(summary = "获得告警配置简单列表", description = "只包含被开启的告警配置,主要用于前端的下拉选项")
|
||||
@PreAuthorize("@ss.hasPermission('iot:alert-config:query')")
|
||||
public CommonResult<List<IotAlertConfigRespVO>> getAlertConfigSimpleList() {
|
||||
List<IotAlertConfigDO> list = alertConfigService.getAlertConfigListByStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
return success(convertList(list, config -> // 只返回 id、name 字段
|
||||
new IotAlertConfigRespVO().setId(config.getId()).setName(config.getName())));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.alert;
|
||||
|
||||
import cn.aagro.pp.framework.common.pojo.CommonResult;
|
||||
import cn.aagro.pp.framework.common.pojo.PageResult;
|
||||
import cn.aagro.pp.framework.common.util.object.BeanUtils;
|
||||
import cn.aagro.pp.module.iot.controller.admin.alert.vo.recrod.IotAlertRecordPageReqVO;
|
||||
import cn.aagro.pp.module.iot.controller.admin.alert.vo.recrod.IotAlertRecordProcessReqVO;
|
||||
import cn.aagro.pp.module.iot.controller.admin.alert.vo.recrod.IotAlertRecordRespVO;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.alert.IotAlertRecordDO;
|
||||
import cn.aagro.pp.module.iot.service.alert.IotAlertRecordService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
|
||||
import static cn.aagro.pp.framework.common.pojo.CommonResult.success;
|
||||
import static java.util.Collections.singleton;
|
||||
|
||||
@Tag(name = "管理后台 - IoT 告警记录")
|
||||
@RestController
|
||||
@RequestMapping("/iot/alert-record")
|
||||
@Validated
|
||||
public class IotAlertRecordController {
|
||||
|
||||
@Resource
|
||||
private IotAlertRecordService alertRecordService;
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得告警记录")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('iot:alert-record:query')")
|
||||
public CommonResult<IotAlertRecordRespVO> getAlertRecord(@RequestParam("id") Long id) {
|
||||
IotAlertRecordDO alertRecord = alertRecordService.getAlertRecord(id);
|
||||
return success(BeanUtils.toBean(alertRecord, IotAlertRecordRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得告警记录分页")
|
||||
@PreAuthorize("@ss.hasPermission('iot:alert-record:query')")
|
||||
public CommonResult<PageResult<IotAlertRecordRespVO>> getAlertRecordPage(@Valid IotAlertRecordPageReqVO pageReqVO) {
|
||||
PageResult<IotAlertRecordDO> pageResult = alertRecordService.getAlertRecordPage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, IotAlertRecordRespVO.class));
|
||||
}
|
||||
|
||||
@PutMapping("/process")
|
||||
@Operation(summary = "处理告警记录")
|
||||
@PreAuthorize("@ss.hasPermission('iot:alert-record:process')")
|
||||
public CommonResult<Boolean> processAlertRecord(@Valid @RequestBody IotAlertRecordProcessReqVO processReqVO) {
|
||||
alertRecordService.processAlertRecordList(singleton(processReqVO.getId()), processReqVO.getProcessRemark());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.alert.vo.config;
|
||||
|
||||
import cn.aagro.pp.framework.common.pojo.PageParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.aagro.pp.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 告警配置分页 Request VO")
|
||||
@Data
|
||||
public class IotAlertConfigPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "配置名称", example = "赵六")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "配置状态", example = "1")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.alert.vo.config;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 告警配置 Response VO")
|
||||
@Data
|
||||
public class IotAlertConfigRespVO {
|
||||
|
||||
@Schema(description = "配置编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3566")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "配置名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "配置描述", example = "你猜")
|
||||
private String description;
|
||||
|
||||
@Schema(description = "告警级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer level;
|
||||
|
||||
@Schema(description = "配置状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "关联的场景联动规则编号数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "1,2,3")
|
||||
private List<Long> sceneRuleIds;
|
||||
|
||||
@Schema(description = "接收的用户编号数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "100,200")
|
||||
private List<Long> receiveUserIds;
|
||||
|
||||
@Schema(description = "接收的用户名称数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "张三,李四")
|
||||
private List<String> receiveUserNames;
|
||||
|
||||
@Schema(description = "接收的类型数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "1,2,3")
|
||||
private List<Integer> receiveTypes;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.alert.vo.config;
|
||||
|
||||
import cn.aagro.pp.framework.common.enums.CommonStatusEnum;
|
||||
import cn.aagro.pp.framework.common.validation.InEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 告警配置新增/修改 Request VO")
|
||||
@Data
|
||||
public class IotAlertConfigSaveReqVO {
|
||||
|
||||
@Schema(description = "配置编号", example = "3566")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "配置名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
|
||||
@NotEmpty(message = "配置名称不能为空")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "配置描述", example = "你猜")
|
||||
private String description;
|
||||
|
||||
@Schema(description = "告警级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "告警级别不能为空")
|
||||
private Integer level;
|
||||
|
||||
@Schema(description = "配置状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "配置状态不能为空")
|
||||
@InEnum(CommonStatusEnum.class)
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "关联的场景联动规则编号数组")
|
||||
@NotEmpty(message = "关联的场景联动规则编号数组不能为空")
|
||||
private List<Long> sceneRuleIds;
|
||||
|
||||
@Schema(description = "接收的用户编号数组")
|
||||
@NotEmpty(message = "接收的用户编号数组不能为空")
|
||||
private List<Long> receiveUserIds;
|
||||
|
||||
@Schema(description = "接收的类型数组")
|
||||
@NotEmpty(message = "接收的类型数组不能为空")
|
||||
private List<Integer> receiveTypes;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.alert.vo.recrod;
|
||||
|
||||
import cn.aagro.pp.framework.common.pojo.PageParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.aagro.pp.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 告警记录分页 Request VO")
|
||||
@Data
|
||||
public class IotAlertRecordPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "告警配置编号", example = "29320")
|
||||
private Long configId;
|
||||
|
||||
@Schema(description = "告警级别", example = "1")
|
||||
private Integer level;
|
||||
|
||||
@Schema(description = "产品编号", example = "2050")
|
||||
private Long productId;
|
||||
|
||||
@Schema(description = "设备编号", example = "21727")
|
||||
private String deviceId;
|
||||
|
||||
@Schema(description = "是否处理", example = "true")
|
||||
private Boolean processStatus;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.alert.vo.recrod;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 告警记录处理 Request VO")
|
||||
@Data
|
||||
public class IotAlertRecordProcessReqVO {
|
||||
|
||||
@Schema(description = "记录编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "记录编号不能为空")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "处理结果(备注)", requiredMode = Schema.RequiredMode.REQUIRED, example = "已处理告警,问题已解决")
|
||||
private String processRemark;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.alert.vo.recrod;
|
||||
|
||||
import cn.aagro.pp.module.iot.core.mq.message.IotDeviceMessage;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 告警记录 Response VO")
|
||||
@Data
|
||||
public class IotAlertRecordRespVO {
|
||||
|
||||
@Schema(description = "记录编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "19904")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "告警配置编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "29320")
|
||||
private Long configId;
|
||||
|
||||
@Schema(description = "告警名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "张三")
|
||||
private String configName;
|
||||
|
||||
@Schema(description = "告警级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer configLevel;
|
||||
|
||||
@Schema(description = "产品编号", example = "2050")
|
||||
private Long productId;
|
||||
|
||||
@Schema(description = "设备编号", example = "21727")
|
||||
private Long deviceId;
|
||||
|
||||
@Schema(description = "触发的设备消息")
|
||||
private IotDeviceMessage deviceMessage;
|
||||
|
||||
@Schema(description = "是否处理", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Boolean processStatus;
|
||||
|
||||
@Schema(description = "处理结果(备注)", example = "你说的对")
|
||||
private String processRemark;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.device;
|
||||
|
||||
import cn.aagro.pp.framework.apilog.core.annotation.ApiAccessLog;
|
||||
import cn.aagro.pp.framework.common.pojo.CommonResult;
|
||||
import cn.aagro.pp.framework.common.pojo.PageParam;
|
||||
import cn.aagro.pp.framework.common.pojo.PageResult;
|
||||
import cn.aagro.pp.framework.common.util.object.BeanUtils;
|
||||
import cn.aagro.pp.framework.excel.core.util.ExcelUtils;
|
||||
import cn.aagro.pp.module.iot.controller.admin.device.vo.device.*;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.device.IotDeviceDO;
|
||||
import cn.aagro.pp.module.iot.enums.product.IotLocationTypeEnum;
|
||||
import cn.aagro.pp.module.iot.service.device.IotDeviceService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Parameters;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.aagro.pp.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
|
||||
import static cn.aagro.pp.framework.common.pojo.CommonResult.success;
|
||||
import static cn.aagro.pp.framework.common.util.collection.CollectionUtils.convertList;
|
||||
|
||||
@Tag(name = "管理后台 - IoT 设备")
|
||||
@RestController
|
||||
@RequestMapping("/iot/device")
|
||||
@Validated
|
||||
public class IotDeviceController {
|
||||
|
||||
@Resource
|
||||
private IotDeviceService deviceService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建设备")
|
||||
@PreAuthorize("@ss.hasPermission('iot:device:create')")
|
||||
public CommonResult<Long> createDevice(@Valid @RequestBody IotDeviceSaveReqVO createReqVO) {
|
||||
return success(deviceService.createDevice(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新设备")
|
||||
@PreAuthorize("@ss.hasPermission('iot:device:update')")
|
||||
public CommonResult<Boolean> updateDevice(@Valid @RequestBody IotDeviceSaveReqVO updateReqVO) {
|
||||
deviceService.updateDevice(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
// TODO @芋艿:参考阿里云:1)绑定网关;2)解绑网关
|
||||
|
||||
@PutMapping("/update-group")
|
||||
@Operation(summary = "更新设备分组")
|
||||
@PreAuthorize("@ss.hasPermission('iot:device:update')")
|
||||
public CommonResult<Boolean> updateDeviceGroup(@Valid @RequestBody IotDeviceUpdateGroupReqVO updateReqVO) {
|
||||
deviceService.updateDeviceGroup(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除单个设备")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('iot:device:delete')")
|
||||
public CommonResult<Boolean> deleteDevice(@RequestParam("id") Long id) {
|
||||
deviceService.deleteDevice(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete-list")
|
||||
@Operation(summary = "删除多个设备")
|
||||
@Parameter(name = "ids", description = "编号数组", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('iot:device:delete')")
|
||||
public CommonResult<Boolean> deleteDeviceList(@RequestParam("ids") Collection<Long> ids) {
|
||||
deviceService.deleteDeviceList(ids);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得设备")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('iot:device:query')")
|
||||
public CommonResult<IotDeviceRespVO> getDevice(@RequestParam("id") Long id) {
|
||||
IotDeviceDO device = deviceService.getDevice(id);
|
||||
return success(BeanUtils.toBean(device, IotDeviceRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得设备分页")
|
||||
@PreAuthorize("@ss.hasPermission('iot:device:query')")
|
||||
public CommonResult<PageResult<IotDeviceRespVO>> getDevicePage(@Valid IotDevicePageReqVO pageReqVO) {
|
||||
PageResult<IotDeviceDO> pageResult = deviceService.getDevicePage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, IotDeviceRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/export-excel")
|
||||
@Operation(summary = "导出设备 Excel")
|
||||
@PreAuthorize("@ss.hasPermission('iot:device:export')")
|
||||
@ApiAccessLog(operateType = EXPORT)
|
||||
public void exportDeviceExcel(@Valid IotDevicePageReqVO exportReqVO,
|
||||
HttpServletResponse response) throws IOException {
|
||||
exportReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
||||
CommonResult<PageResult<IotDeviceRespVO>> result = getDevicePage(exportReqVO);
|
||||
// 导出 Excel
|
||||
ExcelUtils.write(response, "设备.xls", "数据", IotDeviceRespVO.class,
|
||||
result.getData().getList());
|
||||
}
|
||||
|
||||
@GetMapping("/count")
|
||||
@Operation(summary = "获得设备数量")
|
||||
@Parameter(name = "productId", description = "产品编号", example = "1")
|
||||
@PreAuthorize("@ss.hasPermission('iot:device:query')")
|
||||
public CommonResult<Long> getDeviceCount(@RequestParam("productId") Long productId) {
|
||||
return success(deviceService.getDeviceCountByProductId(productId));
|
||||
}
|
||||
|
||||
@GetMapping("/simple-list")
|
||||
@Operation(summary = "获取设备的精简信息列表", description = "主要用于前端的下拉选项")
|
||||
@Parameters({
|
||||
@Parameter(name = "deviceType", description = "设备类型", example = "1"),
|
||||
@Parameter(name = "productId", description = "产品编号", example = "1024")
|
||||
})
|
||||
public CommonResult<List<IotDeviceRespVO>> getDeviceSimpleList(
|
||||
@RequestParam(value = "deviceType", required = false) Integer deviceType,
|
||||
@RequestParam(value = "productId", required = false) Long productId) {
|
||||
List<IotDeviceDO> list = deviceService.getDeviceListByCondition(deviceType, productId);
|
||||
return success(convertList(list, device -> // 只返回 id、name、productId 字段
|
||||
new IotDeviceRespVO().setId(device.getId()).setDeviceName(device.getDeviceName())
|
||||
.setProductId(device.getProductId()).setState(device.getState())));
|
||||
}
|
||||
|
||||
@PostMapping("/import")
|
||||
@Operation(summary = "导入设备")
|
||||
@PreAuthorize("@ss.hasPermission('iot:device:import')")
|
||||
public CommonResult<IotDeviceImportRespVO> importDevice(
|
||||
@RequestParam("file") MultipartFile file,
|
||||
@RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport)
|
||||
throws Exception {
|
||||
List<IotDeviceImportExcelVO> list = ExcelUtils.read(file, IotDeviceImportExcelVO.class);
|
||||
return success(deviceService.importDevice(list, updateSupport));
|
||||
}
|
||||
|
||||
@GetMapping("/get-import-template")
|
||||
@Operation(summary = "获得导入设备模板")
|
||||
public void importTemplate(HttpServletResponse response) throws IOException {
|
||||
// 手动创建导出 demo
|
||||
List<IotDeviceImportExcelVO> list = Arrays.asList(
|
||||
IotDeviceImportExcelVO.builder().deviceName("温度传感器001").parentDeviceName("gateway110")
|
||||
.productKey("1de24640dfe").groupNames("灰度分组,生产分组")
|
||||
.locationType(IotLocationTypeEnum.IP.getType()).build(),
|
||||
IotDeviceImportExcelVO.builder().deviceName("biubiu").productKey("YzvHxd4r67sT4s2B")
|
||||
.groupNames("").locationType(IotLocationTypeEnum.MANUAL.getType()).build());
|
||||
// 输出
|
||||
ExcelUtils.write(response, "设备导入模板.xls", "数据", IotDeviceImportExcelVO.class, list);
|
||||
}
|
||||
|
||||
@GetMapping("/get-auth-info")
|
||||
@Operation(summary = "获得设备连接信息")
|
||||
@PreAuthorize("@ss.hasPermission('iot:device:auth-info')")
|
||||
public CommonResult<IotDeviceAuthInfoRespVO> getDeviceAuthInfo(@RequestParam("id") Long id) {
|
||||
return success(deviceService.getDeviceAuthInfo(id));
|
||||
}
|
||||
|
||||
// TODO @haohao:可以使用 @RequestParam("productKey") String productKey, @RequestParam("deviceNames") List<String> deviceNames 来接收哇?
|
||||
@GetMapping("/list-by-product-key-and-names")
|
||||
@Operation(summary = "通过产品标识和设备名称列表获取设备")
|
||||
@PreAuthorize("@ss.hasPermission('iot:device:query')")
|
||||
public CommonResult<List<IotDeviceRespVO>> getDevicesByProductKeyAndNames(@Valid IotDeviceByProductKeyAndNamesReqVO reqVO) {
|
||||
List<IotDeviceDO> devices = deviceService.getDeviceListByProductKeyAndNames(reqVO.getProductKey(), reqVO.getDeviceNames());
|
||||
return success(BeanUtils.toBean(devices, IotDeviceRespVO.class));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.device;
|
||||
|
||||
import cn.aagro.pp.framework.common.enums.CommonStatusEnum;
|
||||
import cn.aagro.pp.framework.common.pojo.CommonResult;
|
||||
import cn.aagro.pp.framework.common.pojo.PageResult;
|
||||
import cn.aagro.pp.framework.common.util.object.BeanUtils;
|
||||
import cn.aagro.pp.module.iot.controller.admin.device.vo.group.IotDeviceGroupPageReqVO;
|
||||
import cn.aagro.pp.module.iot.controller.admin.device.vo.group.IotDeviceGroupRespVO;
|
||||
import cn.aagro.pp.module.iot.controller.admin.device.vo.group.IotDeviceGroupSaveReqVO;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.device.IotDeviceGroupDO;
|
||||
import cn.aagro.pp.module.iot.service.device.IotDeviceGroupService;
|
||||
import cn.aagro.pp.module.iot.service.device.IotDeviceService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.aagro.pp.framework.common.pojo.CommonResult.success;
|
||||
import static cn.aagro.pp.framework.common.util.collection.CollectionUtils.convertList;
|
||||
|
||||
@Tag(name = "管理后台 - IoT 设备分组")
|
||||
@RestController
|
||||
@RequestMapping("/iot/device-group")
|
||||
@Validated
|
||||
public class IotDeviceGroupController {
|
||||
|
||||
@Resource
|
||||
private IotDeviceGroupService deviceGroupService;
|
||||
@Resource
|
||||
private IotDeviceService deviceService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建设备分组")
|
||||
@PreAuthorize("@ss.hasPermission('iot:device-group:create')")
|
||||
public CommonResult<Long> createDeviceGroup(@Valid @RequestBody IotDeviceGroupSaveReqVO createReqVO) {
|
||||
return success(deviceGroupService.createDeviceGroup(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新设备分组")
|
||||
@PreAuthorize("@ss.hasPermission('iot:device-group:update')")
|
||||
public CommonResult<Boolean> updateDeviceGroup(@Valid @RequestBody IotDeviceGroupSaveReqVO updateReqVO) {
|
||||
deviceGroupService.updateDeviceGroup(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除设备分组")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('iot:device-group:delete')")
|
||||
public CommonResult<Boolean> deleteDeviceGroup(@RequestParam("id") Long id) {
|
||||
deviceGroupService.deleteDeviceGroup(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得设备分组")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('iot:device-group:query')")
|
||||
public CommonResult<IotDeviceGroupRespVO> getDeviceGroup(@RequestParam("id") Long id) {
|
||||
IotDeviceGroupDO deviceGroup = deviceGroupService.getDeviceGroup(id);
|
||||
return success(BeanUtils.toBean(deviceGroup, IotDeviceGroupRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得设备分组分页")
|
||||
@PreAuthorize("@ss.hasPermission('iot:device-group:query')")
|
||||
public CommonResult<PageResult<IotDeviceGroupRespVO>> getDeviceGroupPage(@Valid IotDeviceGroupPageReqVO pageReqVO) {
|
||||
PageResult<IotDeviceGroupDO> pageResult = deviceGroupService.getDeviceGroupPage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, IotDeviceGroupRespVO.class,
|
||||
group -> group.setDeviceCount(deviceService.getDeviceCountByGroupId(group.getId()))));
|
||||
}
|
||||
|
||||
@GetMapping("/simple-list")
|
||||
@Operation(summary = "获取设备分组的精简信息列表", description = "只包含被开启的分组,主要用于前端的下拉选项")
|
||||
public CommonResult<List<IotDeviceGroupRespVO>> getSimpleDeviceGroupList() {
|
||||
List<IotDeviceGroupDO> list = deviceGroupService.getDeviceGroupListByStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
return success(convertList(list, group -> // 只返回 id、name 字段
|
||||
new IotDeviceGroupRespVO().setId(group.getId()).setName(group.getName())));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
### 请求 /iot/device/message/send 接口(属性上报)=> 成功
|
||||
POST {{baseUrl}}/iot/device/message/send
|
||||
Content-Type: application/json
|
||||
tenant-id: {{adminTenantId}}
|
||||
Authorization: Bearer {{token}}
|
||||
|
||||
{
|
||||
"deviceId": 25,
|
||||
"method": "thing.property.post",
|
||||
"params": {
|
||||
"width": 1,
|
||||
"height": "2",
|
||||
"oneThree": "3"
|
||||
}
|
||||
}
|
||||
|
||||
### 请求 /iot/device/downstream 接口(服务调用)=> 成功 TODO 芋艿:未更新为最新
|
||||
POST {{baseUrl}}/iot/device/downstream
|
||||
Content-Type: application/json
|
||||
tenant-id: {{adminTenantId}}
|
||||
Authorization: Bearer {{token}}
|
||||
|
||||
{
|
||||
"id": 25,
|
||||
"type": "service",
|
||||
"identifier": "temperature",
|
||||
"data": {
|
||||
"xx": "yy"
|
||||
}
|
||||
}
|
||||
|
||||
### 请求 /iot/device/downstream 接口(属性设置)=> 成功 TODO 芋艿:未更新为最新
|
||||
POST {{baseUrl}}/iot/device/downstream
|
||||
Content-Type: application/json
|
||||
tenant-id: {{adminTenantId}}
|
||||
Authorization: Bearer {{token}}
|
||||
|
||||
{
|
||||
"id": 25,
|
||||
"type": "property",
|
||||
"identifier": "set",
|
||||
"data": {
|
||||
"xx": "yy"
|
||||
}
|
||||
}
|
||||
|
||||
### 请求 /iot/device/downstream 接口(属性获取)=> 成功 TODO 芋艿:未更新为最新
|
||||
POST {{baseUrl}}/iot/device/downstream
|
||||
Content-Type: application/json
|
||||
tenant-id: {{adminTenantId}}
|
||||
Authorization: Bearer {{token}}
|
||||
|
||||
{
|
||||
"id": 25,
|
||||
"type": "property",
|
||||
"identifier": "get",
|
||||
"data": ["xx", "yy"]
|
||||
}
|
||||
|
||||
### 请求 /iot/device/downstream 接口(配置设置)=> 成功 TODO 芋艿:未更新为最新
|
||||
POST {{baseUrl}}/iot/device/downstream
|
||||
Content-Type: application/json
|
||||
tenant-id: {{adminTenantId}}
|
||||
Authorization: Bearer {{token}}
|
||||
|
||||
{
|
||||
"id": 25,
|
||||
"type": "config",
|
||||
"identifier": "set"
|
||||
}
|
||||
|
||||
### 请求 /iot/device/downstream 接口(OTA 升级)=> 成功 TODO 芋艿:未更新为最新
|
||||
POST {{baseUrl}}/iot/device/downstream
|
||||
Content-Type: application/json
|
||||
tenant-id: {{adminTenantId}}
|
||||
Authorization: Bearer {{token}}
|
||||
|
||||
{
|
||||
"id": 25,
|
||||
"type": "ota",
|
||||
"identifier": "upgrade",
|
||||
"data": {
|
||||
"firmwareId": 1,
|
||||
"version": "1.0.0",
|
||||
"signMethod": "MD5",
|
||||
"fileSign": "d41d8cd98f00b204e9800998ecf8427e",
|
||||
"fileSize": 1024,
|
||||
"fileUrl": "http://example.com/firmware.bin",
|
||||
"information": "{\"desc\":\"升级到最新版本\"}"
|
||||
}
|
||||
}
|
||||
|
||||
### 查询设备消息对分页 - 基础查询(设备编号25)
|
||||
GET {{baseUrl}}/iot/device/message/pair-page?deviceId=25&pageNo=1&pageSize=10
|
||||
Authorization: Bearer {{token}}
|
||||
tenant-id: {{adminTenantId}}
|
||||
|
||||
### 查询设备消息对分页 - 按标识符过滤(identifier=eat)
|
||||
GET {{baseUrl}}/iot/device/message/pair-page?deviceId=25&identifier=eat&pageNo=1&pageSize=10
|
||||
Authorization: Bearer {{token}}
|
||||
tenant-id: {{adminTenantId}}
|
||||
@@ -0,0 +1,92 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.device;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.aagro.pp.framework.common.pojo.CommonResult;
|
||||
import cn.aagro.pp.framework.common.pojo.PageResult;
|
||||
import cn.aagro.pp.framework.common.util.object.BeanUtils;
|
||||
import cn.aagro.pp.module.iot.controller.admin.device.vo.message.IotDeviceMessagePageReqVO;
|
||||
import cn.aagro.pp.module.iot.controller.admin.device.vo.message.IotDeviceMessageRespPairVO;
|
||||
import cn.aagro.pp.module.iot.controller.admin.device.vo.message.IotDeviceMessageRespVO;
|
||||
import cn.aagro.pp.module.iot.controller.admin.device.vo.message.IotDeviceMessageSendReqVO;
|
||||
import cn.aagro.pp.module.iot.core.mq.message.IotDeviceMessage;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.device.IotDeviceMessageDO;
|
||||
import cn.aagro.pp.module.iot.dal.tdengine.IotDeviceMessageMapper;
|
||||
import cn.aagro.pp.module.iot.service.device.IotDeviceService;
|
||||
import cn.aagro.pp.module.iot.service.device.message.IotDeviceMessageService;
|
||||
import cn.aagro.pp.module.iot.service.thingmodel.IotThingModelService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.aagro.pp.framework.common.pojo.CommonResult.success;
|
||||
import static cn.aagro.pp.framework.common.util.collection.CollectionUtils.convertList;
|
||||
import static cn.aagro.pp.framework.common.util.collection.CollectionUtils.convertMap;
|
||||
|
||||
@Tag(name = "管理后台 - IoT 设备消息")
|
||||
@RestController
|
||||
@RequestMapping("/iot/device/message")
|
||||
@Validated
|
||||
public class IotDeviceMessageController {
|
||||
|
||||
@Resource
|
||||
private IotDeviceMessageService deviceMessageService;
|
||||
@Resource
|
||||
private IotDeviceService deviceService;
|
||||
@Resource
|
||||
private IotThingModelService thingModelService;
|
||||
@Resource
|
||||
private IotDeviceMessageMapper deviceMessageMapper;
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得设备消息分页")
|
||||
@PreAuthorize("@ss.hasPermission('iot:device:message-query')")
|
||||
public CommonResult<PageResult<IotDeviceMessageRespVO>> getDeviceMessagePage(
|
||||
@Valid IotDeviceMessagePageReqVO pageReqVO) {
|
||||
PageResult<IotDeviceMessageDO> pageResult = deviceMessageService.getDeviceMessagePage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, IotDeviceMessageRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/pair-page")
|
||||
@Operation(summary = "获得设备消息对分页")
|
||||
@PreAuthorize("@ss.hasPermission('iot:device:message-query')")
|
||||
public CommonResult<PageResult<IotDeviceMessageRespPairVO>> getDeviceMessagePairPage(
|
||||
@Valid IotDeviceMessagePageReqVO pageReqVO) {
|
||||
// 1.1 先按照条件,查询 request 的消息(非 reply)
|
||||
pageReqVO.setReply(false);
|
||||
PageResult<IotDeviceMessageDO> requestMessagePageResult = deviceMessageService.getDeviceMessagePage(pageReqVO);
|
||||
if (CollUtil.isEmpty(requestMessagePageResult.getList())) {
|
||||
return success(PageResult.empty());
|
||||
}
|
||||
// 1.2 接着按照 requestIds,批量查询 reply 消息
|
||||
List<String> requestIds = convertList(requestMessagePageResult.getList(), IotDeviceMessageDO::getRequestId);
|
||||
List<IotDeviceMessageDO> replyMessageList = deviceMessageService.getDeviceMessageListByRequestIdsAndReply(
|
||||
pageReqVO.getDeviceId(), requestIds, true);
|
||||
Map<String, IotDeviceMessageDO> replyMessages = convertMap(replyMessageList, IotDeviceMessageDO::getRequestId);
|
||||
|
||||
// 2. 组装结果
|
||||
List<IotDeviceMessageRespPairVO> pairMessages = convertList(requestMessagePageResult.getList(),
|
||||
requestMessage -> {
|
||||
IotDeviceMessageDO replyMessage = replyMessages.get(requestMessage.getRequestId());
|
||||
return new IotDeviceMessageRespPairVO()
|
||||
.setRequest(BeanUtils.toBean(requestMessage, IotDeviceMessageRespVO.class))
|
||||
.setReply(BeanUtils.toBean(replyMessage, IotDeviceMessageRespVO.class));
|
||||
});
|
||||
return success(new PageResult<>(pairMessages, requestMessagePageResult.getTotal()));
|
||||
}
|
||||
|
||||
@PostMapping("/send")
|
||||
@Operation(summary = "发送消息", description = "可用于设备模拟")
|
||||
@PreAuthorize("@ss.hasPermission('iot:device:message-end')")
|
||||
public CommonResult<Boolean> sendDeviceMessage(@Valid @RequestBody IotDeviceMessageSendReqVO sendReqVO) {
|
||||
deviceMessageService.sendDeviceMessage(BeanUtils.toBean(sendReqVO, IotDeviceMessage.class));
|
||||
return success(true);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.device;
|
||||
|
||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.aagro.pp.framework.common.pojo.CommonResult;
|
||||
import cn.aagro.pp.module.iot.controller.admin.device.vo.property.IotDevicePropertyDetailRespVO;
|
||||
import cn.aagro.pp.module.iot.controller.admin.device.vo.property.IotDevicePropertyHistoryListReqVO;
|
||||
import cn.aagro.pp.module.iot.controller.admin.device.vo.property.IotDevicePropertyRespVO;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.thingmodel.model.ThingModelProperty;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.device.IotDeviceDO;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.device.IotDevicePropertyDO;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.thingmodel.IotThingModelDO;
|
||||
import cn.aagro.pp.module.iot.enums.thingmodel.IotThingModelTypeEnum;
|
||||
import cn.aagro.pp.module.iot.service.device.IotDeviceService;
|
||||
import cn.aagro.pp.module.iot.service.device.property.IotDevicePropertyService;
|
||||
import cn.aagro.pp.module.iot.service.thingmodel.IotThingModelService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
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.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.aagro.pp.framework.common.pojo.CommonResult.success;
|
||||
import static cn.aagro.pp.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("/get-latest")
|
||||
@Operation(summary = "获取设备属性最新属性")
|
||||
@Parameter(name = "deviceId", description = "设备编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('iot:device:property-query')")
|
||||
public CommonResult<List<IotDevicePropertyDetailRespVO>> getLatestDeviceProperties(
|
||||
@RequestParam("deviceId") Long deviceId) {
|
||||
// 1.1 获取设备信息
|
||||
IotDeviceDO device = deviceService.getDevice(deviceId);
|
||||
Assert.notNull(device, "设备不存在");
|
||||
// 1.2 获取设备最新属性
|
||||
Map<String, IotDevicePropertyDO> properties = devicePropertyService.getLatestDeviceProperties(deviceId);
|
||||
// 1.3 根据 productId + type 查询属性类型的物模型
|
||||
List<IotThingModelDO> thingModels = thingModelService.getThingModelListByProductIdAndType(
|
||||
device.getProductId(), IotThingModelTypeEnum.PROPERTY.getType());
|
||||
|
||||
// 2. 基于 thingModels 遍历,拼接 properties
|
||||
return success(convertList(thingModels, thingModel -> {
|
||||
ThingModelProperty thingModelProperty = thingModel.getProperty();
|
||||
Assert.notNull(thingModelProperty, "属性不能为空");
|
||||
IotDevicePropertyDetailRespVO result = new IotDevicePropertyDetailRespVO()
|
||||
.setName(thingModel.getName()).setDataType(thingModelProperty.getDataType())
|
||||
.setDataSpecs(thingModelProperty.getDataSpecs())
|
||||
.setDataSpecsList(thingModelProperty.getDataSpecsList());
|
||||
result.setIdentifier(thingModel.getIdentifier());
|
||||
IotDevicePropertyDO property = properties.get(thingModel.getIdentifier());
|
||||
if (property != null) {
|
||||
result.setValue(property.getValue())
|
||||
.setUpdateTime(LocalDateTimeUtil.toEpochMilli(property.getUpdateTime()));
|
||||
}
|
||||
return result;
|
||||
}));
|
||||
}
|
||||
|
||||
@GetMapping("/history-list")
|
||||
@Operation(summary = "获取设备属性历史数据列表")
|
||||
@PreAuthorize("@ss.hasPermission('iot:device:property-query')")
|
||||
public CommonResult<List<IotDevicePropertyRespVO>> getHistoryDevicePropertyList(
|
||||
@Valid IotDevicePropertyHistoryListReqVO listReqVO) {
|
||||
return success(devicePropertyService.getHistoryDevicePropertyList(listReqVO));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.device.vo.device;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 设备认证信息 Response VO")
|
||||
@Data
|
||||
public class IotDeviceAuthInfoRespVO {
|
||||
|
||||
@Schema(description = "客户端 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "product123.device001")
|
||||
@NotBlank(message = "客户端 ID 不能为空")
|
||||
private String clientId;
|
||||
|
||||
@Schema(description = "用户名", requiredMode = Schema.RequiredMode.REQUIRED, example = "device001&product123")
|
||||
@NotBlank(message = "用户名不能为空")
|
||||
private String username;
|
||||
|
||||
@Schema(description = "密码", requiredMode = Schema.RequiredMode.REQUIRED, example = "1a2b3c4d5e6f7890abcdef1234567890")
|
||||
@NotBlank(message = "密码不能为空")
|
||||
private String password;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.device.vo.device;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - 通过产品标识和设备名称列表获取设备 Request VO")
|
||||
@Data
|
||||
public class IotDeviceByProductKeyAndNamesReqVO {
|
||||
|
||||
@Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "1de24640dfe")
|
||||
@NotBlank(message = "产品标识不能为空")
|
||||
private String productKey;
|
||||
|
||||
@Schema(description = "设备名称列表", requiredMode = Schema.RequiredMode.REQUIRED, example = "device001,device002")
|
||||
@NotEmpty(message = "设备名称列表不能为空")
|
||||
private List<String> deviceNames;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.device.vo.device;
|
||||
|
||||
import cn.idev.excel.annotation.ExcelProperty;
|
||||
import cn.aagro.pp.framework.common.validation.InEnum;
|
||||
import cn.aagro.pp.module.iot.enums.product.IotLocationTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 设备 Excel 导入 VO
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class IotDeviceImportExcelVO {
|
||||
|
||||
@ExcelProperty("设备名称")
|
||||
@NotEmpty(message = "设备名称不能为空")
|
||||
private String deviceName;
|
||||
|
||||
@ExcelProperty("父设备名称")
|
||||
@Schema(description = "父设备名称", example = "网关001")
|
||||
private String parentDeviceName;
|
||||
|
||||
@ExcelProperty("产品标识")
|
||||
@NotEmpty(message = "产品标识不能为空")
|
||||
private String productKey;
|
||||
|
||||
@ExcelProperty("设备分组")
|
||||
private String groupNames;
|
||||
|
||||
@ExcelProperty("上报方式(1:IP 定位, 2:设备上报,3:手动定位)")
|
||||
@NotNull(message = "上报方式不能为空")
|
||||
@InEnum(IotLocationTypeEnum.class)
|
||||
private Integer locationType;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.device.vo.device;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 设备导入 Response VO")
|
||||
@Data
|
||||
@Builder
|
||||
public class IotDeviceImportRespVO {
|
||||
|
||||
@Schema(description = "创建成功的设备名称数组", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private List<String> createDeviceNames;
|
||||
|
||||
@Schema(description = "更新成功的设备名称数组", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private List<String> updateDeviceNames;
|
||||
|
||||
@Schema(description = "导入失败的设备集合,key为设备名称,value为失败原因", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Map<String, String> failureDeviceNames;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.device.vo.device;
|
||||
|
||||
import cn.aagro.pp.framework.common.pojo.PageParam;
|
||||
import cn.aagro.pp.framework.common.validation.InEnum;
|
||||
import cn.aagro.pp.module.iot.core.enums.IotDeviceStateEnum;
|
||||
import cn.aagro.pp.module.iot.enums.product.IotProductDeviceTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 设备分页 Request VO")
|
||||
@Data
|
||||
public class IotDevicePageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "设备名称", example = "王五")
|
||||
private String deviceName;
|
||||
|
||||
@Schema(description = "备注名称", example = "张三")
|
||||
private String nickname;
|
||||
|
||||
@Schema(description = "产品编号", example = "26202")
|
||||
private Long productId;
|
||||
|
||||
@Schema(description = "设备类型", example = "1")
|
||||
@InEnum(IotProductDeviceTypeEnum.class)
|
||||
private Integer deviceType;
|
||||
|
||||
@Schema(description = "设备状态", example = "1")
|
||||
@InEnum(IotDeviceStateEnum.class)
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "设备分组编号", example = "1024")
|
||||
private Long groupId;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.device.vo.device;
|
||||
|
||||
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import cn.idev.excel.annotation.ExcelProperty;
|
||||
import cn.aagro.pp.framework.excel.core.annotations.DictFormat;
|
||||
import cn.aagro.pp.framework.excel.core.convert.DictConvert;
|
||||
import cn.aagro.pp.module.iot.enums.DictTypeConstants;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.aagro.pp.module.iot.enums.DictTypeConstants.DEVICE_STATE;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 设备 Response VO")
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
public class IotDeviceRespVO {
|
||||
|
||||
@Schema(description = "设备编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "177")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "设备名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五")
|
||||
@ExcelProperty("设备名称")
|
||||
private String deviceName;
|
||||
|
||||
@Schema(description = "设备备注名称", example = "张三")
|
||||
@ExcelProperty("设备备注名称")
|
||||
private String nickname;
|
||||
|
||||
@Schema(description = "设备序列号", example = "1024")
|
||||
@ExcelProperty("设备序列号")
|
||||
private String serialNumber;
|
||||
|
||||
@Schema(description = "设备图片", example = "我是一名码农")
|
||||
@ExcelProperty("设备图片")
|
||||
private String picUrl;
|
||||
|
||||
@Schema(description = "设备分组编号数组", example = "1,2")
|
||||
private Set<Long> groupIds;
|
||||
|
||||
@Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "26202")
|
||||
@ExcelProperty("产品编号")
|
||||
private Long productId;
|
||||
|
||||
@Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@ExcelProperty("产品 Key")
|
||||
private String productKey;
|
||||
|
||||
@Schema(description = "设备类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@ExcelProperty("设备类型")
|
||||
private Integer deviceType;
|
||||
|
||||
@Schema(description = "网关设备 ID", example = "16380")
|
||||
private Long gatewayId;
|
||||
|
||||
@Schema(description = "设备状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@ExcelProperty(value = "设备状态", converter = DictConvert.class)
|
||||
@DictFormat(DEVICE_STATE)
|
||||
private Integer state;
|
||||
|
||||
@Schema(description = "最后上线时间")
|
||||
@ExcelProperty("最后上线时间")
|
||||
private LocalDateTime onlineTime;
|
||||
|
||||
@Schema(description = "最后离线时间")
|
||||
@ExcelProperty("最后离线时间")
|
||||
private LocalDateTime offlineTime;
|
||||
|
||||
@Schema(description = "设备激活时间")
|
||||
@ExcelProperty("设备激活时间")
|
||||
private LocalDateTime activeTime;
|
||||
|
||||
@Schema(description = "设备密钥,用于设备认证")
|
||||
@ExcelProperty("设备密钥")
|
||||
private String deviceSecret;
|
||||
|
||||
@Schema(description = "认证类型(如一机一密、动态注册)", example = "2")
|
||||
@ExcelProperty("认证类型(如一机一密、动态注册)")
|
||||
private String authType;
|
||||
|
||||
@Schema(description = "设备配置", example = "{\"abc\": \"efg\"}")
|
||||
private String config;
|
||||
|
||||
@Schema(description = "定位方式", example = "2")
|
||||
@ExcelProperty(value = "定位方式", converter = DictConvert.class)
|
||||
@DictFormat(DictTypeConstants.LOCATION_TYPE)
|
||||
private Integer locationType;
|
||||
|
||||
@Schema(description = "设备位置的纬度", example = "45.000000")
|
||||
private BigDecimal latitude;
|
||||
|
||||
@Schema(description = "设备位置的经度", example = "45.000000")
|
||||
private BigDecimal longitude;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@ExcelProperty("创建时间")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.device.vo.device;
|
||||
|
||||
import cn.aagro.pp.framework.common.validation.InEnum;
|
||||
import cn.aagro.pp.module.iot.enums.product.IotLocationTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Set;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 设备新增/修改 Request VO")
|
||||
@Data
|
||||
public class IotDeviceSaveReqVO {
|
||||
|
||||
@Schema(description = "设备编号", example = "177")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "设备名称", requiredMode = Schema.RequiredMode.AUTO, example = "王五")
|
||||
private String deviceName;
|
||||
|
||||
@Schema(description = "备注名称", example = "张三")
|
||||
private String nickname;
|
||||
|
||||
@Schema(description = "设备序列号", example = "123456")
|
||||
private String serialNumber;
|
||||
|
||||
@Schema(description = "设备图片", example = "https://iocoder.cn/1.png")
|
||||
private String picUrl;
|
||||
|
||||
@Schema(description = "设备分组编号数组", example = "1,2")
|
||||
private Set<Long> groupIds;
|
||||
|
||||
@Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "26202")
|
||||
private Long productId;
|
||||
|
||||
@Schema(description = "网关设备 ID", example = "16380")
|
||||
private Long gatewayId;
|
||||
|
||||
@Schema(description = "设备配置", example = "{\"abc\": \"efg\"}")
|
||||
private String config;
|
||||
|
||||
@Schema(description = "定位类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
|
||||
@InEnum(value = IotLocationTypeEnum.class, message = "定位方式必须是 {value}")
|
||||
private Integer locationType;
|
||||
|
||||
@Schema(description = "设备位置的纬度", example = "16380")
|
||||
private BigDecimal latitude;
|
||||
|
||||
@Schema(description = "设备位置的经度", example = "16380")
|
||||
private BigDecimal longitude;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.device.vo.device;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import java.util.Set;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 设备更新分组 Request VO")
|
||||
@Data
|
||||
public class IotDeviceUpdateGroupReqVO {
|
||||
|
||||
@Schema(description = "设备编号列表", requiredMode = Schema.RequiredMode.REQUIRED, example = "1,2,3")
|
||||
@NotEmpty(message = "设备编号列表不能为空")
|
||||
private Set<Long> ids;
|
||||
|
||||
@Schema(description = "分组编号列表", requiredMode = Schema.RequiredMode.REQUIRED, example = "1,2,3")
|
||||
@NotEmpty(message = "分组编号列表不能为空")
|
||||
private Set<Long> groupIds;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.device.vo.group;
|
||||
|
||||
import cn.aagro.pp.framework.common.pojo.PageParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.aagro.pp.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 设备分组分页 Request VO")
|
||||
@Data
|
||||
public class IotDeviceGroupPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "分组名字", example = "李四")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.device.vo.group;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 设备分组 Response VO")
|
||||
@Data
|
||||
public class IotDeviceGroupRespVO {
|
||||
|
||||
@Schema(description = "分组 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "3583")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "分组名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "分组状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "分组描述", example = "你说的对")
|
||||
private String description;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(description = "设备数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
|
||||
private Long deviceCount;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.device.vo.group;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 设备分组新增/修改 Request VO")
|
||||
@Data
|
||||
public class IotDeviceGroupSaveReqVO {
|
||||
|
||||
@Schema(description = "分组 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "3583")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "分组名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
|
||||
@NotEmpty(message = "分组名字不能为空")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "分组状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "分组状态不能为空")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "分组描述", example = "你说的对")
|
||||
private String description;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.device.vo.message;
|
||||
|
||||
import cn.aagro.pp.framework.common.pojo.PageParam;
|
||||
import cn.aagro.pp.framework.common.validation.InEnum;
|
||||
import cn.aagro.pp.module.iot.core.enums.IotDeviceMessageMethodEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.aagro.pp.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 设备消息分页查询 Request VO")
|
||||
@Data
|
||||
public class IotDeviceMessagePageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "设备编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "设备编号不能为空")
|
||||
private Long deviceId;
|
||||
|
||||
@Schema(description = "消息类型", example = "property")
|
||||
@InEnum(IotDeviceMessageMethodEnum.class)
|
||||
private String method;
|
||||
|
||||
@Schema(description = "是否上行", example = "true")
|
||||
private Boolean upstream;
|
||||
|
||||
@Schema(description = "是否回复", example = "true")
|
||||
private Boolean reply;
|
||||
|
||||
@Schema(description = "标识符", example = "temperature")
|
||||
private String identifier;
|
||||
|
||||
@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;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.device.vo.message;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 设备消息对 Response VO")
|
||||
@Data
|
||||
public class IotDeviceMessageRespPairVO {
|
||||
|
||||
@Schema(description = "请求消息", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private IotDeviceMessageRespVO request;
|
||||
|
||||
@Schema(description = "响应消息")
|
||||
private IotDeviceMessageRespVO reply; // 通过 requestId 配对
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.device.vo.message;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 设备消息 Response VO")
|
||||
@Data
|
||||
public class IotDeviceMessageRespVO {
|
||||
|
||||
@Schema(description = "消息编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private String id;
|
||||
|
||||
@Schema(description = "上报时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime reportTime;
|
||||
|
||||
@Schema(description = "记录时间戳", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime ts;
|
||||
|
||||
@Schema(description = "设备编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "123")
|
||||
private Long deviceId;
|
||||
|
||||
@Schema(description = "服务编号", example = "server_123")
|
||||
private String serverId;
|
||||
|
||||
@Schema(description = "是否上行消息", example = "true", examples = "false")
|
||||
private Boolean upstream;
|
||||
|
||||
@Schema(description = "是否回复消息", example = "false", examples = "true")
|
||||
private Boolean reply;
|
||||
|
||||
@Schema(description = "标识符", example = "temperature")
|
||||
private String identifier;
|
||||
|
||||
// ========== codec(编解码)字段 ==========
|
||||
|
||||
@Schema(description = "请求编号", example = "req_123")
|
||||
private String requestId;
|
||||
|
||||
@Schema(description = "请求方法", requiredMode = Schema.RequiredMode.REQUIRED, example = "thing.property.report")
|
||||
private String method;
|
||||
|
||||
@Schema(description = "请求参数")
|
||||
private Object params;
|
||||
|
||||
@Schema(description = "响应结果")
|
||||
private Object data;
|
||||
|
||||
@Schema(description = "响应错误码", example = "200")
|
||||
private Integer code;
|
||||
|
||||
@Schema(description = "响应提示", example = "操作成功")
|
||||
private String msg;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.device.vo.message;
|
||||
|
||||
import cn.aagro.pp.framework.common.validation.InEnum;
|
||||
import cn.aagro.pp.module.iot.core.enums.IotDeviceMessageMethodEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 设备消息发送 Request VO") // 属性上报、事件上报、状态变更等
|
||||
@Data
|
||||
public class IotDeviceMessageSendReqVO {
|
||||
|
||||
@Schema(description = "请求方法", requiredMode = Schema.RequiredMode.REQUIRED, example = "report")
|
||||
@NotEmpty(message = "请求方法不能为空")
|
||||
@InEnum(IotDeviceMessageMethodEnum.class)
|
||||
private String method;
|
||||
|
||||
@Schema(description = "请求参数")
|
||||
private Object params; // 例如说:属性上报的 properties、事件上报的 params
|
||||
|
||||
@Schema(description = "设备编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "177")
|
||||
@NotNull(message = "设备编号不能为空")
|
||||
private Long deviceId;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.device.vo.property;
|
||||
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.thingmodel.model.dataType.ThingModelDataSpecs;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 设备属性详细 Response VO") // 额外增加 来自 ThingModelProperty 的变量 属性
|
||||
@Data
|
||||
public class IotDevicePropertyDetailRespVO extends IotDevicePropertyRespVO {
|
||||
|
||||
@Schema(description = "属性名称", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String name;
|
||||
|
||||
@Schema(description = "数据类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "int")
|
||||
private String dataType;
|
||||
|
||||
@Schema(description = "数据定义")
|
||||
private ThingModelDataSpecs dataSpecs;
|
||||
|
||||
@Schema(description = "数据定义列表")
|
||||
private List<ThingModelDataSpecs> dataSpecsList;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.device.vo.property;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.aagro.pp.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 设备属性历史列表 Request VO")
|
||||
@Data
|
||||
public class IotDevicePropertyHistoryListReqVO {
|
||||
|
||||
@Schema(description = "设备编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "177")
|
||||
@NotNull(message = "设备编号不能为空")
|
||||
private Long deviceId;
|
||||
|
||||
@Schema(description = "属性标识符", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotEmpty(message = "属性标识符不能为空")
|
||||
private String identifier;
|
||||
|
||||
@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;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.device.vo.property;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 设备属性 Response VO")
|
||||
@Data
|
||||
public class IotDevicePropertyRespVO {
|
||||
|
||||
@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 Long updateTime; // 由于从 TDengine 查询出来的是 Long 类型,所以这里也使用 Long 类型
|
||||
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.ota;
|
||||
|
||||
import cn.aagro.pp.framework.common.pojo.CommonResult;
|
||||
import cn.aagro.pp.framework.common.pojo.PageResult;
|
||||
import cn.aagro.pp.framework.common.util.object.BeanUtils;
|
||||
import cn.aagro.pp.module.iot.controller.admin.ota.vo.firmware.IotOtaFirmwareCreateReqVO;
|
||||
import cn.aagro.pp.module.iot.controller.admin.ota.vo.firmware.IotOtaFirmwarePageReqVO;
|
||||
import cn.aagro.pp.module.iot.controller.admin.ota.vo.firmware.IotOtaFirmwareRespVO;
|
||||
import cn.aagro.pp.module.iot.controller.admin.ota.vo.firmware.IotOtaFirmwareUpdateReqVO;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.ota.IotOtaFirmwareDO;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.product.IotProductDO;
|
||||
import cn.aagro.pp.module.iot.service.ota.IotOtaFirmwareService;
|
||||
import cn.aagro.pp.module.iot.service.product.IotProductService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
|
||||
import static cn.aagro.pp.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - IoT OTA 固件")
|
||||
@RestController
|
||||
@RequestMapping("/iot/ota/firmware")
|
||||
@Validated
|
||||
public class IotOtaFirmwareController {
|
||||
|
||||
@Resource
|
||||
private IotOtaFirmwareService otaFirmwareService;
|
||||
@Resource
|
||||
private IotProductService productService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建 OTA 固件")
|
||||
@PreAuthorize("@ss.hasPermission('iot:ota-firmware:create')")
|
||||
public CommonResult<Long> createOtaFirmware(@Valid @RequestBody IotOtaFirmwareCreateReqVO createReqVO) {
|
||||
return success(otaFirmwareService.createOtaFirmware(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新 OTA 固件")
|
||||
@PreAuthorize("@ss.hasPermission('iot:ota-firmware:update')")
|
||||
public CommonResult<Boolean> updateOtaFirmware(@Valid @RequestBody IotOtaFirmwareUpdateReqVO updateReqVO) {
|
||||
otaFirmwareService.updateOtaFirmware(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得 OTA 固件")
|
||||
@PreAuthorize("@ss.hasPermission('iot:ota-firmware:query')")
|
||||
public CommonResult<IotOtaFirmwareRespVO> getOtaFirmware(@RequestParam("id") Long id) {
|
||||
IotOtaFirmwareDO firmware = otaFirmwareService.getOtaFirmware(id);
|
||||
if (firmware == null) {
|
||||
return success(null);
|
||||
}
|
||||
return success(BeanUtils.toBean(firmware, IotOtaFirmwareRespVO.class, o -> {
|
||||
IotProductDO product = productService.getProduct(firmware.getProductId());
|
||||
if (product != null) {
|
||||
o.setProductName(product.getName());
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得 OTA 固件分页")
|
||||
@PreAuthorize("@ss.hasPermission('iot:ota-firmware:query')")
|
||||
public CommonResult<PageResult<IotOtaFirmwareRespVO>> getOtaFirmwarePage(@Valid IotOtaFirmwarePageReqVO pageReqVO) {
|
||||
PageResult<IotOtaFirmwareDO> pageResult = otaFirmwareService.getOtaFirmwarePage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, IotOtaFirmwareRespVO.class));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.ota;
|
||||
|
||||
import cn.aagro.pp.framework.common.pojo.CommonResult;
|
||||
import cn.aagro.pp.framework.common.pojo.PageResult;
|
||||
import cn.aagro.pp.framework.common.util.object.BeanUtils;
|
||||
import cn.aagro.pp.module.iot.controller.admin.ota.vo.task.IotOtaTaskCreateReqVO;
|
||||
import cn.aagro.pp.module.iot.controller.admin.ota.vo.task.IotOtaTaskPageReqVO;
|
||||
import cn.aagro.pp.module.iot.controller.admin.ota.vo.task.IotOtaTaskRespVO;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.ota.IotOtaTaskDO;
|
||||
import cn.aagro.pp.module.iot.service.ota.IotOtaTaskService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
|
||||
import static cn.aagro.pp.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - IoT OTA 升级任务")
|
||||
@RestController
|
||||
@RequestMapping("/iot/ota/task")
|
||||
@Validated
|
||||
public class IotOtaTaskController {
|
||||
|
||||
@Resource
|
||||
private IotOtaTaskService otaTaskService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建 OTA 升级任务")
|
||||
@PreAuthorize(value = "@ss.hasPermission('iot:ota-task:create')")
|
||||
public CommonResult<Long> createOtaTask(@Valid @RequestBody IotOtaTaskCreateReqVO createReqVO) {
|
||||
return success(otaTaskService.createOtaTask(createReqVO));
|
||||
}
|
||||
|
||||
@PostMapping("/cancel")
|
||||
@Operation(summary = "取消 OTA 升级任务")
|
||||
@Parameter(name = "id", description = "升级任务编号", required = true)
|
||||
@PreAuthorize(value = "@ss.hasPermission('iot:ota-task:cancel')")
|
||||
public CommonResult<Boolean> cancelOtaTask(@RequestParam("id") Long id) {
|
||||
otaTaskService.cancelOtaTask(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得 OTA 升级任务分页")
|
||||
@PreAuthorize(value = "@ss.hasPermission('iot:ota-task:query')")
|
||||
public CommonResult<PageResult<IotOtaTaskRespVO>> getOtaTaskPage(@Valid IotOtaTaskPageReqVO pageReqVO) {
|
||||
PageResult<IotOtaTaskDO> pageResult = otaTaskService.getOtaTaskPage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, IotOtaTaskRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得 OTA 升级任务")
|
||||
@Parameter(name = "id", description = "升级任务编号", required = true, example = "1024")
|
||||
@PreAuthorize(value = "@ss.hasPermission('iot:ota-task:query')")
|
||||
public CommonResult<IotOtaTaskRespVO> getOtaTask(@RequestParam("id") Long id) {
|
||||
IotOtaTaskDO upgradeTask = otaTaskService.getOtaTask(id);
|
||||
return success(BeanUtils.toBean(upgradeTask, IotOtaTaskRespVO.class));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.ota;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.aagro.pp.framework.common.pojo.CommonResult;
|
||||
import cn.aagro.pp.framework.common.pojo.PageResult;
|
||||
import cn.aagro.pp.framework.common.util.collection.MapUtils;
|
||||
import cn.aagro.pp.framework.common.util.object.BeanUtils;
|
||||
import cn.aagro.pp.module.iot.controller.admin.ota.vo.task.record.IotOtaTaskRecordPageReqVO;
|
||||
import cn.aagro.pp.module.iot.controller.admin.ota.vo.task.record.IotOtaTaskRecordRespVO;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.device.IotDeviceDO;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.ota.IotOtaFirmwareDO;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.ota.IotOtaTaskRecordDO;
|
||||
import cn.aagro.pp.module.iot.service.device.IotDeviceService;
|
||||
import cn.aagro.pp.module.iot.service.ota.IotOtaFirmwareService;
|
||||
import cn.aagro.pp.module.iot.service.ota.IotOtaTaskRecordService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Parameters;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.aagro.pp.framework.common.pojo.CommonResult.success;
|
||||
import static cn.aagro.pp.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
|
||||
@Tag(name = "管理后台 - IoT OTA 升级任务记录")
|
||||
@RestController
|
||||
@RequestMapping("/iot/ota/task/record")
|
||||
@Validated
|
||||
public class IotOtaTaskRecordController {
|
||||
|
||||
@Resource
|
||||
private IotOtaTaskRecordService otaTaskRecordService;
|
||||
@Resource
|
||||
private IotDeviceService deviceService;
|
||||
@Resource
|
||||
private IotOtaFirmwareService otaFirmwareService;
|
||||
|
||||
@GetMapping("/get-status-statistics")
|
||||
@Operation(summary = "获得 OTA 升级记录状态统计")
|
||||
@Parameters({
|
||||
@Parameter(name = "firmwareId", description = "固件编号", example = "1024"),
|
||||
@Parameter(name = "taskId", description = "升级任务编号", example = "2048")
|
||||
})
|
||||
@PreAuthorize("@ss.hasPermission('iot:ota-task-record:query')")
|
||||
public CommonResult<Map<Integer, Long>> getOtaTaskRecordStatusStatistics(
|
||||
@RequestParam(value = "firmwareId", required = false) Long firmwareId,
|
||||
@RequestParam(value = "taskId", required = false) Long taskId) {
|
||||
return success(otaTaskRecordService.getOtaTaskRecordStatusStatistics(firmwareId, taskId));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得 OTA 升级记录分页")
|
||||
@PreAuthorize("@ss.hasPermission('iot:ota-task-record:query')")
|
||||
public CommonResult<PageResult<IotOtaTaskRecordRespVO>> getOtaTaskRecordPage(
|
||||
@Valid IotOtaTaskRecordPageReqVO pageReqVO) {
|
||||
PageResult<IotOtaTaskRecordDO> pageResult = otaTaskRecordService.getOtaTaskRecordPage(pageReqVO);
|
||||
if (CollUtil.isEmpty(pageResult.getList())) {
|
||||
return success(PageResult.empty());
|
||||
}
|
||||
|
||||
// 批量查询固件信息
|
||||
Map<Long, IotOtaFirmwareDO> firmwareMap = otaFirmwareService.getOtaFirmwareMap(
|
||||
convertSet(pageResult.getList(), IotOtaTaskRecordDO::getFromFirmwareId));
|
||||
Map<Long, IotDeviceDO> deviceMap = deviceService.getDeviceMap(
|
||||
convertSet(pageResult.getList(), IotOtaTaskRecordDO::getDeviceId));
|
||||
// 转换为响应 VO
|
||||
return success(BeanUtils.toBean(pageResult, IotOtaTaskRecordRespVO.class, (vo) -> {
|
||||
MapUtils.findAndThen(firmwareMap, vo.getFromFirmwareId(), firmware ->
|
||||
vo.setFromFirmwareVersion(firmware.getVersion()));
|
||||
MapUtils.findAndThen(deviceMap, vo.getDeviceId(), device ->
|
||||
vo.setDeviceName(device.getDeviceName()));
|
||||
}));
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得 OTA 升级记录")
|
||||
@PreAuthorize("@ss.hasPermission('iot:ota-task-record:query')")
|
||||
@Parameter(name = "id", description = "升级记录编号", required = true, example = "1024")
|
||||
public CommonResult<IotOtaTaskRecordRespVO> getOtaTaskRecord(@RequestParam("id") Long id) {
|
||||
IotOtaTaskRecordDO upgradeRecord = otaTaskRecordService.getOtaTaskRecord(id);
|
||||
return success(BeanUtils.toBean(upgradeRecord, IotOtaTaskRecordRespVO.class));
|
||||
}
|
||||
|
||||
@PutMapping("/cancel")
|
||||
@Operation(summary = "取消 OTA 升级记录")
|
||||
@PreAuthorize("@ss.hasPermission('iot:ota-task-record:cancel')")
|
||||
@Parameter(name = "id", description = "升级记录编号", required = true, example = "1024")
|
||||
public CommonResult<Boolean> cancelOtaTaskRecord(@RequestParam("id") Long id) {
|
||||
otaTaskRecordService.cancelOtaTaskRecord(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.ota.vo.firmware;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import org.hibernate.validator.constraints.URL;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@Schema(description = "管理后台 - IoT OTA 固件创建 Request VO")
|
||||
@Data
|
||||
public class IotOtaFirmwareCreateReqVO {
|
||||
|
||||
@Schema(description = "固件名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "智能开关固件")
|
||||
@NotEmpty(message = "固件名称不能为空")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "固件描述", example = "某品牌型号固件,测试用")
|
||||
private String description;
|
||||
|
||||
@Schema(description = "版本号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1.0.0")
|
||||
@NotEmpty(message = "版本号不能为空")
|
||||
private String version;
|
||||
|
||||
@Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "产品编号不能为空")
|
||||
private Long productId;
|
||||
|
||||
@Schema(description = "固件文件 URL", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/1.zip")
|
||||
@NotEmpty(message = "固件文件 URL 不能为空")
|
||||
@URL(message = "固件文件 URL 格式错误")
|
||||
private String fileUrl;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.ota.vo.firmware;
|
||||
|
||||
import cn.aagro.pp.framework.common.pojo.PageParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.aagro.pp.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - IoT OTA 固件分页 Request VO")
|
||||
@Data
|
||||
public class IotOtaFirmwarePageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "固件名称", example = "智能开关固件")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "产品标识", example = "1024")
|
||||
private String productId;
|
||||
|
||||
@Schema(description = "创建时间", example = "[2022-07-01 00:00:00, 2022-07-01 23:59:59]")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.ota.vo.firmware;
|
||||
|
||||
import com.fhs.core.trans.vo.VO;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - IoT OTA 固件 Response VO")
|
||||
@Data
|
||||
public class IotOtaFirmwareRespVO implements VO {
|
||||
|
||||
@Schema(description = "固件编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "固件名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "OTA 固件")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "固件描述")
|
||||
private String description;
|
||||
|
||||
@Schema(description = "版本号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1.0.0")
|
||||
private String version;
|
||||
|
||||
@Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long productId;
|
||||
|
||||
@Schema(description = "产品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "智能设备")
|
||||
private String productName;
|
||||
|
||||
@Schema(description = "固件文件 URL", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/firmware.bin")
|
||||
private String fileUrl;
|
||||
|
||||
@Schema(description = "固件文件大小", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long fileSize;
|
||||
|
||||
@Schema(description = "固件文件签名算法", example = "MD5")
|
||||
private String fileDigestAlgorithm;
|
||||
|
||||
@Schema(description = "固件文件签名结果", example = "d41d8cd98f00b204e9800998ecf8427e")
|
||||
private String fileDigestValue;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.ota.vo.firmware;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@Schema(description = "管理后台 - IoT OTA 固件更新 Request VO")
|
||||
@Data
|
||||
public class IotOtaFirmwareUpdateReqVO {
|
||||
|
||||
@Schema(description = "固件编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "固件编号不能为空")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "固件名称", example = "智能开关固件")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "固件描述", example = "某品牌型号固件,测试用")
|
||||
private String description;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.ota.vo.task;
|
||||
|
||||
import cn.aagro.pp.framework.common.validation.InEnum;
|
||||
import cn.aagro.pp.module.iot.enums.ota.IotOtaTaskDeviceScopeEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - IoT OTA 升级任务创建 Request VO")
|
||||
@Data
|
||||
public class IotOtaTaskCreateReqVO {
|
||||
|
||||
@NotEmpty(message = "任务名称不能为空")
|
||||
@Schema(description = "任务名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "升级任务")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "任务描述", example = "升级任务")
|
||||
private String description;
|
||||
|
||||
@Schema(description = "固件编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "固件编号不能为空")
|
||||
private Long firmwareId;
|
||||
|
||||
@Schema(description = "升级范围", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "升级范围不能为空")
|
||||
@InEnum(value = IotOtaTaskDeviceScopeEnum.class)
|
||||
private Integer deviceScope;
|
||||
|
||||
@Schema(description = "选中的设备编号数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "1,2,3")
|
||||
private List<Long> deviceIds;
|
||||
|
||||
// TODO @li:如果 deviceScope 等于 2 时,deviceIds 校验非空;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.ota.vo.task;
|
||||
|
||||
import cn.aagro.pp.framework.common.pojo.PageParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - IoT OTA 升级任务分页 Request VO")
|
||||
@Data
|
||||
public class IotOtaTaskPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "任务名称", example = "升级任务")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "固件编号", example = "1024")
|
||||
private Long firmwareId;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.ota.vo.task;
|
||||
|
||||
import com.fhs.core.trans.vo.VO;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - IoT OTA 升级任务 Response VO")
|
||||
@Data
|
||||
public class IotOtaTaskRespVO implements VO {
|
||||
|
||||
@Schema(description = "任务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "任务名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "升级任务")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "任务描述", example = "升级任务")
|
||||
private String description;
|
||||
|
||||
@Schema(description = "固件编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long firmwareId;
|
||||
|
||||
@Schema(description = "任务状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "升级范围", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer deviceScope;
|
||||
|
||||
@Schema(description = "设备总共数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Integer deviceTotalCount;
|
||||
|
||||
@Schema(description = "设备成功数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "66")
|
||||
private Integer deviceSuccessCount;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2022-07-08 07:30:00")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.ota.vo.task.record;
|
||||
|
||||
import cn.aagro.pp.framework.common.pojo.PageParam;
|
||||
import cn.aagro.pp.framework.common.validation.InEnum;
|
||||
import cn.aagro.pp.module.iot.enums.ota.IotOtaTaskRecordStatusEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - IoT OTA 升级记录分页 Request VO")
|
||||
@Data
|
||||
public class IotOtaTaskRecordPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "升级任务编号", example = "1024")
|
||||
private Long taskId;
|
||||
|
||||
@Schema(description = "升级记录状态", example = "5")
|
||||
@InEnum(IotOtaTaskRecordStatusEnum.class)
|
||||
private Integer status;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.ota.vo.task.record;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - IoT OTA 升级任务记录 Response VO")
|
||||
@Data
|
||||
public class IotOtaTaskRecordRespVO {
|
||||
|
||||
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "固件编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long firmwareId;
|
||||
|
||||
@Schema(description = "任务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2048")
|
||||
private Long taskId;
|
||||
|
||||
@Schema(description = "设备编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long deviceId;
|
||||
|
||||
@Schema(description = "设备名称", example = "智能开关")
|
||||
private String deviceName;
|
||||
|
||||
@Schema(description = "来源的固件编号", example = "1023")
|
||||
private Long fromFirmwareId;
|
||||
|
||||
@Schema(description = "来源固件版本", example = "1.0.0")
|
||||
private String fromFirmwareVersion;
|
||||
|
||||
@Schema(description = "升级状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "升级进度,百分比", requiredMode = Schema.RequiredMode.REQUIRED, example = "50")
|
||||
private Integer progress;
|
||||
|
||||
@Schema(description = "升级进度描述", example = "正在下载固件...")
|
||||
private String description;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.product;
|
||||
|
||||
import cn.aagro.pp.framework.common.enums.CommonStatusEnum;
|
||||
import cn.aagro.pp.framework.common.pojo.CommonResult;
|
||||
import cn.aagro.pp.framework.common.pojo.PageResult;
|
||||
import cn.aagro.pp.framework.common.util.object.BeanUtils;
|
||||
import cn.aagro.pp.module.iot.controller.admin.product.vo.category.IotProductCategoryPageReqVO;
|
||||
import cn.aagro.pp.module.iot.controller.admin.product.vo.category.IotProductCategoryRespVO;
|
||||
import cn.aagro.pp.module.iot.controller.admin.product.vo.category.IotProductCategorySaveReqVO;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.product.IotProductCategoryDO;
|
||||
import cn.aagro.pp.module.iot.service.product.IotProductCategoryService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.aagro.pp.framework.common.pojo.CommonResult.success;
|
||||
import static cn.aagro.pp.framework.common.util.collection.CollectionUtils.convertList;
|
||||
|
||||
@Tag(name = "管理后台 - IoT 产品分类")
|
||||
@RestController
|
||||
@RequestMapping("/iot/product-category")
|
||||
@Validated
|
||||
public class IotProductCategoryController {
|
||||
|
||||
@Resource
|
||||
private IotProductCategoryService productCategoryService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建产品分类")
|
||||
@PreAuthorize("@ss.hasPermission('iot:product-category:create')")
|
||||
public CommonResult<Long> createProductCategory(@Valid @RequestBody IotProductCategorySaveReqVO createReqVO) {
|
||||
return success(productCategoryService.createProductCategory(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新产品分类")
|
||||
@PreAuthorize("@ss.hasPermission('iot:product-category:update')")
|
||||
public CommonResult<Boolean> updateProductCategory(@Valid @RequestBody IotProductCategorySaveReqVO updateReqVO) {
|
||||
productCategoryService.updateProductCategory(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除产品分类")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('iot:product-category:delete')")
|
||||
public CommonResult<Boolean> deleteProductCategory(@RequestParam("id") Long id) {
|
||||
productCategoryService.deleteProductCategory(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得产品分类")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('iot:product-category:query')")
|
||||
public CommonResult<IotProductCategoryRespVO> getProductCategory(@RequestParam("id") Long id) {
|
||||
IotProductCategoryDO productCategory = productCategoryService.getProductCategory(id);
|
||||
return success(BeanUtils.toBean(productCategory, IotProductCategoryRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得产品分类分页")
|
||||
@PreAuthorize("@ss.hasPermission('iot:product-category:query')")
|
||||
public CommonResult<PageResult<IotProductCategoryRespVO>> getProductCategoryPage(@Valid IotProductCategoryPageReqVO pageReqVO) {
|
||||
PageResult<IotProductCategoryDO> pageResult = productCategoryService.getProductCategoryPage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, IotProductCategoryRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/simple-list")
|
||||
@Operation(summary = "获得所有产品分类列表")
|
||||
@PreAuthorize("@ss.hasPermission('iot:product-category:query')")
|
||||
public CommonResult<List<IotProductCategoryRespVO>> getSimpleProductCategoryList() {
|
||||
List<IotProductCategoryDO> list = productCategoryService.getProductCategoryListByStatus(
|
||||
CommonStatusEnum.ENABLE.getStatus());
|
||||
return success(convertList(list, category ->
|
||||
new IotProductCategoryRespVO().setId(category.getId()).setName(category.getName())));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.product;
|
||||
|
||||
import cn.aagro.pp.framework.apilog.core.annotation.ApiAccessLog;
|
||||
import cn.aagro.pp.framework.common.pojo.CommonResult;
|
||||
import cn.aagro.pp.framework.common.pojo.PageParam;
|
||||
import cn.aagro.pp.framework.common.pojo.PageResult;
|
||||
import cn.aagro.pp.framework.common.util.collection.MapUtils;
|
||||
import cn.aagro.pp.framework.common.util.object.BeanUtils;
|
||||
import cn.aagro.pp.framework.excel.core.util.ExcelUtils;
|
||||
import cn.aagro.pp.module.iot.controller.admin.product.vo.product.IotProductPageReqVO;
|
||||
import cn.aagro.pp.module.iot.controller.admin.product.vo.product.IotProductRespVO;
|
||||
import cn.aagro.pp.module.iot.controller.admin.product.vo.product.IotProductSaveReqVO;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.product.IotProductCategoryDO;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.product.IotProductDO;
|
||||
import cn.aagro.pp.module.iot.service.product.IotProductCategoryService;
|
||||
import cn.aagro.pp.module.iot.service.product.IotProductService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.aagro.pp.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
|
||||
import static cn.aagro.pp.framework.common.pojo.CommonResult.success;
|
||||
import static cn.aagro.pp.framework.common.util.collection.CollectionUtils.convertList;
|
||||
|
||||
@Tag(name = "管理后台 - IoT 产品")
|
||||
@RestController
|
||||
@RequestMapping("/iot/product")
|
||||
@Validated
|
||||
public class IotProductController {
|
||||
|
||||
@Resource
|
||||
private IotProductService productService;
|
||||
@Resource
|
||||
private IotProductCategoryService categoryService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建产品")
|
||||
@PreAuthorize("@ss.hasPermission('iot:product:create')")
|
||||
public CommonResult<Long> createProduct(@Valid @RequestBody IotProductSaveReqVO createReqVO) {
|
||||
return success(productService.createProduct(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新产品")
|
||||
@PreAuthorize("@ss.hasPermission('iot:product:update')")
|
||||
public CommonResult<Boolean> updateProduct(@Valid @RequestBody IotProductSaveReqVO updateReqVO) {
|
||||
productService.updateProduct(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PutMapping("/update-status")
|
||||
@Operation(summary = "更新产品状态")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@Parameter(name = "status", description = "状态", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('iot:product:update')")
|
||||
public CommonResult<Boolean> updateProductStatus(@RequestParam("id") Long id,
|
||||
@RequestParam("status") Integer status) {
|
||||
productService.updateProductStatus(id, status);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除产品")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('iot:product:delete')")
|
||||
public CommonResult<Boolean> deleteProduct(@RequestParam("id") Long id) {
|
||||
productService.deleteProduct(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得产品")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('iot:product:query')")
|
||||
public CommonResult<IotProductRespVO> getProduct(@RequestParam("id") Long id) {
|
||||
IotProductDO product = productService.getProduct(id);
|
||||
if (product == null) {
|
||||
return success(null);
|
||||
}
|
||||
// 拼接数据
|
||||
IotProductCategoryDO category = categoryService.getProductCategory(product.getCategoryId());
|
||||
return success(BeanUtils.toBean(product, IotProductRespVO.class, bean -> {
|
||||
if (category != null) {
|
||||
bean.setCategoryName(category.getName());
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
@GetMapping("/get-by-key")
|
||||
@Operation(summary = "通过 ProductKey 获得产品")
|
||||
@Parameter(name = "productKey", description = "产品Key", required = true, example = "abc123")
|
||||
@PreAuthorize("@ss.hasPermission('iot:product:query')")
|
||||
public CommonResult<IotProductRespVO> getProductByKey(@RequestParam("productKey") String productKey) {
|
||||
IotProductDO product = productService.getProductByProductKey(productKey);
|
||||
if (product == null) {
|
||||
return success(null);
|
||||
}
|
||||
// 拼接数据
|
||||
IotProductCategoryDO category = categoryService.getProductCategory(product.getCategoryId());
|
||||
return success(BeanUtils.toBean(product, IotProductRespVO.class, bean -> {
|
||||
if (category != null) {
|
||||
bean.setCategoryName(category.getName());
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得产品分页")
|
||||
@PreAuthorize("@ss.hasPermission('iot:product:query')")
|
||||
public CommonResult<PageResult<IotProductRespVO>> getProductPage(@Valid IotProductPageReqVO pageReqVO) {
|
||||
PageResult<IotProductDO> pageResult = productService.getProductPage(pageReqVO);
|
||||
// 拼接数据
|
||||
Map<Long, IotProductCategoryDO> categoryMap = categoryService.getProductCategoryMap(
|
||||
convertList(pageResult.getList(), IotProductDO::getCategoryId));
|
||||
return success(BeanUtils.toBean(pageResult, IotProductRespVO.class, bean -> {
|
||||
MapUtils.findAndThen(categoryMap, bean.getCategoryId(),
|
||||
category -> bean.setCategoryName(category.getName()));
|
||||
}));
|
||||
}
|
||||
|
||||
@GetMapping("/export-excel")
|
||||
@Operation(summary = "导出产品 Excel")
|
||||
@PreAuthorize("@ss.hasPermission('iot:product:export')")
|
||||
@ApiAccessLog(operateType = EXPORT)
|
||||
public void exportProductExcel(@Valid IotProductPageReqVO exportReqVO,
|
||||
HttpServletResponse response) throws IOException {
|
||||
exportReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
||||
CommonResult<PageResult<IotProductRespVO>> result = getProductPage(exportReqVO);
|
||||
// 导出 Excel
|
||||
ExcelUtils.write(response, "产品.xls", "数据", IotProductRespVO.class,
|
||||
result.getData().getList());
|
||||
}
|
||||
|
||||
@GetMapping("/simple-list")
|
||||
@Operation(summary = "获取产品的精简信息列表", description = "主要用于前端的下拉选项")
|
||||
public CommonResult<List<IotProductRespVO>> getProductSimpleList() {
|
||||
List<IotProductDO> list = productService.getProductList();
|
||||
return success(convertList(list, product -> // 只返回 id、name 字段
|
||||
new IotProductRespVO().setId(product.getId()).setName(product.getName())
|
||||
.setDeviceType(product.getDeviceType()).setLocationType(product.getLocationType())));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.product.vo.category;
|
||||
|
||||
import cn.aagro.pp.framework.common.pojo.PageParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.aagro.pp.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 产品分类分页 Request VO")
|
||||
@Data
|
||||
public class IotProductCategoryPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "分类名字", example = "王五")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.product.vo.category;
|
||||
|
||||
import cn.aagro.pp.framework.excel.core.annotations.DictFormat;
|
||||
import cn.aagro.pp.module.system.enums.DictTypeConstants;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 产品分类 Response VO")
|
||||
@Data
|
||||
public class IotProductCategoryRespVO {
|
||||
|
||||
@Schema(description = "分类 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "25284")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "分类名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "分类排序")
|
||||
private Integer sort;
|
||||
|
||||
@Schema(description = "分类状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@DictFormat(DictTypeConstants.COMMON_STATUS)
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "分类描述", example = "随便")
|
||||
private String description;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.product.vo.category;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 产品分类新增/修改 Request VO")
|
||||
@Data
|
||||
public class IotProductCategorySaveReqVO {
|
||||
|
||||
@Schema(description = "分类 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "25284")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "分类名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五")
|
||||
@NotEmpty(message = "分类名字不能为空")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "分类排序")
|
||||
private Integer sort;
|
||||
|
||||
@Schema(description = "分类状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "分类状态不能为空")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "分类描述", example = "随便")
|
||||
private String description;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.product.vo.product;
|
||||
|
||||
import cn.aagro.pp.framework.common.pojo.PageParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 产品分页 Request VO")
|
||||
@Data
|
||||
public class IotProductPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "产品名称", example = "李四")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "产品标识")
|
||||
private String productKey;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.product.vo.product;
|
||||
|
||||
import cn.aagro.pp.framework.excel.core.annotations.DictFormat;
|
||||
import cn.aagro.pp.framework.excel.core.convert.DictConvert;
|
||||
import cn.aagro.pp.module.iot.enums.DictTypeConstants;
|
||||
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import cn.idev.excel.annotation.ExcelProperty;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 产品 Response VO")
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
public class IotProductRespVO {
|
||||
|
||||
@Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "26087")
|
||||
@ExcelProperty("产品编号")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "产品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
|
||||
@ExcelProperty("产品名称")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@ExcelProperty("产品标识")
|
||||
private String productKey;
|
||||
|
||||
@Schema(description = "产品分类编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Long categoryId;
|
||||
|
||||
@Schema(description = "产品分类名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@ExcelProperty("产品分类")
|
||||
private String categoryName;
|
||||
|
||||
@Schema(description = "产品图标", example = "https://iocoder.cn/1.svg")
|
||||
@ExcelProperty("产品图标")
|
||||
private String icon;
|
||||
|
||||
@Schema(description = "产品图片", example = "https://iocoder.cn/1.png")
|
||||
@ExcelProperty("产品图片")
|
||||
private String picUrl;
|
||||
|
||||
@Schema(description = "产品描述", example = "你猜")
|
||||
@ExcelProperty("产品描述")
|
||||
private String description;
|
||||
|
||||
@Schema(description = "产品状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@ExcelProperty(value = "产品状态", converter = DictConvert.class)
|
||||
@DictFormat(DictTypeConstants.PRODUCT_STATUS)
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "设备类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||
@ExcelProperty(value = "设备类型", converter = DictConvert.class)
|
||||
@DictFormat(DictTypeConstants.PRODUCT_DEVICE_TYPE)
|
||||
private Integer deviceType;
|
||||
|
||||
@Schema(description = "联网方式", example = "2")
|
||||
@ExcelProperty(value = "联网方式", converter = DictConvert.class)
|
||||
@DictFormat(DictTypeConstants.NET_TYPE)
|
||||
private Integer netType;
|
||||
|
||||
@Schema(description = "定位方式", example = "2")
|
||||
@ExcelProperty(value = "定位方式", converter = DictConvert.class)
|
||||
@DictFormat(DictTypeConstants.LOCATION_TYPE)
|
||||
private Integer locationType;
|
||||
|
||||
@Schema(description = "数据格式", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||
@ExcelProperty(value = "数据格式", converter = DictConvert.class)
|
||||
@DictFormat(DictTypeConstants.CODEC_TYPE)
|
||||
private String codecType;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@ExcelProperty("创建时间")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.product.vo.product;
|
||||
|
||||
import cn.aagro.pp.framework.common.validation.InEnum;
|
||||
import cn.aagro.pp.module.iot.enums.product.IotLocationTypeEnum;
|
||||
import cn.aagro.pp.module.iot.enums.product.IotNetTypeEnum;
|
||||
import cn.aagro.pp.module.iot.enums.product.IotProductDeviceTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 产品新增/修改 Request VO")
|
||||
@Data
|
||||
public class IotProductSaveReqVO {
|
||||
|
||||
@Schema(description = "产品编号", requiredMode = Schema.RequiredMode.AUTO, example = "1")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "产品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "温湿度")
|
||||
@NotEmpty(message = "产品名称不能为空")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "产品 Key", requiredMode = Schema.RequiredMode.AUTO, example = "12345abc")
|
||||
private String productKey;
|
||||
|
||||
@Schema(description = "产品分类编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "产品分类编号不能为空")
|
||||
private Long categoryId;
|
||||
|
||||
@Schema(description = "产品图标", example = "https://iocoder.cn/1.svg")
|
||||
private String icon;
|
||||
|
||||
@Schema(description = "产品图片", example = "https://iocoder.cn/1.png")
|
||||
private String picUrl;
|
||||
|
||||
@Schema(description = "产品描述", example = "描述")
|
||||
private String description;
|
||||
|
||||
@Schema(description = "设备类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
|
||||
@InEnum(value = IotProductDeviceTypeEnum.class, message = "设备类型必须是 {value}")
|
||||
@NotNull(message = "设备类型不能为空")
|
||||
private Integer deviceType;
|
||||
|
||||
@Schema(description = "联网方式", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
|
||||
@InEnum(value = IotNetTypeEnum.class, message = "联网方式必须是 {value}")
|
||||
private Integer netType;
|
||||
|
||||
@Schema(description = "定位类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
|
||||
@InEnum(value = IotLocationTypeEnum.class, message = "定位方式必须是 {value}")
|
||||
private Integer locationType;
|
||||
|
||||
@Schema(description = "数据格式", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||
@NotEmpty(message = "数据格式不能为空")
|
||||
private String codecType;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.rule;
|
||||
|
||||
import cn.aagro.pp.framework.common.pojo.CommonResult;
|
||||
import cn.aagro.pp.framework.common.pojo.PageResult;
|
||||
import cn.aagro.pp.framework.common.util.object.BeanUtils;
|
||||
import cn.aagro.pp.module.iot.controller.admin.rule.vo.data.rule.IotDataRulePageReqVO;
|
||||
import cn.aagro.pp.module.iot.controller.admin.rule.vo.data.rule.IotDataRuleRespVO;
|
||||
import cn.aagro.pp.module.iot.controller.admin.rule.vo.data.rule.IotDataRuleSaveReqVO;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.rule.IotDataRuleDO;
|
||||
import cn.aagro.pp.module.iot.service.rule.data.IotDataRuleService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
|
||||
import static cn.aagro.pp.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - IoT 数据流转规则")
|
||||
@RestController
|
||||
@RequestMapping("/iot/data-rule")
|
||||
@Validated
|
||||
public class IotDataRuleController {
|
||||
|
||||
@Resource
|
||||
private IotDataRuleService dataRuleService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建数据流转规则")
|
||||
@PreAuthorize("@ss.hasPermission('iot:data-rule:create')")
|
||||
public CommonResult<Long> createDataRule(@Valid @RequestBody IotDataRuleSaveReqVO createReqVO) {
|
||||
return success(dataRuleService.createDataRule(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新数据流转规则")
|
||||
@PreAuthorize("@ss.hasPermission('iot:data-rule:update')")
|
||||
public CommonResult<Boolean> updateDataRule(@Valid @RequestBody IotDataRuleSaveReqVO updateReqVO) {
|
||||
dataRuleService.updateDataRule(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除数据流转规则")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('iot:data-rule:delete')")
|
||||
public CommonResult<Boolean> deleteDataRule(@RequestParam("id") Long id) {
|
||||
dataRuleService.deleteDataRule(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得数据流转规则")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('iot:data-rule:query')")
|
||||
public CommonResult<IotDataRuleRespVO> getDataRule(@RequestParam("id") Long id) {
|
||||
IotDataRuleDO dataRule = dataRuleService.getDataRule(id);
|
||||
return success(BeanUtils.toBean(dataRule, IotDataRuleRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得数据流转规则分页")
|
||||
@PreAuthorize("@ss.hasPermission('iot:data-rule:query')")
|
||||
public CommonResult<PageResult<IotDataRuleRespVO>> getDataRulePage(@Valid IotDataRulePageReqVO pageReqVO) {
|
||||
PageResult<IotDataRuleDO> pageResult = dataRuleService.getDataRulePage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, IotDataRuleRespVO.class));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.rule;
|
||||
|
||||
import cn.aagro.pp.framework.common.enums.CommonStatusEnum;
|
||||
import cn.aagro.pp.framework.common.pojo.CommonResult;
|
||||
import cn.aagro.pp.framework.common.pojo.PageResult;
|
||||
import cn.aagro.pp.framework.common.util.object.BeanUtils;
|
||||
import cn.aagro.pp.module.iot.controller.admin.rule.vo.data.sink.IotDataSinkPageReqVO;
|
||||
import cn.aagro.pp.module.iot.controller.admin.rule.vo.data.sink.IotDataSinkRespVO;
|
||||
import cn.aagro.pp.module.iot.controller.admin.rule.vo.data.sink.IotDataSinkSaveReqVO;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.rule.IotDataSinkDO;
|
||||
import cn.aagro.pp.module.iot.service.rule.data.IotDataSinkService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.aagro.pp.framework.common.pojo.CommonResult.success;
|
||||
import static cn.aagro.pp.framework.common.util.collection.CollectionUtils.convertList;
|
||||
|
||||
@Tag(name = "管理后台 - IoT 数据流转目的")
|
||||
@RestController
|
||||
@RequestMapping("/iot/data-sink")
|
||||
@Validated
|
||||
public class IotDataSinkController {
|
||||
|
||||
@Resource
|
||||
private IotDataSinkService dataSinkService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建数据目的")
|
||||
@PreAuthorize("@ss.hasPermission('iot:data-sink:create')")
|
||||
public CommonResult<Long> createDataSink(@Valid @RequestBody IotDataSinkSaveReqVO createReqVO) {
|
||||
return success(dataSinkService.createDataSink(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新数据目的")
|
||||
@PreAuthorize("@ss.hasPermission('iot:data-sink:update')")
|
||||
public CommonResult<Boolean> updateDataSink(@Valid @RequestBody IotDataSinkSaveReqVO updateReqVO) {
|
||||
dataSinkService.updateDataSink(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除数据目的")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('iot:data-sink:delete')")
|
||||
public CommonResult<Boolean> deleteDataSink(@RequestParam("id") Long id) {
|
||||
dataSinkService.deleteDataSink(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得数据目的")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('iot:data-sink:query')")
|
||||
public CommonResult<IotDataSinkRespVO> getDataSink(@RequestParam("id") Long id) {
|
||||
IotDataSinkDO sink = dataSinkService.getDataSink(id);
|
||||
return success(BeanUtils.toBean(sink, IotDataSinkRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得数据目的分页")
|
||||
@PreAuthorize("@ss.hasPermission('iot:data-sink:query')")
|
||||
public CommonResult<PageResult<IotDataSinkRespVO>> getDataSinkPage(@Valid IotDataSinkPageReqVO pageReqVO) {
|
||||
PageResult<IotDataSinkDO> pageResult = dataSinkService.getDataSinkPage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, IotDataSinkRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/simple-list")
|
||||
@Operation(summary = "获取数据目的的精简信息列表", description = "主要用于前端的下拉选项")
|
||||
public CommonResult<List<IotDataSinkRespVO>> getDataSinkSimpleList() {
|
||||
List<IotDataSinkDO> list = dataSinkService.getDataSinkListByStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
return success(convertList(list, sink -> // 只返回 id、name 字段
|
||||
new IotDataSinkRespVO().setId(sink.getId()).setName(sink.getName())));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.rule;
|
||||
|
||||
import cn.aagro.pp.framework.common.enums.CommonStatusEnum;
|
||||
import cn.aagro.pp.framework.common.pojo.CommonResult;
|
||||
import cn.aagro.pp.framework.common.pojo.PageResult;
|
||||
import cn.aagro.pp.framework.common.util.object.BeanUtils;
|
||||
import cn.aagro.pp.module.iot.controller.admin.rule.vo.scene.IotSceneRulePageReqVO;
|
||||
import cn.aagro.pp.module.iot.controller.admin.rule.vo.scene.IotSceneRuleRespVO;
|
||||
import cn.aagro.pp.module.iot.controller.admin.rule.vo.scene.IotSceneRuleSaveReqVO;
|
||||
import cn.aagro.pp.module.iot.controller.admin.rule.vo.scene.IotSceneRuleUpdateStatusReqVO;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.rule.IotSceneRuleDO;
|
||||
import cn.aagro.pp.module.iot.service.rule.scene.IotSceneRuleService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.aagro.pp.framework.common.pojo.CommonResult.success;
|
||||
import static cn.aagro.pp.framework.common.util.collection.CollectionUtils.convertList;
|
||||
|
||||
@Tag(name = "管理后台 - IoT 场景联动")
|
||||
@RestController
|
||||
@RequestMapping("/iot/scene-rule")
|
||||
@Validated
|
||||
public class IotSceneRuleController {
|
||||
|
||||
@Resource
|
||||
private IotSceneRuleService sceneRuleService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建场景联动")
|
||||
@PreAuthorize("@ss.hasPermission('iot:scene-rule:create')")
|
||||
public CommonResult<Long> createSceneRule(@Valid @RequestBody IotSceneRuleSaveReqVO createReqVO) {
|
||||
return success(sceneRuleService.createSceneRule(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新场景联动")
|
||||
@PreAuthorize("@ss.hasPermission('iot:scene-rule:update')")
|
||||
public CommonResult<Boolean> updateSceneRule(@Valid @RequestBody IotSceneRuleSaveReqVO updateReqVO) {
|
||||
sceneRuleService.updateSceneRule(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PutMapping("/update-status")
|
||||
@Operation(summary = "更新场景联动状态")
|
||||
@PreAuthorize("@ss.hasPermission('iot:scene-rule:update')")
|
||||
public CommonResult<Boolean> updateSceneRuleStatus(@Valid @RequestBody IotSceneRuleUpdateStatusReqVO updateReqVO) {
|
||||
sceneRuleService.updateSceneRuleStatus(updateReqVO.getId(), updateReqVO.getStatus());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除场景联动")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('iot:scene-rule:delete')")
|
||||
public CommonResult<Boolean> deleteSceneRule(@RequestParam("id") Long id) {
|
||||
sceneRuleService.deleteSceneRule(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得场景联动")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('iot:scene-rule:query')")
|
||||
public CommonResult<IotSceneRuleRespVO> getSceneRule(@RequestParam("id") Long id) {
|
||||
IotSceneRuleDO sceneRule = sceneRuleService.getSceneRule(id);
|
||||
return success(BeanUtils.toBean(sceneRule, IotSceneRuleRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得场景联动分页")
|
||||
@PreAuthorize("@ss.hasPermission('iot:scene-rule:query')")
|
||||
public CommonResult<PageResult<IotSceneRuleRespVO>> getSceneRulePage(@Valid IotSceneRulePageReqVO pageReqVO) {
|
||||
PageResult<IotSceneRuleDO> pageResult = sceneRuleService.getSceneRulePage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, IotSceneRuleRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/simple-list")
|
||||
@Operation(summary = "获取场景联动的精简信息列表", description = "主要用于前端的下拉选项")
|
||||
public CommonResult<List<IotSceneRuleRespVO>> getSceneRuleSimpleList() {
|
||||
List<IotSceneRuleDO> list = sceneRuleService.getSceneRuleListByStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
return success(convertList(list, scene -> // 只返回 id、name 字段
|
||||
new IotSceneRuleRespVO().setId(scene.getId()).setName(scene.getName())));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.rule.vo.data;
|
||||
@@ -0,0 +1,26 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.rule.vo.data.rule;
|
||||
|
||||
import cn.aagro.pp.framework.common.pojo.PageParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.aagro.pp.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 数据流转规则分页 Request VO")
|
||||
@Data
|
||||
public class IotDataRulePageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "数据流转规则名称", example = "芋艿")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "数据流转规则状态", example = "1")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.rule.vo.data.rule;
|
||||
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.rule.IotDataRuleDO;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 数据流转规则 Response VO")
|
||||
@Data
|
||||
public class IotDataRuleRespVO {
|
||||
|
||||
@Schema(description = "数据流转规则编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "8540")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "数据流转规则名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "数据流转规则描述", example = "你猜")
|
||||
private String description;
|
||||
|
||||
@Schema(description = "数据流转规则状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "数据源配置数组", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private List<IotDataRuleDO.SourceConfig> sourceConfigs;
|
||||
|
||||
@Schema(description = "数据目的编号数组", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private List<Long> sinkIds;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.rule.vo.data.rule;
|
||||
|
||||
import cn.aagro.pp.framework.common.enums.CommonStatusEnum;
|
||||
import cn.aagro.pp.framework.common.validation.InEnum;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.rule.IotDataRuleDO;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 数据流转规则新增/修改 Request VO")
|
||||
@Data
|
||||
public class IotDataRuleSaveReqVO {
|
||||
|
||||
@Schema(description = "数据流转规则编号", example = "8540")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "数据流转规则名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿")
|
||||
@NotEmpty(message = "数据流转规则名称不能为空")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "数据流转规则描述", example = "你猜")
|
||||
private String description;
|
||||
|
||||
@Schema(description = "数据流转规则状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "数据流转规则状态不能为空")
|
||||
@InEnum(CommonStatusEnum.class)
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "数据源配置数组", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotEmpty(message = "数据源配置数组不能为空")
|
||||
private List<IotDataRuleDO.SourceConfig> sourceConfigs;
|
||||
|
||||
@Schema(description = "数据目的编号数组", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotEmpty(message = "数据目的编号数组不能为空")
|
||||
private List<Long> sinkIds;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.rule.vo.data.sink;
|
||||
|
||||
import cn.aagro.pp.framework.common.enums.CommonStatusEnum;
|
||||
import cn.aagro.pp.framework.common.pojo.PageParam;
|
||||
import cn.aagro.pp.framework.common.validation.InEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.aagro.pp.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 数据流转目的分页 Request VO")
|
||||
@Data
|
||||
public class IotDataSinkPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "数据目的名称", example = "赵六")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "数据目的状态", example = "2")
|
||||
@InEnum(CommonStatusEnum.class)
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.rule.vo.data.sink;
|
||||
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.rule.config.IotAbstractDataSinkConfig;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 数据流转目的 Response VO")
|
||||
@Data
|
||||
public class IotDataSinkRespVO {
|
||||
|
||||
@Schema(description = "数据目的编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "18564")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "数据目的名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "数据目的描述", example = "随便")
|
||||
private String description;
|
||||
|
||||
@Schema(description = "数据目的状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "数据目的类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer type;
|
||||
|
||||
@Schema(description = "数据目的配置")
|
||||
private IotAbstractDataSinkConfig config;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.rule.vo.data.sink;
|
||||
|
||||
import cn.aagro.pp.framework.common.enums.CommonStatusEnum;
|
||||
import cn.aagro.pp.framework.common.validation.InEnum;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.rule.config.IotAbstractDataSinkConfig;
|
||||
import cn.aagro.pp.module.iot.enums.rule.IotDataSinkTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 数据流转目的新增/修改 Request VO")
|
||||
@Data
|
||||
public class IotDataSinkSaveReqVO {
|
||||
|
||||
@Schema(description = "数据目的编号", example = "18564")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "数据目的名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
|
||||
@NotEmpty(message = "数据目的名称不能为空")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "数据目的描述", example = "随便")
|
||||
private String description;
|
||||
|
||||
@Schema(description = "数据目的状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "数据目的状态不能为空")
|
||||
@InEnum(CommonStatusEnum.class)
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "数据目的类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "数据目的类型不能为空")
|
||||
@InEnum(IotDataSinkTypeEnum.class)
|
||||
private Integer type;
|
||||
|
||||
@Schema(description = "数据目的配置")
|
||||
@NotNull(message = "数据目的配置不能为空")
|
||||
private IotAbstractDataSinkConfig config;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.rule.vo.scene;
|
||||
|
||||
import cn.aagro.pp.framework.common.enums.CommonStatusEnum;
|
||||
import cn.aagro.pp.framework.common.pojo.PageParam;
|
||||
import cn.aagro.pp.framework.common.validation.InEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.aagro.pp.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 场景联动分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class IotSceneRulePageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "场景名称", example = "赵六")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "场景描述", example = "你猜")
|
||||
private String description;
|
||||
|
||||
@Schema(description = "场景状态", example = "1")
|
||||
@InEnum(CommonStatusEnum.class)
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.rule.vo.scene;
|
||||
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.rule.IotSceneRuleDO;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 场景联动 Response VO")
|
||||
@Data
|
||||
public class IotSceneRuleRespVO {
|
||||
|
||||
@Schema(description = "场景编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "15865")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "场景名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "场景描述", example = "你猜")
|
||||
private String description;
|
||||
|
||||
@Schema(description = "场景状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "触发器数组", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private List<IotSceneRuleDO.Trigger> triggers;
|
||||
|
||||
@Schema(description = "执行器数组", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private List<IotSceneRuleDO.Action> actions;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.rule.vo.scene;
|
||||
|
||||
import cn.aagro.pp.framework.common.enums.CommonStatusEnum;
|
||||
import cn.aagro.pp.framework.common.validation.InEnum;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.rule.IotSceneRuleDO;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 场景联动新增/修改 Request VO")
|
||||
@Data
|
||||
public class IotSceneRuleSaveReqVO {
|
||||
|
||||
@Schema(description = "场景编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "15865")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "场景名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
|
||||
@NotEmpty(message = "场景名称不能为空")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "场景描述", example = "你猜")
|
||||
private String description;
|
||||
|
||||
@Schema(description = "场景状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||
@NotNull(message = "场景状态不能为空")
|
||||
@InEnum(CommonStatusEnum.class)
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "触发器数组", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotEmpty(message = "触发器数组不能为空")
|
||||
private List<IotSceneRuleDO.Trigger> triggers;
|
||||
|
||||
@Schema(description = "执行器数组", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotEmpty(message = "执行器数组不能为空")
|
||||
private List<IotSceneRuleDO.Action> actions;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.rule.vo.scene;
|
||||
|
||||
import cn.aagro.pp.framework.common.enums.CommonStatusEnum;
|
||||
import cn.aagro.pp.framework.common.validation.InEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 场景联动更新状态 Request VO")
|
||||
@Data
|
||||
public class IotSceneRuleUpdateStatusReqVO {
|
||||
|
||||
@Schema(description = "场景联动编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "场景联动编号不能为空")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
|
||||
@NotNull(message = "状态不能为空")
|
||||
@InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}")
|
||||
private Integer status;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
### 请求 /iot/statistics/get-device-message-summary-by-date 接口(小时)
|
||||
GET {{baseUrl}}/iot/statistics/get-device-message-summary-by-date?interval=0×[0]=2025-06-13 00:00:00×[1]=2025-06-14 23:59:59
|
||||
Content-Type: application/json
|
||||
tenant-id: {{adminTenantId}}
|
||||
Authorization: Bearer {{token}}
|
||||
|
||||
### 请求 /iot/statistics/get-device-message-summary-by-date 接口(天)
|
||||
GET {{baseUrl}}/iot/statistics/get-device-message-summary-by-date?interval=1×[0]=2025-06-13 00:00:00×[1]=2025-06-14 23:59:59
|
||||
Content-Type: application/json
|
||||
tenant-id: {{adminTenantId}}
|
||||
Authorization: Bearer {{token}}
|
||||
@@ -0,0 +1,77 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.statistics;
|
||||
|
||||
import cn.aagro.pp.framework.common.pojo.CommonResult;
|
||||
import cn.aagro.pp.framework.common.util.date.LocalDateTimeUtils;
|
||||
import cn.aagro.pp.module.iot.controller.admin.statistics.vo.IotStatisticsDeviceMessageReqVO;
|
||||
import cn.aagro.pp.module.iot.controller.admin.statistics.vo.IotStatisticsDeviceMessageSummaryByDateRespVO;
|
||||
import cn.aagro.pp.module.iot.controller.admin.statistics.vo.IotStatisticsSummaryRespVO;
|
||||
import cn.aagro.pp.module.iot.core.enums.IotDeviceStateEnum;
|
||||
import cn.aagro.pp.module.iot.service.device.IotDeviceService;
|
||||
import cn.aagro.pp.module.iot.service.device.message.IotDeviceMessageService;
|
||||
import cn.aagro.pp.module.iot.service.product.IotProductCategoryService;
|
||||
import cn.aagro.pp.module.iot.service.product.IotProductService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
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 javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.aagro.pp.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - IoT 数据统计")
|
||||
@RestController
|
||||
@RequestMapping("/iot/statistics")
|
||||
@Validated
|
||||
public class IotStatisticsController {
|
||||
|
||||
@Resource
|
||||
private IotDeviceService deviceService;
|
||||
@Resource
|
||||
private IotProductCategoryService productCategoryService;
|
||||
@Resource
|
||||
private IotProductService productService;
|
||||
@Resource
|
||||
private IotDeviceMessageService deviceMessageService;
|
||||
|
||||
@GetMapping("/get-summary")
|
||||
@Operation(summary = "获取全局的数据统计")
|
||||
public CommonResult<IotStatisticsSummaryRespVO> getStatisticsSummary(){
|
||||
IotStatisticsSummaryRespVO respVO = new IotStatisticsSummaryRespVO();
|
||||
// 1.1 获取总数
|
||||
respVO.setProductCategoryCount(productCategoryService.getProductCategoryCount(null));
|
||||
respVO.setProductCount(productService.getProductCount(null));
|
||||
respVO.setDeviceCount(deviceService.getDeviceCount(null));
|
||||
respVO.setDeviceMessageCount(deviceMessageService.getDeviceMessageCount(null));
|
||||
// 1.2 获取今日新增数量
|
||||
LocalDateTime todayStart = LocalDateTimeUtils.getToday();
|
||||
respVO.setProductCategoryTodayCount(productCategoryService.getProductCategoryCount(todayStart));
|
||||
respVO.setProductTodayCount(productService.getProductCount(todayStart));
|
||||
respVO.setDeviceTodayCount(deviceService.getDeviceCount(todayStart));
|
||||
respVO.setDeviceMessageTodayCount(deviceMessageService.getDeviceMessageCount(todayStart));
|
||||
|
||||
// 2. 获取各个品类下设备数量统计
|
||||
respVO.setProductCategoryDeviceCounts(productCategoryService.getProductCategoryDeviceCountMap());
|
||||
|
||||
// 3. 获取设备状态数量统计
|
||||
Map<Integer, Long> deviceCountMap = deviceService.getDeviceCountMapByState();
|
||||
respVO.setDeviceOnlineCount(deviceCountMap.getOrDefault(IotDeviceStateEnum.ONLINE.getState(), 0L));
|
||||
respVO.setDeviceOfflineCount(deviceCountMap.getOrDefault(IotDeviceStateEnum.OFFLINE.getState(), 0L));
|
||||
respVO.setDeviceInactiveCount(deviceCountMap.getOrDefault(IotDeviceStateEnum.INACTIVE.getState(), 0L));
|
||||
return success(respVO);
|
||||
}
|
||||
|
||||
@GetMapping("/get-device-message-summary-by-date")
|
||||
@Operation(summary = "获取设备消息的数据统计")
|
||||
public CommonResult<List<IotStatisticsDeviceMessageSummaryByDateRespVO>> getDeviceMessageSummaryByDate(
|
||||
@Valid IotStatisticsDeviceMessageReqVO reqVO) {
|
||||
return success(deviceMessageService.getDeviceMessageSummaryByDate(reqVO));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.statistics.vo;
|
||||
|
||||
import cn.aagro.pp.framework.common.enums.DateIntervalEnum;
|
||||
import cn.aagro.pp.framework.common.validation.InEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import javax.validation.constraints.Size;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.aagro.pp.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 设备消息数量统计 Response VO")
|
||||
@Data
|
||||
public class IotStatisticsDeviceMessageReqVO {
|
||||
|
||||
@Schema(description = "时间间隔类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@InEnum(value = DateIntervalEnum.class, message = "时间间隔类型,必须是 {value}")
|
||||
private Integer interval;
|
||||
|
||||
@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;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.statistics.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 设备消息数量统计 Response VO")
|
||||
@Data
|
||||
public class IotStatisticsDeviceMessageSummaryByDateRespVO {
|
||||
|
||||
@Schema(description = "时间轴", requiredMode = Schema.RequiredMode.REQUIRED, example = "202401")
|
||||
private String time;
|
||||
|
||||
@Schema(description = "上行消息数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
|
||||
private Integer upstreamCount;
|
||||
|
||||
@Schema(description = "上行消息数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "20")
|
||||
private Integer downstreamCount;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.statistics.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 管理后台 - IoT 统计 Response VO
|
||||
*/
|
||||
@Schema(description = "管理后台 - IoT 统计 Response VO")
|
||||
@Data
|
||||
public class IotStatisticsSummaryRespVO {
|
||||
|
||||
@Schema(description = "品类数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
|
||||
private Long productCategoryCount;
|
||||
|
||||
@Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "20")
|
||||
private Long productCount;
|
||||
|
||||
@Schema(description = "设备数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
|
||||
private Long deviceCount;
|
||||
|
||||
@Schema(description = "上报数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000")
|
||||
private Long deviceMessageCount;
|
||||
|
||||
@Schema(description = "今日新增品类数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
|
||||
private Long productCategoryTodayCount;
|
||||
|
||||
@Schema(description = "今日新增产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "20")
|
||||
private Long productTodayCount;
|
||||
|
||||
@Schema(description = "今日新增设备数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
|
||||
private Long deviceTodayCount;
|
||||
|
||||
@Schema(description = "今日新增上报数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000")
|
||||
private Long deviceMessageTodayCount;
|
||||
|
||||
@Schema(description = "在线数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "80")
|
||||
private Long deviceOnlineCount;
|
||||
|
||||
@Schema(description = "离线数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "15")
|
||||
private Long deviceOfflineCount;
|
||||
|
||||
@Schema(description = "待激活设备数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "5")
|
||||
private Long deviceInactiveCount;
|
||||
|
||||
@Schema(description = "按品类统计的设备数量")
|
||||
private Map<String, Integer> productCategoryDeviceCounts;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
### 请求 /iot/product-thing-model/create 接口 => 成功
|
||||
POST {{baseUrl}}/iot/product-thing-model/create
|
||||
Content-Type: application/json
|
||||
tenant-id: {{adminTenentId}}
|
||||
Authorization: Bearer {{token}}
|
||||
|
||||
{
|
||||
"productId": 12,
|
||||
"productKey": "CJVS54fObwZJ9Qe5CJVS54fObwZJ9Qe5",
|
||||
"identifier": "Temperature",
|
||||
"name": "温度",
|
||||
"description": "当前温度值",
|
||||
"type": 1,
|
||||
"property": {
|
||||
"identifier": "Temperature",
|
||||
"name": "温度",
|
||||
"accessMode": "r",
|
||||
"required": true,
|
||||
"dataType": "int",
|
||||
"dataSpecs": {
|
||||
"dataType": "int",
|
||||
"max": "200",
|
||||
"min": "0",
|
||||
"step": "10",
|
||||
"defaultValue": "30",
|
||||
"unit": "%",
|
||||
"unitName": "百分比"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
### 请求 /iot/product-thing-model/create 接口 => 成功
|
||||
POST {{baseUrl}}/iot/product-thing-model/create
|
||||
Content-Type: application/json
|
||||
tenant-id: {{adminTenentId}}
|
||||
Authorization: Bearer {{token}}
|
||||
|
||||
{
|
||||
"productId": 12,
|
||||
"productKey": "CJVS54fObwZJ9Qe5CJVS54fObwZJ9Qe5",
|
||||
"identifier": "switch",
|
||||
"name": "开关",
|
||||
"description": "温度计开关",
|
||||
"type": 1,
|
||||
"property": {
|
||||
"identifier": "switch",
|
||||
"name": "开关",
|
||||
"accessMode": "rw",
|
||||
"required": true,
|
||||
"dataType": "bool",
|
||||
"dataSpecsList": [
|
||||
{
|
||||
"dataType": "bool",
|
||||
"name": "关",
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"dataType": "bool",
|
||||
"name": "开",
|
||||
"value": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
### 请求 /iot/product-thing-model/create 接口 => 成功
|
||||
POST {{baseUrl}}/iot/product-thing-model/create
|
||||
Content-Type: application/json
|
||||
tenant-id: {{adminTenentId}}
|
||||
Authorization: Bearer {{token}}
|
||||
|
||||
{
|
||||
"productId": 12,
|
||||
"productKey": "CJVS54fObwZJ9Qe5CJVS54fObwZJ9Qe5",
|
||||
"identifier": "argb",
|
||||
"name": "温度计 argb 颜色",
|
||||
"description": "温度计 argb 颜色",
|
||||
"type": 1,
|
||||
"property": {
|
||||
"identifier": "argb",
|
||||
"name": "温度计 argb 颜色",
|
||||
"accessMode": "rw",
|
||||
"required": true,
|
||||
"dataType": "array",
|
||||
"dataSpecs": {
|
||||
"dataType": "array",
|
||||
"size": 10,
|
||||
"childDataType": "struct",
|
||||
"dataSpecsList": [
|
||||
{
|
||||
"identifier": "switch",
|
||||
"name": "开关",
|
||||
"accessMode": "rw",
|
||||
"required": true,
|
||||
"dataType": "struct",
|
||||
"childDataType": "bool",
|
||||
"dataSpecsList": [
|
||||
{
|
||||
"dataType": "bool",
|
||||
"name": "关",
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"dataType": "bool",
|
||||
"name": "开",
|
||||
"value": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"identifier": "Temperature",
|
||||
"name": "温度",
|
||||
"accessMode": "r",
|
||||
"required": true,
|
||||
"dataType": "struct",
|
||||
"childDataType": "int",
|
||||
"dataSpecs": {
|
||||
"dataType": "int",
|
||||
"max": "200",
|
||||
"min": "0",
|
||||
"step": "10",
|
||||
"defaultValue": "30",
|
||||
"unit": "%",
|
||||
"unitName": "百分比"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
### 请求 /iot/product-thing-model/update 接口 => 成功
|
||||
PUT {{baseUrl}}/iot/product-thing-model/update
|
||||
Content-Type: application/json
|
||||
tenant-id: {{adminTenentId}}
|
||||
Authorization: Bearer {{token}}
|
||||
|
||||
{
|
||||
"id": 33,
|
||||
"productId": 12,
|
||||
"productKey": "CJVS54fObwZJ9Qe5CJVS54fObwZJ9Qe5",
|
||||
"identifier": "switch",
|
||||
"name": "开关",
|
||||
"description": "温度计开关",
|
||||
"type": 1,
|
||||
"property": {
|
||||
"identifier": "switch",
|
||||
"name": "开关",
|
||||
"accessMode": "r",
|
||||
"required": true,
|
||||
"dataType": "bool",
|
||||
"dataSpecsList": [
|
||||
{
|
||||
"dataType": "bool",
|
||||
"name": "关",
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"dataType": "bool",
|
||||
"name": "开",
|
||||
"value": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
### 请求 /iot/product-thing-model/delete 接口 => 成功
|
||||
DELETE {{baseUrl}}/iot/product-thing-model/delete?id=36
|
||||
tenant-id: {{adminTenentId}}
|
||||
Authorization: Bearer {{token}}
|
||||
|
||||
### 请求 /iot/product-thing-model/get 接口 => 成功
|
||||
GET {{baseUrl}}/iot/product-thing-model/get?id=67
|
||||
tenant-id: {{adminTenentId}}
|
||||
Authorization: Bearer {{token}}
|
||||
|
||||
### 请求 /iot/product-thing-model/get-tsl 接口 => 成功
|
||||
GET {{baseUrl}}/iot/product-thing-model/get-tsl?productId=1001
|
||||
tenant-id: {{adminTenentId}}
|
||||
Authorization: Bearer {{token}}
|
||||
@@ -0,0 +1,111 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.thingmodel;
|
||||
|
||||
import cn.aagro.pp.framework.common.pojo.CommonResult;
|
||||
import cn.aagro.pp.framework.common.pojo.PageResult;
|
||||
import cn.aagro.pp.framework.common.util.object.BeanUtils;
|
||||
import cn.aagro.pp.module.iot.controller.admin.thingmodel.vo.*;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.product.IotProductDO;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.thingmodel.IotThingModelDO;
|
||||
import cn.aagro.pp.module.iot.enums.thingmodel.IotThingModelTypeEnum;
|
||||
import cn.aagro.pp.module.iot.service.product.IotProductService;
|
||||
import cn.aagro.pp.module.iot.service.thingmodel.IotThingModelService;
|
||||
import com.google.common.base.Objects;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.aagro.pp.framework.common.pojo.CommonResult.success;
|
||||
import static cn.aagro.pp.framework.common.util.collection.CollectionUtils.convertList;
|
||||
import static cn.aagro.pp.framework.common.util.collection.CollectionUtils.filterList;
|
||||
|
||||
@Tag(name = "管理后台 - IoT 产品物模型")
|
||||
@RestController
|
||||
@RequestMapping("/iot/thing-model")
|
||||
@Validated
|
||||
public class IotThingModelController {
|
||||
|
||||
@Resource
|
||||
private IotThingModelService thingModelService;
|
||||
@Resource
|
||||
private IotProductService productService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建产品物模型")
|
||||
@PreAuthorize("@ss.hasPermission('iot:thing-model:create')")
|
||||
public CommonResult<Long> createThingModel(@Valid @RequestBody IotThingModelSaveReqVO createReqVO) {
|
||||
return success(thingModelService.createThingModel(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新产品物模型")
|
||||
@PreAuthorize("@ss.hasPermission('iot:thing-model:update')")
|
||||
public CommonResult<Boolean> updateThingModel(@Valid @RequestBody IotThingModelSaveReqVO updateReqVO) {
|
||||
thingModelService.updateThingModel(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除产品物模型")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('iot:thing-model:delete')")
|
||||
public CommonResult<Boolean> deleteThingModel(@RequestParam("id") Long id) {
|
||||
thingModelService.deleteThingModel(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得产品物模型")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('iot:thing-model:query')")
|
||||
public CommonResult<IotThingModelRespVO> getThingModel(@RequestParam("id") Long id) {
|
||||
IotThingModelDO thingModel = thingModelService.getThingModel(id);
|
||||
return success(BeanUtils.toBean(thingModel, IotThingModelRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/get-tsl")
|
||||
@Operation(summary = "获得产品物模型 TSL")
|
||||
@Parameter(name = "productId", description = "产品 ID", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('iot:thing-model:query')")
|
||||
public CommonResult<IotThingModelTSLRespVO> getThingModelTsl(@RequestParam("productId") Long productId) {
|
||||
// 1. 获得产品
|
||||
IotProductDO product = productService.getProduct(productId);
|
||||
if (product == null) {
|
||||
return success(null);
|
||||
}
|
||||
IotThingModelTSLRespVO tslRespVO = new IotThingModelTSLRespVO()
|
||||
.setProductId(product.getId()).setProductKey(product.getProductKey());
|
||||
// 2. 获得物模型定义
|
||||
List<IotThingModelDO> thingModels = thingModelService.getThingModelListByProductId(productId);
|
||||
tslRespVO.setProperties(convertList(filterList(thingModels, item ->
|
||||
Objects.equal(IotThingModelTypeEnum.PROPERTY.getType(), item.getType())), IotThingModelDO::getProperty))
|
||||
.setServices(convertList(filterList(thingModels, item ->
|
||||
Objects.equal(IotThingModelTypeEnum.SERVICE.getType(), item.getType())), IotThingModelDO::getService))
|
||||
.setEvents(convertList(filterList(thingModels, item ->
|
||||
Objects.equal(IotThingModelTypeEnum.EVENT.getType(), item.getType())), IotThingModelDO::getEvent));
|
||||
return success(tslRespVO);
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
@Operation(summary = "获得产品物模型列表")
|
||||
@PreAuthorize("@ss.hasPermission('iot:thing-model:query')")
|
||||
public CommonResult<List<IotThingModelRespVO>> getThingModelListByProductId(@Valid IotThingModelListReqVO reqVO) {
|
||||
List<IotThingModelDO> list = thingModelService.getThingModelList(reqVO);
|
||||
return success(BeanUtils.toBean(list, IotThingModelRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得产品物模型分页")
|
||||
@PreAuthorize("@ss.hasPermission('iot:thing-model:query')")
|
||||
public CommonResult<PageResult<IotThingModelRespVO>> getThingModelPage(@Valid IotThingModelPageReqVO pageReqVO) {
|
||||
PageResult<IotThingModelDO> pageResult = thingModelService.getProductThingModelPage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, IotThingModelRespVO.class));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.thingmodel.vo;
|
||||
|
||||
import cn.aagro.pp.framework.common.validation.InEnum;
|
||||
import cn.aagro.pp.module.iot.enums.thingmodel.IotThingModelTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 产品物模型 List Request VO")
|
||||
@Data
|
||||
public class IotThingModelListReqVO {
|
||||
|
||||
@Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "产品编号不能为空")
|
||||
private Long productId;
|
||||
|
||||
@Schema(description = "功能标识", example = "temperature")
|
||||
private String identifier;
|
||||
|
||||
@Schema(description = "功能名称", example = "温度")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "功能类型", example = "1")
|
||||
@InEnum(IotThingModelTypeEnum.class)
|
||||
private Integer type;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.thingmodel.vo;
|
||||
|
||||
import cn.aagro.pp.framework.common.pojo.PageParam;
|
||||
import cn.aagro.pp.framework.common.validation.InEnum;
|
||||
import cn.aagro.pp.module.iot.enums.thingmodel.IotThingModelTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 产品物模型分页 Request VO")
|
||||
@Data
|
||||
public class IotThingModelPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "产品编号不能为空")
|
||||
private Long productId;
|
||||
|
||||
@Schema(description = "功能标识", example = "temperature")
|
||||
private String identifier;
|
||||
|
||||
@Schema(description = "功能名称", example = "温度")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "功能类型", example = "1")
|
||||
@InEnum(IotThingModelTypeEnum.class)
|
||||
private Integer type;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.thingmodel.vo;
|
||||
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.thingmodel.model.ThingModelEvent;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.thingmodel.model.ThingModelProperty;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.thingmodel.model.ThingModelService;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 产品物模型 Response VO")
|
||||
@Data
|
||||
public class IotThingModelRespVO {
|
||||
|
||||
@Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "21816")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long productId;
|
||||
|
||||
@Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "temperature_sensor")
|
||||
private String productKey;
|
||||
|
||||
@Schema(description = "功能标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "temperature")
|
||||
private String identifier;
|
||||
|
||||
@Schema(description = "功能名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "温度")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "功能描述", requiredMode = Schema.RequiredMode.REQUIRED, example = "测量当前环境温度")
|
||||
private String description;
|
||||
|
||||
@Schema(description = "功能类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer type;
|
||||
|
||||
@Schema(description = "属性", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private ThingModelProperty property;
|
||||
|
||||
@Schema(description = "服务", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private ThingModelEvent event;
|
||||
|
||||
@Schema(description = "事件", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private ThingModelService service;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.thingmodel.vo;
|
||||
|
||||
import cn.aagro.pp.framework.common.validation.InEnum;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.thingmodel.model.ThingModelEvent;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.thingmodel.model.ThingModelProperty;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.thingmodel.model.ThingModelService;
|
||||
import cn.aagro.pp.module.iot.enums.thingmodel.IotThingModelTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 产品物模型新增/修改 Request VO")
|
||||
@Data
|
||||
public class IotThingModelSaveReqVO {
|
||||
|
||||
@Schema(description = "编号", example = "1")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "产品ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "产品ID不能为空")
|
||||
private Long productId;
|
||||
|
||||
@Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "temperature_001")
|
||||
@NotEmpty(message = "产品标识不能为空")
|
||||
private String productKey;
|
||||
|
||||
@Schema(description = "功能标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "temp_monitor")
|
||||
@NotEmpty(message = "功能标识不能为空")
|
||||
private String identifier;
|
||||
|
||||
@Schema(description = "功能名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "温度监测器")
|
||||
@NotEmpty(message = "功能名称不能为空")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "功能描述", requiredMode = Schema.RequiredMode.REQUIRED, example = "用于监测环境温度的传感器")
|
||||
private String description;
|
||||
|
||||
@Schema(description = "功能类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "功能类型不能为空")
|
||||
@InEnum(IotThingModelTypeEnum.class)
|
||||
private Integer type;
|
||||
|
||||
@Schema(description = "属性", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Valid
|
||||
private ThingModelProperty property;
|
||||
|
||||
@Schema(description = "服务", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Valid
|
||||
private ThingModelService service;
|
||||
|
||||
@Schema(description = "事件", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Valid
|
||||
private ThingModelEvent event;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package cn.aagro.pp.module.iot.controller.admin.thingmodel.vo;
|
||||
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.thingmodel.model.ThingModelEvent;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.thingmodel.model.ThingModelProperty;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.thingmodel.model.ThingModelService;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 产品物模型 TSL Response VO")
|
||||
@Data
|
||||
public class IotThingModelTSLRespVO {
|
||||
|
||||
@Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long productId;
|
||||
|
||||
@Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "temperature_sensor")
|
||||
private String productKey;
|
||||
|
||||
@Schema(description = "属性列表", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private List<ThingModelProperty> properties;
|
||||
|
||||
@Schema(description = "服务列表", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private List<ThingModelEvent> events;
|
||||
|
||||
@Schema(description = "事件列表", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private List<ThingModelService> services;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* 提供 RESTful API 给前端:
|
||||
* 1. admin 包:提供给管理后台 aagro-ui-admin 前端项目
|
||||
* 2. app 包:提供给用户 APP aagro-ui-app 前端项目,它的 Controller 和 VO 都要添加 App 前缀,用于和管理后台进行区分
|
||||
*/
|
||||
package cn.aagro.pp.module.iot.controller;
|
||||
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* 提供 POJO 类的实体转换
|
||||
*
|
||||
* 目前使用 MapStruct 框架
|
||||
*/
|
||||
package cn.aagro.pp.module.iot.convert;
|
||||
@@ -0,0 +1,50 @@
|
||||
package cn.aagro.pp.module.iot.convert.thingmodel;
|
||||
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.thingmodel.model.ThingModelEvent;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.thingmodel.model.ThingModelProperty;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.thingmodel.model.ThingModelService;
|
||||
import cn.aagro.pp.module.iot.controller.admin.thingmodel.vo.IotThingModelSaveReqVO;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.thingmodel.IotThingModelDO;
|
||||
import cn.aagro.pp.module.iot.enums.thingmodel.IotThingModelTypeEnum;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.Named;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@Mapper
|
||||
public interface IotThingModelConvert {
|
||||
|
||||
IotThingModelConvert INSTANCE = Mappers.getMapper(IotThingModelConvert.class);
|
||||
|
||||
@Mapping(target = "property", expression = "java(convertToProperty(bean))")
|
||||
@Mapping(target = "event", expression = "java(convertToEvent(bean))")
|
||||
@Mapping(target = "service", expression = "java(convertToService(bean))")
|
||||
IotThingModelDO convert(IotThingModelSaveReqVO bean);
|
||||
|
||||
@Named("convertToProperty")
|
||||
default ThingModelProperty convertToProperty(IotThingModelSaveReqVO bean) {
|
||||
if (Objects.equals(bean.getType(), IotThingModelTypeEnum.PROPERTY.getType())) {
|
||||
return bean.getProperty();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Named("convertToEvent")
|
||||
default ThingModelEvent convertToEvent(IotThingModelSaveReqVO bean) {
|
||||
if (Objects.equals(bean.getType(), IotThingModelTypeEnum.EVENT.getType())) {
|
||||
return bean.getEvent();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Named("convertToService")
|
||||
default ThingModelService convertToService(IotThingModelSaveReqVO bean) {
|
||||
if (Objects.equals(bean.getType(), IotThingModelTypeEnum.SERVICE.getType())) {
|
||||
return bean.getService();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package cn.aagro.pp.module.iot.dal.dataobject.alert;
|
||||
|
||||
import cn.aagro.pp.framework.common.enums.CommonStatusEnum;
|
||||
import cn.aagro.pp.framework.mybatis.core.dataobject.BaseDO;
|
||||
import cn.aagro.pp.framework.mybatis.core.type.IntegerListTypeHandler;
|
||||
import cn.aagro.pp.framework.mybatis.core.type.LongListTypeHandler;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.rule.IotSceneRuleDO;
|
||||
import cn.aagro.pp.module.iot.enums.DictTypeConstants;
|
||||
import cn.aagro.pp.module.iot.enums.alert.IotAlertReceiveTypeEnum;
|
||||
import cn.aagro.pp.module.system.api.user.dto.AdminUserRespDTO;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* IoT 告警配置 DO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@TableName(value = "iot_alert_config", autoResultMap = true)
|
||||
@KeySequence("iot_alert_config_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class IotAlertConfigDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 配置编号
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 配置名称
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 配置描述
|
||||
*/
|
||||
private String description;
|
||||
/**
|
||||
* 配置状态
|
||||
*
|
||||
* 字典 {@link DictTypeConstants#ALERT_LEVEL}
|
||||
*/
|
||||
private Integer level;
|
||||
/**
|
||||
* 配置状态
|
||||
*
|
||||
* 枚举 {@link CommonStatusEnum}
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 关联的场景联动规则编号数组
|
||||
*
|
||||
* 关联 {@link IotSceneRuleDO#getId()}
|
||||
*/
|
||||
@TableField(typeHandler = LongListTypeHandler.class)
|
||||
private List<Long> sceneRuleIds;
|
||||
|
||||
/**
|
||||
* 接收的用户编号数组
|
||||
*
|
||||
* 关联 {@link AdminUserRespDTO#getId()}
|
||||
*/
|
||||
@TableField(typeHandler = LongListTypeHandler.class)
|
||||
private List<Long> receiveUserIds;
|
||||
/**
|
||||
* 接收的类型数组
|
||||
*
|
||||
* 枚举 {@link IotAlertReceiveTypeEnum}
|
||||
*/
|
||||
@TableField(typeHandler = IntegerListTypeHandler.class)
|
||||
private List<Integer> receiveTypes;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package cn.aagro.pp.module.iot.dal.dataobject.alert;
|
||||
|
||||
import cn.aagro.pp.framework.mybatis.core.dataobject.BaseDO;
|
||||
import cn.aagro.pp.module.iot.core.mq.message.IotDeviceMessage;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.device.IotDeviceDO;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.product.IotProductDO;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.rule.IotSceneRuleDO;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* IoT 告警记录 DO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@TableName(value = "iot_alert_record", autoResultMap = true)
|
||||
@KeySequence("iot_alert_record_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class IotAlertRecordDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 记录编号
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 告警名称
|
||||
*
|
||||
* 冗余 {@link IotAlertConfigDO#getId()}
|
||||
*/
|
||||
private Long configId;
|
||||
/**
|
||||
* 告警名称
|
||||
*
|
||||
* 冗余 {@link IotAlertConfigDO#getName()}
|
||||
*/
|
||||
private String configName;
|
||||
/**
|
||||
* 告警级别
|
||||
*
|
||||
* 冗余 {@link IotAlertConfigDO#getLevel()}
|
||||
* 字典 {@link cn.aagro.pp.module.iot.enums.DictTypeConstants#ALERT_LEVEL}
|
||||
*/
|
||||
private Integer configLevel;
|
||||
/**
|
||||
* 场景规则编号
|
||||
*
|
||||
* 关联 {@link IotSceneRuleDO#getId()}
|
||||
*/
|
||||
private Long sceneRuleId;
|
||||
|
||||
/**
|
||||
* 产品编号
|
||||
*
|
||||
* 关联 {@link IotProductDO#getId()}
|
||||
*/
|
||||
private Long productId;
|
||||
/**
|
||||
* 设备编号
|
||||
*
|
||||
* 关联 {@link IotDeviceDO#getId()}
|
||||
*/
|
||||
private Long deviceId;
|
||||
/**
|
||||
* 触发的设备消息
|
||||
*/
|
||||
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||
private IotDeviceMessage deviceMessage;
|
||||
|
||||
/**
|
||||
* 是否处理
|
||||
*/
|
||||
private Boolean processStatus;
|
||||
/**
|
||||
* 处理结果(备注)
|
||||
*/
|
||||
private String processRemark;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
package cn.aagro.pp.module.iot.dal.dataobject.device;
|
||||
|
||||
import cn.aagro.pp.framework.mybatis.core.type.LongSetTypeHandler;
|
||||
import cn.aagro.pp.framework.tenant.core.db.TenantBaseDO;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.ota.IotOtaFirmwareDO;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.product.IotProductDO;
|
||||
import cn.aagro.pp.module.iot.core.enums.IotDeviceStateEnum;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* IoT 设备 DO
|
||||
*
|
||||
* @author haohao
|
||||
*/
|
||||
@TableName(value = "iot_device", autoResultMap = true)
|
||||
@KeySequence("iot_device_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class IotDeviceDO extends TenantBaseDO {
|
||||
|
||||
/**
|
||||
* 设备编号 - 全部设备
|
||||
*/
|
||||
public static final Long DEVICE_ID_ALL = 0L;
|
||||
|
||||
/**
|
||||
* 设备 ID,主键,自增
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 设备名称,在产品内唯一,用于标识设备
|
||||
*/
|
||||
private String deviceName;
|
||||
/**
|
||||
* 设备备注名称
|
||||
*/
|
||||
private String nickname;
|
||||
/**
|
||||
* 设备序列号
|
||||
*/
|
||||
private String serialNumber;
|
||||
/**
|
||||
* 设备图片
|
||||
*/
|
||||
private String picUrl;
|
||||
/**
|
||||
* 设备分组编号集合
|
||||
*
|
||||
* 关联 {@link IotDeviceGroupDO#getId()}
|
||||
*/
|
||||
@TableField(typeHandler = LongSetTypeHandler.class)
|
||||
private Set<Long> groupIds;
|
||||
|
||||
/**
|
||||
* 产品编号
|
||||
* <p>
|
||||
* 关联 {@link IotProductDO#getId()}
|
||||
*/
|
||||
private Long productId;
|
||||
/**
|
||||
* 产品标识
|
||||
* <p>
|
||||
* 冗余 {@link IotProductDO#getProductKey()}
|
||||
*/
|
||||
private String productKey;
|
||||
/**
|
||||
* 设备类型
|
||||
* <p>
|
||||
* 冗余 {@link IotProductDO#getDeviceType()}
|
||||
*/
|
||||
private Integer deviceType;
|
||||
/**
|
||||
* 网关设备编号
|
||||
* <p>
|
||||
* 子设备需要关联的网关设备 ID
|
||||
* <p>
|
||||
* 关联 {@link IotDeviceDO#getId()}
|
||||
*/
|
||||
private Long gatewayId;
|
||||
|
||||
/**
|
||||
* 设备状态
|
||||
* <p>
|
||||
* 枚举 {@link IotDeviceStateEnum}
|
||||
*/
|
||||
private Integer state;
|
||||
/**
|
||||
* 最后上线时间
|
||||
*/
|
||||
private LocalDateTime onlineTime;
|
||||
/**
|
||||
* 最后离线时间
|
||||
*/
|
||||
private LocalDateTime offlineTime;
|
||||
/**
|
||||
* 设备激活时间
|
||||
*/
|
||||
private LocalDateTime activeTime;
|
||||
|
||||
/**
|
||||
* 设备的 IP 地址
|
||||
*/
|
||||
private String ip;
|
||||
/**
|
||||
* 固件编号
|
||||
*
|
||||
* 关联 {@link IotOtaFirmwareDO#getId()}
|
||||
*/
|
||||
private Long firmwareId;
|
||||
|
||||
/**
|
||||
* 设备密钥,用于设备认证
|
||||
*/
|
||||
private String deviceSecret;
|
||||
/**
|
||||
* 认证类型(如一机一密、动态注册)
|
||||
*/
|
||||
// TODO @haohao:是不是要枚举哈
|
||||
private String authType;
|
||||
|
||||
/**
|
||||
* 定位方式
|
||||
* <p>
|
||||
* 枚举 {@link cn.aagro.pp.module.iot.enums.product.IotLocationTypeEnum}
|
||||
*/
|
||||
private Integer locationType;
|
||||
/**
|
||||
* 设备位置的纬度
|
||||
*/
|
||||
private BigDecimal latitude;
|
||||
/**
|
||||
* 设备位置的经度
|
||||
*/
|
||||
private BigDecimal longitude;
|
||||
/**
|
||||
* 地区编码
|
||||
* <p>
|
||||
* 关联 Area 的 id
|
||||
*/
|
||||
private Integer areaId;
|
||||
/**
|
||||
* 设备详细地址
|
||||
*/
|
||||
private String address;
|
||||
|
||||
/**
|
||||
* 设备配置
|
||||
*
|
||||
* JSON 格式,可下发给 device 进行自定义配置
|
||||
*/
|
||||
private String config;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package cn.aagro.pp.module.iot.dal.dataobject.device;
|
||||
|
||||
import cn.aagro.pp.framework.mybatis.core.dataobject.BaseDO;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.*;
|
||||
|
||||
/**
|
||||
* IoT 设备分组 DO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@TableName("iot_device_group")
|
||||
@KeySequence("iot_device_group_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class IotDeviceGroupDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 分组 ID
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 分组名字
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 分组状态
|
||||
*
|
||||
* 枚举 {@link cn.aagro.pp.framework.common.enums.CommonStatusEnum}
|
||||
*/
|
||||
private Integer status;
|
||||
/**
|
||||
* 分组描述
|
||||
*/
|
||||
private String description;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
package cn.aagro.pp.module.iot.dal.dataobject.device;
|
||||
|
||||
import cn.aagro.pp.module.iot.core.enums.IotDeviceMessageMethodEnum;
|
||||
import cn.aagro.pp.module.iot.core.mq.message.IotDeviceMessage;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.thingmodel.IotThingModelDO;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* IoT 设备消息数据 DO
|
||||
*
|
||||
* 目前使用 TDengine 存储
|
||||
*
|
||||
* @author alwayssuper
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class IotDeviceMessageDO {
|
||||
|
||||
/**
|
||||
* 消息编号
|
||||
*/
|
||||
private String id;
|
||||
/**
|
||||
* 上报时间戳
|
||||
*/
|
||||
private Long reportTime;
|
||||
/**
|
||||
* 存储时间戳
|
||||
*/
|
||||
private Long ts;
|
||||
|
||||
/**
|
||||
* 设备编号
|
||||
*
|
||||
* 关联 {@link IotDeviceDO#getId()}
|
||||
*/
|
||||
private Long deviceId;
|
||||
/**
|
||||
* 租户编号
|
||||
*/
|
||||
private Long tenantId;
|
||||
|
||||
/**
|
||||
* 服务编号,该消息由哪个 server 发送
|
||||
*/
|
||||
private String serverId;
|
||||
|
||||
/**
|
||||
* 是否上行消息
|
||||
*
|
||||
* 由 {@link cn.aagro.pp.module.iot.core.util.IotDeviceMessageUtils#isUpstreamMessage(IotDeviceMessage)} 计算。
|
||||
* 计算并存储的目的:方便计算多少条上行、多少条下行
|
||||
*/
|
||||
private Boolean upstream;
|
||||
/**
|
||||
* 是否回复消息
|
||||
*
|
||||
* 由 {@link cn.aagro.pp.module.iot.core.util.IotDeviceMessageUtils#isReplyMessage(IotDeviceMessage)} 计算。
|
||||
* 计算并存储的目的:方便计算多少条请求、多少条回复
|
||||
*/
|
||||
private Boolean reply;
|
||||
/**
|
||||
* 标识符
|
||||
*
|
||||
* 例如说:{@link IotThingModelDO#getIdentifier()}
|
||||
* 目前,只有事件上报、服务调用才有!!!
|
||||
*/
|
||||
private String identifier;
|
||||
|
||||
// ========== codec(编解码)字段 ==========
|
||||
|
||||
/**
|
||||
* 请求编号
|
||||
*
|
||||
* 由设备生成,对应阿里云 IoT 的 Alink 协议中的 id、华为云 IoTDA 协议的 request_id
|
||||
*/
|
||||
private String requestId;
|
||||
/**
|
||||
* 请求方法
|
||||
*
|
||||
* 枚举 {@link IotDeviceMessageMethodEnum}
|
||||
* 例如说:thing.property.report 属性上报
|
||||
*/
|
||||
private String method;
|
||||
/**
|
||||
* 请求参数
|
||||
*
|
||||
* 例如说:属性上报的 properties、事件上报的 params
|
||||
*/
|
||||
private Object params;
|
||||
/**
|
||||
* 响应结果
|
||||
*/
|
||||
private Object data;
|
||||
/**
|
||||
* 响应错误码
|
||||
*/
|
||||
private Integer code;
|
||||
/**
|
||||
* 响应提示
|
||||
*/
|
||||
private String msg;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package cn.aagro.pp.module.iot.dal.dataobject.device;
|
||||
|
||||
import cn.aagro.pp.module.iot.dal.redis.device.DevicePropertyRedisDAO;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* IoT 设备属性项 Redis DO
|
||||
*
|
||||
* @see cn.aagro.pp.module.iot.dal.redis.RedisKeyConstants#DEVICE_PROPERTY
|
||||
* @see DevicePropertyRedisDAO
|
||||
*
|
||||
* @author haohao
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class IotDevicePropertyDO {
|
||||
|
||||
/**
|
||||
* 属性值(最新)
|
||||
*/
|
||||
private Object value;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package cn.aagro.pp.module.iot.dal.dataobject.ota;
|
||||
|
||||
import cn.hutool.crypto.digest.DigestAlgorithm;
|
||||
import cn.aagro.pp.framework.mybatis.core.dataobject.BaseDO;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* IoT OTA 固件 DO
|
||||
*
|
||||
* @see <a href="阿里云 IoT - OTA 升级">https://help.aliyun.com/zh/iot/user-guide/ota-upgrade-overview</a>
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@TableName(value = "iot_ota_firmware", autoResultMap = true)
|
||||
@KeySequence("iot_ota_firmware_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class IotOtaFirmwareDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 固件编号
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 固件名称
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 固件描述
|
||||
*/
|
||||
private String description;
|
||||
/**
|
||||
* 版本号
|
||||
*/
|
||||
private String version;
|
||||
|
||||
/**
|
||||
* 产品编号
|
||||
*
|
||||
* 关联 {@link cn.aagro.pp.module.iot.dal.dataobject.product.IotProductDO#getId()}
|
||||
*/
|
||||
private Long productId;
|
||||
|
||||
/**
|
||||
* 固件文件 URL
|
||||
*/
|
||||
private String fileUrl;
|
||||
/**
|
||||
* 固件文件大小
|
||||
*/
|
||||
private Long fileSize;
|
||||
/**
|
||||
* 固件文件签名算法
|
||||
*
|
||||
* 枚举 {@link DigestAlgorithm},目前只使用 MD5
|
||||
*/
|
||||
private String fileDigestAlgorithm;
|
||||
/**
|
||||
* 固件文件签名结果
|
||||
*/
|
||||
private String fileDigestValue;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package cn.aagro.pp.module.iot.dal.dataobject.ota;
|
||||
|
||||
import cn.aagro.pp.framework.mybatis.core.dataobject.BaseDO;
|
||||
import cn.aagro.pp.module.iot.enums.ota.IotOtaTaskDeviceScopeEnum;
|
||||
import cn.aagro.pp.module.iot.enums.ota.IotOtaTaskStatusEnum;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* IoT OTA 升级任务 DO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@TableName(value = "iot_ota_task", autoResultMap = true)
|
||||
@KeySequence("iot_ota_task_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class IotOtaTaskDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 任务编号
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 任务名称
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 任务描述
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 固件编号
|
||||
* <p>
|
||||
* 关联 {@link IotOtaFirmwareDO#getId()}
|
||||
*/
|
||||
private Long firmwareId;
|
||||
|
||||
/**
|
||||
* 任务状态
|
||||
* <p>
|
||||
* 关联 {@link IotOtaTaskStatusEnum}
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 设备升级范围
|
||||
* <p>
|
||||
* 关联 {@link IotOtaTaskDeviceScopeEnum}
|
||||
*/
|
||||
private Integer deviceScope;
|
||||
/**
|
||||
* 设备总数数量
|
||||
*/
|
||||
private Integer deviceTotalCount;
|
||||
/**
|
||||
* 设备成功数量
|
||||
*/
|
||||
private Integer deviceSuccessCount;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package cn.aagro.pp.module.iot.dal.dataobject.ota;
|
||||
|
||||
import cn.aagro.pp.framework.mybatis.core.dataobject.BaseDO;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.device.IotDeviceDO;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.device.IotDeviceMessageDO;
|
||||
import cn.aagro.pp.module.iot.enums.ota.IotOtaTaskRecordStatusEnum;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* IoT OTA 升级任务记录 DO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@TableName(value = "iot_ota_task_record", autoResultMap = true)
|
||||
@KeySequence("iot_ota_task_record_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class IotOtaTaskRecordDO extends BaseDO {
|
||||
|
||||
public static final String DESCRIPTION_CANCEL_BY_TASK = "管理员手动取消升级任务(批量)";
|
||||
|
||||
public static final String DESCRIPTION_CANCEL_BY_RECORD = "管理员手动取消升级记录(单个)";
|
||||
|
||||
/**
|
||||
* 升级记录编号
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 固件编号
|
||||
*
|
||||
* 关联 {@link IotOtaFirmwareDO#getId()}
|
||||
*/
|
||||
private Long firmwareId;
|
||||
/**
|
||||
* 任务编号
|
||||
*
|
||||
* 关联 {@link IotOtaTaskDO#getId()}
|
||||
*/
|
||||
private Long taskId;
|
||||
|
||||
/**
|
||||
* 设备编号
|
||||
*
|
||||
* 关联 {@link IotDeviceDO#getId()}
|
||||
*/
|
||||
private Long deviceId;
|
||||
/**
|
||||
* 来源的固件编号
|
||||
*
|
||||
* 关联 {@link IotDeviceDO#getFirmwareId()}
|
||||
*/
|
||||
private Long fromFirmwareId;
|
||||
|
||||
/**
|
||||
* 升级状态
|
||||
*
|
||||
* 关联 {@link IotOtaTaskRecordStatusEnum}
|
||||
*/
|
||||
private Integer status;
|
||||
/**
|
||||
* 升级进度,百分比
|
||||
*/
|
||||
private Integer progress;
|
||||
/**
|
||||
* 升级进度描述
|
||||
*
|
||||
* 注意,只记录设备最后一次的升级进度描述
|
||||
* 如果想看历史记录,可以查看 {@link IotDeviceMessageDO} 设备日志
|
||||
*/
|
||||
private String description;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package cn.aagro.pp.module.iot.dal.dataobject.product;
|
||||
|
||||
import cn.aagro.pp.framework.mybatis.core.dataobject.BaseDO;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.*;
|
||||
|
||||
/**
|
||||
* IoT 产品分类 DO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@TableName("iot_product_category")
|
||||
@KeySequence("iot_product_category_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class IotProductCategoryDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 分类 ID
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 分类名字
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 分类排序
|
||||
*/
|
||||
private Integer sort;
|
||||
/**
|
||||
* 分类状态
|
||||
*
|
||||
* 枚举 {@link cn.aagro.pp.framework.common.enums.CommonStatusEnum}
|
||||
*/
|
||||
private Integer status;
|
||||
/**
|
||||
* 分类描述
|
||||
*/
|
||||
private String description;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package cn.aagro.pp.module.iot.dal.dataobject.product;
|
||||
|
||||
import cn.aagro.pp.framework.tenant.core.db.TenantBaseDO;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.*;
|
||||
|
||||
/**
|
||||
* IoT 产品 DO
|
||||
*
|
||||
* @author ahh
|
||||
*/
|
||||
@TableName("iot_product")
|
||||
@KeySequence("iot_product_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class IotProductDO extends TenantBaseDO {
|
||||
|
||||
/**
|
||||
* 产品 ID
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 产品名称
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 产品标识
|
||||
*/
|
||||
private String productKey;
|
||||
/**
|
||||
* 产品分类编号
|
||||
* <p>
|
||||
* 关联 {@link IotProductCategoryDO#getId()}
|
||||
*/
|
||||
private Long categoryId;
|
||||
/**
|
||||
* 产品图标
|
||||
*/
|
||||
private String icon;
|
||||
/**
|
||||
* 产品图片
|
||||
*/
|
||||
private String picUrl;
|
||||
/**
|
||||
* 产品描述
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 产品状态
|
||||
* <p>
|
||||
* 枚举 {@link cn.aagro.pp.module.iot.enums.product.IotProductStatusEnum}
|
||||
*/
|
||||
private Integer status;
|
||||
/**
|
||||
* 设备类型
|
||||
* <p>
|
||||
* 枚举 {@link cn.aagro.pp.module.iot.enums.product.IotProductDeviceTypeEnum}
|
||||
*/
|
||||
private Integer deviceType;
|
||||
/**
|
||||
* 联网方式
|
||||
* <p>
|
||||
* 枚举 {@link cn.aagro.pp.module.iot.enums.product.IotNetTypeEnum}
|
||||
*/
|
||||
private Integer netType;
|
||||
/**
|
||||
* 定位方式
|
||||
* <p>
|
||||
* 枚举 {@link cn.aagro.pp.module.iot.enums.product.IotLocationTypeEnum}
|
||||
*/
|
||||
private Integer locationType;
|
||||
/**
|
||||
* 数据格式(编解码器类型)
|
||||
* <p>
|
||||
* 字典 {@link cn.aagro.pp.module.iot.enums.DictTypeConstants#CODEC_TYPE}
|
||||
*
|
||||
* 目的:用于 gateway-server 解析消息格式
|
||||
*/
|
||||
private String codecType;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
package cn.aagro.pp.module.iot.dal.dataobject.rule;
|
||||
|
||||
import cn.aagro.pp.framework.common.enums.CommonStatusEnum;
|
||||
import cn.aagro.pp.framework.mybatis.core.dataobject.BaseDO;
|
||||
import cn.aagro.pp.framework.mybatis.core.type.LongListTypeHandler;
|
||||
import cn.aagro.pp.module.iot.core.enums.IotDeviceMessageMethodEnum;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.device.IotDeviceDO;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.product.IotProductDO;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.thingmodel.IotThingModelDO;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* IoT 数据流转规则 DO
|
||||
*
|
||||
* 监听 {@link SourceConfig} 数据源,转发到 {@link IotDataSinkDO} 数据目的
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@TableName(value = "iot_data_rule", autoResultMap = true)
|
||||
@KeySequence("iot_data_rule_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class IotDataRuleDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 数据流转规格编号
|
||||
*/
|
||||
private Long id;
|
||||
/**
|
||||
* 数据流转规格名称
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 数据流转规格描述
|
||||
*/
|
||||
private String description;
|
||||
/**
|
||||
* 数据流转规格状态
|
||||
*
|
||||
* 枚举 {@link CommonStatusEnum}
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 数据源配置数组
|
||||
*/
|
||||
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||
private List<SourceConfig> sourceConfigs;
|
||||
/**
|
||||
* 数据目的编号数组
|
||||
*
|
||||
* 关联 {@link IotDataSinkDO#getId()}
|
||||
*/
|
||||
@TableField(typeHandler = LongListTypeHandler.class)
|
||||
private List<Long> sinkIds;
|
||||
|
||||
// TODO @芋艿:未来考虑使用 groovy;支持数据处理;
|
||||
|
||||
/**
|
||||
* 数据源配置
|
||||
*/
|
||||
@Data
|
||||
public static class SourceConfig {
|
||||
|
||||
/**
|
||||
* 消息方法
|
||||
*
|
||||
* 枚举 {@link IotDeviceMessageMethodEnum} 中的 upstream 上行部分
|
||||
*/
|
||||
@NotEmpty(message = "消息方法不能为空")
|
||||
private String method;
|
||||
|
||||
/**
|
||||
* 产品编号
|
||||
*
|
||||
* 关联 {@link IotProductDO#getId()}
|
||||
*/
|
||||
private Long productId;
|
||||
/**
|
||||
* 设备编号
|
||||
*
|
||||
* 关联 {@link IotDeviceDO#getId()}
|
||||
* 特殊:如果为 {@link IotDeviceDO#DEVICE_ID_ALL} 时,则是全部设备
|
||||
*/
|
||||
@NotEmpty(message = "设备编号不能为空")
|
||||
private Long deviceId;
|
||||
|
||||
/**
|
||||
* 标识符
|
||||
*
|
||||
* 1. 物模型时,对应:{@link IotThingModelDO#getIdentifier()}
|
||||
*/
|
||||
private String identifier;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package cn.aagro.pp.module.iot.dal.dataobject.rule;
|
||||
|
||||
import cn.aagro.pp.framework.common.enums.CommonStatusEnum;
|
||||
import cn.aagro.pp.framework.mybatis.core.dataobject.BaseDO;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.rule.config.IotAbstractDataSinkConfig;
|
||||
import cn.aagro.pp.module.iot.enums.rule.IotDataSinkTypeEnum;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* IoT 数据流转目的 DO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@TableName(value = "iot_data_sink", autoResultMap = true)
|
||||
@KeySequence("iot_data_bridge_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class IotDataSinkDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 数据流转目的编号
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 数据流转目的名称
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 数据流转目的描述
|
||||
*/
|
||||
private String description;
|
||||
/**
|
||||
* 数据流转目的状态
|
||||
*
|
||||
* 枚举 {@link CommonStatusEnum}
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 数据流转目的类型
|
||||
*
|
||||
* 枚举 {@link IotDataSinkTypeEnum}
|
||||
*/
|
||||
private Integer type;
|
||||
/**
|
||||
* 数据流转目的配置
|
||||
*/
|
||||
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||
private IotAbstractDataSinkConfig config;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,245 @@
|
||||
package cn.aagro.pp.module.iot.dal.dataobject.rule;
|
||||
|
||||
import cn.aagro.pp.framework.common.enums.CommonStatusEnum;
|
||||
import cn.aagro.pp.framework.tenant.core.db.TenantBaseDO;
|
||||
import cn.aagro.pp.module.iot.core.mq.message.IotDeviceMessage;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.alert.IotAlertConfigDO;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.device.IotDeviceDO;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.product.IotProductDO;
|
||||
import cn.aagro.pp.module.iot.dal.dataobject.thingmodel.IotThingModelDO;
|
||||
import cn.aagro.pp.module.iot.enums.rule.IotSceneRuleActionTypeEnum;
|
||||
import cn.aagro.pp.module.iot.enums.rule.IotSceneRuleConditionOperatorEnum;
|
||||
import cn.aagro.pp.module.iot.enums.rule.IotSceneRuleConditionTypeEnum;
|
||||
import cn.aagro.pp.module.iot.enums.rule.IotSceneRuleTriggerTypeEnum;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* IoT 场景联动规则 DO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@TableName(value = "iot_scene_rule", autoResultMap = true)
|
||||
@KeySequence("iot_scene_rule_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class IotSceneRuleDO extends TenantBaseDO {
|
||||
|
||||
/**
|
||||
* 场景联动编号
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 场景联动名称
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 场景联动描述
|
||||
*/
|
||||
private String description;
|
||||
/**
|
||||
* 场景联动状态
|
||||
*
|
||||
* 枚举 {@link CommonStatusEnum}
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 场景定义配置
|
||||
*/
|
||||
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||
private List<Trigger> triggers;
|
||||
|
||||
/**
|
||||
* 场景动作配置
|
||||
*/
|
||||
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||
private List<Action> actions;
|
||||
|
||||
/**
|
||||
* 场景定义配置
|
||||
*/
|
||||
@Data
|
||||
public static class Trigger {
|
||||
|
||||
// ========== 事件部分 ==========
|
||||
|
||||
/**
|
||||
* 场景事件类型
|
||||
*
|
||||
* 枚举 {@link IotSceneRuleTriggerTypeEnum}
|
||||
* 1. {@link IotSceneRuleTriggerTypeEnum#DEVICE_STATE_UPDATE} 时,operator 非空,并且 value 为在线状态
|
||||
* 2. {@link IotSceneRuleTriggerTypeEnum#DEVICE_PROPERTY_POST}
|
||||
* {@link IotSceneRuleTriggerTypeEnum#DEVICE_EVENT_POST} 时,identifier、operator 非空,并且 value 为属性值
|
||||
* 3. {@link IotSceneRuleTriggerTypeEnum#DEVICE_EVENT_POST}
|
||||
* {@link IotSceneRuleTriggerTypeEnum#DEVICE_SERVICE_INVOKE} 时,identifier 非空,但是 operator、value 为空
|
||||
* 4. {@link IotSceneRuleTriggerTypeEnum#TIMER} 时,conditions 非空,并且设备无关(无需 productId、deviceId 字段)
|
||||
*/
|
||||
private Integer type;
|
||||
|
||||
/**
|
||||
* 产品编号
|
||||
*
|
||||
* 关联 {@link IotProductDO#getId()}
|
||||
*/
|
||||
private Long productId;
|
||||
/**
|
||||
* 设备编号
|
||||
*
|
||||
* 关联 {@link IotDeviceDO#getId()}
|
||||
* 特殊:如果为 {@link IotDeviceDO#DEVICE_ID_ALL} 时,则是全部设备
|
||||
*/
|
||||
private Long deviceId;
|
||||
/**
|
||||
* 物模型标识符
|
||||
*
|
||||
* 对应:{@link IotThingModelDO#getIdentifier()}
|
||||
*/
|
||||
private String identifier;
|
||||
/**
|
||||
* 操作符
|
||||
*
|
||||
* 枚举 {@link IotSceneRuleConditionOperatorEnum}
|
||||
*/
|
||||
private String operator;
|
||||
/**
|
||||
* 参数(属性值、在线状态)
|
||||
* <p>
|
||||
* 如果有多个值,则使用 "," 分隔,类似 "1,2,3"。
|
||||
* 例如说,{@link IotSceneRuleConditionOperatorEnum#IN}、{@link IotSceneRuleConditionOperatorEnum#BETWEEN}
|
||||
*/
|
||||
private String value;
|
||||
|
||||
/**
|
||||
* CRON 表达式
|
||||
*/
|
||||
private String cronExpression;
|
||||
|
||||
// ========== 条件部分 ==========
|
||||
|
||||
/**
|
||||
* 触发条件分组(状态条件分组)的数组
|
||||
* <p>
|
||||
* 第一层 List:分组与分组之间,是“或”的关系
|
||||
* 第二层 List:条件与条件之间,是“且”的关系
|
||||
*/
|
||||
private List<List<TriggerCondition>> conditionGroups;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 触发条件(状态条件)
|
||||
*/
|
||||
@Data
|
||||
public static class TriggerCondition {
|
||||
|
||||
/**
|
||||
* 触发条件类型
|
||||
*
|
||||
* 枚举 {@link IotSceneRuleConditionTypeEnum}
|
||||
* 1. {@link IotSceneRuleConditionTypeEnum#DEVICE_STATE} 时,operator 非空,并且 value 为在线状态
|
||||
* 2. {@link IotSceneRuleConditionTypeEnum#DEVICE_PROPERTY} 时,identifier、operator 非空,并且 value 为属性值
|
||||
* 3. {@link IotSceneRuleConditionTypeEnum#CURRENT_TIME} 时,operator 非空(使用 DATE_TIME_ 和 TIME_ 部分),并且 value 非空
|
||||
*/
|
||||
private Integer type;
|
||||
|
||||
/**
|
||||
* 产品编号
|
||||
*
|
||||
* 关联 {@link IotProductDO#getId()}
|
||||
*/
|
||||
private Long productId;
|
||||
/**
|
||||
* 设备编号
|
||||
*
|
||||
* 关联 {@link IotDeviceDO#getId()}
|
||||
*/
|
||||
private Long deviceId;
|
||||
/**
|
||||
* 标识符(属性)
|
||||
*
|
||||
* 关联 {@link IotThingModelDO#getIdentifier()}
|
||||
*/
|
||||
private String identifier;
|
||||
/**
|
||||
* 操作符
|
||||
*
|
||||
* 枚举 {@link IotSceneRuleConditionOperatorEnum}
|
||||
*/
|
||||
private String operator;
|
||||
/**
|
||||
* 参数
|
||||
*
|
||||
* 如果有多个值,则使用 "," 分隔,类似 "1,2,3"。
|
||||
* 例如说,{@link IotSceneRuleConditionOperatorEnum#IN}、{@link IotSceneRuleConditionOperatorEnum#BETWEEN}
|
||||
*/
|
||||
private String param;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 场景动作配置
|
||||
*/
|
||||
@Data
|
||||
public static class Action {
|
||||
|
||||
/**
|
||||
* 执行类型
|
||||
*
|
||||
* 枚举 {@link IotSceneRuleActionTypeEnum}
|
||||
* 1. {@link IotSceneRuleActionTypeEnum#DEVICE_PROPERTY_SET} 时,params 非空
|
||||
* {@link IotSceneRuleActionTypeEnum#DEVICE_SERVICE_INVOKE} 时,params 非空
|
||||
* 2. {@link IotSceneRuleActionTypeEnum#ALERT_TRIGGER} 时,alertConfigId 为空,因为是 {@link IotAlertConfigDO} 里面关联它
|
||||
* 3. {@link IotSceneRuleActionTypeEnum#ALERT_RECOVER} 时,alertConfigId 非空
|
||||
*/
|
||||
private Integer type;
|
||||
|
||||
/**
|
||||
* 产品编号
|
||||
*
|
||||
* 关联 {@link IotProductDO#getId()}
|
||||
*/
|
||||
private Long productId;
|
||||
/**
|
||||
* 设备编号
|
||||
*
|
||||
* 关联 {@link IotDeviceDO#getId()}
|
||||
*/
|
||||
private Long deviceId;
|
||||
|
||||
/**
|
||||
* 标识符(服务)
|
||||
* <p>
|
||||
* 关联 {@link IotThingModelDO#getIdentifier()}
|
||||
*/
|
||||
private String identifier;
|
||||
|
||||
/**
|
||||
* 请求参数
|
||||
*
|
||||
* 一般来说,对应 {@link IotDeviceMessage#getParams()} 请求参数
|
||||
*/
|
||||
private String params;
|
||||
|
||||
/**
|
||||
* 告警配置编号
|
||||
*
|
||||
* 关联 {@link IotAlertConfigDO#getId()}
|
||||
*/
|
||||
private Long alertConfigId;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package cn.aagro.pp.module.iot.dal.dataobject.rule.config;
|
||||
|
||||
import cn.aagro.pp.module.iot.enums.rule.IotDataSinkTypeEnum;
|
||||
import com.fasterxml.jackson.annotation.JsonSubTypes;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* IoT IotDataBridgeConfig 抽象类
|
||||
*
|
||||
* 用于表示数据目的配置数据的通用类型,根据具体的 "type" 字段动态映射到对应的子类
|
||||
* 提供多态支持,适用于不同类型的数据结构序列化和反序列化场景。
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Data
|
||||
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type", visible = true)
|
||||
@JsonSubTypes({
|
||||
@JsonSubTypes.Type(value = IotDataSinkHttpConfig.class, name = "1"),
|
||||
@JsonSubTypes.Type(value = IotDataSinkTcpConfig.class, name = "2"),
|
||||
@JsonSubTypes.Type(value = IotDataSinkWebSocketConfig.class, name = "3"),
|
||||
@JsonSubTypes.Type(value = IotDataSinkMqttConfig.class, name = "10"),
|
||||
@JsonSubTypes.Type(value = IotDataSinkRedisConfig.class, name = "21"),
|
||||
@JsonSubTypes.Type(value = IotDataSinkRocketMQConfig.class, name = "30"),
|
||||
@JsonSubTypes.Type(value = IotDataSinkRabbitMQConfig.class, name = "31"),
|
||||
@JsonSubTypes.Type(value = IotDataSinkKafkaConfig.class, name = "32"),
|
||||
})
|
||||
public abstract class IotAbstractDataSinkConfig {
|
||||
|
||||
/**
|
||||
* 配置类型
|
||||
*
|
||||
* 枚举 {@link IotDataSinkTypeEnum#getType()}
|
||||
*/
|
||||
private String type;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package cn.aagro.pp.module.iot.dal.dataobject.rule.config;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* IoT HTTP 配置 {@link IotAbstractDataSinkConfig} 实现类
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Data
|
||||
public class IotDataSinkHttpConfig extends IotAbstractDataSinkConfig {
|
||||
|
||||
/**
|
||||
* 请求 URL
|
||||
*/
|
||||
private String url;
|
||||
/**
|
||||
* 请求方法
|
||||
*/
|
||||
private String method;
|
||||
/**
|
||||
* 请求头
|
||||
*/
|
||||
private Map<String, String> headers;
|
||||
/**
|
||||
* 请求参数
|
||||
*/
|
||||
private Map<String, String> query;
|
||||
/**
|
||||
* 请求体
|
||||
*/
|
||||
private String body;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package cn.aagro.pp.module.iot.dal.dataobject.rule.config;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* IoT Kafka 配置 {@link IotAbstractDataSinkConfig} 实现类
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Data
|
||||
public class IotDataSinkKafkaConfig extends IotAbstractDataSinkConfig {
|
||||
|
||||
/**
|
||||
* Kafka 服务器地址
|
||||
*/
|
||||
private String bootstrapServers;
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
private String username;
|
||||
/**
|
||||
* 密码
|
||||
*/
|
||||
private String password;
|
||||
/**
|
||||
* 是否启用 SSL
|
||||
*/
|
||||
private Boolean ssl;
|
||||
|
||||
/**
|
||||
* 主题
|
||||
*/
|
||||
private String topic;
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user