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