Merge branch 'feature/iot' of https://gitee.com/zhijiantianya/ruoyi-vue-pro into master-jdk17
This commit is contained in:
commit
eb7269083a
1
.gitignore
vendored
1
.gitignore
vendored
@ -51,3 +51,4 @@ rebel.xml
|
||||
application-my.yaml
|
||||
|
||||
/yudao-ui-app/unpackage/
|
||||
**/.DS_Store
|
||||
|
4
pom.xml
4
pom.xml
@ -16,7 +16,7 @@
|
||||
<module>yudao-module-system</module>
|
||||
<module>yudao-module-infra</module>
|
||||
<!-- <module>yudao-module-member</module>-->
|
||||
<!-- <module>yudao-module-bpm</module>-->
|
||||
<module>yudao-module-bpm</module>
|
||||
<!-- <module>yudao-module-report</module>-->
|
||||
<!-- <module>yudao-module-mp</module>-->
|
||||
<!-- <module>yudao-module-pay</module>-->
|
||||
@ -24,7 +24,7 @@
|
||||
<!-- <module>yudao-module-crm</module>-->
|
||||
<!-- <module>yudao-module-erp</module>-->
|
||||
<!-- <module>yudao-module-ai</module>-->
|
||||
<!-- <module>yudao-module-iot</module>-->
|
||||
<module>yudao-module-iot</module>
|
||||
</modules>
|
||||
|
||||
<name>${project.artifactId}</name>
|
||||
|
@ -32,8 +32,9 @@
|
||||
<dm8.jdbc.version>8.1.3.140</dm8.jdbc.version>
|
||||
<kingbase.jdbc.version>8.6.0</kingbase.jdbc.version>
|
||||
<opengauss.jdbc.version>5.1.0</opengauss.jdbc.version>
|
||||
<taos.version>3.3.3</taos.version>
|
||||
<!-- 消息队列 -->
|
||||
<rocketmq-spring.version>2.3.1</rocketmq-spring.version>
|
||||
<rocketmq-spring.version>2.3.2</rocketmq-spring.version>
|
||||
<!-- 服务保障相关 -->
|
||||
<lock4j.version>2.2.7</lock4j.version>
|
||||
<!-- 监控相关 -->
|
||||
@ -65,6 +66,8 @@
|
||||
<bizlog-sdk.version>3.0.6</bizlog-sdk.version>
|
||||
<netty.version>4.1.116.Final</netty.version>
|
||||
<mqtt.version>1.2.5</mqtt.version>
|
||||
<pf4j-spring.version>0.9.0</pf4j-spring.version>
|
||||
<vertx.version>4.5.13</vertx.version>
|
||||
<!-- 三方云服务相关 -->
|
||||
<commons-io.version>2.17.0</commons-io.version>
|
||||
<commons-compress.version>1.27.1</commons-compress.version>
|
||||
@ -263,6 +266,12 @@
|
||||
<version>${kingbase.jdbc.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.taosdata.jdbc</groupId>
|
||||
<artifactId>taos-jdbcdriver</artifactId>
|
||||
<version>${taos.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Job 定时任务相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
@ -276,7 +285,6 @@
|
||||
<artifactId>yudao-spring-boot-starter-mq</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.rocketmq</groupId>
|
||||
<artifactId>rocketmq-spring-boot-starter</artifactId>
|
||||
@ -591,6 +599,36 @@
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!-- PF4J -->
|
||||
<dependency>
|
||||
<groupId>org.pf4j</groupId>
|
||||
<artifactId>pf4j-spring</artifactId>
|
||||
<version>${pf4j-spring.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!-- Vert.x -->
|
||||
<dependency>
|
||||
<groupId>io.vertx</groupId>
|
||||
<artifactId>vertx-core</artifactId>
|
||||
<version>${vertx.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.vertx</groupId>
|
||||
<artifactId>vertx-web</artifactId>
|
||||
<version>${vertx.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.vertx</groupId>
|
||||
<artifactId>vertx-mqtt</artifactId>
|
||||
<version>${vertx.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- MQTT -->
|
||||
<dependency>
|
||||
<groupId>org.eclipse.paho</groupId>
|
||||
|
@ -0,0 +1,17 @@
|
||||
package cn.iocoder.yudao.framework.common.enums;
|
||||
|
||||
/**
|
||||
* RPC 相关的枚举
|
||||
*
|
||||
* 虽然放在 yudao-spring-boot-starter-rpc 会相对合适,但是每个 API 模块需要使用到,所以暂时只好放在此处
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public class RpcConstants {
|
||||
|
||||
/**
|
||||
* RPC API 的前缀
|
||||
*/
|
||||
public static final String RPC_API_PREFIX = "/rpc-api";
|
||||
|
||||
}
|
@ -7,13 +7,15 @@ import cn.hutool.core.util.ReflectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import cn.hutool.http.HttpResponse;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.util.UriComponents;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.net.URI;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@ -23,6 +25,16 @@ import java.util.Map;
|
||||
*/
|
||||
public class HttpUtils {
|
||||
|
||||
/**
|
||||
* 编码 URL 参数
|
||||
*
|
||||
* @param value 参数
|
||||
* @return 编码后的参数
|
||||
*/
|
||||
public static String encodeUtf8(String value) {
|
||||
return URLEncoder.encode(value, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static String replaceUrlQuery(String url, String key, String value) {
|
||||
UrlBuilder builder = UrlBuilder.of(url, Charset.defaultCharset());
|
||||
|
@ -1,9 +1,11 @@
|
||||
package cn.iocoder.yudao.framework.common.util.number;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.NumberUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 数字的工具类,补全 {@link cn.hutool.core.util.NumberUtil} 的功能
|
||||
@ -20,6 +22,18 @@ public class NumberUtils {
|
||||
return StrUtil.isNotEmpty(str) ? Integer.valueOf(str) : null;
|
||||
}
|
||||
|
||||
public static boolean isAllNumber(List<String> values) {
|
||||
if (CollUtil.isEmpty(values)) {
|
||||
return false;
|
||||
}
|
||||
for (String value : values) {
|
||||
if (!NumberUtil.isNumber(value)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过经纬度获取地球上两点之间的距离
|
||||
*
|
||||
|
@ -98,4 +98,8 @@ public class ServletUtils {
|
||||
return JakartaServletUtil.getParamMap(request);
|
||||
}
|
||||
|
||||
public static Map<String, String> getHeaderMap(HttpServletRequest request) {
|
||||
return JakartaServletUtil.getHeaderMap(request);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -97,12 +97,26 @@ public class SpringExpressionUtils {
|
||||
* @return 执行界面
|
||||
*/
|
||||
public static Object parseExpression(String expressionString) {
|
||||
return parseExpression(expressionString, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 Bean 工厂,解析 EL 表达式的结果
|
||||
*
|
||||
* @param expressionString EL 表达式
|
||||
* @param variables 变量
|
||||
* @return 执行界面
|
||||
*/
|
||||
public static Object parseExpression(String expressionString, Map<String, Object> variables) {
|
||||
if (StrUtil.isBlank(expressionString)) {
|
||||
return null;
|
||||
}
|
||||
Expression expression = EXPRESSION_PARSER.parseExpression(expressionString);
|
||||
StandardEvaluationContext context = new StandardEvaluationContext();
|
||||
context.setBeanResolver(new BeanFactoryResolver(SpringUtil.getApplicationContext()));
|
||||
if (MapUtil.isNotEmpty(variables)) {
|
||||
context.setVariables(variables);
|
||||
}
|
||||
return expression.getValue(context);
|
||||
}
|
||||
|
||||
|
@ -45,6 +45,7 @@ public class TenantUtils {
|
||||
*
|
||||
* @param tenantId 租户编号
|
||||
* @param callable 逻辑
|
||||
* @return 结果
|
||||
*/
|
||||
public static <V> V execute(Long tenantId, Callable<V> callable) {
|
||||
Long oldTenantId = TenantContextHolder.getTenantId();
|
||||
@ -78,6 +79,25 @@ public class TenantUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 忽略租户,执行对应的逻辑
|
||||
*
|
||||
* @param callable 逻辑
|
||||
* @return 结果
|
||||
*/
|
||||
public static <V> V executeIgnore(Callable<V> callable) {
|
||||
Boolean oldIgnore = TenantContextHolder.isIgnore();
|
||||
try {
|
||||
TenantContextHolder.setIgnore(true);
|
||||
// 执行逻辑
|
||||
return callable.call();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
TenantContextHolder.setIgnore(oldIgnore);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将多租户编号,添加到 header 中
|
||||
*
|
||||
|
@ -1,5 +1,6 @@
|
||||
package cn.iocoder.yudao.framework.excel.core.util;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.util.http.HttpUtils;
|
||||
import cn.iocoder.yudao.framework.excel.core.handler.SelectSheetWriteHandler;
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
import com.alibaba.excel.converters.longconverter.LongStringConverter;
|
||||
@ -8,8 +9,6 @@ import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -40,7 +39,7 @@ public class ExcelUtils {
|
||||
.registerConverter(new LongStringConverter()) // 避免 Long 类型丢失精度
|
||||
.sheet(sheetName).doWrite(data);
|
||||
// 设置 header 和 contentType。写在最后的原因是,避免报错时,响应 contentType 已经被修改了
|
||||
response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, StandardCharsets.UTF_8.name()));
|
||||
response.addHeader("Content-Disposition", "attachment;filename=" + HttpUtils.encodeUtf8(filename));
|
||||
response.setContentType("application/vnd.ms-excel;charset=UTF-8");
|
||||
}
|
||||
|
||||
|
@ -63,6 +63,11 @@
|
||||
<artifactId>opengauss-jdbc</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.taosdata.jdbc</groupId>
|
||||
<artifactId>taos-jdbcdriver</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
|
@ -0,0 +1,58 @@
|
||||
package cn.iocoder.yudao.framework.mybatis.core.type;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.framework.common.util.string.StrUtils;
|
||||
import org.apache.ibatis.type.JdbcType;
|
||||
import org.apache.ibatis.type.MappedJdbcTypes;
|
||||
import org.apache.ibatis.type.MappedTypes;
|
||||
import org.apache.ibatis.type.TypeHandler;
|
||||
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Set<Long> 的类型转换器实现类,对应数据库的 varchar 类型
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@MappedJdbcTypes(JdbcType.VARCHAR)
|
||||
@MappedTypes(List.class)
|
||||
public class LongSetTypeHandler implements TypeHandler<Set<Long>> {
|
||||
|
||||
private static final String COMMA = ",";
|
||||
|
||||
@Override
|
||||
public void setParameter(PreparedStatement ps, int i, Set<Long> strings, JdbcType jdbcType) throws SQLException {
|
||||
// 设置占位符
|
||||
ps.setString(i, CollUtil.join(strings, COMMA));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Long> getResult(ResultSet rs, String columnName) throws SQLException {
|
||||
String value = rs.getString(columnName);
|
||||
return getResult(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Long> getResult(ResultSet rs, int columnIndex) throws SQLException {
|
||||
String value = rs.getString(columnIndex);
|
||||
return getResult(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Long> getResult(CallableStatement cs, int columnIndex) throws SQLException {
|
||||
String value = cs.getString(columnIndex);
|
||||
return getResult(value);
|
||||
}
|
||||
|
||||
private Set<Long> getResult(String value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return StrUtils.splitToLongSet(value, COMMA);
|
||||
}
|
||||
}
|
@ -62,9 +62,9 @@ public class BannerApplicationRunner implements ApplicationRunner {
|
||||
if (isNotPresent("cn.iocoder.yudao.module.ai.framework.web.config.AiWebConfiguration")) {
|
||||
System.out.println("[AI 大模型 yudao-module-ai - 已禁用][参考 https://doc.iocoder.cn/ai/build/ 开启]");
|
||||
}
|
||||
// IOT 物联网
|
||||
// IoT 物联网
|
||||
if (isNotPresent("cn.iocoder.yudao.module.iot.framework.web.config.IotWebConfiguration")) {
|
||||
System.out.println("[IOT 物联网 yudao-module-iot - 已禁用][参考 https://doc.iocoder.cn/iot/build/ 开启]");
|
||||
System.out.println("[IoT 物联网 yudao-module-iot - 已禁用][参考 https://doc.iocoder.cn/iot/build/ 开启]");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -395,11 +395,11 @@ public class GlobalExceptionHandler {
|
||||
return CommonResult.error(NOT_IMPLEMENTED.getCode(),
|
||||
"[AI 大模型 yudao-module-ai - 表结构未导入][参考 https://cloud.iocoder.cn/ai/build/ 开启]");
|
||||
}
|
||||
// 9. IOT 物联网
|
||||
// 9. IoT 物联网
|
||||
if (message.contains("iot_")) {
|
||||
log.error("[IOT 物联网 yudao-module-iot - 表结构未导入][参考 https://doc.iocoder.cn/iot/build/ 开启]");
|
||||
log.error("[IoT 物联网 yudao-module-iot - 表结构未导入][参考 https://doc.iocoder.cn/iot/build/ 开启]");
|
||||
return CommonResult.error(NOT_IMPLEMENTED.getCode(),
|
||||
"[IOT 物联网 yudao-module-iot - 表结构未导入][参考 https://doc.iocoder.cn/iot/build/ 开启]");
|
||||
"[IoT 物联网 yudao-module-iot - 表结构未导入][参考 https://doc.iocoder.cn/iot/build/ 开启]");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -66,7 +66,9 @@ public class CrmReceivableDO extends BaseDO {
|
||||
*/
|
||||
private LocalDateTime returnTime;
|
||||
/**
|
||||
* 回款方式,关联枚举{@link CrmReceivableReturnTypeEnum}
|
||||
* 回款方式
|
||||
*
|
||||
* 枚举 {@link CrmReceivableReturnTypeEnum}
|
||||
*/
|
||||
private Integer returnType;
|
||||
/**
|
||||
|
@ -2,13 +2,13 @@ package cn.iocoder.yudao.module.infra.framework.file.core.utils;
|
||||
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.framework.common.util.http.HttpUtils;
|
||||
import com.alibaba.ttl.TransmittableThreadLocal;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.SneakyThrows;
|
||||
import org.apache.tika.Tika;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URLEncoder;
|
||||
|
||||
/**
|
||||
* 文件类型 Utils
|
||||
@ -60,7 +60,7 @@ public class FileTypeUtils {
|
||||
*/
|
||||
public static void writeAttachment(HttpServletResponse response, String filename, byte[] content) throws IOException {
|
||||
// 设置 header 和 contentType
|
||||
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
|
||||
response.setHeader("Content-Disposition", "attachment;filename=" + HttpUtils.encodeUtf8(filename));
|
||||
String contentType = getMineType(content, filename);
|
||||
response.setContentType(contentType);
|
||||
// 针对 video 的特殊处理,解决视频地址在移动端播放的兼容性问题
|
||||
|
@ -10,6 +10,7 @@
|
||||
<modules>
|
||||
<module>yudao-module-iot-api</module>
|
||||
<module>yudao-module-iot-biz</module>
|
||||
<module>yudao-module-iot-plugins</module>
|
||||
</modules>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>${project.artifactId}</name>
|
||||
<!-- TODO 芋艿:需要在整理下,特别是 PF4J -->
|
||||
<description>
|
||||
物联网 模块 API,暴露给其它模块调用
|
||||
</description>
|
||||
@ -21,6 +22,32 @@
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-common</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Web 相关 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
<scope>provided</scope> <!-- 设置为 provided,只有工具类需要使用到 -->
|
||||
</dependency>
|
||||
|
||||
<!-- 工具类相关 -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<scope>provided</scope> <!-- 设置为 provided,只有工具类需要使用到 -->
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.pf4j</groupId> <!-- PF4J:内置插件机制 -->
|
||||
<artifactId>pf4j-spring</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 参数校验 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
@ -0,0 +1,93 @@
|
||||
package cn.iocoder.yudao.module.iot.api.device;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.module.iot.api.device.dto.control.upstream.*;
|
||||
import cn.iocoder.yudao.module.iot.enums.ApiConstants;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
/**
|
||||
* 设备数据 Upstream 上行 API
|
||||
*
|
||||
* 目的:设备 -> 插件 -> 服务端
|
||||
*
|
||||
* @author haohao
|
||||
*/
|
||||
public interface IotDeviceUpstreamApi {
|
||||
|
||||
String PREFIX = ApiConstants.PREFIX + "/device/upstream";
|
||||
|
||||
// ========== 设备相关 ==========
|
||||
|
||||
/**
|
||||
* 更新设备状态
|
||||
*
|
||||
* @param updateReqDTO 更新设备状态 DTO
|
||||
*/
|
||||
@PostMapping(PREFIX + "/update-state")
|
||||
CommonResult<Boolean> updateDeviceState(@Valid @RequestBody IotDeviceStateUpdateReqDTO updateReqDTO);
|
||||
|
||||
/**
|
||||
* 上报设备属性数据
|
||||
*
|
||||
* @param reportReqDTO 上报设备属性数据 DTO
|
||||
*/
|
||||
@PostMapping(PREFIX + "/report-property")
|
||||
CommonResult<Boolean> reportDeviceProperty(@Valid @RequestBody IotDevicePropertyReportReqDTO reportReqDTO);
|
||||
|
||||
/**
|
||||
* 上报设备事件数据
|
||||
*
|
||||
* @param reportReqDTO 设备事件
|
||||
*/
|
||||
@PostMapping(PREFIX + "/report-event")
|
||||
CommonResult<Boolean> reportDeviceEvent(@Valid @RequestBody IotDeviceEventReportReqDTO reportReqDTO);
|
||||
|
||||
// TODO @芋艿:这个需要 plugins 接入下
|
||||
/**
|
||||
* 注册设备
|
||||
*
|
||||
* @param registerReqDTO 注册设备 DTO
|
||||
*/
|
||||
@PostMapping(PREFIX + "/register")
|
||||
CommonResult<Boolean> registerDevice(@Valid @RequestBody IotDeviceRegisterReqDTO registerReqDTO);
|
||||
|
||||
// TODO @芋艿:这个需要 plugins 接入下
|
||||
/**
|
||||
* 注册子设备
|
||||
*
|
||||
* @param registerReqDTO 注册子设备 DTO
|
||||
*/
|
||||
@PostMapping(PREFIX + "/register-sub")
|
||||
CommonResult<Boolean> registerSubDevice(@Valid @RequestBody IotDeviceRegisterSubReqDTO registerReqDTO);
|
||||
|
||||
// TODO @芋艿:这个需要 plugins 接入下
|
||||
/**
|
||||
* 注册设备拓扑
|
||||
*
|
||||
* @param addReqDTO 注册设备拓扑 DTO
|
||||
*/
|
||||
@PostMapping(PREFIX + "/add-topology")
|
||||
CommonResult<Boolean> addDeviceTopology(@Valid @RequestBody IotDeviceTopologyAddReqDTO addReqDTO);
|
||||
|
||||
// TODO @芋艿:考虑 http 认证
|
||||
/**
|
||||
* 认证 Emqx 连接
|
||||
*
|
||||
* @param authReqDTO 认证 Emqx 连接 DTO
|
||||
*/
|
||||
@PostMapping(PREFIX + "/authenticate-emqx-connection")
|
||||
CommonResult<Boolean> authenticateEmqxConnection(@Valid @RequestBody IotDeviceEmqxAuthReqDTO authReqDTO);
|
||||
|
||||
// ========== 插件相关 ==========
|
||||
|
||||
/**
|
||||
* 心跳插件实例
|
||||
*
|
||||
* @param heartbeatReqDTO 心跳插件实例 DTO
|
||||
*/
|
||||
@PostMapping(PREFIX + "/heartbeat-plugin-instance")
|
||||
CommonResult<Boolean> heartbeatPluginInstance(@Valid @RequestBody IotPluginInstanceHeartbeatReqDTO heartbeatReqDTO);
|
||||
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package cn.iocoder.yudao.module.iot.api.device.dto.control.downstream;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* IoT 设备【配置】设置 Request DTO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
public class IotDeviceConfigSetReqDTO extends IotDeviceDownstreamAbstractReqDTO {
|
||||
|
||||
/**
|
||||
* 配置
|
||||
*/
|
||||
@NotNull(message = "配置不能为空")
|
||||
private Map<String, Object> config;
|
||||
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package cn.iocoder.yudao.module.iot.api.device.dto.control.downstream;
|
||||
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* IoT 设备下行的抽象 Request DTO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
public abstract class IotDeviceDownstreamAbstractReqDTO {
|
||||
|
||||
/**
|
||||
* 请求编号
|
||||
*/
|
||||
private String requestId;
|
||||
|
||||
/**
|
||||
* 产品标识
|
||||
*/
|
||||
@NotEmpty(message = "产品标识不能为空")
|
||||
private String productKey;
|
||||
/**
|
||||
* 设备名称
|
||||
*/
|
||||
@NotEmpty(message = "设备名称不能为空")
|
||||
private String deviceName;
|
||||
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
package cn.iocoder.yudao.module.iot.api.device.dto.control.downstream;
|
||||
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* IoT 设备【OTA】升级下发 Request DTO(更新固件消息)
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
public class IotDeviceOtaUpgradeReqDTO extends IotDeviceDownstreamAbstractReqDTO {
|
||||
|
||||
/**
|
||||
* 固件编号
|
||||
*/
|
||||
private Long firmwareId;
|
||||
/**
|
||||
* 固件版本
|
||||
*/
|
||||
private String version;
|
||||
|
||||
/**
|
||||
* 签名方式
|
||||
*
|
||||
* 例如说:MD5、SHA256
|
||||
*/
|
||||
private String signMethod;
|
||||
/**
|
||||
* 固件文件签名
|
||||
*/
|
||||
private String fileSign;
|
||||
/**
|
||||
* 固件文件大小
|
||||
*/
|
||||
private Long fileSize;
|
||||
/**
|
||||
* 固件文件 URL
|
||||
*/
|
||||
private String fileUrl;
|
||||
|
||||
/**
|
||||
* 自定义信息,建议使用 JSON 格式
|
||||
*/
|
||||
private String information;
|
||||
|
||||
public static IotDeviceOtaUpgradeReqDTO build(Map<?, ?> map) {
|
||||
return new IotDeviceOtaUpgradeReqDTO()
|
||||
.setFirmwareId(MapUtil.getLong(map, "firmwareId")).setVersion((String) map.get("version"))
|
||||
.setSignMethod((String) map.get("signMethod")).setFileSign((String) map.get("fileSign"))
|
||||
.setFileSize(MapUtil.getLong(map, "fileSize")).setFileUrl((String) map.get("fileUrl"))
|
||||
.setInformation((String) map.get("information"));
|
||||
}
|
||||
|
||||
public static Map<?, ?> build(IotDeviceOtaUpgradeReqDTO dto) {
|
||||
return MapUtil.builder()
|
||||
.put("firmwareId", dto.getFirmwareId()).put("version", dto.getVersion())
|
||||
.put("signMethod", dto.getSignMethod()).put("fileSign", dto.getFileSign())
|
||||
.put("fileSize", dto.getFileSize()).put("fileUrl", dto.getFileUrl())
|
||||
.put("information", dto.getInformation())
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package cn.iocoder.yudao.module.iot.api.device.dto.control.downstream;
|
||||
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
// TODO @芋艿:从 server => plugin => device 是否有必要?从阿里云 iot 来看,没有这个功能?!
|
||||
// TODO @芋艿:是不是改成 read 更好?在看看阿里云的 topic 设计
|
||||
/**
|
||||
* IoT 设备【属性】获取 Request DTO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
public class IotDevicePropertyGetReqDTO extends IotDeviceDownstreamAbstractReqDTO {
|
||||
|
||||
/**
|
||||
* 属性标识数组
|
||||
*/
|
||||
@NotEmpty(message = "属性标识数组不能为空")
|
||||
private List<String> identifiers;
|
||||
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package cn.iocoder.yudao.module.iot.api.device.dto.control.downstream;
|
||||
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* IoT 设备【属性】设置 Request DTO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
public class IotDevicePropertySetReqDTO extends IotDeviceDownstreamAbstractReqDTO {
|
||||
|
||||
/**
|
||||
* 属性参数
|
||||
*/
|
||||
@NotEmpty(message = "属性参数不能为空")
|
||||
private Map<String, Object> properties;
|
||||
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package cn.iocoder.yudao.module.iot.api.device.dto.control.downstream;
|
||||
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* IoT 设备【服务】调用 Request DTO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
public class IotDeviceServiceInvokeReqDTO extends IotDeviceDownstreamAbstractReqDTO {
|
||||
|
||||
/**
|
||||
* 服务标识
|
||||
*/
|
||||
@NotEmpty(message = "服务标识不能为空")
|
||||
private String identifier;
|
||||
/**
|
||||
* 调用参数
|
||||
*/
|
||||
private Map<String, Object> params;
|
||||
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package cn.iocoder.yudao.module.iot.api.device.dto.control.upstream;
|
||||
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import lombok.Data;
|
||||
|
||||
// TODO @芋艿:要不要继承 IotDeviceUpstreamAbstractReqDTO
|
||||
// TODO @芋艿:@haohao:后续其它认证的设计
|
||||
/**
|
||||
* IoT 认证 Emqx 连接 Request DTO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
public class IotDeviceEmqxAuthReqDTO {
|
||||
|
||||
/**
|
||||
* 客户端 ID
|
||||
*/
|
||||
@NotEmpty(message = "客户端 ID 不能为空")
|
||||
private String clientId;
|
||||
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
@NotEmpty(message = "用户名不能为空")
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* 密码
|
||||
*/
|
||||
@NotEmpty(message = "密码不能为空")
|
||||
private String password;
|
||||
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package cn.iocoder.yudao.module.iot.api.device.dto.control.upstream;
|
||||
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* IoT 设备【事件】上报 Request DTO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
public class IotDeviceEventReportReqDTO extends IotDeviceUpstreamAbstractReqDTO {
|
||||
|
||||
/**
|
||||
* 事件标识
|
||||
*/
|
||||
@NotEmpty(message = "事件标识不能为空")
|
||||
private String identifier;
|
||||
/**
|
||||
* 事件参数
|
||||
*/
|
||||
private Map<String, Object> params;
|
||||
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package cn.iocoder.yudao.module.iot.api.device.dto.control.upstream;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
// TODO @芋艿:待实现:/ota/${productKey}/${deviceName}/progress
|
||||
/**
|
||||
* IoT 设备【OTA】升级进度 Request DTO(上报更新固件进度)
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
public class IotDeviceOtaProgressReqDTO extends IotDeviceUpstreamAbstractReqDTO {
|
||||
|
||||
/**
|
||||
* 固件编号
|
||||
*/
|
||||
private Long firmwareId;
|
||||
|
||||
/**
|
||||
* 升级状态
|
||||
*
|
||||
* 枚举 {@link cn.iocoder.yudao.module.iot.enums.ota.IotOtaUpgradeRecordStatusEnum}
|
||||
*/
|
||||
private Integer status;
|
||||
/**
|
||||
* 升级进度,百分比
|
||||
*/
|
||||
private Integer progress;
|
||||
|
||||
/**
|
||||
* 升级进度描述
|
||||
*/
|
||||
private String description;
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package cn.iocoder.yudao.module.iot.api.device.dto.control.upstream;
|
||||
|
||||
// TODO @芋艿:待实现:/ota/${productKey}/${deviceName}/pull
|
||||
/**
|
||||
* IoT 设备【OTA】升级下拉 Request DTO(拉取固件更新)
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public class IotDeviceOtaPullReqDTO {
|
||||
|
||||
/**
|
||||
* 固件编号
|
||||
*/
|
||||
private Long firmwareId;
|
||||
|
||||
/**
|
||||
* 固件版本
|
||||
*/
|
||||
private String version;
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package cn.iocoder.yudao.module.iot.api.device.dto.control.upstream;
|
||||
|
||||
// TODO @芋艿:待实现:/ota/${productKey}/${deviceName}/report
|
||||
/**
|
||||
* IoT 设备【OTA】上报 Request DTO(上报固件版本)
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public class IotDeviceOtaReportReqDTO {
|
||||
|
||||
/**
|
||||
* 固件编号
|
||||
*/
|
||||
private Long firmwareId;
|
||||
|
||||
/**
|
||||
* 固件版本
|
||||
*/
|
||||
private String version;
|
||||
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package cn.iocoder.yudao.module.iot.api.device.dto.control.upstream;
|
||||
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* IoT 设备【属性】上报 Request DTO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
public class IotDevicePropertyReportReqDTO extends IotDeviceUpstreamAbstractReqDTO {
|
||||
|
||||
/**
|
||||
* 属性参数
|
||||
*/
|
||||
@NotEmpty(message = "属性参数不能为空")
|
||||
private Map<String, Object> properties;
|
||||
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package cn.iocoder.yudao.module.iot.api.device.dto.control.upstream;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* IoT 设备【注册】自己 Request DTO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
public class IotDeviceRegisterReqDTO extends IotDeviceUpstreamAbstractReqDTO {
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
package cn.iocoder.yudao.module.iot.api.device.dto.control.upstream;
|
||||
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* IoT 设备【注册】子设备 Request DTO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
public class IotDeviceRegisterSubReqDTO extends IotDeviceUpstreamAbstractReqDTO {
|
||||
|
||||
// TODO @芋艿:看看要不要优化命名
|
||||
/**
|
||||
* 子设备数组
|
||||
*/
|
||||
@NotEmpty(message = "子设备不能为空")
|
||||
private List<Device> params;
|
||||
|
||||
/**
|
||||
* 设备信息
|
||||
*/
|
||||
@Data
|
||||
public static class Device {
|
||||
|
||||
/**
|
||||
* 产品标识
|
||||
*/
|
||||
@NotEmpty(message = "产品标识不能为空")
|
||||
private String productKey;
|
||||
|
||||
/**
|
||||
* 设备名称
|
||||
*/
|
||||
@NotEmpty(message = "设备名称不能为空")
|
||||
private String deviceName;
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package cn.iocoder.yudao.module.iot.api.device.dto.control.upstream;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStateEnum;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* IoT 设备【状态】更新 Request DTO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
public class IotDeviceStateUpdateReqDTO extends IotDeviceUpstreamAbstractReqDTO {
|
||||
|
||||
/**
|
||||
* 设备状态
|
||||
*/
|
||||
@NotNull(message = "设备状态不能为空")
|
||||
@InEnum(IotDeviceStateEnum.class) // 只使用:在线、离线
|
||||
private Integer state;
|
||||
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package cn.iocoder.yudao.module.iot.api.device.dto.control.upstream;
|
||||
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
// TODO @芋艿:要写清楚,是来自设备网关,还是设备。
|
||||
/**
|
||||
* IoT 设备【拓扑】添加 Request DTO
|
||||
*/
|
||||
@Data
|
||||
public class IotDeviceTopologyAddReqDTO extends IotDeviceUpstreamAbstractReqDTO {
|
||||
|
||||
// TODO @芋艿:看看要不要优化命名
|
||||
/**
|
||||
* 子设备数组
|
||||
*/
|
||||
@NotEmpty(message = "子设备不能为空")
|
||||
private List<IotDeviceRegisterSubReqDTO.Device> params;
|
||||
|
||||
/**
|
||||
* 设备信息
|
||||
*/
|
||||
@Data
|
||||
public static class Device {
|
||||
|
||||
/**
|
||||
* 产品标识
|
||||
*/
|
||||
@NotEmpty(message = "产品标识不能为空")
|
||||
private String productKey;
|
||||
|
||||
/**
|
||||
* 设备名称
|
||||
*/
|
||||
@NotEmpty(message = "设备名称不能为空")
|
||||
private String deviceName;
|
||||
|
||||
// TODO @芋艿:阿里云还有 sign 签名
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
package cn.iocoder.yudao.module.iot.api.device.dto.control.upstream;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.util.json.databind.TimestampLocalDateTimeSerializer;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* IoT 设备上行的抽象 Request DTO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
public abstract class IotDeviceUpstreamAbstractReqDTO {
|
||||
|
||||
/**
|
||||
* 请求编号
|
||||
*/
|
||||
private String requestId;
|
||||
|
||||
/**
|
||||
* 插件实例的进程编号
|
||||
*/
|
||||
private String processId;
|
||||
|
||||
/**
|
||||
* 产品标识
|
||||
*/
|
||||
@NotEmpty(message = "产品标识不能为空")
|
||||
private String productKey;
|
||||
/**
|
||||
* 设备名称
|
||||
*/
|
||||
@NotEmpty(message = "设备名称不能为空")
|
||||
private String deviceName;
|
||||
|
||||
/**
|
||||
* 上报时间
|
||||
*/
|
||||
@JsonSerialize(using = TimestampLocalDateTimeSerializer.class) // 解决 iot plugins 序列化 LocalDateTime 是数组,导致无法解析的问题
|
||||
private LocalDateTime reportTime;
|
||||
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package cn.iocoder.yudao.module.iot.api.device.dto.control.upstream;
|
||||
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* IoT 插件实例心跳 Request DTO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
public class IotPluginInstanceHeartbeatReqDTO {
|
||||
|
||||
/**
|
||||
* 请求编号
|
||||
*/
|
||||
@NotEmpty(message = "请求编号不能为空")
|
||||
private String processId;
|
||||
|
||||
/**
|
||||
* 插件包标识符
|
||||
*/
|
||||
@NotEmpty(message = "插件包标识符不能为空")
|
||||
private String pluginKey;
|
||||
|
||||
/**
|
||||
* 插件实例所在 IP
|
||||
*/
|
||||
@NotEmpty(message = "插件实例所在 IP 不能为空")
|
||||
private String hostIp;
|
||||
/**
|
||||
* 插件实例的进程编号
|
||||
*/
|
||||
@NotNull(message = "插件实例的进程编号不能为空")
|
||||
private Integer downstreamPort;
|
||||
|
||||
/**
|
||||
* 是否在线
|
||||
*/
|
||||
@NotNull(message = "是否在线不能为空")
|
||||
private Boolean online;
|
||||
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
/**
|
||||
* TODO 芋艿:占位
|
||||
*/
|
||||
package cn.iocoder.yudao.module.iot.api.device.dto;
|
@ -0,0 +1,16 @@
|
||||
package cn.iocoder.yudao.module.iot.enums;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.RpcConstants;
|
||||
|
||||
/**
|
||||
* API 相关的枚举
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public class ApiConstants {
|
||||
|
||||
public static final String PREFIX = RpcConstants.RPC_API_PREFIX + "/iot";
|
||||
|
||||
public static final String VERSION = "1.0.0";
|
||||
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package cn.iocoder.yudao.module.iot.enums;
|
||||
|
||||
/**
|
||||
* IoT 字典类型的枚举类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public class DictTypeConstants {
|
||||
|
||||
public static final String PRODUCT_STATUS = "iot_product_status";
|
||||
public static final String PRODUCT_DEVICE_TYPE = "iot_product_device_type";
|
||||
public static final String NET_TYPE = "iot_net_type";
|
||||
public static final String PROTOCOL_TYPE = "iot_protocol_type";
|
||||
public static final String DATA_FORMAT = "iot_data_format";
|
||||
public static final String VALIDATE_TYPE = "iot_validate_type";
|
||||
|
||||
public static final String DEVICE_STATE = "iot_device_state";
|
||||
|
||||
public static final String IOT_DATA_BRIDGE_DIRECTION_ENUM = "iot_data_bridge_direction_enum";
|
||||
public static final String IOT_DATA_BRIDGE_TYPE_ENUM = "iot_data_bridge_type_enum";
|
||||
|
||||
}
|
@ -9,24 +9,67 @@ import cn.iocoder.yudao.framework.common.exception.ErrorCode;
|
||||
*/
|
||||
public interface ErrorCodeConstants {
|
||||
|
||||
// ========== IoT 产品相关 1-050-001-000 ============
|
||||
// ========== 产品相关 1-050-001-000 ============
|
||||
ErrorCode PRODUCT_NOT_EXISTS = new ErrorCode(1_050_001_000, "产品不存在");
|
||||
ErrorCode PRODUCT_IDENTIFICATION_EXISTS = new ErrorCode(1_050_001_001, "产品标识已经存在");
|
||||
ErrorCode PRODUCT_KEY_EXISTS = new ErrorCode(1_050_001_001, "产品标识已经存在");
|
||||
ErrorCode PRODUCT_STATUS_NOT_DELETE = new ErrorCode(1_050_001_002, "产品状是发布状态,不允许删除");
|
||||
ErrorCode PRODUCT_STATUS_NOT_ALLOW_THING_MODEL = new ErrorCode(1_050_001_003, "产品状是发布状态,不允许操作物模型");
|
||||
|
||||
// ========== IoT 产品物模型 1-050-002-000 ============
|
||||
ErrorCode THINK_MODEL_FUNCTION_NOT_EXISTS = new ErrorCode(1_050_002_000, "产品物模型不存在");
|
||||
ErrorCode THINK_MODEL_FUNCTION_EXISTS_BY_PRODUCT_KEY = new ErrorCode(1_050_002_001, "ProductKey 对应的产品物模型已存在");
|
||||
ErrorCode THINK_MODEL_FUNCTION_IDENTIFIER_EXISTS = new ErrorCode(1_050_002_002, "存在重复的功能标识符。");
|
||||
ErrorCode THINK_MODEL_FUNCTION_NAME_EXISTS = new ErrorCode(1_050_002_003, "存在重复的功能名称。");
|
||||
ErrorCode THINK_MODEL_FUNCTION_IDENTIFIER_INVALID = new ErrorCode(1_050_002_003, "产品物模型标识无效");
|
||||
// ========== 产品物模型 1-050-002-000 ============
|
||||
ErrorCode THING_MODEL_NOT_EXISTS = new ErrorCode(1_050_002_000, "产品物模型不存在");
|
||||
ErrorCode THING_MODEL_EXISTS_BY_PRODUCT_KEY = new ErrorCode(1_050_002_001, "ProductKey 对应的产品物模型已存在");
|
||||
ErrorCode THING_MODEL_IDENTIFIER_EXISTS = new ErrorCode(1_050_002_002, "存在重复的功能标识符。");
|
||||
ErrorCode THING_MODEL_NAME_EXISTS = new ErrorCode(1_050_002_003, "存在重复的功能名称。");
|
||||
ErrorCode THING_MODEL_IDENTIFIER_INVALID = new ErrorCode(1_050_002_003, "产品物模型标识无效");
|
||||
|
||||
// ========== IoT 设备 1-050-003-000 ============
|
||||
// ========== 设备 1-050-003-000 ============
|
||||
ErrorCode DEVICE_NOT_EXISTS = new ErrorCode(1_050_003_000, "设备不存在");
|
||||
ErrorCode DEVICE_NAME_EXISTS = new ErrorCode(1_050_003_001, "设备名称在同一产品下必须唯一");
|
||||
ErrorCode DEVICE_HAS_CHILDREN = new ErrorCode(1_050_003_002, "有子设备,不允许删除");
|
||||
ErrorCode DEVICE_NAME_CANNOT_BE_MODIFIED = new ErrorCode(1_050_003_003, "设备名称不能修改");
|
||||
ErrorCode DEVICE_PRODUCT_CANNOT_BE_MODIFIED = new ErrorCode(1_050_003_004, "产品不能修改");
|
||||
ErrorCode DEVICE_INVALID_DEVICE_STATUS = new ErrorCode(1_050_003_005, "无效的设备状态");
|
||||
ErrorCode DEVICE_KEY_EXISTS = new ErrorCode(1_050_003_003, "设备标识已经存在");
|
||||
ErrorCode DEVICE_GATEWAY_NOT_EXISTS = new ErrorCode(1_050_003_004, "网关设备不存在");
|
||||
ErrorCode DEVICE_NOT_GATEWAY = new ErrorCode(1_050_003_005, "设备不是网关设备");
|
||||
ErrorCode DEVICE_IMPORT_LIST_IS_EMPTY = new ErrorCode(1_050_003_006, "导入设备数据不能为空!");
|
||||
ErrorCode DEVICE_DOWNSTREAM_FAILED = new ErrorCode(1_050_003_007, "执行失败,原因:{}");
|
||||
|
||||
}
|
||||
// ========== 产品分类 1-050-004-000 ==========
|
||||
ErrorCode PRODUCT_CATEGORY_NOT_EXISTS = new ErrorCode(1_050_004_000, "产品分类不存在");
|
||||
|
||||
// ========== 设备分组 1-050-005-000 ==========
|
||||
ErrorCode DEVICE_GROUP_NOT_EXISTS = new ErrorCode(1_050_005_000, "设备分组不存在");
|
||||
ErrorCode DEVICE_GROUP_DELETE_FAIL_DEVICE_EXISTS = new ErrorCode(1_050_005_001, "设备分组下存在设备,不允许删除");
|
||||
|
||||
// ========== 插件配置 1-050-006-000 ==========
|
||||
ErrorCode PLUGIN_CONFIG_NOT_EXISTS = new ErrorCode(1_050_006_000, "插件配置不存在");
|
||||
ErrorCode PLUGIN_INSTALL_FAILED = new ErrorCode(1_050_006_001, "插件安装失败");
|
||||
ErrorCode PLUGIN_INSTALL_FAILED_FILE_NAME_NOT_MATCH = new ErrorCode(1_050_006_002, "插件安装失败,文件名与原插件id不匹配");
|
||||
ErrorCode PLUGIN_CONFIG_DELETE_FAILED_RUNNING = new ErrorCode(1_050_006_003, "请先停止插件");
|
||||
ErrorCode PLUGIN_STATUS_INVALID = new ErrorCode(1_050_006_004, "插件状态无效");
|
||||
ErrorCode PLUGIN_CONFIG_KEY_DUPLICATE = new ErrorCode(1_050_006_005, "插件标识已存在");
|
||||
ErrorCode PLUGIN_START_FAILED = new ErrorCode(1_050_006_006, "插件启动失败");
|
||||
ErrorCode PLUGIN_STOP_FAILED = new ErrorCode(1_050_006_007, "插件停止失败");
|
||||
|
||||
// ========== 插件实例 1-050-007-000 ==========
|
||||
|
||||
// ========== 固件相关 1-050-008-000 ==========
|
||||
|
||||
ErrorCode OTA_FIRMWARE_NOT_EXISTS = new ErrorCode(1_050_008_000, "固件信息不存在");
|
||||
ErrorCode OTA_FIRMWARE_PRODUCT_VERSION_DUPLICATE = new ErrorCode(1_050_008_001, "产品版本号重复");
|
||||
|
||||
ErrorCode OTA_UPGRADE_TASK_NOT_EXISTS = new ErrorCode(1_050_008_100, "升级任务不存在");
|
||||
ErrorCode OTA_UPGRADE_TASK_NAME_DUPLICATE = new ErrorCode(1_050_008_101, "升级任务名称重复");
|
||||
ErrorCode OTA_UPGRADE_TASK_DEVICE_IDS_EMPTY = new ErrorCode(1_050_008_102, "设备编号列表不能为空");
|
||||
ErrorCode OTA_UPGRADE_TASK_DEVICE_LIST_EMPTY = new ErrorCode(1_050_008_103, "设备列表不能为空");
|
||||
ErrorCode OTA_UPGRADE_TASK_CANNOT_CANCEL = new ErrorCode(1_050_008_104, "升级任务不能取消");
|
||||
|
||||
ErrorCode OTA_UPGRADE_RECORD_NOT_EXISTS = new ErrorCode(1_050_008_200, "升级记录不存在");
|
||||
ErrorCode OTA_UPGRADE_RECORD_DUPLICATE = new ErrorCode(1_050_008_201, "升级记录重复");
|
||||
ErrorCode OTA_UPGRADE_RECORD_CANNOT_RETRY = new ErrorCode(1_050_008_202, "升级记录不能重试");
|
||||
|
||||
// ========== MQTT 通信相关 1-050-009-000 ==========
|
||||
ErrorCode MQTT_TOPIC_ILLEGAL = new ErrorCode(1_050_009_000, "topic illegal");
|
||||
|
||||
// ========== IoT 数据桥梁 1-050-010-000 ==========
|
||||
ErrorCode DATA_BRIDGE_NOT_EXISTS = new ErrorCode(1_050_010_000, "IoT 数据桥梁不存在");
|
||||
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package cn.iocoder.yudao.module.iot.enums.device;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
// TODO @芋艿:需要添加对应的 DTO,以及上下行的链路,网关、网关服务、设备等
|
||||
/**
|
||||
* IoT 设备消息标识符枚举
|
||||
*/
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public enum IotDeviceMessageIdentifierEnum {
|
||||
|
||||
PROPERTY_GET("get"), // 下行 TODO 芋艿:【讨论】貌似这个“上行”更合理?device 主动拉取配置。和 IotDevicePropertyGetReqDTO 一样的配置
|
||||
PROPERTY_SET("set"), // 下行
|
||||
PROPERTY_REPORT("report"), // 上行
|
||||
|
||||
STATE_ONLINE("online"), // 上行
|
||||
STATE_OFFLINE("offline"), // 上行
|
||||
|
||||
CONFIG_GET("get"), // 上行 TODO 芋艿:【讨论】暂时没有上行的场景
|
||||
CONFIG_SET("set"), // 下行
|
||||
|
||||
SERVICE_INVOKE("${identifier}"), // 下行
|
||||
SERVICE_REPLY_SUFFIX("_reply"), // 芋艿:TODO 芋艿:【讨论】上行 or 下行
|
||||
|
||||
OTA_UPGRADE("upgrade"), // 下行
|
||||
OTA_PULL("pull"), // 上行
|
||||
OTA_PROGRESS("progress"), // 上行
|
||||
OTA_REPORT("report"), // 上行
|
||||
|
||||
REGISTER_REGISTER("register"), // 上行
|
||||
REGISTER_REGISTER_SUB("register_sub"), // 上行
|
||||
REGISTER_UNREGISTER_SUB("unregister_sub"), // 下行
|
||||
|
||||
TOPOLOGY_ADD("topology_add"), // 下行;
|
||||
;
|
||||
|
||||
/**
|
||||
* 标志符
|
||||
*/
|
||||
private final String identifier;
|
||||
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package cn.iocoder.yudao.module.iot.enums.device;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* IoT 设备消息类型枚举
|
||||
*/
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public enum IotDeviceMessageTypeEnum implements ArrayValuable<String> {
|
||||
|
||||
STATE("state"), // 设备状态
|
||||
PROPERTY("property"), // 设备属性:可参考 https://help.aliyun.com/zh/iot/user-guide/device-properties-events-and-services 设备属性、事件、服务
|
||||
EVENT("event"), // 设备事件:可参考 https://help.aliyun.com/zh/iot/user-guide/device-properties-events-and-services 设备属性、事件、服务
|
||||
SERVICE("service"), // 设备服务:可参考 https://help.aliyun.com/zh/iot/user-guide/device-properties-events-and-services 设备属性、事件、服务
|
||||
CONFIG("config"), // 设备配置:可参考 https://help.aliyun.com/zh/iot/user-guide/remote-configuration-1 远程配置
|
||||
OTA("ota"), // 设备 OTA:可参考 https://help.aliyun.com/zh/iot/user-guide/ota-update OTA 升级
|
||||
REGISTER("register"), // 设备注册:可参考 https://help.aliyun.com/zh/iot/user-guide/register-devices 设备身份注册
|
||||
TOPOLOGY("topology"),; // 设备拓扑:可参考 https://help.aliyun.com/zh/iot/user-guide/manage-topological-relationships 设备拓扑
|
||||
|
||||
public static final String[] ARRAYS = Arrays.stream(values()).map(IotDeviceMessageTypeEnum::getType).toArray(String[]::new);
|
||||
|
||||
/**
|
||||
* 属性
|
||||
*/
|
||||
private final String type;
|
||||
|
||||
@Override
|
||||
public String[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
package cn.iocoder.yudao.module.iot.enums.device;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* IoT 设备状态枚举
|
||||
*
|
||||
* @author haohao
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Getter
|
||||
public enum IotDeviceStateEnum implements ArrayValuable<Integer> {
|
||||
|
||||
INACTIVE(0, "未激活"),
|
||||
ONLINE(1, "在线"),
|
||||
OFFLINE(2, "离线");
|
||||
|
||||
public static final Integer[] ARRAYS = Arrays.stream(values()).map(IotDeviceStateEnum::getState).toArray(Integer[]::new);
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
private final Integer state;
|
||||
/**
|
||||
* 状态名
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
@Override
|
||||
public Integer[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
public static boolean isOnline(Integer state) {
|
||||
return ONLINE.getState().equals(state);
|
||||
}
|
||||
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
package cn.iocoder.yudao.module.iot.enums.device;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* IoT 设备状态枚举
|
||||
*
|
||||
* @author haohao
|
||||
*/
|
||||
@Getter
|
||||
public enum IotDeviceStatusEnum implements ArrayValuable<Integer> {
|
||||
|
||||
INACTIVE(0, "未激活"),
|
||||
ONLINE(1, "在线"),
|
||||
OFFLINE(2, "离线"),
|
||||
DISABLED(3, "已禁用");
|
||||
|
||||
public static final Integer[] ARRAYS = Arrays.stream(values()).map(IotDeviceStatusEnum::getStatus).toArray(Integer[]::new);
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
private final Integer status;
|
||||
/**
|
||||
* 状态名
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
IotDeviceStatusEnum(Integer status, String name) {
|
||||
this.status = status;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public static IotDeviceStatusEnum fromStatus(Integer status) {
|
||||
for (IotDeviceStatusEnum value : values()) {
|
||||
if (value.getStatus().equals(status)) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isValidStatus(Integer status) {
|
||||
return fromStatus(status) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package cn.iocoder.yudao.module.iot.enums.ota;
|
||||
|
||||
|
||||
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* IoT OTA 升级记录的范围枚举
|
||||
*
|
||||
* @author haohao
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Getter
|
||||
public enum IotOtaUpgradeRecordStatusEnum implements ArrayValuable<Integer> {
|
||||
|
||||
PENDING(0), // 待推送
|
||||
PUSHED(10), // 已推送
|
||||
UPGRADING(20), // 升级中
|
||||
SUCCESS(30), // 升级成功
|
||||
FAILURE(40), // 升级失败
|
||||
CANCELED(50),; // 已取消
|
||||
|
||||
public static final Integer[] ARRAYS = Arrays.stream(values()).map(IotOtaUpgradeRecordStatusEnum::getStatus).toArray(Integer[]::new);
|
||||
|
||||
/**
|
||||
* 范围
|
||||
*/
|
||||
private final Integer status;
|
||||
|
||||
@Override
|
||||
public Integer[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package cn.iocoder.yudao.module.iot.enums.ota;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* IoT OTA 升级任务的范围枚举
|
||||
*
|
||||
* @author haohao
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Getter
|
||||
public enum IotOtaUpgradeTaskScopeEnum implements ArrayValuable<Integer> {
|
||||
|
||||
ALL(1), // 全部设备:只包括当前产品下的设备,不包括未来创建的设备
|
||||
SELECT(2); // 指定设备
|
||||
|
||||
public static final Integer[] ARRAYS = Arrays.stream(values()).map(IotOtaUpgradeTaskScopeEnum::getScope).toArray(Integer[]::new);
|
||||
|
||||
/**
|
||||
* 范围
|
||||
*/
|
||||
private final Integer scope;
|
||||
|
||||
@Override
|
||||
public Integer[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package cn.iocoder.yudao.module.iot.enums.ota;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* IoT OTA 升级任务的范围枚举
|
||||
*
|
||||
* @author haohao
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Getter
|
||||
public enum IotOtaUpgradeTaskStatusEnum implements ArrayValuable<Integer> {
|
||||
|
||||
IN_PROGRESS(10), // 进行中:升级中
|
||||
COMPLETED(20), // 已完成:已结束,全部升级完成
|
||||
INCOMPLETE(21), // 未完成:已结束,部分升级完成
|
||||
CANCELED(30),; // 已取消:一般是主动取消任务
|
||||
|
||||
public static final Integer[] ARRAYS = Arrays.stream(values()).map(IotOtaUpgradeTaskStatusEnum::getStatus).toArray(Integer[]::new);
|
||||
|
||||
/**
|
||||
* 范围
|
||||
*/
|
||||
private final Integer status;
|
||||
|
||||
@Override
|
||||
public Integer[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package cn.iocoder.yudao.module.iot.enums.plugin;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* IoT 部署方式枚举
|
||||
*
|
||||
* @author haohao
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Getter
|
||||
public enum IotPluginDeployTypeEnum implements ArrayValuable<Integer> {
|
||||
|
||||
JAR(0, "JAR 部署"),
|
||||
STANDALONE(1, "独立部署");
|
||||
|
||||
public static final Integer[] ARRAYS = Arrays.stream(values()).map(IotPluginDeployTypeEnum::getDeployType).toArray(Integer[]::new);
|
||||
|
||||
/**
|
||||
* 部署方式
|
||||
*/
|
||||
private final Integer deployType;
|
||||
/**
|
||||
* 部署方式名
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
@Override
|
||||
public Integer[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package cn.iocoder.yudao.module.iot.enums.plugin;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* IoT 插件状态枚举
|
||||
*
|
||||
* @author haohao
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Getter
|
||||
public enum IotPluginStatusEnum implements ArrayValuable<Integer> {
|
||||
|
||||
STOPPED(0, "停止"),
|
||||
RUNNING(1, "运行");
|
||||
|
||||
public static final Integer[] ARRAYS = Arrays.stream(values()).map(IotPluginStatusEnum::getStatus).toArray(Integer[]::new);
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
private final Integer status;
|
||||
/**
|
||||
* 状态名
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
@Override
|
||||
public Integer[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package cn.iocoder.yudao.module.iot.enums.plugin;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* IoT 插件类型枚举
|
||||
*
|
||||
* @author haohao
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum IotPluginTypeEnum implements ArrayValuable<Integer> {
|
||||
|
||||
NORMAL(0, "普通插件"),
|
||||
DEVICE(1, "设备插件");
|
||||
|
||||
public static final Integer[] ARRAYS = Arrays.stream(values()).map(IotPluginTypeEnum::getType).toArray(Integer[]::new);
|
||||
|
||||
/**
|
||||
* 类型
|
||||
*/
|
||||
private final Integer type;
|
||||
/**
|
||||
* 类型名
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
@Override
|
||||
public Integer[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
package cn.iocoder.yudao.module.iot.enums.product;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* IOT 访问方式枚举类
|
||||
*
|
||||
* @author ahh
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum IotAccessModeEnum {
|
||||
|
||||
READ("r"),
|
||||
WRITE("w"),
|
||||
READ_WRITE("rw");
|
||||
|
||||
private final String mode;
|
||||
|
||||
}
|
@ -7,7 +7,7 @@ import lombok.Getter;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* IOT 联网方式枚举类
|
||||
* IoT 联网方式枚举类
|
||||
*
|
||||
* @author ahh
|
||||
*/
|
||||
|
@ -7,7 +7,7 @@ import lombok.Getter;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* IOT 产品的设备类型
|
||||
* IoT 产品的设备类型
|
||||
*
|
||||
* @author ahh
|
||||
*/
|
||||
@ -16,7 +16,7 @@ import java.util.Arrays;
|
||||
public enum IotProductDeviceTypeEnum implements ArrayValuable<Integer> {
|
||||
|
||||
DIRECT(0, "直连设备"),
|
||||
GATEWAY_CHILD(1, "网关子设备"),
|
||||
GATEWAY_SUB(1, "网关子设备"),
|
||||
GATEWAY(2, "网关设备");
|
||||
|
||||
/**
|
||||
@ -36,4 +36,24 @@ public enum IotProductDeviceTypeEnum implements ArrayValuable<Integer> {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否是网关
|
||||
*
|
||||
* @param type 类型
|
||||
* @return 是否是网关
|
||||
*/
|
||||
public static boolean isGateway(Integer type) {
|
||||
return GATEWAY.getType().equals(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否是网关子设备
|
||||
*
|
||||
* @param type 类型
|
||||
* @return 是否是网关子设备
|
||||
*/
|
||||
public static boolean isGatewaySub(Integer type) {
|
||||
return GATEWAY_SUB.getType().equals(type);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ import lombok.Getter;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* IOT 产品的状态枚举类
|
||||
* IoT 产品的状态枚举类
|
||||
*
|
||||
* @author ahh
|
||||
*/
|
||||
@ -18,12 +18,12 @@ public enum IotProductStatusEnum implements ArrayValuable<Integer> {
|
||||
UNPUBLISHED(0, "开发中"),
|
||||
PUBLISHED(1, "已发布");
|
||||
|
||||
public static final Integer[] ARRAYS = Arrays.stream(values()).map(IotProductStatusEnum::getType).toArray(Integer[]::new);
|
||||
public static final Integer[] ARRAYS = Arrays.stream(values()).map(IotProductStatusEnum::getStatus).toArray(Integer[]::new);
|
||||
|
||||
/**
|
||||
* 类型
|
||||
*/
|
||||
private final Integer type;
|
||||
private final Integer status;
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
|
@ -7,7 +7,7 @@ import lombok.Getter;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* IOT 接入网关协议枚举类
|
||||
* IoT 接入网关协议枚举类
|
||||
*
|
||||
* @author ahh
|
||||
*/
|
||||
|
@ -7,7 +7,7 @@ import lombok.Getter;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* IOT 数据校验级别枚举类
|
||||
* IoT 数据校验级别枚举类
|
||||
*
|
||||
* @author ahh
|
||||
*/
|
||||
|
@ -0,0 +1,31 @@
|
||||
package cn.iocoder.yudao.module.iot.enums.rule;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* IoT 告警配置的接收方式枚举
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Getter
|
||||
public enum IotAlertConfigReceiveTypeEnum implements ArrayValuable<Integer> {
|
||||
|
||||
SMS(1), // 短信
|
||||
MAIL(2), // 邮箱
|
||||
NOTIFY(3); // 通知
|
||||
|
||||
private final Integer type;
|
||||
|
||||
public static final Integer[] ARRAYS = Arrays.stream(values()).map(IotAlertConfigReceiveTypeEnum::getType).toArray(Integer[]::new);
|
||||
|
||||
@Override
|
||||
public Integer[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package cn.iocoder.yudao.module.iot.enums.rule;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* IoT 数据桥接的方向枚举
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Getter
|
||||
public enum IotDataBridgeDirectionEnum implements ArrayValuable<Integer> {
|
||||
|
||||
INPUT(1), // 输入
|
||||
OUTPUT(2); // 输出
|
||||
|
||||
private final Integer type;
|
||||
|
||||
public static final Integer[] ARRAYS = Arrays.stream(values()).map(IotDataBridgeDirectionEnum::getType).toArray(Integer[]::new);
|
||||
|
||||
@Override
|
||||
public Integer[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
package cn.iocoder.yudao.module.iot.enums.rule;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* IoT 数据桥接的类型枚举
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Getter
|
||||
public enum IotDataBridgeTypeEnum implements ArrayValuable<Integer> {
|
||||
|
||||
HTTP(1, "HTTP"),
|
||||
TCP(2, "TCP"),
|
||||
WEBSOCKET(3, "WEBSOCKET"),
|
||||
|
||||
MQTT(10, "MQTT"),
|
||||
|
||||
DATABASE(20, "DATABASE"),
|
||||
REDIS_STREAM(21, "REDIS_STREAM"),
|
||||
|
||||
ROCKETMQ(30, "ROCKETMQ"),
|
||||
RABBITMQ(31, "RABBITMQ"),
|
||||
KAFKA(32, "KAFKA");
|
||||
|
||||
private final Integer type;
|
||||
|
||||
private final String name;
|
||||
|
||||
public static final Integer[] ARRAYS = Arrays.stream(values()).map(IotDataBridgeTypeEnum::getType).toArray(Integer[]::new);
|
||||
|
||||
@Override
|
||||
public Integer[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package cn.iocoder.yudao.module.iot.enums.rule;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* IoT 规则场景的触发类型枚举
|
||||
*
|
||||
* 设备触发,定时触发
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Getter
|
||||
public enum IotRuleSceneActionTypeEnum implements ArrayValuable<Integer> {
|
||||
|
||||
DEVICE_CONTROL(1), // 设备执行
|
||||
ALERT(2), // 告警执行
|
||||
DATA_BRIDGE(3); // 桥接执行
|
||||
|
||||
private final Integer type;
|
||||
|
||||
public static final Integer[] ARRAYS = Arrays.stream(values()).map(IotRuleSceneActionTypeEnum::getType).toArray(Integer[]::new);
|
||||
|
||||
@Override
|
||||
public Integer[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
package cn.iocoder.yudao.module.iot.enums.rule;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* IoT 场景触发条件参数的操作符枚举
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Getter
|
||||
public enum IotRuleSceneTriggerConditionParameterOperatorEnum implements ArrayValuable<String> {
|
||||
|
||||
EQUALS("=", "#source == #value"),
|
||||
NOT_EQUALS("!=", "!(#source == #value)"),
|
||||
|
||||
GREATER_THAN(">", "#source > #value"),
|
||||
GREATER_THAN_OR_EQUALS(">=", "#source >= #value"),
|
||||
|
||||
LESS_THAN("<", "#source < #value"),
|
||||
LESS_THAN_OR_EQUALS("<=", "#source <= #value"),
|
||||
|
||||
IN("in", "#values.contains(#source)"),
|
||||
NOT_IN("not in", "!(#values.contains(#source))"),
|
||||
|
||||
BETWEEN("between", "(#source >= #values.get(0)) && (#source <= #values.get(1))"),
|
||||
NOT_BETWEEN("not between", "(#source < #values.get(0)) || (#source > #values.get(1))"),
|
||||
|
||||
LIKE("like", "#source.contains(#value)"), // 字符串匹配
|
||||
NOT_NULL("not null", "#source != null && #source.length() > 0"); // 非空
|
||||
|
||||
private final String operator;
|
||||
private final String springExpression;
|
||||
|
||||
public static final String[] ARRAYS = Arrays.stream(values()).map(IotRuleSceneTriggerConditionParameterOperatorEnum::getOperator).toArray(String[]::new);
|
||||
|
||||
/**
|
||||
* Spring 表达式 - 原始值
|
||||
*/
|
||||
public static final String SPRING_EXPRESSION_SOURCE = "source";
|
||||
/**
|
||||
* Spring 表达式 - 目标值
|
||||
*/
|
||||
public static final String SPRING_EXPRESSION_VALUE = "value";
|
||||
/**
|
||||
* Spring 表达式 - 目标值数组
|
||||
*/
|
||||
public static final String SPRING_EXPRESSION_VALUE_List = "values";
|
||||
|
||||
public static IotRuleSceneTriggerConditionParameterOperatorEnum operatorOf(String operator) {
|
||||
return ArrayUtil.firstMatch(item -> item.getOperator().equals(operator), values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package cn.iocoder.yudao.module.iot.enums.rule;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* IoT 场景流转的触发类型枚举
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Getter
|
||||
public enum IotRuleSceneTriggerTypeEnum implements ArrayValuable<Integer> {
|
||||
|
||||
DEVICE(1), // 设备触发
|
||||
TIMER(2); // 定时触发
|
||||
|
||||
private final Integer type;
|
||||
|
||||
public static final Integer[] ARRAYS = Arrays.stream(values()).map(IotRuleSceneTriggerTypeEnum::getType).toArray(Integer[]::new);
|
||||
|
||||
@Override
|
||||
public Integer[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package cn.iocoder.yudao.module.iot.enums.thingmodel;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* IoT 数据定义的数据类型枚举类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum IotDataSpecsDataTypeEnum implements ArrayValuable<String> {
|
||||
|
||||
INT("int"),
|
||||
FLOAT("float"),
|
||||
DOUBLE("double"),
|
||||
ENUM("enum"),
|
||||
BOOL("bool"),
|
||||
TEXT("text"),
|
||||
DATE("date"),
|
||||
STRUCT("struct"),
|
||||
ARRAY("array");
|
||||
|
||||
public static final String[] ARRAYS = Arrays.stream(values()).map(IotDataSpecsDataTypeEnum::getDataType).toArray(String[]::new);
|
||||
|
||||
private final String dataType;
|
||||
|
||||
@Override
|
||||
public String[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package cn.iocoder.yudao.module.iot.enums.thingmodel;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* IoT 产品物模型属性读取类型枚举
|
||||
*
|
||||
* @author ahh
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum IotThingModelAccessModeEnum implements ArrayValuable<String> {
|
||||
|
||||
READ_ONLY("r"),
|
||||
READ_WRITE("rw");
|
||||
|
||||
public static final String[] ARRAYS = Arrays.stream(values()).map(IotThingModelAccessModeEnum::getMode).toArray(String[]::new);
|
||||
|
||||
private final String mode;
|
||||
|
||||
@Override
|
||||
public String[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package cn.iocoder.yudao.module.iot.enums.thingmodel;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
|
||||
/**
|
||||
* IoT 产品物模型参数是输入参数还是输出参数枚举
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum IotThingModelParamDirectionEnum implements ArrayValuable<String> {
|
||||
|
||||
INPUT("input"), // 输入参数
|
||||
OUTPUT("output"); // 输出参数
|
||||
|
||||
public static final String[] ARRAYS = Arrays.stream(values()).map(IotThingModelParamDirectionEnum::getDirection).toArray(String[]::new);
|
||||
|
||||
private final String direction;
|
||||
|
||||
@Override
|
||||
public String[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package cn.iocoder.yudao.module.iot.enums.thingmodel;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* IoT 产品物模型服务调用方式枚举
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum IotThingModelServiceCallTypeEnum implements ArrayValuable<String> {
|
||||
|
||||
ASYNC("async"), // 异步调用
|
||||
SYNC("sync"); // 同步调用
|
||||
|
||||
public static final String[] ARRAYS = Arrays.stream(values()).map(IotThingModelServiceCallTypeEnum::getType).toArray(String[]::new);
|
||||
|
||||
private final String type;
|
||||
|
||||
@Override
|
||||
public String[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package cn.iocoder.yudao.module.iot.enums.thingmodel;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* IoT 产品物模型事件类型枚举
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum IotThingModelServiceEventTypeEnum implements ArrayValuable<String> {
|
||||
|
||||
INFO("info"), // 信息
|
||||
ALERT("alert"), // 告警
|
||||
ERROR("error"); // 故障
|
||||
|
||||
public static final String[] ARRAYS = Arrays.stream(values()).map(IotThingModelServiceEventTypeEnum::getType).toArray(String[]::new);
|
||||
|
||||
private final String type;
|
||||
|
||||
@Override
|
||||
public String[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package cn.iocoder.yudao.module.iot.enums.product;
|
||||
package cn.iocoder.yudao.module.iot.enums.thingmodel;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
|
||||
import lombok.AllArgsConstructor;
|
||||
@ -7,19 +7,19 @@ import lombok.Getter;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* IOT 产品功能(物模型)类型枚举类
|
||||
* IoT 产品功能(物模型)类型枚举类
|
||||
*
|
||||
* @author ahh
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum IotProductFunctionTypeEnum implements ArrayValuable<Integer> {
|
||||
public enum IotThingModelTypeEnum implements ArrayValuable<Integer> {
|
||||
|
||||
PROPERTY(1, "属性"),
|
||||
SERVICE(2, "服务"),
|
||||
EVENT(3, "事件");
|
||||
|
||||
public static final Integer[] ARRAYS = Arrays.stream(values()).map(IotProductFunctionTypeEnum::getType).toArray(Integer[]::new);
|
||||
public static final Integer[] ARRAYS = Arrays.stream(values()).map(IotThingModelTypeEnum::getType).toArray(Integer[]::new);
|
||||
|
||||
/**
|
||||
* 类型
|
@ -25,6 +25,11 @@
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-biz-tenant</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Web 相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
@ -37,11 +42,21 @@
|
||||
</dependency>
|
||||
|
||||
<!-- DB 相关 -->
|
||||
<dependency>
|
||||
<groupId>com.taosdata.jdbc</groupId>
|
||||
<artifactId>taos-jdbcdriver</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-mybatis</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-redis</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Test 测试相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
@ -54,11 +69,64 @@
|
||||
<artifactId>yudao-spring-boot-starter-excel</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- MQTT -->
|
||||
<!-- 消息队列相关 -->
|
||||
<dependency>
|
||||
<groupId>org.eclipse.paho</groupId>
|
||||
<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
|
||||
<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>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.pf4j</groupId> <!-- PF4J:内置插件机制 -->
|
||||
<artifactId>pf4j-spring</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- TODO @芋艿:bom 管理 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.groovy</groupId>
|
||||
<artifactId>groovy-all</artifactId>
|
||||
<version>4.0.25</version>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
|
||||
<!-- TODO @芋艿:bom 管理 -->
|
||||
<dependency>
|
||||
<groupId>org.graalvm.js</groupId>
|
||||
<artifactId>js</artifactId>
|
||||
<version>24.1.2</version>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.graalvm.js</groupId>
|
||||
<artifactId>js-scriptengine</artifactId>
|
||||
<version>24.1.2</version>
|
||||
</dependency>
|
||||
|
||||
<!-- TODO @芋艿:合理注释 -->
|
||||
<!-- IoT 数据桥梁的执行器所需消息队列。如果您只需要使用 rocketmq 那么则注释掉其它消息队列即可 -->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.apache.rocketmq</groupId>-->
|
||||
<!-- <artifactId>rocketmq-spring-boot-starter</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.springframework.kafka</groupId>-->
|
||||
<!-- <artifactId>spring-kafka</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.springframework.boot</groupId>-->
|
||||
<!-- <artifactId>spring-boot-starter-amqp</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
@ -0,0 +1,61 @@
|
||||
package cn.iocoder.yudao.module.iot;
|
||||
|
||||
import cn.hutool.script.ScriptUtil;
|
||||
import javax.script.Bindings;
|
||||
import javax.script.ScriptEngine;
|
||||
import javax.script.ScriptException;
|
||||
|
||||
/**
|
||||
* TODO 芋艿:测试脚本的接入
|
||||
*/
|
||||
public class ScriptTest {
|
||||
|
||||
public static void main2(String[] args) {
|
||||
// 创建一个 Groovy 脚本引擎
|
||||
ScriptEngine engine = ScriptUtil.createGroovyEngine();
|
||||
|
||||
// 创建绑定参数
|
||||
Bindings bindings = engine.createBindings();
|
||||
bindings.put("name", "Alice");
|
||||
bindings.put("age", 30);
|
||||
|
||||
// 定义一个稍微复杂的 Groovy 脚本
|
||||
String script = "def greeting = 'Hello, ' + name + '!';\n" +
|
||||
"def ageInFiveYears = age + 5;\n" +
|
||||
"def message = greeting + ' In five years, you will be ' + ageInFiveYears + ' years old.';\n" +
|
||||
"return message.toUpperCase();\n";
|
||||
|
||||
try {
|
||||
// 执行脚本并获取结果
|
||||
Object result = engine.eval(script, bindings);
|
||||
System.out.println(result); // 输出: HELLO, ALICE! IN FIVE YEARS, YOU WILL BE 35 YEARS OLD.
|
||||
} catch (ScriptException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
// 创建一个 JavaScript 脚本引擎
|
||||
ScriptEngine jsEngine = ScriptUtil.createJsEngine();
|
||||
|
||||
// 创建绑定参数
|
||||
Bindings jsBindings = jsEngine.createBindings();
|
||||
jsBindings.put("name", "Bob");
|
||||
jsBindings.put("age", 25);
|
||||
|
||||
// 定义一个简单的 JavaScript 脚本
|
||||
String jsScript = "var greeting = 'Hello, ' + name + '!';\n" +
|
||||
"var ageInTenYears = age + 10;\n" +
|
||||
"var message = greeting + ' In ten years, you will be ' + ageInTenYears + ' years old.';\n" +
|
||||
"message.toUpperCase();\n";
|
||||
|
||||
try {
|
||||
// 执行脚本并获取结果
|
||||
Object jsResult = jsEngine.eval(jsScript, jsBindings);
|
||||
System.out.println(jsResult); // 输出: HELLO, BOB! IN TEN YEARS, YOU WILL BE 35 YEARS OLD.
|
||||
} catch (ScriptException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
package cn.iocoder.yudao.module.iot.api.device;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.module.iot.api.device.dto.control.upstream.*;
|
||||
import cn.iocoder.yudao.module.iot.service.device.control.IotDeviceUpstreamService;
|
||||
import cn.iocoder.yudao.module.iot.service.plugin.IotPluginInstanceService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
/**
|
||||
* * 设备数据 Upstream 上行 API 实现类
|
||||
*/
|
||||
@RestController
|
||||
@Validated
|
||||
public class IoTDeviceUpstreamApiImpl implements IotDeviceUpstreamApi {
|
||||
|
||||
@Resource
|
||||
private IotDeviceUpstreamService deviceUpstreamService;
|
||||
@Resource
|
||||
private IotPluginInstanceService pluginInstanceService;
|
||||
|
||||
// ========== 设备相关 ==========
|
||||
|
||||
@Override
|
||||
public CommonResult<Boolean> updateDeviceState(IotDeviceStateUpdateReqDTO updateReqDTO) {
|
||||
deviceUpstreamService.updateDeviceState(updateReqDTO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<Boolean> reportDeviceProperty(IotDevicePropertyReportReqDTO reportReqDTO) {
|
||||
deviceUpstreamService.reportDeviceProperty(reportReqDTO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<Boolean> reportDeviceEvent(IotDeviceEventReportReqDTO reportReqDTO) {
|
||||
deviceUpstreamService.reportDeviceEvent(reportReqDTO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<Boolean> registerDevice(IotDeviceRegisterReqDTO registerReqDTO) {
|
||||
deviceUpstreamService.registerDevice(registerReqDTO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<Boolean> registerSubDevice(IotDeviceRegisterSubReqDTO registerReqDTO) {
|
||||
deviceUpstreamService.registerSubDevice(registerReqDTO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<Boolean> addDeviceTopology(IotDeviceTopologyAddReqDTO addReqDTO) {
|
||||
deviceUpstreamService.addDeviceTopology(addReqDTO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<Boolean> authenticateEmqxConnection(IotDeviceEmqxAuthReqDTO authReqDTO) {
|
||||
boolean result = deviceUpstreamService.authenticateEmqxConnection(authReqDTO);
|
||||
return success(result);
|
||||
}
|
||||
|
||||
// ========== 插件相关 ==========
|
||||
|
||||
@Override
|
||||
public CommonResult<Boolean> heartbeatPluginInstance(IotPluginInstanceHeartbeatReqDTO heartbeatReqDTO) {
|
||||
pluginInstanceService.heartbeatPluginInstance(heartbeatReqDTO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
/**
|
||||
* 占位
|
||||
*
|
||||
* TODO 芋艿:后续删除
|
||||
*/
|
||||
package cn.iocoder.yudao.module.iot.api;
|
@ -0,0 +1,75 @@
|
||||
### 请求 /iot/device/downstream 接口(服务调用) => 成功
|
||||
POST {{baseUrl}}/iot/device/downstream
|
||||
Content-Type: application/json
|
||||
tenant-id: {{adminTenentId}}
|
||||
Authorization: Bearer {{token}}
|
||||
|
||||
{
|
||||
"id": 25,
|
||||
"type": "service",
|
||||
"identifier": "temperature",
|
||||
"data": {
|
||||
"xx": "yy"
|
||||
}
|
||||
}
|
||||
|
||||
### 请求 /iot/device/downstream 接口(属性设置) => 成功
|
||||
POST {{baseUrl}}/iot/device/downstream
|
||||
Content-Type: application/json
|
||||
tenant-id: {{adminTenentId}}
|
||||
Authorization: Bearer {{token}}
|
||||
|
||||
{
|
||||
"id": 25,
|
||||
"type": "property",
|
||||
"identifier": "set",
|
||||
"data": {
|
||||
"xx": "yy"
|
||||
}
|
||||
}
|
||||
|
||||
### 请求 /iot/device/downstream 接口(属性获取) => 成功
|
||||
POST {{baseUrl}}/iot/device/downstream
|
||||
Content-Type: application/json
|
||||
tenant-id: {{adminTenentId}}
|
||||
Authorization: Bearer {{token}}
|
||||
|
||||
{
|
||||
"id": 25,
|
||||
"type": "property",
|
||||
"identifier": "get",
|
||||
"data": ["xx", "yy"]
|
||||
}
|
||||
|
||||
### 请求 /iot/device/downstream 接口(配置设置) => 成功
|
||||
POST {{baseUrl}}/iot/device/downstream
|
||||
Content-Type: application/json
|
||||
tenant-id: {{adminTenentId}}
|
||||
Authorization: Bearer {{token}}
|
||||
|
||||
{
|
||||
"id": 25,
|
||||
"type": "config",
|
||||
"identifier": "set"
|
||||
}
|
||||
|
||||
### 请求 /iot/device/downstream 接口(OTA 升级) => 成功
|
||||
POST {{baseUrl}}/iot/device/downstream
|
||||
Content-Type: application/json
|
||||
tenant-id: {{adminTenentId}}
|
||||
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\":\"升级到最新版本\"}"
|
||||
}
|
||||
}
|
@ -1,24 +1,37 @@
|
||||
package cn.iocoder.yudao.module.iot.controller.admin.device;
|
||||
|
||||
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDevicePageReqVO;
|
||||
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDeviceRespVO;
|
||||
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDeviceSaveReqVO;
|
||||
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDeviceStatusUpdateReqVO;
|
||||
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
||||
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.control.IotDeviceDownstreamReqVO;
|
||||
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.control.IotDeviceUpstreamReqVO;
|
||||
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.*;
|
||||
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
|
||||
import cn.iocoder.yudao.module.iot.service.device.IotDeviceService;
|
||||
import cn.iocoder.yudao.module.iot.service.device.control.IotDeviceDownstreamService;
|
||||
import cn.iocoder.yudao.module.iot.service.device.control.IotDeviceUpstreamService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.Valid;
|
||||
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 java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||
|
||||
@Tag(name = "管理后台 - IoT 设备")
|
||||
@RestController
|
||||
@ -28,6 +41,10 @@ public class IotDeviceController {
|
||||
|
||||
@Resource
|
||||
private IotDeviceService deviceService;
|
||||
@Resource
|
||||
private IotDeviceUpstreamService deviceUpstreamService;
|
||||
@Resource
|
||||
private IotDeviceDownstreamService deviceDownstreamService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建设备")
|
||||
@ -36,14 +53,6 @@ public class IotDeviceController {
|
||||
return success(deviceService.createDevice(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update-status")
|
||||
@Operation(summary = "更新设备状态")
|
||||
@PreAuthorize("@ss.hasPermission('iot:device:update')")
|
||||
public CommonResult<Boolean> updateDeviceStatus(@Valid @RequestBody IotDeviceStatusUpdateReqVO updateReqVO) {
|
||||
deviceService.updateDeviceStatus(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新设备")
|
||||
@PreAuthorize("@ss.hasPermission('iot:device:update')")
|
||||
@ -52,8 +61,18 @@ public class IotDeviceController {
|
||||
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 = "删除设备")
|
||||
@Operation(summary = "删除单个设备")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('iot:device:delete')")
|
||||
public CommonResult<Boolean> deleteDevice(@RequestParam("id") Long id) {
|
||||
@ -61,6 +80,15 @@ public class IotDeviceController {
|
||||
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")
|
||||
@ -78,6 +106,19 @@ public class IotDeviceController {
|
||||
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")
|
||||
@ -86,4 +127,62 @@ public class IotDeviceController {
|
||||
return success(deviceService.getDeviceCountByProductId(productId));
|
||||
}
|
||||
|
||||
@GetMapping("/simple-list")
|
||||
@Operation(summary = "获取设备的精简信息列表", description = "主要用于前端的下拉选项")
|
||||
@Parameter(name = "deviceType", description = "设备类型", example = "1")
|
||||
public CommonResult<List<IotDeviceRespVO>> getSimpleDeviceList(
|
||||
@RequestParam(value = "deviceType", required = false) Integer deviceType) {
|
||||
List<IotDeviceDO> list = deviceService.getDeviceListByDeviceType(deviceType);
|
||||
return success(convertList(list, device -> // 只返回 id、name 字段
|
||||
new IotDeviceRespVO().setId(device.getId()).setDeviceName(device.getDeviceName())));
|
||||
}
|
||||
|
||||
@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("灰度分组,生产分组").build(),
|
||||
IotDeviceImportExcelVO.builder().deviceName("biubiu")
|
||||
.productKey("YzvHxd4r67sT4s2B").groupNames("").build());
|
||||
// 输出
|
||||
ExcelUtils.write(response, "设备导入模板.xls", "数据", IotDeviceImportExcelVO.class, list);
|
||||
}
|
||||
|
||||
@PostMapping("/upstream")
|
||||
@Operation(summary = "设备上行", description = "可用于设备模拟")
|
||||
@PreAuthorize("@ss.hasPermission('iot:device:upstream')")
|
||||
public CommonResult<Boolean> upstreamDevice(@Valid @RequestBody IotDeviceUpstreamReqVO upstreamReqVO) {
|
||||
deviceUpstreamService.upstreamDevice(upstreamReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PostMapping("/downstream")
|
||||
@Operation(summary = "设备下行", description = "可用于设备模拟")
|
||||
@PreAuthorize("@ss.hasPermission('iot:device:downstream')")
|
||||
public CommonResult<Boolean> downstreamDevice(@Valid @RequestBody IotDeviceDownstreamReqVO downstreamReqVO) {
|
||||
deviceDownstreamService.downstreamDevice(downstreamReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
// TODO @haohao:是不是默认详情接口,不返回 secret,然后这个接口,用于统一返回。然后接口名可以更通用一点。
|
||||
@GetMapping("/mqtt-connection-params")
|
||||
@Operation(summary = "获取 MQTT 连接参数")
|
||||
@PreAuthorize("@ss.hasPermission('iot:device:mqtt-connection-params')")
|
||||
public CommonResult<IotDeviceMqttConnectionParamsRespVO> getMqttConnectionParams(@RequestParam("deviceId") Long deviceId) {
|
||||
return success(deviceService.getMqttConnectionParams(deviceId));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
package cn.iocoder.yudao.module.iot.controller.admin.device;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.group.IotDeviceGroupPageReqVO;
|
||||
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.group.IotDeviceGroupRespVO;
|
||||
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.group.IotDeviceGroupSaveReqVO;
|
||||
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceGroupDO;
|
||||
import cn.iocoder.yudao.module.iot.service.device.IotDeviceGroupService;
|
||||
import cn.iocoder.yudao.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 jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||
|
||||
@Tag(name = "管理后台 - IoT 设备分组")
|
||||
@RestController
|
||||
@RequestMapping("/iot/device-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,39 @@
|
||||
package cn.iocoder.yudao.module.iot.controller.admin.device;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDeviceLogPageReqVO;
|
||||
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDeviceLogRespVO;
|
||||
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceLogDO;
|
||||
import cn.iocoder.yudao.module.iot.service.device.data.IotDeviceLogService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
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.RestController;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - IoT 设备日志")
|
||||
@RestController
|
||||
@RequestMapping("/iot/device/log")
|
||||
@Validated
|
||||
public class IotDeviceLogController {
|
||||
|
||||
@Resource
|
||||
private IotDeviceLogService deviceLogService;
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得设备日志分页")
|
||||
@PreAuthorize("@ss.hasPermission('iot:device:log-query')")
|
||||
public CommonResult<PageResult<IotDeviceLogRespVO>> getDeviceLogPage(@Valid IotDeviceLogPageReqVO pageReqVO) {
|
||||
PageResult<IotDeviceLogDO> pageResult = deviceLogService.getDeviceLogPage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, IotDeviceLogRespVO.class));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,95 @@
|
||||
package cn.iocoder.yudao.module.iot.controller.admin.device;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDevicePropertyHistoryPageReqVO;
|
||||
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDevicePropertyRespVO;
|
||||
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
|
||||
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDevicePropertyDO;
|
||||
import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO;
|
||||
import cn.iocoder.yudao.module.iot.service.device.IotDeviceService;
|
||||
import cn.iocoder.yudao.module.iot.service.device.data.IotDevicePropertyService;
|
||||
import cn.iocoder.yudao.module.iot.service.thingmodel.IotThingModelService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Parameters;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
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 java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||
|
||||
@Tag(name = "管理后台 - IoT 设备属性")
|
||||
@RestController
|
||||
@RequestMapping("/iot/device/property")
|
||||
@Validated
|
||||
public class IotDevicePropertyController {
|
||||
|
||||
@Resource
|
||||
private IotDevicePropertyService devicePropertyService;
|
||||
@Resource
|
||||
private IotThingModelService thingModelService;
|
||||
@Resource
|
||||
private IotDeviceService deviceService;
|
||||
|
||||
@GetMapping("/latest")
|
||||
@Operation(summary = "获取设备属性最新属性")
|
||||
@Parameters({
|
||||
@Parameter(name = "deviceId", description = "设备编号", required = true),
|
||||
@Parameter(name = "identifier", description = "标识符"),
|
||||
@Parameter(name = "name", description = "名称")
|
||||
})
|
||||
@PreAuthorize("@ss.hasPermission('iot:device:property-query')")
|
||||
public CommonResult<List<IotDevicePropertyRespVO>> getLatestDeviceProperties(
|
||||
@RequestParam("deviceId") Long deviceId,
|
||||
@RequestParam(value = "identifier", required = false) String identifier,
|
||||
@RequestParam(value = "name", required = false) String name) {
|
||||
Map<String, IotDevicePropertyDO> properties = devicePropertyService.getLatestDeviceProperties(deviceId);
|
||||
|
||||
// 拼接数据
|
||||
IotDeviceDO device = deviceService.getDevice(deviceId);
|
||||
Assert.notNull(device, "设备不存在");
|
||||
List<IotThingModelDO> thingModels = thingModelService.getThingModelListByProductId(device.getProductId());
|
||||
return success(convertList(properties.entrySet(), entry -> {
|
||||
IotThingModelDO thingModel = CollUtil.findOne(thingModels,
|
||||
item -> item.getIdentifier().equals(entry.getKey()));
|
||||
if (thingModel == null || thingModel.getProperty() == null) {
|
||||
return null;
|
||||
}
|
||||
if (StrUtil.isNotEmpty(identifier) && !StrUtil.contains(thingModel.getIdentifier(), identifier)) {
|
||||
return null;
|
||||
}
|
||||
if (StrUtil.isNotEmpty(name) && !StrUtil.contains(thingModel.getName(), name)) {
|
||||
return null;
|
||||
}
|
||||
// 构建对象
|
||||
IotDevicePropertyDO property = entry.getValue();
|
||||
return new IotDevicePropertyRespVO().setProperty(thingModel.getProperty())
|
||||
.setValue(property.getValue()).setUpdateTime(LocalDateTimeUtil.toEpochMilli(property.getUpdateTime()));
|
||||
}));
|
||||
}
|
||||
|
||||
@GetMapping("/history-page")
|
||||
@Operation(summary = "获取设备属性历史数据")
|
||||
@PreAuthorize("@ss.hasPermission('iot:device:property-query')")
|
||||
public CommonResult<PageResult<IotDevicePropertyRespVO>> getHistoryDevicePropertyPage(
|
||||
@Valid IotDevicePropertyHistoryPageReqVO pageReqVO) {
|
||||
Assert.notEmpty(pageReqVO.getIdentifier(), "标识符不能为空");
|
||||
return success(devicePropertyService.getHistoryDevicePropertyPage(pageReqVO));
|
||||
}
|
||||
|
||||
}
|
@ -1,87 +0,0 @@
|
||||
package cn.iocoder.yudao.module.iot.controller.admin.device.vo;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStatusEnum;
|
||||
import cn.iocoder.yudao.module.iot.enums.product.IotProductDeviceTypeEnum;
|
||||
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.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 设备分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class IotDevicePageReqVO extends PageParam {
|
||||
|
||||
// TODO @芋艿:需要去掉一些多余的字段;
|
||||
|
||||
@Schema(description = "设备唯一标识符", example = "24602")
|
||||
private String deviceKey;
|
||||
|
||||
@Schema(description = "设备名称", example = "王五")
|
||||
private String deviceName;
|
||||
|
||||
@Schema(description = "备注名称", example = "张三")
|
||||
private String nickname;
|
||||
|
||||
@Schema(description = "产品编号", example = "26202")
|
||||
private Long productId;
|
||||
|
||||
@Schema(description = "产品标识")
|
||||
private String productKey;
|
||||
|
||||
@Schema(description = "设备类型", example = "1")
|
||||
@InEnum(IotProductDeviceTypeEnum.class)
|
||||
private Integer deviceType;
|
||||
|
||||
@Schema(description = "网关设备 ID", example = "16380")
|
||||
private Long gatewayId;
|
||||
|
||||
@Schema(description = "设备状态", example = "1")
|
||||
@InEnum(IotDeviceStatusEnum.class)
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "设备状态最后更新时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] statusLastUpdateTime;
|
||||
|
||||
@Schema(description = "最后上线时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] lastOnlineTime;
|
||||
|
||||
@Schema(description = "最后离线时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] lastOfflineTime;
|
||||
|
||||
@Schema(description = "设备激活时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] activeTime;
|
||||
|
||||
@Schema(description = "设备密钥,用于设备认证,需安全存储")
|
||||
private String deviceSecret;
|
||||
|
||||
@Schema(description = "MQTT 客户端 ID", example = "24602")
|
||||
private String mqttClientId;
|
||||
|
||||
@Schema(description = "MQTT 用户名", example = "芋艿")
|
||||
private String mqttUsername;
|
||||
|
||||
@Schema(description = "MQTT 密码")
|
||||
private String mqttPassword;
|
||||
|
||||
@Schema(description = "认证类型(如一机一密、动态注册)", example = "2")
|
||||
private String authType;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
package cn.iocoder.yudao.module.iot.controller.admin.device.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 设备新增/修改 Request VO")
|
||||
@Data
|
||||
public class IotDeviceSaveReqVO {
|
||||
|
||||
@Schema(description = "设备编号", example = "177")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "设备名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五")
|
||||
private String deviceName;
|
||||
|
||||
@Schema(description = "备注名称", example = "张三")
|
||||
private String nickname;
|
||||
|
||||
@Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "26202")
|
||||
private Long productId;
|
||||
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
package cn.iocoder.yudao.module.iot.controller.admin.device.vo;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStatusEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 设备状态更新 Request VO")
|
||||
@Data
|
||||
public class IotDeviceStatusUpdateReqVO {
|
||||
|
||||
@Schema(description = "设备编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "设备编号不能为空")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "设备状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "设备状态不能为空")
|
||||
@InEnum(IotDeviceStatusEnum.class)
|
||||
private Integer status;
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package cn.iocoder.yudao.module.iot.controller.admin.device.vo.control;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 设备下行 Request VO") // 服务调用、属性设置、属性获取等
|
||||
@Data
|
||||
public class IotDeviceDownstreamReqVO {
|
||||
|
||||
@Schema(description = "设备编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "177")
|
||||
@NotNull(message = "设备编号不能为空")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "消息类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "property")
|
||||
@NotEmpty(message = "消息类型不能为空")
|
||||
@InEnum(IotDeviceMessageTypeEnum.class)
|
||||
private String type;
|
||||
|
||||
@Schema(description = "标识符", requiredMode = Schema.RequiredMode.REQUIRED, example = "report")
|
||||
@NotEmpty(message = "标识符不能为空")
|
||||
private String identifier; // 参见 IotDeviceMessageIdentifierEnum 枚举类
|
||||
|
||||
@Schema(description = "请求参数", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Object data; // 例如说:服务调用的 params、属性设置的 properties
|
||||
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package cn.iocoder.yudao.module.iot.controller.admin.device.vo.control;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 设备上行 Request VO") // 属性上报、事件上报、状态变更等
|
||||
@Data
|
||||
public class IotDeviceUpstreamReqVO {
|
||||
|
||||
@Schema(description = "设备编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "177")
|
||||
@NotNull(message = "设备编号不能为空")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "消息类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "property")
|
||||
@NotEmpty(message = "消息类型不能为空")
|
||||
@InEnum(IotDeviceMessageTypeEnum.class)
|
||||
private String type;
|
||||
|
||||
@Schema(description = "标识符", requiredMode = Schema.RequiredMode.REQUIRED, example = "report")
|
||||
@NotEmpty(message = "标识符不能为空")
|
||||
private String identifier; // 参见 IotDeviceMessageIdentifierEnum 枚举类
|
||||
|
||||
@Schema(description = "请求参数", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Object data; // 例如说:属性上报的 properties、事件上报的 params
|
||||
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package cn.iocoder.yudao.module.iot.controller.admin.device.vo.data;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 设备日志分页查询 Request VO")
|
||||
@Data
|
||||
public class IotDeviceLogPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "设备标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "device123")
|
||||
@NotEmpty(message = "设备标识不能为空")
|
||||
private String deviceKey;
|
||||
|
||||
@Schema(description = "消息类型", example = "property")
|
||||
private String type; // 参见 IotDeviceMessageTypeEnum 枚举,精准匹配
|
||||
|
||||
@Schema(description = "标识符", example = "temperature")
|
||||
private String identifier; // 参见 IotDeviceMessageIdentifierEnum 枚举,模糊匹配
|
||||
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package cn.iocoder.yudao.module.iot.controller.admin.device.vo.data;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 设备日志 Response VO")
|
||||
@Data
|
||||
public class IotDeviceLogRespVO {
|
||||
|
||||
@Schema(description = "日志编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private String id;
|
||||
|
||||
@Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "product123")
|
||||
private String productKey;
|
||||
|
||||
@Schema(description = "设备标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "device123")
|
||||
private String deviceKey;
|
||||
|
||||
@Schema(description = "消息类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "property")
|
||||
private String type;
|
||||
|
||||
@Schema(description = "标识符", requiredMode = Schema.RequiredMode.REQUIRED, example = "temperature")
|
||||
private String identifier;
|
||||
|
||||
@Schema(description = "日志内容", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String content;
|
||||
|
||||
@Schema(description = "上报时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime reportTime;
|
||||
|
||||
@Schema(description = "记录时间戳", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime ts;
|
||||
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package cn.iocoder.yudao.module.iot.controller.admin.device.vo.data;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 设备属性历史分页 Request VO")
|
||||
@Data
|
||||
public class IotDevicePropertyHistoryPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "设备编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "177")
|
||||
@NotNull(message = "设备编号不能为空")
|
||||
private Long deviceId;
|
||||
|
||||
@Schema(description = "设备 Key", hidden = true)
|
||||
private String deviceKey; // 非前端传递,后端自己查询设置
|
||||
|
||||
@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,20 @@
|
||||
package cn.iocoder.yudao.module.iot.controller.admin.device.vo.data;
|
||||
|
||||
import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelProperty;
|
||||
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 ThingModelProperty property;
|
||||
|
||||
@Schema(description = "最新值", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Object value;
|
||||
|
||||
@Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Long updateTime; // 由于从 TDengine 查询出来的是 Long 类型,所以这里也使用 Long 类型
|
||||
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package cn.iocoder.yudao.module.iot.controller.admin.device.vo.device;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 设备 Excel 导入 VO
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Accessors(chain = false) // 设置 chain = false,避免设备导入有问题
|
||||
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;
|
||||
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package cn.iocoder.yudao.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,25 @@
|
||||
package cn.iocoder.yudao.module.iot.controller.admin.device.vo.device;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 设备 MQTT 连接参数 Response VO")
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
public class IotDeviceMqttConnectionParamsRespVO {
|
||||
|
||||
@Schema(description = "MQTT 客户端 ID", example = "24602")
|
||||
@ExcelProperty("MQTT 客户端 ID")
|
||||
private String mqttClientId;
|
||||
|
||||
@Schema(description = "MQTT 用户名", example = "芋艿")
|
||||
@ExcelProperty("MQTT 用户名")
|
||||
private String mqttUsername;
|
||||
|
||||
@Schema(description = "MQTT 密码")
|
||||
@ExcelProperty("MQTT 密码")
|
||||
private String mqttPassword;
|
||||
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package cn.iocoder.yudao.module.iot.controller.admin.device.vo.device;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStateEnum;
|
||||
import cn.iocoder.yudao.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;
|
||||
|
||||
}
|
@ -1,12 +1,16 @@
|
||||
package cn.iocoder.yudao.module.iot.controller.admin.device.vo;
|
||||
package cn.iocoder.yudao.module.iot.controller.admin.device.vo.device;
|
||||
|
||||
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
|
||||
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
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.iocoder.yudao.module.iot.enums.DictTypeConstants.DEVICE_STATE;
|
||||
|
||||
@Schema(description = "管理后台 - IoT 设备 Response VO")
|
||||
@Data
|
||||
@ -21,9 +25,24 @@ public class IotDeviceRespVO {
|
||||
private String deviceKey;
|
||||
|
||||
@Schema(description = "设备名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五")
|
||||
@ExcelProperty("设备名称备")
|
||||
@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;
|
||||
@ -36,28 +55,21 @@ public class IotDeviceRespVO {
|
||||
@ExcelProperty("设备类型")
|
||||
private Integer deviceType;
|
||||
|
||||
@Schema(description = "设备备注名称", example = "张三")
|
||||
@ExcelProperty("设备备注名称")
|
||||
private String nickname;
|
||||
|
||||
@Schema(description = "网关设备 ID", example = "16380")
|
||||
private Long gatewayId;
|
||||
|
||||
@Schema(description = "设备状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@ExcelProperty("设备状态")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "设备状态最后更新时间")
|
||||
@ExcelProperty("设备状态最后更新时间")
|
||||
private LocalDateTime statusLastUpdateTime;
|
||||
@ExcelProperty(value = "设备状态", converter = DictConvert.class)
|
||||
@DictFormat(DEVICE_STATE)
|
||||
private Integer state;
|
||||
|
||||
@Schema(description = "最后上线时间")
|
||||
@ExcelProperty("最后上线时间")
|
||||
private LocalDateTime lastOnlineTime;
|
||||
private LocalDateTime onlineTime;
|
||||
|
||||
@Schema(description = "最后离线时间")
|
||||
@ExcelProperty("最后离线时间")
|
||||
private LocalDateTime lastOfflineTime;
|
||||
private LocalDateTime offlineTime;
|
||||
|
||||
@Schema(description = "设备激活时间")
|
||||
@ExcelProperty("设备激活时间")
|
||||
@ -67,22 +79,13 @@ public class IotDeviceRespVO {
|
||||
@ExcelProperty("设备密钥")
|
||||
private String deviceSecret;
|
||||
|
||||
@Schema(description = "MQTT 客户端 ID", example = "24602")
|
||||
@ExcelProperty("MQTT 客户端 ID")
|
||||
private String mqttClientId;
|
||||
|
||||
@Schema(description = "MQTT 用户名", example = "芋艿")
|
||||
@ExcelProperty("MQTT 用户名")
|
||||
private String mqttUsername;
|
||||
|
||||
@Schema(description = "MQTT 密码")
|
||||
@ExcelProperty("MQTT 密码")
|
||||
private String mqttPassword;
|
||||
|
||||
@Schema(description = "认证类型(如一机一密、动态注册)", example = "2")
|
||||
@ExcelProperty("认证类型(如一机一密、动态注册)")
|
||||
private String authType;
|
||||
|
||||
@Schema(description = "设备配置", example = "{\"abc\": \"efg\"}")
|
||||
private String config;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@ExcelProperty("创建时间")
|
||||
private LocalDateTime createTime;
|
@ -0,0 +1,44 @@
|
||||
package cn.iocoder.yudao.module.iot.controller.admin.device.vo.device;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
|
||||
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 = "177")
|
||||
@Size(max = 50, message = "设备编号长度不能超过 50 个字符")
|
||||
private String deviceKey;
|
||||
|
||||
@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;
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package cn.iocoder.yudao.module.iot.controller.admin.device.vo.device;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import lombok.Data;
|
||||
|
||||
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.iocoder.yudao.module.iot.controller.admin.device.vo.group;
|
||||
|
||||
import cn.iocoder.yudao.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.iocoder.yudao.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.iocoder.yudao.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,26 @@
|
||||
package cn.iocoder.yudao.module.iot.controller.admin.device.vo.group;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
@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,62 @@
|
||||
package cn.iocoder.yudao.module.iot.controller.admin.ota;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.iot.controller.admin.ota.vo.firmware.IotOtaFirmwarePageReqVO;
|
||||
import cn.iocoder.yudao.module.iot.controller.admin.ota.vo.firmware.IotOtaFirmwareRespVO;
|
||||
import cn.iocoder.yudao.module.iot.controller.admin.ota.vo.firmware.IotOtaFirmwareCreateReqVO;
|
||||
import cn.iocoder.yudao.module.iot.controller.admin.ota.vo.firmware.IotOtaFirmwareUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.iot.dal.dataobject.ota.IotOtaFirmwareDO;
|
||||
import cn.iocoder.yudao.module.iot.service.ota.IotOtaFirmwareService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - IoT OTA 固件")
|
||||
@RestController
|
||||
@RequestMapping("/iot/ota-firmware")
|
||||
@Validated
|
||||
public class IotOtaFirmwareController {
|
||||
|
||||
@Resource
|
||||
private IotOtaFirmwareService otaFirmwareService;
|
||||
|
||||
@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 otaFirmware = otaFirmwareService.getOtaFirmware(id);
|
||||
return success(BeanUtils.toBean(otaFirmware, IotOtaFirmwareRespVO.class));
|
||||
}
|
||||
|
||||
@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,75 @@
|
||||
package cn.iocoder.yudao.module.iot.controller.admin.ota;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.iot.controller.admin.ota.vo.upgrade.record.IotOtaUpgradeRecordPageReqVO;
|
||||
import cn.iocoder.yudao.module.iot.controller.admin.ota.vo.upgrade.record.IotOtaUpgradeRecordRespVO;
|
||||
import cn.iocoder.yudao.module.iot.dal.dataobject.ota.IotOtaUpgradeRecordDO;
|
||||
import cn.iocoder.yudao.module.iot.service.ota.IotOtaUpgradeRecordService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - IoT OTA 升级记录")
|
||||
@RestController
|
||||
@RequestMapping("/iot/ota-upgrade-record")
|
||||
@Validated
|
||||
public class IotOtaUpgradeRecordController {
|
||||
|
||||
@Resource
|
||||
private IotOtaUpgradeRecordService upgradeRecordService;
|
||||
|
||||
@GetMapping("/get-statistics")
|
||||
@Operation(summary = "固件升级设备统计")
|
||||
@PreAuthorize("@ss.hasPermission('iot:ota-upgrade-record:query')")
|
||||
@Parameter(name = "firmwareId", description = "固件编号", required = true, example = "1024")
|
||||
public CommonResult<Map<Integer, Long>> getOtaUpgradeRecordStatistics(@RequestParam(value = "firmwareId") Long firmwareId) {
|
||||
return success(upgradeRecordService.getOtaUpgradeRecordStatistics(firmwareId));
|
||||
}
|
||||
|
||||
@GetMapping("/get-count")
|
||||
@Operation(summary = "获得升级记录分页 tab 数量")
|
||||
@PreAuthorize("@ss.hasPermission('iot:ota-upgrade-record:query')")
|
||||
public CommonResult<Map<Integer, Long>> getOtaUpgradeRecordCount(
|
||||
@Valid IotOtaUpgradeRecordPageReqVO pageReqVO) {
|
||||
return success(upgradeRecordService.getOtaUpgradeRecordCount(pageReqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得升级记录分页")
|
||||
@PreAuthorize("@ss.hasPermission('iot:ota-upgrade-record:query')")
|
||||
public CommonResult<PageResult<IotOtaUpgradeRecordRespVO>> getUpgradeRecordPage(
|
||||
@Valid IotOtaUpgradeRecordPageReqVO pageReqVO) {
|
||||
PageResult<IotOtaUpgradeRecordDO> pageResult = upgradeRecordService.getUpgradeRecordPage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, IotOtaUpgradeRecordRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得升级记录")
|
||||
@PreAuthorize("@ss.hasPermission('iot:ota-upgrade-record:query')")
|
||||
@Parameter(name = "id", description = "升级记录编号", required = true, example = "1024")
|
||||
public CommonResult<IotOtaUpgradeRecordRespVO> getUpgradeRecord(@RequestParam("id") Long id) {
|
||||
IotOtaUpgradeRecordDO upgradeRecord = upgradeRecordService.getUpgradeRecord(id);
|
||||
return success(BeanUtils.toBean(upgradeRecord, IotOtaUpgradeRecordRespVO.class));
|
||||
}
|
||||
|
||||
@PutMapping("/retry")
|
||||
@Operation(summary = "重试升级记录")
|
||||
@PreAuthorize("@ss.hasPermission('iot:ota-upgrade-record:retry')")
|
||||
@Parameter(name = "id", description = "升级记录编号", required = true, example = "1024")
|
||||
public CommonResult<Boolean> retryUpgradeRecord(@RequestParam("id") Long id) {
|
||||
upgradeRecordService.retryUpgradeRecord(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
package cn.iocoder.yudao.module.iot.controller.admin.ota;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.iot.controller.admin.ota.vo.upgrade.task.IotOtaUpgradeTaskPageReqVO;
|
||||
import cn.iocoder.yudao.module.iot.controller.admin.ota.vo.upgrade.task.IotOtaUpgradeTaskRespVO;
|
||||
import cn.iocoder.yudao.module.iot.controller.admin.ota.vo.upgrade.task.IotOtaUpgradeTaskSaveReqVO;
|
||||
import cn.iocoder.yudao.module.iot.dal.dataobject.ota.IotOtaUpgradeTaskDO;
|
||||
import cn.iocoder.yudao.module.iot.service.ota.IotOtaUpgradeTaskService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - IoT OTA 升级任务")
|
||||
@RestController
|
||||
@RequestMapping("/iot/ota-upgrade-task")
|
||||
@Validated
|
||||
public class IotOtaUpgradeTaskController {
|
||||
|
||||
@Resource
|
||||
private IotOtaUpgradeTaskService upgradeTaskService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建升级任务")
|
||||
@PreAuthorize(value = "@ss.hasPermission('iot:ota-upgrade-task:create')")
|
||||
public CommonResult<Long> createUpgradeTask(@Valid @RequestBody IotOtaUpgradeTaskSaveReqVO createReqVO) {
|
||||
return success(upgradeTaskService.createUpgradeTask(createReqVO));
|
||||
}
|
||||
|
||||
@PostMapping("/cancel")
|
||||
@Operation(summary = "取消升级任务")
|
||||
@Parameter(name = "id", description = "升级任务编号", required = true)
|
||||
@PreAuthorize(value = "@ss.hasPermission('iot:ota-upgrade-task:cancel')")
|
||||
public CommonResult<Boolean> cancelUpgradeTask(@RequestParam("id") Long id) {
|
||||
upgradeTaskService.cancelUpgradeTask(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得升级任务分页")
|
||||
@PreAuthorize(value = "@ss.hasPermission('iot:ota-upgrade-task:query')")
|
||||
public CommonResult<PageResult<IotOtaUpgradeTaskRespVO>> getUpgradeTaskPage(@Valid IotOtaUpgradeTaskPageReqVO pageReqVO) {
|
||||
PageResult<IotOtaUpgradeTaskDO> pageResult = upgradeTaskService.getUpgradeTaskPage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, IotOtaUpgradeTaskRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得升级任务")
|
||||
@Parameter(name = "id", description = "升级任务编号", required = true, example = "1024")
|
||||
@PreAuthorize(value = "@ss.hasPermission('iot:ota-upgrade-task:query')")
|
||||
public CommonResult<IotOtaUpgradeTaskRespVO> getUpgradeTask(@RequestParam("id") Long id) {
|
||||
IotOtaUpgradeTaskDO upgradeTask = upgradeTaskService.getUpgradeTask(id);
|
||||
return success(BeanUtils.toBean(upgradeTask, IotOtaUpgradeTaskRespVO.class));
|
||||
}
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user