Commit c4c451320d21c7a2d0a1b1a31d981b24487b6b1f

Authored by YunaiV
2 parents 32a4a99e 21945e6b

Merge branch 'feature/iot' of https://gitee.com/zhijiantianya/ruoyi-vue-pro into master-jdk17

Showing 441 changed files with 18589 additions and 11832 deletions

Too many changes.

To preserve performance only 100 of 441 files are displayed.

@@ -24,7 +24,7 @@ @@ -24,7 +24,7 @@
24 <!-- <module>yudao-module-crm</module>--> 24 <!-- <module>yudao-module-crm</module>-->
25 <!-- <module>yudao-module-erp</module>--> 25 <!-- <module>yudao-module-erp</module>-->
26 <!-- <module>yudao-module-ai</module>--> 26 <!-- <module>yudao-module-ai</module>-->
27 -<!-- <module>yudao-module-iot</module>--> 27 + <module>yudao-module-iot</module>
28 </modules> 28 </modules>
29 29
30 <name>${project.artifactId}</name> 30 <name>${project.artifactId}</name>
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/DateIntervalEnum.java
@@ -16,6 +16,7 @@ import java.util.Arrays; @@ -16,6 +16,7 @@ import java.util.Arrays;
16 @AllArgsConstructor 16 @AllArgsConstructor
17 public enum DateIntervalEnum implements ArrayValuable<Integer> { 17 public enum DateIntervalEnum implements ArrayValuable<Integer> {
18 18
  19 + HOUR(0, "小时"), // 特殊:字典里,暂时不会有这个枚举!!!因为大多数情况下,用不到这个间隔
19 DAY(1, "天"), 20 DAY(1, "天"),
20 WEEK(2, "周"), 21 WEEK(2, "周"),
21 MONTH(3, "月"), 22 MONTH(3, "月"),
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java
@@ -8,6 +8,7 @@ import cn.hutool.core.lang.Assert; @@ -8,6 +8,7 @@ import cn.hutool.core.lang.Assert;
8 import cn.hutool.core.util.StrUtil; 8 import cn.hutool.core.util.StrUtil;
9 import cn.iocoder.yudao.framework.common.enums.DateIntervalEnum; 9 import cn.iocoder.yudao.framework.common.enums.DateIntervalEnum;
10 10
  11 +import java.sql.Timestamp;
11 import java.time.*; 12 import java.time.*;
12 import java.time.format.DateTimeFormatter; 13 import java.time.format.DateTimeFormatter;
13 import java.time.format.DateTimeParseException; 14 import java.time.format.DateTimeParseException;
@@ -16,8 +17,7 @@ import java.time.temporal.TemporalAdjusters; @@ -16,8 +17,7 @@ import java.time.temporal.TemporalAdjusters;
16 import java.util.ArrayList; 17 import java.util.ArrayList;
17 import java.util.List; 18 import java.util.List;
18 19
19 -import static cn.hutool.core.date.DatePattern.UTC_MS_WITH_XXX_OFFSET_PATTERN;  
20 -import static cn.hutool.core.date.DatePattern.createFormatter; 20 +import static cn.hutool.core.date.DatePattern.*;
21 21
22 /** 22 /**
23 * 时间工具类,用于 {@link LocalDateTime} 23 * 时间工具类,用于 {@link LocalDateTime}
@@ -90,6 +90,21 @@ public class LocalDateTimeUtils { @@ -90,6 +90,21 @@ public class LocalDateTimeUtils {
90 * @param time 指定时间 90 * @param time 指定时间
91 * @return 是否 91 * @return 是否
92 */ 92 */
  93 + public static boolean isBetween(LocalDateTime startTime, LocalDateTime endTime, Timestamp time) {
  94 + if (startTime == null || endTime == null || time == null) {
  95 + return false;
  96 + }
  97 + return LocalDateTimeUtil.isIn(LocalDateTimeUtil.of(time), startTime, endTime);
  98 + }
  99 +
  100 + /**
  101 + * 判指定断时间,是否在该时间范围内
  102 + *
  103 + * @param startTime 开始时间
  104 + * @param endTime 结束时间
  105 + * @param time 指定时间
  106 + * @return 是否
  107 + */
93 public static boolean isBetween(LocalDateTime startTime, LocalDateTime endTime, String time) { 108 public static boolean isBetween(LocalDateTime startTime, LocalDateTime endTime, String time) {
94 if (startTime == null || endTime == null || time == null) { 109 if (startTime == null || endTime == null || time == null) {
95 return false; 110 return false;
@@ -234,6 +249,11 @@ public class LocalDateTimeUtils { @@ -234,6 +249,11 @@ public class LocalDateTimeUtils {
234 // 2. 循环,生成时间范围 249 // 2. 循环,生成时间范围
235 List<LocalDateTime[]> timeRanges = new ArrayList<>(); 250 List<LocalDateTime[]> timeRanges = new ArrayList<>();
236 switch (intervalEnum) { 251 switch (intervalEnum) {
  252 + case HOUR:
  253 + while (startTime.isBefore(endTime)) {
  254 + timeRanges.add(new LocalDateTime[]{startTime, startTime.plusHours(1).minusNanos(1)});
  255 + startTime = startTime.plusHours(1);
  256 + }
237 case DAY: 257 case DAY:
238 while (startTime.isBefore(endTime)) { 258 while (startTime.isBefore(endTime)) {
239 timeRanges.add(new LocalDateTime[]{startTime, startTime.plusDays(1).minusNanos(1)}); 259 timeRanges.add(new LocalDateTime[]{startTime, startTime.plusDays(1).minusNanos(1)});
@@ -297,6 +317,8 @@ public class LocalDateTimeUtils { @@ -297,6 +317,8 @@ public class LocalDateTimeUtils {
297 317
298 // 2. 循环,生成时间范围 318 // 2. 循环,生成时间范围
299 switch (intervalEnum) { 319 switch (intervalEnum) {
  320 + case HOUR:
  321 + return LocalDateTimeUtil.format(startTime, DatePattern.NORM_DATETIME_MINUTE_PATTERN);
300 case DAY: 322 case DAY:
301 return LocalDateTimeUtil.format(startTime, DatePattern.NORM_DATE_PATTERN); 323 return LocalDateTimeUtil.format(startTime, DatePattern.NORM_DATE_PATTERN);
302 case WEEK: 324 case WEEK:
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/json/JsonUtils.java
@@ -3,18 +3,22 @@ package cn.iocoder.yudao.framework.common.util.json; @@ -3,18 +3,22 @@ package cn.iocoder.yudao.framework.common.util.json;
3 import cn.hutool.core.util.ArrayUtil; 3 import cn.hutool.core.util.ArrayUtil;
4 import cn.hutool.core.util.StrUtil; 4 import cn.hutool.core.util.StrUtil;
5 import cn.hutool.json.JSONUtil; 5 import cn.hutool.json.JSONUtil;
  6 +import cn.iocoder.yudao.framework.common.util.json.databind.TimestampLocalDateTimeDeserializer;
  7 +import cn.iocoder.yudao.framework.common.util.json.databind.TimestampLocalDateTimeSerializer;
6 import com.fasterxml.jackson.annotation.JsonInclude; 8 import com.fasterxml.jackson.annotation.JsonInclude;
7 import com.fasterxml.jackson.core.type.TypeReference; 9 import com.fasterxml.jackson.core.type.TypeReference;
8 import com.fasterxml.jackson.databind.DeserializationFeature; 10 import com.fasterxml.jackson.databind.DeserializationFeature;
9 import com.fasterxml.jackson.databind.JsonNode; 11 import com.fasterxml.jackson.databind.JsonNode;
10 import com.fasterxml.jackson.databind.ObjectMapper; 12 import com.fasterxml.jackson.databind.ObjectMapper;
11 import com.fasterxml.jackson.databind.SerializationFeature; 13 import com.fasterxml.jackson.databind.SerializationFeature;
  14 +import com.fasterxml.jackson.databind.module.SimpleModule;
12 import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; 15 import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
13 import lombok.SneakyThrows; 16 import lombok.SneakyThrows;
14 import lombok.extern.slf4j.Slf4j; 17 import lombok.extern.slf4j.Slf4j;
15 18
16 import java.io.IOException; 19 import java.io.IOException;
17 import java.lang.reflect.Type; 20 import java.lang.reflect.Type;
  21 +import java.time.LocalDateTime;
18 import java.util.ArrayList; 22 import java.util.ArrayList;
19 import java.util.List; 23 import java.util.List;
20 24
@@ -32,7 +36,11 @@ public class JsonUtils { @@ -32,7 +36,11 @@ public class JsonUtils {
32 objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); 36 objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
33 objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); 37 objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
34 objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); // 忽略 null 值 38 objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); // 忽略 null 值
35 - objectMapper.registerModules(new JavaTimeModule()); // 解决 LocalDateTime 的序列化 39 + // 解决 LocalDateTime 的序列化
  40 + SimpleModule simpleModule = new JavaTimeModule()
  41 + .addSerializer(LocalDateTime.class, TimestampLocalDateTimeSerializer.INSTANCE)
  42 + .addDeserializer(LocalDateTime.class, TimestampLocalDateTimeDeserializer.INSTANCE);
  43 + objectMapper.registerModules(simpleModule);
36 } 44 }
37 45
38 /** 46 /**
@@ -99,6 +107,18 @@ public class JsonUtils { @@ -99,6 +107,18 @@ public class JsonUtils {
99 } 107 }
100 } 108 }
101 109
  110 + public static <T> T parseObject(byte[] text, Type type) {
  111 + if (ArrayUtil.isEmpty(text)) {
  112 + return null;
  113 + }
  114 + try {
  115 + return objectMapper.readValue(text, objectMapper.getTypeFactory().constructType(type));
  116 + } catch (IOException e) {
  117 + log.error("json parse err,json:{}", text, e);
  118 + throw new RuntimeException(e);
  119 + }
  120 + }
  121 +
102 /** 122 /**
103 * 将字符串解析成指定类型的对象 123 * 将字符串解析成指定类型的对象
104 * 使用 {@link #parseObject(String, Class)} 时,在@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS) 的场景下, 124 * 使用 {@link #parseObject(String, Class)} 时,在@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS) 的场景下,
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/object/ObjectUtils.java
@@ -60,4 +60,8 @@ public class ObjectUtils { @@ -60,4 +60,8 @@ public class ObjectUtils {
60 return Arrays.asList(array).contains(obj); 60 return Arrays.asList(array).contains(obj);
61 } 61 }
62 62
  63 + public static boolean isNotAllEmpty(Object... objs) {
  64 + return !ObjectUtil.isAllEmpty(objs);
  65 + }
  66 +
63 } 67 }
yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/redis/config/YudaoRedisMQConsumerAutoConfiguration.java
@@ -69,9 +69,8 @@ public class YudaoRedisMQConsumerAutoConfiguration { @@ -69,9 +69,8 @@ public class YudaoRedisMQConsumerAutoConfiguration {
69 @ConditionalOnBean(AbstractRedisStreamMessageListener.class) // 只有 AbstractStreamMessageListener 存在的时候,才需要注册 Redis pubsub 监听 69 @ConditionalOnBean(AbstractRedisStreamMessageListener.class) // 只有 AbstractStreamMessageListener 存在的时候,才需要注册 Redis pubsub 监听
70 public RedisPendingMessageResendJob redisPendingMessageResendJob(List<AbstractRedisStreamMessageListener<?>> listeners, 70 public RedisPendingMessageResendJob redisPendingMessageResendJob(List<AbstractRedisStreamMessageListener<?>> listeners,
71 RedisMQTemplate redisTemplate, 71 RedisMQTemplate redisTemplate,
72 - @Value("${spring.application.name}") String groupName,  
73 RedissonClient redissonClient) { 72 RedissonClient redissonClient) {
74 - return new RedisPendingMessageResendJob(listeners, redisTemplate, groupName, redissonClient); 73 + return new RedisPendingMessageResendJob(listeners, redisTemplate, redissonClient);
75 } 74 }
76 75
77 /** 76 /**
@@ -141,14 +140,14 @@ public class YudaoRedisMQConsumerAutoConfiguration { @@ -141,14 +140,14 @@ public class YudaoRedisMQConsumerAutoConfiguration {
141 * 140 *
142 * @return 消费者名字 141 * @return 消费者名字
143 */ 142 */
144 - private static String buildConsumerName() { 143 + public static String buildConsumerName() {
145 return String.format("%s@%d", SystemUtil.getHostInfo().getAddress(), SystemUtil.getCurrentPID()); 144 return String.format("%s@%d", SystemUtil.getHostInfo().getAddress(), SystemUtil.getCurrentPID());
146 } 145 }
147 146
148 /** 147 /**
149 * 校验 Redis 版本号,是否满足最低的版本号要求! 148 * 校验 Redis 版本号,是否满足最低的版本号要求!
150 */ 149 */
151 - private static void checkRedisVersion(RedisTemplate<String, ?> redisTemplate) { 150 + public static void checkRedisVersion(RedisTemplate<String, ?> redisTemplate) {
152 // 获得 Redis 版本 151 // 获得 Redis 版本
153 Properties info = redisTemplate.execute((RedisCallback<Properties>) RedisServerCommands::info); 152 Properties info = redisTemplate.execute((RedisCallback<Properties>) RedisServerCommands::info);
154 String version = MapUtil.getStr(info, "redis_version"); 153 String version = MapUtil.getStr(info, "redis_version");
yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/redis/core/job/RedisPendingMessageResendJob.java
@@ -35,7 +35,6 @@ public class RedisPendingMessageResendJob { @@ -35,7 +35,6 @@ public class RedisPendingMessageResendJob {
35 35
36 private final List<AbstractRedisStreamMessageListener<?>> listeners; 36 private final List<AbstractRedisStreamMessageListener<?>> listeners;
37 private final RedisMQTemplate redisTemplate; 37 private final RedisMQTemplate redisTemplate;
38 - private final String groupName;  
39 private final RedissonClient redissonClient; 38 private final RedissonClient redissonClient;
40 39
41 /** 40 /**
@@ -64,13 +63,13 @@ public class RedisPendingMessageResendJob { @@ -64,13 +63,13 @@ public class RedisPendingMessageResendJob {
64 private void execute() { 63 private void execute() {
65 StreamOperations<String, Object, Object> ops = redisTemplate.getRedisTemplate().opsForStream(); 64 StreamOperations<String, Object, Object> ops = redisTemplate.getRedisTemplate().opsForStream();
66 listeners.forEach(listener -> { 65 listeners.forEach(listener -> {
67 - PendingMessagesSummary pendingMessagesSummary = Objects.requireNonNull(ops.pending(listener.getStreamKey(), groupName)); 66 + PendingMessagesSummary pendingMessagesSummary = Objects.requireNonNull(ops.pending(listener.getStreamKey(), listener.getGroup()));
68 // 每个消费者的 pending 队列消息数量 67 // 每个消费者的 pending 队列消息数量
69 Map<String, Long> pendingMessagesPerConsumer = pendingMessagesSummary.getPendingMessagesPerConsumer(); 68 Map<String, Long> pendingMessagesPerConsumer = pendingMessagesSummary.getPendingMessagesPerConsumer();
70 pendingMessagesPerConsumer.forEach((consumerName, pendingMessageCount) -> { 69 pendingMessagesPerConsumer.forEach((consumerName, pendingMessageCount) -> {
71 log.info("[processPendingMessage][消费者({}) 消息数量({})]", consumerName, pendingMessageCount); 70 log.info("[processPendingMessage][消费者({}) 消息数量({})]", consumerName, pendingMessageCount);
72 // 每个消费者的 pending消息的详情信息 71 // 每个消费者的 pending消息的详情信息
73 - PendingMessages pendingMessages = ops.pending(listener.getStreamKey(), Consumer.from(groupName, consumerName), Range.unbounded(), pendingMessageCount); 72 + PendingMessages pendingMessages = ops.pending(listener.getStreamKey(), Consumer.from(listener.getGroup(), consumerName), Range.unbounded(), pendingMessageCount);
74 if (pendingMessages.isEmpty()) { 73 if (pendingMessages.isEmpty()) {
75 return; 74 return;
76 } 75 }
@@ -91,7 +90,7 @@ public class RedisPendingMessageResendJob { @@ -91,7 +90,7 @@ public class RedisPendingMessageResendJob {
91 .ofObject(records.get(0).getValue()) // 设置内容 90 .ofObject(records.get(0).getValue()) // 设置内容
92 .withStreamKey(listener.getStreamKey())); 91 .withStreamKey(listener.getStreamKey()));
93 // ack 消息消费完成 92 // ack 消息消费完成
94 - redisTemplate.getRedisTemplate().opsForStream().acknowledge(groupName, records.get(0)); 93 + redisTemplate.getRedisTemplate().opsForStream().acknowledge(listener.getGroup(), records.get(0));
95 log.info("[processPendingMessage][消息({})重新投递成功]", records.get(0).getId()); 94 log.info("[processPendingMessage][消息({})重新投递成功]", records.get(0).getId());
96 }); 95 });
97 }); 96 });
yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/redis/core/stream/AbstractRedisStreamMessageListener.java
@@ -53,6 +53,12 @@ public abstract class AbstractRedisStreamMessageListener&lt;T extends AbstractRedis @@ -53,6 +53,12 @@ public abstract class AbstractRedisStreamMessageListener&lt;T extends AbstractRedis
53 this.streamKey = messageType.getDeclaredConstructor().newInstance().getStreamKey(); 53 this.streamKey = messageType.getDeclaredConstructor().newInstance().getStreamKey();
54 } 54 }
55 55
  56 + protected AbstractRedisStreamMessageListener(String streamKey, String group) {
  57 + this.messageType = null;
  58 + this.streamKey = streamKey;
  59 + this.group = group;
  60 + }
  61 +
56 @Override 62 @Override
57 public void onMessage(ObjectRecord<String, String> message) { 63 public void onMessage(ObjectRecord<String, String> message) {
58 // 消费消息 64 // 消费消息
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/config/YudaoMybatisAutoConfiguration.java
1 package cn.iocoder.yudao.framework.mybatis.config; 1 package cn.iocoder.yudao.framework.mybatis.config;
2 2
  3 +import cn.hutool.core.collection.CollUtil;
3 import cn.hutool.core.util.StrUtil; 4 import cn.hutool.core.util.StrUtil;
4 import cn.iocoder.yudao.framework.mybatis.core.handler.DefaultDBFieldHandler; 5 import cn.iocoder.yudao.framework.mybatis.core.handler.DefaultDBFieldHandler;
5 import com.baomidou.mybatisplus.annotation.DbType; 6 import com.baomidou.mybatisplus.annotation.DbType;
6 import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration; 7 import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration;
7 import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; 8 import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
8 import com.baomidou.mybatisplus.core.incrementer.IKeyGenerator; 9 import com.baomidou.mybatisplus.core.incrementer.IKeyGenerator;
  10 +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
9 import com.baomidou.mybatisplus.extension.incrementer.*; 11 import com.baomidou.mybatisplus.extension.incrementer.*;
10 import com.baomidou.mybatisplus.extension.parser.JsqlParserGlobal; 12 import com.baomidou.mybatisplus.extension.parser.JsqlParserGlobal;
11 import com.baomidou.mybatisplus.extension.parser.cache.JdkSerialCaffeineJsqlParseCache; 13 import com.baomidou.mybatisplus.extension.parser.cache.JdkSerialCaffeineJsqlParseCache;
12 import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; 14 import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
13 import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; 15 import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
  16 +import com.fasterxml.jackson.databind.ObjectMapper;
14 import org.apache.ibatis.annotations.Mapper; 17 import org.apache.ibatis.annotations.Mapper;
15 import org.mybatis.spring.annotation.MapperScan; 18 import org.mybatis.spring.annotation.MapperScan;
16 import org.springframework.boot.autoconfigure.AutoConfiguration; 19 import org.springframework.boot.autoconfigure.AutoConfiguration;
@@ -18,6 +21,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -18,6 +21,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
18 import org.springframework.context.annotation.Bean; 21 import org.springframework.context.annotation.Bean;
19 import org.springframework.core.env.ConfigurableEnvironment; 22 import org.springframework.core.env.ConfigurableEnvironment;
20 23
  24 +import java.util.List;
21 import java.util.concurrent.TimeUnit; 25 import java.util.concurrent.TimeUnit;
22 26
23 /** 27 /**
@@ -75,4 +79,11 @@ public class YudaoMybatisAutoConfiguration { @@ -75,4 +79,11 @@ public class YudaoMybatisAutoConfiguration {
75 throw new IllegalArgumentException(StrUtil.format("DbType{} 找不到合适的 IKeyGenerator 实现类", dbType)); 79 throw new IllegalArgumentException(StrUtil.format("DbType{} 找不到合适的 IKeyGenerator 实现类", dbType));
76 } 80 }
77 81
  82 + @Bean
  83 + public JacksonTypeHandler jacksonTypeHandler(List<ObjectMapper> objectMappers) {
  84 + // 特殊:设置 JacksonTypeHandler 的 ObjectMapper!
  85 + JacksonTypeHandler.setObjectMapper(CollUtil.getFirst(objectMappers));
  86 + return new JacksonTypeHandler(Object.class);
  87 + }
  88 +
78 } 89 }
yudao-framework/yudao-spring-boot-starter-protection/src/main/java/cn/iocoder/yudao/framework/ratelimiter/core/aop/RateLimiterAspect.java
@@ -39,7 +39,7 @@ public class RateLimiterAspect { @@ -39,7 +39,7 @@ public class RateLimiterAspect {
39 39
40 @Before("@annotation(rateLimiter)") 40 @Before("@annotation(rateLimiter)")
41 public void beforePointCut(JoinPoint joinPoint, RateLimiter rateLimiter) { 41 public void beforePointCut(JoinPoint joinPoint, RateLimiter rateLimiter) {
42 - // 获得 IdempotentKeyResolver 对象 42 + // 获得 RateLimiterKeyResolver 对象
43 RateLimiterKeyResolver keyResolver = keyResolvers.get(rateLimiter.keyResolver()); 43 RateLimiterKeyResolver keyResolver = keyResolvers.get(rateLimiter.keyResolver());
44 Assert.notNull(keyResolver, "找不到对应的 RateLimiterKeyResolver"); 44 Assert.notNull(keyResolver, "找不到对应的 RateLimiterKeyResolver");
45 // 解析 Key 45 // 解析 Key
yudao-module-iot/pom.xml
1 <?xml version="1.0" encoding="UTF-8"?> 1 <?xml version="1.0" encoding="UTF-8"?>
2 <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 2 <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3 - xmlns="http://maven.apache.org/POM/4.0.0"  
4 - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 3 + xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5 <parent> 4 <parent>
6 <artifactId>yudao</artifactId> 5 <artifactId>yudao</artifactId>
7 <groupId>cn.iocoder.boot</groupId> 6 <groupId>cn.iocoder.boot</groupId>
8 <version>${revision}</version> 7 <version>${revision}</version>
9 </parent> 8 </parent>
10 <modules> 9 <modules>
11 - <module>yudao-module-iot-api</module>  
12 <module>yudao-module-iot-biz</module> 10 <module>yudao-module-iot-biz</module>
13 - <module>yudao-module-iot-plugins</module> 11 + <module>yudao-module-iot-core</module>
  12 + <module>yudao-module-iot-gateway</module>
14 </modules> 13 </modules>
15 <modelVersion>4.0.0</modelVersion> 14 <modelVersion>4.0.0</modelVersion>
16 15
@@ -20,7 +19,7 @@ @@ -20,7 +19,7 @@
20 <name>${project.artifactId}</name> 19 <name>${project.artifactId}</name>
21 <description> 20 <description>
22 物联网模块 21 物联网模块
23 - <!-- TODO 芋艿:需要补充下说明! --> 22 + <!-- TODO 芋艿:需要补充下说明! -->
24 </description> 23 </description>
25 24
26 </project> 25 </project>
27 \ No newline at end of file 26 \ No newline at end of file
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/api/device/IotDeviceUpstreamApi.java deleted
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 -}  
94 \ No newline at end of file 0 \ 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 deleted
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/IotDeviceOtaUpgradeReqDTO.java deleted
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 deleted
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 deleted
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 deleted
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/IotDeviceEventReportReqDTO.java deleted
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 deleted
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 deleted
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 deleted
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 deleted
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 -}  
23 \ No newline at end of file 0 \ 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 deleted
1 -package cn.iocoder.yudao.module.iot.api.device.dto.control.upstream;  
2 -  
3 -import lombok.Data;  
4 -  
5 -/**  
6 - * IoT 设备【注册】自己 Request DTO  
7 - *  
8 - * @author 芋道源码  
9 - */  
10 -@Data  
11 -public class IotDeviceRegisterReqDTO extends IotDeviceUpstreamAbstractReqDTO {  
12 -}  
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/api/device/dto/control/upstream/IotDeviceRegisterSubReqDTO.java deleted
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 deleted
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 deleted
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/IotPluginInstanceHeartbeatReqDTO.java deleted
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/package-info.java deleted
1 -/**  
2 - * 占位  
3 - *  
4 - * TODO 芋艿:后续删除  
5 - */  
6 -package cn.iocoder.yudao.module.iot.api;  
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/ApiConstants.java deleted
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/plugin/IotPluginDeployTypeEnum.java deleted
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 deleted
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 deleted
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/IotDataFormatEnum.java deleted
1 -package cn.iocoder.yudao.module.iot.enums.product;  
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 - *  
12 - * @author ahh  
13 - * @see <a href="https://help.aliyun.com/zh/iot/user-guide/message-parsing">阿里云 - 什么是消息解析</a>  
14 - */  
15 -@AllArgsConstructor  
16 -@Getter  
17 -public enum IotDataFormatEnum implements ArrayValuable<Integer> {  
18 -  
19 - JSON(0, "标准数据格式(JSON)"),  
20 - CUSTOMIZE(1, "透传/自定义");  
21 -  
22 - public static final Integer[] ARRAYS = Arrays.stream(values()).map(IotDataFormatEnum::getType).toArray(Integer[]::new);  
23 -  
24 - /**  
25 - * 类型  
26 - */  
27 - private final Integer type;  
28 - /**  
29 - * 描述  
30 - */  
31 - private final String description;  
32 -  
33 - @Override  
34 - public Integer[] array() {  
35 - return ARRAYS;  
36 - }  
37 -  
38 -}  
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/product/IotProtocolTypeEnum.java deleted
1 -package cn.iocoder.yudao.module.iot.enums.product;  
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 ahh  
13 - */  
14 -@AllArgsConstructor  
15 -@Getter  
16 -public enum IotProtocolTypeEnum implements ArrayValuable<Integer> {  
17 -  
18 - CUSTOM(0, "自定义"),  
19 - MODBUS(1, "Modbus"),  
20 - OPC_UA(2, "OPC UA"),  
21 - ZIGBEE(3, "ZigBee"),  
22 - BLE(4, "BLE");  
23 -  
24 - public static final Integer[] ARRAYS = Arrays.stream(values()).map(IotProtocolTypeEnum::getType).toArray(Integer[]::new);  
25 -  
26 - /**  
27 - * 类型  
28 - */  
29 - private final Integer type;  
30 - /**  
31 - * 描述  
32 - */  
33 - private final String description;  
34 -  
35 - @Override  
36 - public Integer[] array() {  
37 - return ARRAYS;  
38 - }  
39 -  
40 -}  
yudao-module-iot/yudao-module-iot-biz/pom.xml
1 <?xml version="1.0" encoding="UTF-8"?> 1 <?xml version="1.0" encoding="UTF-8"?>
2 <project xmlns="http://maven.apache.org/POM/4.0.0" 2 <project xmlns="http://maven.apache.org/POM/4.0.0"
3 - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
4 - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 3 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5 <parent> 4 <parent>
6 <artifactId>yudao-module-iot</artifactId> 5 <artifactId>yudao-module-iot</artifactId>
7 <groupId>cn.iocoder.boot</groupId> 6 <groupId>cn.iocoder.boot</groupId>
@@ -15,7 +14,7 @@ @@ -15,7 +14,7 @@
15 <name>${project.artifactId}</name> 14 <name>${project.artifactId}</name>
16 <description> 15 <description>
17 物联网 模块,主要实现 产品管理、设备管理、协议管理等功能。 16 物联网 模块,主要实现 产品管理、设备管理、协议管理等功能。
18 - <!-- TODO 芋艿:后续补充下 --> 17 + <!-- TODO 芋艿:后续补充下 -->
19 </description> 18 </description>
20 19
21 <dependencies> 20 <dependencies>
@@ -26,7 +25,7 @@ @@ -26,7 +25,7 @@
26 </dependency> 25 </dependency>
27 <dependency> 26 <dependency>
28 <groupId>cn.iocoder.boot</groupId> 27 <groupId>cn.iocoder.boot</groupId>
29 - <artifactId>yudao-module-iot-api</artifactId> 28 + <artifactId>yudao-module-iot-core</artifactId>
30 <version>${revision}</version> 29 <version>${revision}</version>
31 </dependency> 30 </dependency>
32 31
@@ -75,10 +74,11 @@ @@ -75,10 +74,11 @@
75 </dependency> 74 </dependency>
76 75
77 <!-- 消息队列相关 --> 76 <!-- 消息队列相关 -->
  77 + <!-- TODO @芋艿:临时打开 -->
78 <dependency> 78 <dependency>
79 <groupId>org.apache.rocketmq</groupId> 79 <groupId>org.apache.rocketmq</groupId>
80 <artifactId>rocketmq-spring-boot-starter</artifactId> 80 <artifactId>rocketmq-spring-boot-starter</artifactId>
81 - <optional>true</optional> 81 +<!-- <optional>true</optional>-->
82 </dependency> 82 </dependency>
83 <dependency> 83 <dependency>
84 <groupId>org.springframework.kafka</groupId> 84 <groupId>org.springframework.kafka</groupId>
@@ -91,47 +91,17 @@ @@ -91,47 +91,17 @@
91 <optional>true</optional> 91 <optional>true</optional>
92 </dependency> 92 </dependency>
93 93
94 - <dependency>  
95 - <groupId>org.pf4j</groupId> <!-- PF4J:内置插件机制 -->  
96 - <artifactId>pf4j-spring</artifactId>  
97 - </dependency>  
98 -  
99 - <!-- TODO @芋艿:bom 管理 -->  
100 - <dependency>  
101 - <groupId>org.apache.groovy</groupId>  
102 - <artifactId>groovy-all</artifactId>  
103 - <version>4.0.25</version>  
104 - <type>pom</type>  
105 - </dependency>  
106 -  
107 - <!-- TODO @芋艿:bom 管理 -->  
108 - <dependency>  
109 - <groupId>org.graalvm.js</groupId>  
110 - <artifactId>js</artifactId>  
111 - <version>24.1.2</version>  
112 - <type>pom</type>  
113 - </dependency>  
114 - <dependency>  
115 - <groupId>org.graalvm.js</groupId>  
116 - <artifactId>js-scriptengine</artifactId>  
117 - <version>24.1.2</version>  
118 - </dependency>  
119 -  
120 - <!-- TODO @芋艿:合理注释 -->  
121 - <!-- IoT 数据桥梁的执行器所需消息队列。如果您只需要使用 rocketmq 那么则注释掉其它消息队列即可 --> 94 + <!-- IoT 网络组件:接收来自设备的上行数据 -->
122 <!-- <dependency>--> 95 <!-- <dependency>-->
123 - <!-- <groupId>org.apache.rocketmq</groupId>-->  
124 - <!-- <artifactId>rocketmq-spring-boot-starter</artifactId>--> 96 + <!-- <groupId>cn.iocoder.boot</groupId>-->
  97 + <!-- <artifactId>yudao-module-iot-net-component-http</artifactId>-->
  98 + <!-- <version>${revision}</version>-->
125 <!-- </dependency>--> 99 <!-- </dependency>-->
126 <!-- <dependency>--> 100 <!-- <dependency>-->
127 - <!-- <groupId>org.springframework.kafka</groupId>-->  
128 - <!-- <artifactId>spring-kafka</artifactId>--> 101 + <!-- <groupId>cn.iocoder.boot</groupId>-->
  102 + <!-- <artifactId>yudao-module-iot-net-component-emqx</artifactId>-->
  103 + <!-- <version>${revision}</version>-->
129 <!-- </dependency>--> 104 <!-- </dependency>-->
130 - <!-- <dependency>-->  
131 - <!-- <groupId>org.springframework.boot</groupId>-->  
132 - <!-- <artifactId>spring-boot-starter-amqp</artifactId>-->  
133 - <!-- </dependency>-->  
134 -  
135 </dependencies> 105 </dependencies>
136 106
137 </project> 107 </project>
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/ScriptTest.java deleted
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/IoTDeviceApiImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.api.device;
  2 +
  3 +import cn.iocoder.yudao.framework.common.enums.RpcConstants;
  4 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  5 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  6 +import cn.iocoder.yudao.module.iot.core.biz.IotDeviceCommonApi;
  7 +import cn.iocoder.yudao.module.iot.core.biz.dto.IotDeviceAuthReqDTO;
  8 +import cn.iocoder.yudao.module.iot.core.biz.dto.IotDeviceGetReqDTO;
  9 +import cn.iocoder.yudao.module.iot.core.biz.dto.IotDeviceRespDTO;
  10 +import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
  11 +import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
  12 +import cn.iocoder.yudao.module.iot.service.device.IotDeviceService;
  13 +import cn.iocoder.yudao.module.iot.service.product.IotProductService;
  14 +import jakarta.annotation.Resource;
  15 +import jakarta.annotation.security.PermitAll;
  16 +import org.springframework.context.annotation.Primary;
  17 +import org.springframework.validation.annotation.Validated;
  18 +import org.springframework.web.bind.annotation.PostMapping;
  19 +import org.springframework.web.bind.annotation.RequestBody;
  20 +import org.springframework.web.bind.annotation.RestController;
  21 +
  22 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  23 +
  24 +/**
  25 + * IoT 设备 API 实现类
  26 + *
  27 + * @author haohao
  28 + */
  29 +@RestController
  30 +@Validated
  31 +@Primary // 保证优先匹配,因为 yudao-iot-gateway 也有 IotDeviceCommonApi 的实现,并且也可能会被 biz 引入
  32 +public class IoTDeviceApiImpl implements IotDeviceCommonApi {
  33 +
  34 + @Resource
  35 + private IotDeviceService deviceService;
  36 + @Resource
  37 + private IotProductService productService;
  38 +
  39 + @Override
  40 + @PostMapping(RpcConstants.RPC_API_PREFIX + "/iot/device/auth")
  41 + @PermitAll
  42 + public CommonResult<Boolean> authDevice(@RequestBody IotDeviceAuthReqDTO authReqDTO) {
  43 + return success(deviceService.authDevice(authReqDTO));
  44 + }
  45 +
  46 + @Override
  47 + @PostMapping(RpcConstants.RPC_API_PREFIX + "/iot/device/get") // 特殊:方便调用,暂时使用 POST,实际更推荐 GET
  48 + @PermitAll
  49 + public CommonResult<IotDeviceRespDTO> getDevice(@RequestBody IotDeviceGetReqDTO getReqDTO) {
  50 + IotDeviceDO device = getReqDTO.getId() != null ? deviceService.getDeviceFromCache(getReqDTO.getId())
  51 + : deviceService.getDeviceFromCache(getReqDTO.getProductKey(), getReqDTO.getDeviceName());
  52 + return success(BeanUtils.toBean(device, IotDeviceRespDTO.class, deviceDTO -> {
  53 + IotProductDO product = productService.getProductFromCache(deviceDTO.getProductId());
  54 + if (product != null) {
  55 + deviceDTO.setCodecType(product.getCodecType());
  56 + }
  57 + }));
  58 + }
  59 +
  60 +}
0 \ No newline at end of file 61 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/api/device/IoTDeviceUpstreamApiImpl.java deleted
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 -}  
78 \ No newline at end of file 0 \ 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
1 /** 1 /**
2 - * 占位  
3 - *  
4 - * TODO 芋艿:后续删除 2 + * iot API 包,定义并实现提供给其它模块的 API
5 */ 3 */
6 package cn.iocoder.yudao.module.iot.api; 4 package cn.iocoder.yudao.module.iot.api;
7 \ No newline at end of file 5 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/alert/IotAlertConfigController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.controller.admin.alert;
  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.alert.vo.config.IotAlertConfigPageReqVO;
  8 +import cn.iocoder.yudao.module.iot.controller.admin.alert.vo.config.IotAlertConfigRespVO;
  9 +import cn.iocoder.yudao.module.iot.controller.admin.alert.vo.config.IotAlertConfigSaveReqVO;
  10 +import cn.iocoder.yudao.module.iot.dal.dataobject.alert.IotAlertConfigDO;
  11 +import cn.iocoder.yudao.module.iot.service.alert.IotAlertConfigService;
  12 +import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
  13 +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
  14 +import io.swagger.v3.oas.annotations.Operation;
  15 +import io.swagger.v3.oas.annotations.Parameter;
  16 +import io.swagger.v3.oas.annotations.tags.Tag;
  17 +import jakarta.annotation.Resource;
  18 +import jakarta.validation.Valid;
  19 +
  20 +import org.springframework.security.access.prepost.PreAuthorize;
  21 +import org.springframework.validation.annotation.Validated;
  22 +import org.springframework.web.bind.annotation.*;
  23 +
  24 +import java.util.List;
  25 +import java.util.Map;
  26 +import java.util.Objects;
  27 +import java.util.stream.Collectors;
  28 +
  29 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  30 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
  31 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSetByFlatMap;
  32 +
  33 +@Tag(name = "管理后台 - IoT 告警配置")
  34 +@RestController
  35 +@RequestMapping("/iot/alert-config")
  36 +@Validated
  37 +public class IotAlertConfigController {
  38 +
  39 + @Resource
  40 + private IotAlertConfigService alertConfigService;
  41 +
  42 + @Resource
  43 + private AdminUserApi adminUserApi;
  44 +
  45 + @PostMapping("/create")
  46 + @Operation(summary = "创建告警配置")
  47 + @PreAuthorize("@ss.hasPermission('iot:alert-config:create')")
  48 + public CommonResult<Long> createAlertConfig(@Valid @RequestBody IotAlertConfigSaveReqVO createReqVO) {
  49 + return success(alertConfigService.createAlertConfig(createReqVO));
  50 + }
  51 +
  52 + @PutMapping("/update")
  53 + @Operation(summary = "更新告警配置")
  54 + @PreAuthorize("@ss.hasPermission('iot:alert-config:update')")
  55 + public CommonResult<Boolean> updateAlertConfig(@Valid @RequestBody IotAlertConfigSaveReqVO updateReqVO) {
  56 + alertConfigService.updateAlertConfig(updateReqVO);
  57 + return success(true);
  58 + }
  59 +
  60 + @DeleteMapping("/delete")
  61 + @Operation(summary = "删除告警配置")
  62 + @Parameter(name = "id", description = "编号", required = true)
  63 + @PreAuthorize("@ss.hasPermission('iot:alert-config:delete')")
  64 + public CommonResult<Boolean> deleteAlertConfig(@RequestParam("id") Long id) {
  65 + alertConfigService.deleteAlertConfig(id);
  66 + return success(true);
  67 + }
  68 +
  69 + @GetMapping("/get")
  70 + @Operation(summary = "获得告警配置")
  71 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  72 + @PreAuthorize("@ss.hasPermission('iot:alert-config:query')")
  73 + public CommonResult<IotAlertConfigRespVO> getAlertConfig(@RequestParam("id") Long id) {
  74 + IotAlertConfigDO alertConfig = alertConfigService.getAlertConfig(id);
  75 + return success(BeanUtils.toBean(alertConfig, IotAlertConfigRespVO.class));
  76 + }
  77 +
  78 + @GetMapping("/page")
  79 + @Operation(summary = "获得告警配置分页")
  80 + @PreAuthorize("@ss.hasPermission('iot:alert-config:query')")
  81 + public CommonResult<PageResult<IotAlertConfigRespVO>> getAlertConfigPage(@Valid IotAlertConfigPageReqVO pageReqVO) {
  82 + PageResult<IotAlertConfigDO> pageResult = alertConfigService.getAlertConfigPage(pageReqVO);
  83 +
  84 + // 转换返回
  85 + Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
  86 + convertSetByFlatMap(pageResult.getList(), config -> config.getReceiveUserIds().stream()));
  87 + return success(BeanUtils.toBean(pageResult, IotAlertConfigRespVO.class, vo -> {
  88 + vo.setReceiveUserNames(vo.getReceiveUserIds().stream()
  89 + .map(userMap::get)
  90 + .filter(Objects::nonNull)
  91 + .map(AdminUserRespDTO::getNickname)
  92 + .collect(Collectors.toList()));
  93 + }));
  94 + }
  95 +
  96 + @GetMapping("/simple-list")
  97 + @Operation(summary = "获得告警配置简单列表", description = "只包含被开启的告警配置,主要用于前端的下拉选项")
  98 + @PreAuthorize("@ss.hasPermission('iot:alert-config:query')")
  99 + public CommonResult<List<IotAlertConfigRespVO>> getAlertConfigSimpleList() {
  100 + List<IotAlertConfigDO> list = alertConfigService.getAlertConfigListByStatus(CommonStatusEnum.ENABLE.getStatus());
  101 + return success(convertList(list, config -> // 只返回 id、name 字段
  102 + new IotAlertConfigRespVO().setId(config.getId()).setName(config.getName())));
  103 + }
  104 +
  105 +}
0 \ No newline at end of file 106 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/alert/IotAlertRecordController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.controller.admin.alert;
  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.alert.vo.recrod.IotAlertRecordPageReqVO;
  7 +import cn.iocoder.yudao.module.iot.controller.admin.alert.vo.recrod.IotAlertRecordProcessReqVO;
  8 +import cn.iocoder.yudao.module.iot.controller.admin.alert.vo.recrod.IotAlertRecordRespVO;
  9 +import cn.iocoder.yudao.module.iot.dal.dataobject.alert.IotAlertRecordDO;
  10 +import cn.iocoder.yudao.module.iot.service.alert.IotAlertRecordService;
  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 +import static java.util.Collections.singleton;
  22 +
  23 +@Tag(name = "管理后台 - IoT 告警记录")
  24 +@RestController
  25 +@RequestMapping("/iot/alert-record")
  26 +@Validated
  27 +public class IotAlertRecordController {
  28 +
  29 + @Resource
  30 + private IotAlertRecordService alertRecordService;
  31 +
  32 + @GetMapping("/get")
  33 + @Operation(summary = "获得告警记录")
  34 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  35 + @PreAuthorize("@ss.hasPermission('iot:alert-record:query')")
  36 + public CommonResult<IotAlertRecordRespVO> getAlertRecord(@RequestParam("id") Long id) {
  37 + IotAlertRecordDO alertRecord = alertRecordService.getAlertRecord(id);
  38 + return success(BeanUtils.toBean(alertRecord, IotAlertRecordRespVO.class));
  39 + }
  40 +
  41 + @GetMapping("/page")
  42 + @Operation(summary = "获得告警记录分页")
  43 + @PreAuthorize("@ss.hasPermission('iot:alert-record:query')")
  44 + public CommonResult<PageResult<IotAlertRecordRespVO>> getAlertRecordPage(@Valid IotAlertRecordPageReqVO pageReqVO) {
  45 + PageResult<IotAlertRecordDO> pageResult = alertRecordService.getAlertRecordPage(pageReqVO);
  46 + return success(BeanUtils.toBean(pageResult, IotAlertRecordRespVO.class));
  47 + }
  48 +
  49 + @PutMapping("/process")
  50 + @Operation(summary = "处理告警记录")
  51 + @PreAuthorize("@ss.hasPermission('iot:alert-record:process')")
  52 + public CommonResult<Boolean> processAlertRecord(@Valid @RequestBody IotAlertRecordProcessReqVO processReqVO) {
  53 + alertRecordService.processAlertRecordList(singleton(processReqVO.getId()), processReqVO.getProcessRemark());
  54 + return success(true);
  55 + }
  56 +
  57 +}
0 \ No newline at end of file 58 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/alert/vo/config/IotAlertConfigPageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.controller.admin.alert.vo.config;
  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 org.springframework.format.annotation.DateTimeFormat;
  7 +
  8 +import java.time.LocalDateTime;
  9 +
  10 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  11 +
  12 +@Schema(description = "管理后台 - IoT 告警配置分页 Request VO")
  13 +@Data
  14 +public class IotAlertConfigPageReqVO extends PageParam {
  15 +
  16 + @Schema(description = "配置名称", example = "赵六")
  17 + private String name;
  18 +
  19 + @Schema(description = "配置状态", example = "1")
  20 + private Integer status;
  21 +
  22 + @Schema(description = "创建时间")
  23 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  24 + private LocalDateTime[] createTime;
  25 +
  26 +}
0 \ No newline at end of file 27 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/alert/vo/config/IotAlertConfigRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.controller.admin.alert.vo.config;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import java.time.LocalDateTime;
  7 +import java.util.List;
  8 +
  9 +@Schema(description = "管理后台 - IoT 告警配置 Response VO")
  10 +@Data
  11 +public class IotAlertConfigRespVO {
  12 +
  13 + @Schema(description = "配置编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3566")
  14 + private Long id;
  15 +
  16 + @Schema(description = "配置名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
  17 + private String name;
  18 +
  19 + @Schema(description = "配置描述", example = "你猜")
  20 + private String description;
  21 +
  22 + @Schema(description = "告警级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  23 + private Integer level;
  24 +
  25 + @Schema(description = "配置状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  26 + private Integer status;
  27 +
  28 + @Schema(description = "关联的场景联动规则编号数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "1,2,3")
  29 + private List<Long> sceneRuleIds;
  30 +
  31 + @Schema(description = "接收的用户编号数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "100,200")
  32 + private List<Long> receiveUserIds;
  33 +
  34 + @Schema(description = "接收的用户名称数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "张三,李四")
  35 + private List<String> receiveUserNames;
  36 +
  37 + @Schema(description = "接收的类型数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "1,2,3")
  38 + private List<Integer> receiveTypes;
  39 +
  40 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  41 + private LocalDateTime createTime;
  42 +
  43 +}
0 \ No newline at end of file 44 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/alert/vo/config/IotAlertConfigSaveReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.controller.admin.alert.vo.config;
  2 +
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  4 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  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 +import java.util.List;
  11 +
  12 +@Schema(description = "管理后台 - IoT 告警配置新增/修改 Request VO")
  13 +@Data
  14 +public class IotAlertConfigSaveReqVO {
  15 +
  16 + @Schema(description = "配置编号", example = "3566")
  17 + private Long id;
  18 +
  19 + @Schema(description = "配置名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
  20 + @NotEmpty(message = "配置名称不能为空")
  21 + private String name;
  22 +
  23 + @Schema(description = "配置描述", example = "你猜")
  24 + private String description;
  25 +
  26 + @Schema(description = "告警级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  27 + @NotNull(message = "告警级别不能为空")
  28 + private Integer level;
  29 +
  30 + @Schema(description = "配置状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  31 + @NotNull(message = "配置状态不能为空")
  32 + @InEnum(CommonStatusEnum.class)
  33 + private Integer status;
  34 +
  35 + @Schema(description = "关联的场景联动规则编号数组")
  36 + @NotEmpty(message = "关联的场景联动规则编号数组不能为空")
  37 + private List<Long> sceneRuleIds;
  38 +
  39 + @Schema(description = "接收的用户编号数组")
  40 + @NotEmpty(message = "接收的用户编号数组不能为空")
  41 + private List<Long> receiveUserIds;
  42 +
  43 + @Schema(description = "接收的类型数组")
  44 + @NotEmpty(message = "接收的类型数组不能为空")
  45 + private List<Integer> receiveTypes;
  46 +
  47 +}
0 \ No newline at end of file 48 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/alert/vo/recrod/IotAlertRecordPageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.controller.admin.alert.vo.recrod;
  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 org.springframework.format.annotation.DateTimeFormat;
  7 +
  8 +import java.time.LocalDateTime;
  9 +
  10 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  11 +
  12 +@Schema(description = "管理后台 - IoT 告警记录分页 Request VO")
  13 +@Data
  14 +public class IotAlertRecordPageReqVO extends PageParam {
  15 +
  16 + @Schema(description = "告警配置编号", example = "29320")
  17 + private Long configId;
  18 +
  19 + @Schema(description = "告警级别", example = "1")
  20 + private Integer level;
  21 +
  22 + @Schema(description = "产品编号", example = "2050")
  23 + private Long productId;
  24 +
  25 + @Schema(description = "设备编号", example = "21727")
  26 + private String deviceId;
  27 +
  28 + @Schema(description = "是否处理", example = "true")
  29 + private Boolean processStatus;
  30 +
  31 + @Schema(description = "创建时间")
  32 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  33 + private LocalDateTime[] createTime;
  34 +
  35 +}
0 \ No newline at end of file 36 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/alert/vo/recrod/IotAlertRecordProcessReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.controller.admin.alert.vo.recrod;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import jakarta.validation.constraints.NotNull;
  5 +import lombok.Data;
  6 +
  7 +@Schema(description = "管理后台 - IoT 告警记录处理 Request VO")
  8 +@Data
  9 +public class IotAlertRecordProcessReqVO {
  10 +
  11 + @Schema(description = "记录编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  12 + @NotNull(message = "记录编号不能为空")
  13 + private Long id;
  14 +
  15 + @Schema(description = "处理结果(备注)", requiredMode = Schema.RequiredMode.REQUIRED, example = "已处理告警,问题已解决")
  16 + private String processRemark;
  17 +
  18 +}
0 \ No newline at end of file 19 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/alert/vo/recrod/IotAlertRecordRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.controller.admin.alert.vo.recrod;
  2 +
  3 +import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Data;
  6 +
  7 +import java.time.LocalDateTime;
  8 +
  9 +@Schema(description = "管理后台 - IoT 告警记录 Response VO")
  10 +@Data
  11 +public class IotAlertRecordRespVO {
  12 +
  13 + @Schema(description = "记录编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "19904")
  14 + private Long id;
  15 +
  16 + @Schema(description = "告警配置编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "29320")
  17 + private Long configId;
  18 +
  19 + @Schema(description = "告警名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "张三")
  20 + private String configName;
  21 +
  22 + @Schema(description = "告警级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  23 + private Integer configLevel;
  24 +
  25 + @Schema(description = "产品编号", example = "2050")
  26 + private Long productId;
  27 +
  28 + @Schema(description = "设备编号", example = "21727")
  29 + private Long deviceId;
  30 +
  31 + @Schema(description = "触发的设备消息")
  32 + private IotDeviceMessage deviceMessage;
  33 +
  34 + @Schema(description = "是否处理", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  35 + private Boolean processStatus;
  36 +
  37 + @Schema(description = "处理结果(备注)", example = "你说的对")
  38 + private String processRemark;
  39 +
  40 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  41 + private LocalDateTime createTime;
  42 +
  43 +}
0 \ No newline at end of file 44 \ 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
@@ -6,15 +6,13 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam; @@ -6,15 +6,13 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam;
6 import cn.iocoder.yudao.framework.common.pojo.PageResult; 6 import cn.iocoder.yudao.framework.common.pojo.PageResult;
7 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 7 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
8 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; 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.*; 9 import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.*;
12 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; 10 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
  11 +import cn.iocoder.yudao.module.iot.enums.product.IotLocationTypeEnum;
13 import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; 12 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;  
16 import io.swagger.v3.oas.annotations.Operation; 13 import io.swagger.v3.oas.annotations.Operation;
17 import io.swagger.v3.oas.annotations.Parameter; 14 import io.swagger.v3.oas.annotations.Parameter;
  15 +import io.swagger.v3.oas.annotations.Parameters;
18 import io.swagger.v3.oas.annotations.tags.Tag; 16 import io.swagger.v3.oas.annotations.tags.Tag;
19 import jakarta.annotation.Resource; 17 import jakarta.annotation.Resource;
20 import jakarta.servlet.http.HttpServletResponse; 18 import jakarta.servlet.http.HttpServletResponse;
@@ -41,10 +39,6 @@ public class IotDeviceController { @@ -41,10 +39,6 @@ public class IotDeviceController {
41 39
42 @Resource 40 @Resource
43 private IotDeviceService deviceService; 41 private IotDeviceService deviceService;
44 - @Resource  
45 - private IotDeviceUpstreamService deviceUpstreamService;  
46 - @Resource  
47 - private IotDeviceDownstreamService deviceDownstreamService;  
48 42
49 @PostMapping("/create") 43 @PostMapping("/create")
50 @Operation(summary = "创建设备") 44 @Operation(summary = "创建设备")
@@ -111,7 +105,7 @@ public class IotDeviceController { @@ -111,7 +105,7 @@ public class IotDeviceController {
111 @PreAuthorize("@ss.hasPermission('iot:device:export')") 105 @PreAuthorize("@ss.hasPermission('iot:device:export')")
112 @ApiAccessLog(operateType = EXPORT) 106 @ApiAccessLog(operateType = EXPORT)
113 public void exportDeviceExcel(@Valid IotDevicePageReqVO exportReqVO, 107 public void exportDeviceExcel(@Valid IotDevicePageReqVO exportReqVO,
114 - HttpServletResponse response) throws IOException { 108 + HttpServletResponse response) throws IOException {
115 exportReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); 109 exportReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
116 CommonResult<PageResult<IotDeviceRespVO>> result = getDevicePage(exportReqVO); 110 CommonResult<PageResult<IotDeviceRespVO>> result = getDevicePage(exportReqVO);
117 // 导出 Excel 111 // 导出 Excel
@@ -129,12 +123,17 @@ public class IotDeviceController { @@ -129,12 +123,17 @@ public class IotDeviceController {
129 123
130 @GetMapping("/simple-list") 124 @GetMapping("/simple-list")
131 @Operation(summary = "获取设备的精简信息列表", description = "主要用于前端的下拉选项") 125 @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()))); 126 + @Parameters({
  127 + @Parameter(name = "deviceType", description = "设备类型", example = "1"),
  128 + @Parameter(name = "productId", description = "产品编号", example = "1024")
  129 + })
  130 + public CommonResult<List<IotDeviceRespVO>> getDeviceSimpleList(
  131 + @RequestParam(value = "deviceType", required = false) Integer deviceType,
  132 + @RequestParam(value = "productId", required = false) Long productId) {
  133 + List<IotDeviceDO> list = deviceService.getDeviceListByCondition(deviceType, productId);
  134 + return success(convertList(list, device -> // 只返回 id、name、productId 字段
  135 + new IotDeviceRespVO().setId(device.getId()).setDeviceName(device.getDeviceName())
  136 + .setProductId(device.getProductId()).setState(device.getState())));
138 } 137 }
139 138
140 @PostMapping("/import") 139 @PostMapping("/import")
@@ -154,35 +153,28 @@ public class IotDeviceController { @@ -154,35 +153,28 @@ public class IotDeviceController {
154 // 手动创建导出 demo 153 // 手动创建导出 demo
155 List<IotDeviceImportExcelVO> list = Arrays.asList( 154 List<IotDeviceImportExcelVO> list = Arrays.asList(
156 IotDeviceImportExcelVO.builder().deviceName("温度传感器001").parentDeviceName("gateway110") 155 IotDeviceImportExcelVO.builder().deviceName("温度传感器001").parentDeviceName("gateway110")
157 - .productKey("1de24640dfe").groupNames("灰度分组,生产分组").build(),  
158 - IotDeviceImportExcelVO.builder().deviceName("biubiu")  
159 - .productKey("YzvHxd4r67sT4s2B").groupNames("").build()); 156 + .productKey("1de24640dfe").groupNames("灰度分组,生产分组")
  157 + .locationType(IotLocationTypeEnum.IP.getType()).build(),
  158 + IotDeviceImportExcelVO.builder().deviceName("biubiu").productKey("YzvHxd4r67sT4s2B")
  159 + .groupNames("").locationType(IotLocationTypeEnum.MANUAL.getType()).build());
160 // 输出 160 // 输出
161 ExcelUtils.write(response, "设备导入模板.xls", "数据", IotDeviceImportExcelVO.class, list); 161 ExcelUtils.write(response, "设备导入模板.xls", "数据", IotDeviceImportExcelVO.class, list);
162 } 162 }
163 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); 164 + @GetMapping("/get-auth-info")
  165 + @Operation(summary = "获得设备连接信息")
  166 + @PreAuthorize("@ss.hasPermission('iot:device:auth-info')")
  167 + public CommonResult<IotDeviceAuthInfoRespVO> getDeviceAuthInfo(@RequestParam("id") Long id) {
  168 + return success(deviceService.getDeviceAuthInfo(id));
170 } 169 }
171 170
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)); 171 + // TODO @haohao:可以使用 @RequestParam("productKey") String productKey, @RequestParam("deviceNames") List<String> deviceNames 来接收哇?
  172 + @GetMapping("/list-by-product-key-and-names")
  173 + @Operation(summary = "通过产品标识和设备名称列表获取设备")
  174 + @PreAuthorize("@ss.hasPermission('iot:device:query')")
  175 + public CommonResult<List<IotDeviceRespVO>> getDevicesByProductKeyAndNames(@Valid IotDeviceByProductKeyAndNamesReqVO reqVO) {
  176 + List<IotDeviceDO> devices = deviceService.getDeviceListByProductKeyAndNames(reqVO.getProductKey(), reqVO.getDeviceNames());
  177 + return success(BeanUtils.toBean(devices, IotDeviceRespVO.class));
186 } 178 }
187 179
188 -}  
189 \ No newline at end of file 180 \ No newline at end of file
  181 +}
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/IotDeviceLogController.java deleted
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 -}  
40 \ No newline at end of file 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/IotDeviceController.http renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/IotDeviceMessageController.http
1 -### 请求 /iot/device/downstream 接口(服务调用) => 成功 1 +### 请求 /iot/device/message/send 接口(属性上报)=> 成功
  2 +POST {{baseUrl}}/iot/device/message/send
  3 +Content-Type: application/json
  4 +tenant-id: {{adminTenantId}}
  5 +Authorization: Bearer {{token}}
  6 +
  7 +{
  8 + "deviceId": 25,
  9 + "method": "thing.property.post",
  10 + "params": {
  11 + "width": 1,
  12 + "height": "2",
  13 + "oneThree": "3"
  14 + }
  15 +}
  16 +
  17 +### 请求 /iot/device/downstream 接口(服务调用)=> 成功 TODO 芋艿:未更新为最新
2 POST {{baseUrl}}/iot/device/downstream 18 POST {{baseUrl}}/iot/device/downstream
3 Content-Type: application/json 19 Content-Type: application/json
4 -tenant-id: {{adminTenentId}} 20 +tenant-id: {{adminTenantId}}
5 Authorization: Bearer {{token}} 21 Authorization: Bearer {{token}}
6 22
7 { 23 {
@@ -13,10 +29,10 @@ Authorization: Bearer {{token}} @@ -13,10 +29,10 @@ Authorization: Bearer {{token}}
13 } 29 }
14 } 30 }
15 31
16 -### 请求 /iot/device/downstream 接口(属性设置) => 成功 32 +### 请求 /iot/device/downstream 接口(属性设置)=> 成功 TODO 芋艿:未更新为最新
17 POST {{baseUrl}}/iot/device/downstream 33 POST {{baseUrl}}/iot/device/downstream
18 Content-Type: application/json 34 Content-Type: application/json
19 -tenant-id: {{adminTenentId}} 35 +tenant-id: {{adminTenantId}}
20 Authorization: Bearer {{token}} 36 Authorization: Bearer {{token}}
21 37
22 { 38 {
@@ -28,10 +44,10 @@ Authorization: Bearer {{token}} @@ -28,10 +44,10 @@ Authorization: Bearer {{token}}
28 } 44 }
29 } 45 }
30 46
31 -### 请求 /iot/device/downstream 接口(属性获取) => 成功 47 +### 请求 /iot/device/downstream 接口(属性获取)=> 成功 TODO 芋艿:未更新为最新
32 POST {{baseUrl}}/iot/device/downstream 48 POST {{baseUrl}}/iot/device/downstream
33 Content-Type: application/json 49 Content-Type: application/json
34 -tenant-id: {{adminTenentId}} 50 +tenant-id: {{adminTenantId}}
35 Authorization: Bearer {{token}} 51 Authorization: Bearer {{token}}
36 52
37 { 53 {
@@ -41,10 +57,10 @@ Authorization: Bearer {{token}} @@ -41,10 +57,10 @@ Authorization: Bearer {{token}}
41 "data": ["xx", "yy"] 57 "data": ["xx", "yy"]
42 } 58 }
43 59
44 -### 请求 /iot/device/downstream 接口(配置设置) => 成功 60 +### 请求 /iot/device/downstream 接口(配置设置)=> 成功 TODO 芋艿:未更新为最新
45 POST {{baseUrl}}/iot/device/downstream 61 POST {{baseUrl}}/iot/device/downstream
46 Content-Type: application/json 62 Content-Type: application/json
47 -tenant-id: {{adminTenentId}} 63 +tenant-id: {{adminTenantId}}
48 Authorization: Bearer {{token}} 64 Authorization: Bearer {{token}}
49 65
50 { 66 {
@@ -53,10 +69,10 @@ Authorization: Bearer {{token}} @@ -53,10 +69,10 @@ Authorization: Bearer {{token}}
53 "identifier": "set" 69 "identifier": "set"
54 } 70 }
55 71
56 -### 请求 /iot/device/downstream 接口(OTA 升级) => 成功 72 +### 请求 /iot/device/downstream 接口(OTA 升级)=> 成功 TODO 芋艿:未更新为最新
57 POST {{baseUrl}}/iot/device/downstream 73 POST {{baseUrl}}/iot/device/downstream
58 Content-Type: application/json 74 Content-Type: application/json
59 -tenant-id: {{adminTenentId}} 75 +tenant-id: {{adminTenantId}}
60 Authorization: Bearer {{token}} 76 Authorization: Bearer {{token}}
61 77
62 { 78 {
@@ -72,4 +88,14 @@ Authorization: Bearer {{token}} @@ -72,4 +88,14 @@ Authorization: Bearer {{token}}
72 "fileUrl": "http://example.com/firmware.bin", 88 "fileUrl": "http://example.com/firmware.bin",
73 "information": "{\"desc\":\"升级到最新版本\"}" 89 "information": "{\"desc\":\"升级到最新版本\"}"
74 } 90 }
75 -}  
76 \ No newline at end of file 91 \ No newline at end of file
  92 +}
  93 +
  94 +### 查询设备消息对分页 - 基础查询(设备编号25)
  95 +GET {{baseUrl}}/iot/device/message/pair-page?deviceId=25&pageNo=1&pageSize=10
  96 +Authorization: Bearer {{token}}
  97 +tenant-id: {{adminTenantId}}
  98 +
  99 +### 查询设备消息对分页 - 按标识符过滤(identifier=eat)
  100 +GET {{baseUrl}}/iot/device/message/pair-page?deviceId=25&identifier=eat&pageNo=1&pageSize=10
  101 +Authorization: Bearer {{token}}
  102 +tenant-id: {{adminTenantId}}
77 \ No newline at end of file 103 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/IotDeviceMessageController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.controller.admin.device;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  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.message.IotDeviceMessagePageReqVO;
  8 +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.message.IotDeviceMessageRespPairVO;
  9 +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.message.IotDeviceMessageRespVO;
  10 +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.message.IotDeviceMessageSendReqVO;
  11 +import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
  12 +import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceMessageDO;
  13 +import cn.iocoder.yudao.module.iot.dal.tdengine.IotDeviceMessageMapper;
  14 +import cn.iocoder.yudao.module.iot.service.device.IotDeviceService;
  15 +import cn.iocoder.yudao.module.iot.service.device.message.IotDeviceMessageService;
  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.tags.Tag;
  19 +import jakarta.annotation.Resource;
  20 +import jakarta.validation.Valid;
  21 +import org.springframework.security.access.prepost.PreAuthorize;
  22 +import org.springframework.validation.annotation.Validated;
  23 +import org.springframework.web.bind.annotation.*;
  24 +
  25 +import java.util.List;
  26 +import java.util.Map;
  27 +
  28 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  29 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
  30 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
  31 +
  32 +@Tag(name = "管理后台 - IoT 设备消息")
  33 +@RestController
  34 +@RequestMapping("/iot/device/message")
  35 +@Validated
  36 +public class IotDeviceMessageController {
  37 +
  38 + @Resource
  39 + private IotDeviceMessageService deviceMessageService;
  40 + @Resource
  41 + private IotDeviceService deviceService;
  42 + @Resource
  43 + private IotThingModelService thingModelService;
  44 + @Resource
  45 + private IotDeviceMessageMapper deviceMessageMapper;
  46 +
  47 + @GetMapping("/page")
  48 + @Operation(summary = "获得设备消息分页")
  49 + @PreAuthorize("@ss.hasPermission('iot:device:message-query')")
  50 + public CommonResult<PageResult<IotDeviceMessageRespVO>> getDeviceMessagePage(
  51 + @Valid IotDeviceMessagePageReqVO pageReqVO) {
  52 + PageResult<IotDeviceMessageDO> pageResult = deviceMessageService.getDeviceMessagePage(pageReqVO);
  53 + return success(BeanUtils.toBean(pageResult, IotDeviceMessageRespVO.class));
  54 + }
  55 +
  56 + @GetMapping("/pair-page")
  57 + @Operation(summary = "获得设备消息对分页")
  58 + @PreAuthorize("@ss.hasPermission('iot:device:message-query')")
  59 + public CommonResult<PageResult<IotDeviceMessageRespPairVO>> getDeviceMessagePairPage(
  60 + @Valid IotDeviceMessagePageReqVO pageReqVO) {
  61 + // 1.1 先按照条件,查询 request 的消息(非 reply)
  62 + pageReqVO.setReply(false);
  63 + PageResult<IotDeviceMessageDO> requestMessagePageResult = deviceMessageService.getDeviceMessagePage(pageReqVO);
  64 + if (CollUtil.isEmpty(requestMessagePageResult.getList())) {
  65 + return success(PageResult.empty());
  66 + }
  67 + // 1.2 接着按照 requestIds,批量查询 reply 消息
  68 + List<String> requestIds = convertList(requestMessagePageResult.getList(), IotDeviceMessageDO::getRequestId);
  69 + List<IotDeviceMessageDO> replyMessageList = deviceMessageService.getDeviceMessageListByRequestIdsAndReply(
  70 + pageReqVO.getDeviceId(), requestIds, true);
  71 + Map<String, IotDeviceMessageDO> replyMessages = convertMap(replyMessageList, IotDeviceMessageDO::getRequestId);
  72 +
  73 + // 2. 组装结果
  74 + List<IotDeviceMessageRespPairVO> pairMessages = convertList(requestMessagePageResult.getList(),
  75 + requestMessage -> {
  76 + IotDeviceMessageDO replyMessage = replyMessages.get(requestMessage.getRequestId());
  77 + return new IotDeviceMessageRespPairVO()
  78 + .setRequest(BeanUtils.toBean(requestMessage, IotDeviceMessageRespVO.class))
  79 + .setReply(BeanUtils.toBean(replyMessage, IotDeviceMessageRespVO.class));
  80 + });
  81 + return success(new PageResult<>(pairMessages, requestMessagePageResult.getTotal()));
  82 + }
  83 +
  84 + @PostMapping("/send")
  85 + @Operation(summary = "发送消息", description = "可用于设备模拟")
  86 + @PreAuthorize("@ss.hasPermission('iot:device:message-end')")
  87 + public CommonResult<Boolean> sendDeviceMessage(@Valid @RequestBody IotDeviceMessageSendReqVO sendReqVO) {
  88 + deviceMessageService.sendDeviceMessage(BeanUtils.toBean(sendReqVO, IotDeviceMessage.class));
  89 + return success(true);
  90 + }
  91 +
  92 +}
0 \ No newline at end of file 93 \ 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
1 package cn.iocoder.yudao.module.iot.controller.admin.device; 1 package cn.iocoder.yudao.module.iot.controller.admin.device;
2 2
3 -import cn.hutool.core.collection.CollUtil;  
4 import cn.hutool.core.date.LocalDateTimeUtil; 3 import cn.hutool.core.date.LocalDateTimeUtil;
5 import cn.hutool.core.lang.Assert; 4 import cn.hutool.core.lang.Assert;
6 -import cn.hutool.core.util.StrUtil;  
7 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 5 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; 6 +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.property.IotDevicePropertyDetailRespVO;
  7 +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.property.IotDevicePropertyHistoryListReqVO;
  8 +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.property.IotDevicePropertyRespVO;
  9 +import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.ThingModelProperty;
11 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; 10 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
12 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDevicePropertyDO; 11 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDevicePropertyDO;
13 import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO; 12 import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO;
  13 +import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelTypeEnum;
14 import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; 14 import cn.iocoder.yudao.module.iot.service.device.IotDeviceService;
15 -import cn.iocoder.yudao.module.iot.service.device.data.IotDevicePropertyService; 15 +import cn.iocoder.yudao.module.iot.service.device.property.IotDevicePropertyService;
16 import cn.iocoder.yudao.module.iot.service.thingmodel.IotThingModelService; 16 import cn.iocoder.yudao.module.iot.service.thingmodel.IotThingModelService;
17 import io.swagger.v3.oas.annotations.Operation; 17 import io.swagger.v3.oas.annotations.Operation;
18 import io.swagger.v3.oas.annotations.Parameter; 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; 19 import io.swagger.v3.oas.annotations.tags.Tag;
21 import jakarta.annotation.Resource; 20 import jakarta.annotation.Resource;
22 import jakarta.validation.Valid; 21 import jakarta.validation.Valid;
@@ -46,50 +45,45 @@ public class IotDevicePropertyController { @@ -46,50 +45,45 @@ public class IotDevicePropertyController {
46 @Resource 45 @Resource
47 private IotDeviceService deviceService; 46 private IotDeviceService deviceService;
48 47
49 - @GetMapping("/latest") 48 + @GetMapping("/get-latest")
50 @Operation(summary = "获取设备属性最新属性") 49 @Operation(summary = "获取设备属性最新属性")
51 - @Parameters({  
52 - @Parameter(name = "deviceId", description = "设备编号", required = true),  
53 - @Parameter(name = "identifier", description = "标识符"),  
54 - @Parameter(name = "name", description = "名称")  
55 - }) 50 + @Parameter(name = "deviceId", description = "设备编号", required = true)
56 @PreAuthorize("@ss.hasPermission('iot:device:property-query')") 51 @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 - // 拼接数据 52 + public CommonResult<List<IotDevicePropertyDetailRespVO>> getLatestDeviceProperties(
  53 + @RequestParam("deviceId") Long deviceId) {
  54 + // 1.1 获取设备信息
64 IotDeviceDO device = deviceService.getDevice(deviceId); 55 IotDeviceDO device = deviceService.getDevice(deviceId);
65 Assert.notNull(device, "设备不存在"); 56 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; 57 + // 1.2 获取设备最新属性
  58 + Map<String, IotDevicePropertyDO> properties = devicePropertyService.getLatestDeviceProperties(deviceId);
  59 + // 1.3 根据 productId + type 查询属性类型的物模型
  60 + List<IotThingModelDO> thingModels = thingModelService.getThingModelListByProductIdAndType(
  61 + device.getProductId(), IotThingModelTypeEnum.PROPERTY.getType());
  62 +
  63 + // 2. 基于 thingModels 遍历,拼接 properties
  64 + return success(convertList(thingModels, thingModel -> {
  65 + ThingModelProperty thingModelProperty = thingModel.getProperty();
  66 + Assert.notNull(thingModelProperty, "属性不能为空");
  67 + IotDevicePropertyDetailRespVO result = new IotDevicePropertyDetailRespVO()
  68 + .setName(thingModel.getName()).setDataType(thingModelProperty.getDataType())
  69 + .setDataSpecs(thingModelProperty.getDataSpecs())
  70 + .setDataSpecsList(thingModelProperty.getDataSpecsList());
  71 + result.setIdentifier(thingModel.getIdentifier());
  72 + IotDevicePropertyDO property = properties.get(thingModel.getIdentifier());
  73 + if (property != null) {
  74 + result.setValue(property.getValue())
  75 + .setUpdateTime(LocalDateTimeUtil.toEpochMilli(property.getUpdateTime()));
78 } 76 }
79 - // 构建对象  
80 - IotDevicePropertyDO property = entry.getValue();  
81 - return new IotDevicePropertyRespVO().setProperty(thingModel.getProperty())  
82 - .setValue(property.getValue()).setUpdateTime(LocalDateTimeUtil.toEpochMilli(property.getUpdateTime())); 77 + return result;
83 })); 78 }));
84 } 79 }
85 80
86 - @GetMapping("/history-page")  
87 - @Operation(summary = "获取设备属性历史数据") 81 + @GetMapping("/history-list")
  82 + @Operation(summary = "获取设备属性历史数据列表")
88 @PreAuthorize("@ss.hasPermission('iot:device:property-query')") 83 @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)); 84 + public CommonResult<List<IotDevicePropertyRespVO>> getHistoryDevicePropertyList(
  85 + @Valid IotDevicePropertyHistoryListReqVO listReqVO) {
  86 + return success(devicePropertyService.getHistoryDevicePropertyList(listReqVO));
93 } 87 }
94 88
95 } 89 }
96 \ No newline at end of file 90 \ 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/control/IotDeviceDownstreamReqVO.java deleted
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 deleted
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 deleted
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 -}  
23 \ No newline at end of file 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/data/IotDeviceLogRespVO.java deleted
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 -}  
37 \ No newline at end of file 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/device/IotDeviceAuthInfoRespVO.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.NotBlank;
  5 +import lombok.Data;
  6 +
  7 +@Schema(description = "管理后台 - IoT 设备认证信息 Response VO")
  8 +@Data
  9 +public class IotDeviceAuthInfoRespVO {
  10 +
  11 + @Schema(description = "客户端 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "product123.device001")
  12 + @NotBlank(message = "客户端 ID 不能为空")
  13 + private String clientId;
  14 +
  15 + @Schema(description = "用户名", requiredMode = Schema.RequiredMode.REQUIRED, example = "device001&product123")
  16 + @NotBlank(message = "用户名不能为空")
  17 + private String username;
  18 +
  19 + @Schema(description = "密码", requiredMode = Schema.RequiredMode.REQUIRED, example = "1a2b3c4d5e6f7890abcdef1234567890")
  20 + @NotBlank(message = "密码不能为空")
  21 + private String password;
  22 +
  23 +}
0 \ No newline at end of file 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/IotDeviceByProductKeyAndNamesReqVO.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.NotBlank;
  5 +import jakarta.validation.constraints.NotEmpty;
  6 +import lombok.Data;
  7 +
  8 +import java.util.List;
  9 +
  10 +@Schema(description = "管理后台 - 通过产品标识和设备名称列表获取设备 Request VO")
  11 +@Data
  12 +public class IotDeviceByProductKeyAndNamesReqVO {
  13 +
  14 + @Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "1de24640dfe")
  15 + @NotBlank(message = "产品标识不能为空")
  16 + private String productKey;
  17 +
  18 + @Schema(description = "设备名称列表", requiredMode = Schema.RequiredMode.REQUIRED, example = "device001,device002")
  19 + @NotEmpty(message = "设备名称列表不能为空")
  20 + private List<String> deviceNames;
  21 +
  22 +}
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/device/IotDeviceImportExcelVO.java
1 package cn.iocoder.yudao.module.iot.controller.admin.device.vo.device; 1 package cn.iocoder.yudao.module.iot.controller.admin.device.vo.device;
2 2
3 import cn.idev.excel.annotation.ExcelProperty; 3 import cn.idev.excel.annotation.ExcelProperty;
  4 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  5 +import cn.iocoder.yudao.module.iot.enums.product.IotLocationTypeEnum;
4 import io.swagger.v3.oas.annotations.media.Schema; 6 import io.swagger.v3.oas.annotations.media.Schema;
5 import jakarta.validation.constraints.NotEmpty; 7 import jakarta.validation.constraints.NotEmpty;
  8 +import jakarta.validation.constraints.NotNull;
6 import lombok.AllArgsConstructor; 9 import lombok.AllArgsConstructor;
7 import lombok.Builder; 10 import lombok.Builder;
8 import lombok.Data; 11 import lombok.Data;
@@ -34,4 +37,9 @@ public class IotDeviceImportExcelVO { @@ -34,4 +37,9 @@ public class IotDeviceImportExcelVO {
34 @ExcelProperty("设备分组") 37 @ExcelProperty("设备分组")
35 private String groupNames; 38 private String groupNames;
36 39
  40 + @ExcelProperty("上报方式(1:IP 定位, 2:设备上报,3:手动定位)")
  41 + @NotNull(message = "上报方式不能为空")
  42 + @InEnum(IotLocationTypeEnum.class)
  43 + private Integer locationType;
  44 +
37 } 45 }
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/device/IotDeviceMqttConnectionParamsRespVO.java deleted
1 -package cn.iocoder.yudao.module.iot.controller.admin.device.vo.device;  
2 -  
3 -import cn.idev.excel.annotation.ExcelIgnoreUnannotated;  
4 -import cn.idev.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 -}  
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/device/IotDevicePageReqVO.java
@@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.iot.controller.admin.device.vo.device; @@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.iot.controller.admin.device.vo.device;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.PageParam; 3 import cn.iocoder.yudao.framework.common.pojo.PageParam;
4 import cn.iocoder.yudao.framework.common.validation.InEnum; 4 import cn.iocoder.yudao.framework.common.validation.InEnum;
5 -import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStateEnum; 5 +import cn.iocoder.yudao.module.iot.core.enums.IotDeviceStateEnum;
6 import cn.iocoder.yudao.module.iot.enums.product.IotProductDeviceTypeEnum; 6 import cn.iocoder.yudao.module.iot.enums.product.IotProductDeviceTypeEnum;
7 import io.swagger.v3.oas.annotations.media.Schema; 7 import io.swagger.v3.oas.annotations.media.Schema;
8 import lombok.Data; 8 import lombok.Data;
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.device; 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;  
5 import cn.idev.excel.annotation.ExcelIgnoreUnannotated; 3 import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
6 import cn.idev.excel.annotation.ExcelProperty; 4 import cn.idev.excel.annotation.ExcelProperty;
  5 +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
  6 +import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
  7 +import cn.iocoder.yudao.module.iot.enums.DictTypeConstants;
7 import io.swagger.v3.oas.annotations.media.Schema; 8 import io.swagger.v3.oas.annotations.media.Schema;
8 import lombok.Data; 9 import lombok.Data;
9 10
  11 +import java.math.BigDecimal;
10 import java.time.LocalDateTime; 12 import java.time.LocalDateTime;
11 import java.util.Set; 13 import java.util.Set;
12 14
@@ -20,10 +22,6 @@ public class IotDeviceRespVO { @@ -20,10 +22,6 @@ public class IotDeviceRespVO {
20 @Schema(description = "设备编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "177") 22 @Schema(description = "设备编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "177")
21 private Long id; 23 private Long id;
22 24
23 - @Schema(description = "设备唯一标识符", requiredMode = Schema.RequiredMode.REQUIRED)  
24 - @ExcelProperty("设备唯一标识符")  
25 - private String deviceKey;  
26 -  
27 @Schema(description = "设备名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五") 25 @Schema(description = "设备名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五")
28 @ExcelProperty("设备名称") 26 @ExcelProperty("设备名称")
29 private String deviceName; 27 private String deviceName;
@@ -86,8 +84,19 @@ public class IotDeviceRespVO { @@ -86,8 +84,19 @@ public class IotDeviceRespVO {
86 @Schema(description = "设备配置", example = "{\"abc\": \"efg\"}") 84 @Schema(description = "设备配置", example = "{\"abc\": \"efg\"}")
87 private String config; 85 private String config;
88 86
  87 + @Schema(description = "定位方式", example = "2")
  88 + @ExcelProperty(value = "定位方式", converter = DictConvert.class)
  89 + @DictFormat(DictTypeConstants.LOCATION_TYPE)
  90 + private Integer locationType;
  91 +
  92 + @Schema(description = "设备位置的纬度", example = "45.000000")
  93 + private BigDecimal latitude;
  94 +
  95 + @Schema(description = "设备位置的经度", example = "45.000000")
  96 + private BigDecimal longitude;
  97 +
89 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) 98 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
90 @ExcelProperty("创建时间") 99 @ExcelProperty("创建时间")
91 private LocalDateTime createTime; 100 private LocalDateTime createTime;
92 101
93 -} 102 -}
  103 +}
94 \ No newline at end of file 104 \ 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/IotDeviceSaveReqVO.java
1 package cn.iocoder.yudao.module.iot.controller.admin.device.vo.device; 1 package cn.iocoder.yudao.module.iot.controller.admin.device.vo.device;
2 2
  3 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  4 +import cn.iocoder.yudao.module.iot.enums.product.IotLocationTypeEnum;
3 import io.swagger.v3.oas.annotations.media.Schema; 5 import io.swagger.v3.oas.annotations.media.Schema;
4 -import jakarta.validation.constraints.Size;  
5 import lombok.Data; 6 import lombok.Data;
6 7
  8 +import java.math.BigDecimal;
7 import java.util.Set; 9 import java.util.Set;
8 10
9 @Schema(description = "管理后台 - IoT 设备新增/修改 Request VO") 11 @Schema(description = "管理后台 - IoT 设备新增/修改 Request VO")
@@ -13,10 +15,6 @@ public class IotDeviceSaveReqVO { @@ -13,10 +15,6 @@ public class IotDeviceSaveReqVO {
13 @Schema(description = "设备编号", example = "177") 15 @Schema(description = "设备编号", example = "177")
14 private Long id; 16 private Long id;
15 17
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 = "王五") 18 @Schema(description = "设备名称", requiredMode = Schema.RequiredMode.AUTO, example = "王五")
21 private String deviceName; 19 private String deviceName;
22 20
@@ -41,4 +39,14 @@ public class IotDeviceSaveReqVO { @@ -41,4 +39,14 @@ public class IotDeviceSaveReqVO {
41 @Schema(description = "设备配置", example = "{\"abc\": \"efg\"}") 39 @Schema(description = "设备配置", example = "{\"abc\": \"efg\"}")
42 private String config; 40 private String config;
43 41
  42 + @Schema(description = "定位类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
  43 + @InEnum(value = IotLocationTypeEnum.class, message = "定位方式必须是 {value}")
  44 + private Integer locationType;
  45 +
  46 + @Schema(description = "设备位置的纬度", example = "16380")
  47 + private BigDecimal latitude;
  48 +
  49 + @Schema(description = "设备位置的经度", example = "16380")
  50 + private BigDecimal longitude;
  51 +
44 } 52 }
45 \ No newline at end of file 53 \ 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/message/IotDeviceMessagePageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.controller.admin.device.vo.message;
  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.core.enums.IotDeviceMessageMethodEnum;
  6 +import io.swagger.v3.oas.annotations.media.Schema;
  7 +import jakarta.validation.constraints.NotNull;
  8 +import jakarta.validation.constraints.Size;
  9 +import lombok.Data;
  10 +import org.springframework.format.annotation.DateTimeFormat;
  11 +
  12 +import java.time.LocalDateTime;
  13 +
  14 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  15 +
  16 +@Schema(description = "管理后台 - IoT 设备消息分页查询 Request VO")
  17 +@Data
  18 +public class IotDeviceMessagePageReqVO extends PageParam {
  19 +
  20 + @Schema(description = "设备编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  21 + @NotNull(message = "设备编号不能为空")
  22 + private Long deviceId;
  23 +
  24 + @Schema(description = "消息类型", example = "property")
  25 + @InEnum(IotDeviceMessageMethodEnum.class)
  26 + private String method;
  27 +
  28 + @Schema(description = "是否上行", example = "true")
  29 + private Boolean upstream;
  30 +
  31 + @Schema(description = "是否回复", example = "true")
  32 + private Boolean reply;
  33 +
  34 + @Schema(description = "标识符", example = "temperature")
  35 + private String identifier;
  36 +
  37 + @Schema(description = "时间范围", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
  38 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  39 + @Size(min = 2, max = 2, message = "请选择时间范围")
  40 + private LocalDateTime[] times;
  41 +
  42 +}
0 \ No newline at end of file 43 \ 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/message/IotDeviceMessageRespPairVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.controller.admin.device.vo.message;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +@Schema(description = "管理后台 - IoT 设备消息对 Response VO")
  7 +@Data
  8 +public class IotDeviceMessageRespPairVO {
  9 +
  10 + @Schema(description = "请求消息", requiredMode = Schema.RequiredMode.REQUIRED)
  11 + private IotDeviceMessageRespVO request;
  12 +
  13 + @Schema(description = "响应消息")
  14 + private IotDeviceMessageRespVO reply; // 通过 requestId 配对
  15 +
  16 +}
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/message/IotDeviceMessageRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.controller.admin.device.vo.message;
  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 IotDeviceMessageRespVO {
  11 +
  12 + @Schema(description = "消息编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  13 + private String id;
  14 +
  15 + @Schema(description = "上报时间", requiredMode = Schema.RequiredMode.REQUIRED)
  16 + private LocalDateTime reportTime;
  17 +
  18 + @Schema(description = "记录时间戳", requiredMode = Schema.RequiredMode.REQUIRED)
  19 + private LocalDateTime ts;
  20 +
  21 + @Schema(description = "设备编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "123")
  22 + private Long deviceId;
  23 +
  24 + @Schema(description = "服务编号", example = "server_123")
  25 + private String serverId;
  26 +
  27 + @Schema(description = "是否上行消息", example = "true", examples = "false")
  28 + private Boolean upstream;
  29 +
  30 + @Schema(description = "是否回复消息", example = "false", examples = "true")
  31 + private Boolean reply;
  32 +
  33 + @Schema(description = "标识符", example = "temperature")
  34 + private String identifier;
  35 +
  36 + // ========== codec(编解码)字段 ==========
  37 +
  38 + @Schema(description = "请求编号", example = "req_123")
  39 + private String requestId;
  40 +
  41 + @Schema(description = "请求方法", requiredMode = Schema.RequiredMode.REQUIRED, example = "thing.property.report")
  42 + private String method;
  43 +
  44 + @Schema(description = "请求参数")
  45 + private Object params;
  46 +
  47 + @Schema(description = "响应结果")
  48 + private Object data;
  49 +
  50 + @Schema(description = "响应错误码", example = "200")
  51 + private Integer code;
  52 +
  53 + @Schema(description = "响应提示", example = "操作成功")
  54 + private String msg;
  55 +
  56 +}
0 \ No newline at end of file 57 \ 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/message/IotDeviceMessageSendReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.controller.admin.device.vo.message;
  2 +
  3 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  4 +import cn.iocoder.yudao.module.iot.core.enums.IotDeviceMessageMethodEnum;
  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 IotDeviceMessageSendReqVO {
  13 +
  14 + @Schema(description = "请求方法", requiredMode = Schema.RequiredMode.REQUIRED, example = "report")
  15 + @NotEmpty(message = "请求方法不能为空")
  16 + @InEnum(IotDeviceMessageMethodEnum.class)
  17 + private String method;
  18 +
  19 + @Schema(description = "请求参数")
  20 + private Object params; // 例如说:属性上报的 properties、事件上报的 params
  21 +
  22 + @Schema(description = "设备编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "177")
  23 + @NotNull(message = "设备编号不能为空")
  24 + private Long deviceId;
  25 +
  26 +}
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/property/IotDevicePropertyDetailRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.controller.admin.device.vo.property;
  2 +
  3 +import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.dataType.ThingModelDataSpecs;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Data;
  6 +
  7 +import java.util.List;
  8 +
  9 +@Schema(description = "管理后台 - IoT 设备属性详细 Response VO") // 额外增加 来自 ThingModelProperty 的变量 属性
  10 +@Data
  11 +public class IotDevicePropertyDetailRespVO extends IotDevicePropertyRespVO {
  12 +
  13 + @Schema(description = "属性名称", requiredMode = Schema.RequiredMode.REQUIRED)
  14 + private String name;
  15 +
  16 + @Schema(description = "数据类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "int")
  17 + private String dataType;
  18 +
  19 + @Schema(description = "数据定义")
  20 + private ThingModelDataSpecs dataSpecs;
  21 +
  22 + @Schema(description = "数据定义列表")
  23 + private List<ThingModelDataSpecs> dataSpecsList;
  24 +
  25 +}
0 \ No newline at end of file 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/data/IotDevicePropertyHistoryPageReqVO.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/property/IotDevicePropertyHistoryListReqVO.java
1 -package cn.iocoder.yudao.module.iot.controller.admin.device.vo.data; 1 +package cn.iocoder.yudao.module.iot.controller.admin.device.vo.property;
2 2
3 -import cn.iocoder.yudao.framework.common.pojo.PageParam;  
4 import io.swagger.v3.oas.annotations.media.Schema; 3 import io.swagger.v3.oas.annotations.media.Schema;
5 import jakarta.validation.constraints.NotEmpty; 4 import jakarta.validation.constraints.NotEmpty;
6 import jakarta.validation.constraints.NotNull; 5 import jakarta.validation.constraints.NotNull;
@@ -12,17 +11,14 @@ import java.time.LocalDateTime; @@ -12,17 +11,14 @@ import java.time.LocalDateTime;
12 11
13 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; 12 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
14 13
15 -@Schema(description = "管理后台 - IoT 设备属性历史分页 Request VO") 14 +@Schema(description = "管理后台 - IoT 设备属性历史列表 Request VO")
16 @Data 15 @Data
17 -public class IotDevicePropertyHistoryPageReqVO extends PageParam { 16 +public class IotDevicePropertyHistoryListReqVO {
18 17
19 @Schema(description = "设备编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "177") 18 @Schema(description = "设备编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "177")
20 @NotNull(message = "设备编号不能为空") 19 @NotNull(message = "设备编号不能为空")
21 private Long deviceId; 20 private Long deviceId;
22 21
23 - @Schema(description = "设备 Key", hidden = true)  
24 - private String deviceKey; // 非前端传递,后端自己查询设置  
25 -  
26 @Schema(description = "属性标识符", requiredMode = Schema.RequiredMode.REQUIRED) 22 @Schema(description = "属性标识符", requiredMode = Schema.RequiredMode.REQUIRED)
27 @NotEmpty(message = "属性标识符不能为空") 23 @NotEmpty(message = "属性标识符不能为空")
28 private String identifier; 24 private String identifier;
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/data/IotDevicePropertyRespVO.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/property/IotDevicePropertyRespVO.java
1 -package cn.iocoder.yudao.module.iot.controller.admin.device.vo.data; 1 +package cn.iocoder.yudao.module.iot.controller.admin.device.vo.property;
2 2
3 -import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelProperty;  
4 import io.swagger.v3.oas.annotations.media.Schema; 3 import io.swagger.v3.oas.annotations.media.Schema;
5 import lombok.Data; 4 import lombok.Data;
6 5
@@ -8,10 +7,10 @@ import lombok.Data; @@ -8,10 +7,10 @@ import lombok.Data;
8 @Data 7 @Data
9 public class IotDevicePropertyRespVO { 8 public class IotDevicePropertyRespVO {
10 9
11 - @Schema(description = "属性定义", requiredMode = Schema.RequiredMode.REQUIRED)  
12 - private ThingModelProperty property; 10 + @Schema(description = "属性标识符", requiredMode = Schema.RequiredMode.REQUIRED)
  11 + private String identifier;
13 12
14 - @Schema(description = "最新值", requiredMode = Schema.RequiredMode.REQUIRED) 13 + @Schema(description = "属性值", requiredMode = Schema.RequiredMode.REQUIRED)
15 private Object value; 14 private Object value;
16 15
17 @Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED) 16 @Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED)
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/ota/IotOtaFirmwareController.java
@@ -3,13 +3,14 @@ package cn.iocoder.yudao.module.iot.controller.admin.ota; @@ -3,13 +3,14 @@ package cn.iocoder.yudao.module.iot.controller.admin.ota;
3 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 3 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 import cn.iocoder.yudao.framework.common.pojo.PageResult; 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 5 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  6 +import cn.iocoder.yudao.module.iot.controller.admin.ota.vo.firmware.IotOtaFirmwareCreateReqVO;
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.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.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; 9 import cn.iocoder.yudao.module.iot.controller.admin.ota.vo.firmware.IotOtaFirmwareUpdateReqVO;
10 import cn.iocoder.yudao.module.iot.dal.dataobject.ota.IotOtaFirmwareDO; 10 import cn.iocoder.yudao.module.iot.dal.dataobject.ota.IotOtaFirmwareDO;
  11 +import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
11 import cn.iocoder.yudao.module.iot.service.ota.IotOtaFirmwareService; 12 import cn.iocoder.yudao.module.iot.service.ota.IotOtaFirmwareService;
12 -import com.fhs.core.trans.anno.TransMethodResult; 13 +import cn.iocoder.yudao.module.iot.service.product.IotProductService;
13 import io.swagger.v3.oas.annotations.Operation; 14 import io.swagger.v3.oas.annotations.Operation;
14 import io.swagger.v3.oas.annotations.tags.Tag; 15 import io.swagger.v3.oas.annotations.tags.Tag;
15 import jakarta.annotation.Resource; 16 import jakarta.annotation.Resource;
@@ -22,12 +23,14 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @@ -22,12 +23,14 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
22 23
23 @Tag(name = "管理后台 - IoT OTA 固件") 24 @Tag(name = "管理后台 - IoT OTA 固件")
24 @RestController 25 @RestController
25 -@RequestMapping("/iot/ota-firmware") 26 +@RequestMapping("/iot/ota/firmware")
26 @Validated 27 @Validated
27 public class IotOtaFirmwareController { 28 public class IotOtaFirmwareController {
28 29
29 @Resource 30 @Resource
30 private IotOtaFirmwareService otaFirmwareService; 31 private IotOtaFirmwareService otaFirmwareService;
  32 + @Resource
  33 + private IotProductService productService;
31 34
32 @PostMapping("/create") 35 @PostMapping("/create")
33 @Operation(summary = "创建 OTA 固件") 36 @Operation(summary = "创建 OTA 固件")
@@ -47,10 +50,17 @@ public class IotOtaFirmwareController { @@ -47,10 +50,17 @@ public class IotOtaFirmwareController {
47 @GetMapping("/get") 50 @GetMapping("/get")
48 @Operation(summary = "获得 OTA 固件") 51 @Operation(summary = "获得 OTA 固件")
49 @PreAuthorize("@ss.hasPermission('iot:ota-firmware:query')") 52 @PreAuthorize("@ss.hasPermission('iot:ota-firmware:query')")
50 - @TransMethodResult  
51 public CommonResult<IotOtaFirmwareRespVO> getOtaFirmware(@RequestParam("id") Long id) { 53 public CommonResult<IotOtaFirmwareRespVO> getOtaFirmware(@RequestParam("id") Long id) {
52 - IotOtaFirmwareDO otaFirmware = otaFirmwareService.getOtaFirmware(id);  
53 - return success(BeanUtils.toBean(otaFirmware, IotOtaFirmwareRespVO.class)); 54 + IotOtaFirmwareDO firmware = otaFirmwareService.getOtaFirmware(id);
  55 + if (firmware == null) {
  56 + return success(null);
  57 + }
  58 + return success(BeanUtils.toBean(firmware, IotOtaFirmwareRespVO.class, o -> {
  59 + IotProductDO product = productService.getProduct(firmware.getProductId());
  60 + if (product != null) {
  61 + o.setProductName(product.getName());
  62 + }
  63 + }));
54 } 64 }
55 65
56 @GetMapping("/page") 66 @GetMapping("/page")
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/ota/IotOtaTaskController.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.task.IotOtaTaskPageReqVO;
  7 +import cn.iocoder.yudao.module.iot.controller.admin.ota.vo.task.IotOtaTaskRespVO;
  8 +import cn.iocoder.yudao.module.iot.controller.admin.ota.vo.task.IotOtaTaskCreateReqVO;
  9 +import cn.iocoder.yudao.module.iot.dal.dataobject.ota.IotOtaTaskDO;
  10 +import cn.iocoder.yudao.module.iot.service.ota.IotOtaTaskService;
  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/task")
  25 +@Validated
  26 +public class IotOtaTaskController {
  27 +
  28 + @Resource
  29 + private IotOtaTaskService otaTaskService;
  30 +
  31 + @PostMapping("/create")
  32 + @Operation(summary = "创建 OTA 升级任务")
  33 + @PreAuthorize(value = "@ss.hasPermission('iot:ota-task:create')")
  34 + public CommonResult<Long> createOtaTask(@Valid @RequestBody IotOtaTaskCreateReqVO createReqVO) {
  35 + return success(otaTaskService.createOtaTask(createReqVO));
  36 + }
  37 +
  38 + @PostMapping("/cancel")
  39 + @Operation(summary = "取消 OTA 升级任务")
  40 + @Parameter(name = "id", description = "升级任务编号", required = true)
  41 + @PreAuthorize(value = "@ss.hasPermission('iot:ota-task:cancel')")
  42 + public CommonResult<Boolean> cancelOtaTask(@RequestParam("id") Long id) {
  43 + otaTaskService.cancelOtaTask(id);
  44 + return success(true);
  45 + }
  46 +
  47 + @GetMapping("/page")
  48 + @Operation(summary = "获得 OTA 升级任务分页")
  49 + @PreAuthorize(value = "@ss.hasPermission('iot:ota-task:query')")
  50 + public CommonResult<PageResult<IotOtaTaskRespVO>> getOtaTaskPage(@Valid IotOtaTaskPageReqVO pageReqVO) {
  51 + PageResult<IotOtaTaskDO> pageResult = otaTaskService.getOtaTaskPage(pageReqVO);
  52 + return success(BeanUtils.toBean(pageResult, IotOtaTaskRespVO.class));
  53 + }
  54 +
  55 + @GetMapping("/get")
  56 + @Operation(summary = "获得 OTA 升级任务")
  57 + @Parameter(name = "id", description = "升级任务编号", required = true, example = "1024")
  58 + @PreAuthorize(value = "@ss.hasPermission('iot:ota-task:query')")
  59 + public CommonResult<IotOtaTaskRespVO> getOtaTask(@RequestParam("id") Long id) {
  60 + IotOtaTaskDO upgradeTask = otaTaskService.getOtaTask(id);
  61 + return success(BeanUtils.toBean(upgradeTask, IotOtaTaskRespVO.class));
  62 + }
  63 +
  64 +}
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/ota/IotOtaTaskRecordController.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.collection.MapUtils;
  6 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  7 +import cn.iocoder.yudao.module.iot.controller.admin.ota.vo.task.record.IotOtaTaskRecordPageReqVO;
  8 +import cn.iocoder.yudao.module.iot.controller.admin.ota.vo.task.record.IotOtaTaskRecordRespVO;
  9 +import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
  10 +import cn.iocoder.yudao.module.iot.dal.dataobject.ota.IotOtaFirmwareDO;
  11 +import cn.iocoder.yudao.module.iot.dal.dataobject.ota.IotOtaTaskRecordDO;
  12 +import cn.iocoder.yudao.module.iot.service.device.IotDeviceService;
  13 +import cn.iocoder.yudao.module.iot.service.ota.IotOtaFirmwareService;
  14 +import cn.iocoder.yudao.module.iot.service.ota.IotOtaTaskRecordService;
  15 +import io.swagger.v3.oas.annotations.Operation;
  16 +import io.swagger.v3.oas.annotations.Parameter;
  17 +import io.swagger.v3.oas.annotations.Parameters;
  18 +import io.swagger.v3.oas.annotations.tags.Tag;
  19 +import jakarta.annotation.Resource;
  20 +import jakarta.validation.Valid;
  21 +import org.dromara.hutool.core.collection.CollUtil;
  22 +import org.springframework.security.access.prepost.PreAuthorize;
  23 +import org.springframework.validation.annotation.Validated;
  24 +import org.springframework.web.bind.annotation.GetMapping;
  25 +import org.springframework.web.bind.annotation.PutMapping;
  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.Map;
  31 +
  32 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  33 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
  34 +
  35 +@Tag(name = "管理后台 - IoT OTA 升级任务记录")
  36 +@RestController
  37 +@RequestMapping("/iot/ota/task/record")
  38 +@Validated
  39 +public class IotOtaTaskRecordController {
  40 +
  41 + @Resource
  42 + private IotOtaTaskRecordService otaTaskRecordService;
  43 + @Resource
  44 + private IotDeviceService deviceService;
  45 + @Resource
  46 + private IotOtaFirmwareService otaFirmwareService;
  47 +
  48 + @GetMapping("/get-status-statistics")
  49 + @Operation(summary = "获得 OTA 升级记录状态统计")
  50 + @Parameters({
  51 + @Parameter(name = "firmwareId", description = "固件编号", example = "1024"),
  52 + @Parameter(name = "taskId", description = "升级任务编号", example = "2048")
  53 + })
  54 + @PreAuthorize("@ss.hasPermission('iot:ota-task-record:query')")
  55 + public CommonResult<Map<Integer, Long>> getOtaTaskRecordStatusStatistics(
  56 + @RequestParam(value = "firmwareId", required = false) Long firmwareId,
  57 + @RequestParam(value = "taskId", required = false) Long taskId) {
  58 + return success(otaTaskRecordService.getOtaTaskRecordStatusStatistics(firmwareId, taskId));
  59 + }
  60 +
  61 + @GetMapping("/page")
  62 + @Operation(summary = "获得 OTA 升级记录分页")
  63 + @PreAuthorize("@ss.hasPermission('iot:ota-task-record:query')")
  64 + public CommonResult<PageResult<IotOtaTaskRecordRespVO>> getOtaTaskRecordPage(
  65 + @Valid IotOtaTaskRecordPageReqVO pageReqVO) {
  66 + PageResult<IotOtaTaskRecordDO> pageResult = otaTaskRecordService.getOtaTaskRecordPage(pageReqVO);
  67 + if (CollUtil.isEmpty(pageResult.getList())) {
  68 + return success(PageResult.empty());
  69 + }
  70 +
  71 + // 批量查询固件信息
  72 + Map<Long, IotOtaFirmwareDO> firmwareMap = otaFirmwareService.getOtaFirmwareMap(
  73 + convertSet(pageResult.getList(), IotOtaTaskRecordDO::getFromFirmwareId));
  74 + Map<Long, IotDeviceDO> deviceMap = deviceService.getDeviceMap(
  75 + convertSet(pageResult.getList(), IotOtaTaskRecordDO::getDeviceId));
  76 + // 转换为响应 VO
  77 + return success(BeanUtils.toBean(pageResult, IotOtaTaskRecordRespVO.class, (vo) -> {
  78 + MapUtils.findAndThen(firmwareMap, vo.getFromFirmwareId(), firmware ->
  79 + vo.setFromFirmwareVersion(firmware.getVersion()));
  80 + MapUtils.findAndThen(deviceMap, vo.getDeviceId(), device ->
  81 + vo.setDeviceName(device.getDeviceName()));
  82 + }));
  83 + }
  84 +
  85 + @GetMapping("/get")
  86 + @Operation(summary = "获得 OTA 升级记录")
  87 + @PreAuthorize("@ss.hasPermission('iot:ota-task-record:query')")
  88 + @Parameter(name = "id", description = "升级记录编号", required = true, example = "1024")
  89 + public CommonResult<IotOtaTaskRecordRespVO> getOtaTaskRecord(@RequestParam("id") Long id) {
  90 + IotOtaTaskRecordDO upgradeRecord = otaTaskRecordService.getOtaTaskRecord(id);
  91 + return success(BeanUtils.toBean(upgradeRecord, IotOtaTaskRecordRespVO.class));
  92 + }
  93 +
  94 + @PutMapping("/cancel")
  95 + @Operation(summary = "取消 OTA 升级记录")
  96 + @PreAuthorize("@ss.hasPermission('iot:ota-task-record:cancel')")
  97 + @Parameter(name = "id", description = "升级记录编号", required = true, example = "1024")
  98 + public CommonResult<Boolean> cancelOtaTaskRecord(@RequestParam("id") Long id) {
  99 + otaTaskRecordService.cancelOtaTaskRecord(id);
  100 + return success(true);
  101 + }
  102 +
  103 +}
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/ota/IotOtaUpgradeRecordController.java deleted
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 com.fhs.core.trans.anno.TransMethodResult;  
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 java.util.Map;  
21 -  
22 -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;  
23 -  
24 -@Tag(name = "管理后台 - IoT OTA 升级记录")  
25 -@RestController  
26 -@RequestMapping("/iot/ota-upgrade-record")  
27 -@Validated  
28 -public class IotOtaUpgradeRecordController {  
29 -  
30 - @Resource  
31 - private IotOtaUpgradeRecordService upgradeRecordService;  
32 -  
33 - @GetMapping("/get-statistics")  
34 - @Operation(summary = "固件升级设备统计")  
35 - @PreAuthorize("@ss.hasPermission('iot:ota-upgrade-record:query')")  
36 - @Parameter(name = "firmwareId", description = "固件编号", required = true, example = "1024")  
37 - public CommonResult<Map<Integer, Long>> getOtaUpgradeRecordStatistics(@RequestParam(value = "firmwareId") Long firmwareId) {  
38 - return success(upgradeRecordService.getOtaUpgradeRecordStatistics(firmwareId));  
39 - }  
40 -  
41 - @GetMapping("/get-count")  
42 - @Operation(summary = "获得升级记录分页 tab 数量")  
43 - @PreAuthorize("@ss.hasPermission('iot:ota-upgrade-record:query')")  
44 - public CommonResult<Map<Integer, Long>> getOtaUpgradeRecordCount(  
45 - @Valid IotOtaUpgradeRecordPageReqVO pageReqVO) {  
46 - return success(upgradeRecordService.getOtaUpgradeRecordCount(pageReqVO));  
47 - }  
48 -  
49 - @GetMapping("/page")  
50 - @Operation(summary = "获得升级记录分页")  
51 - @PreAuthorize("@ss.hasPermission('iot:ota-upgrade-record:query')")  
52 - @TransMethodResult  
53 - public CommonResult<PageResult<IotOtaUpgradeRecordRespVO>> getUpgradeRecordPage(  
54 - @Valid IotOtaUpgradeRecordPageReqVO pageReqVO) {  
55 - PageResult<IotOtaUpgradeRecordDO> pageResult = upgradeRecordService.getUpgradeRecordPage(pageReqVO);  
56 - return success(BeanUtils.toBean(pageResult, IotOtaUpgradeRecordRespVO.class));  
57 - }  
58 -  
59 - @GetMapping("/get")  
60 - @Operation(summary = "获得升级记录")  
61 - @PreAuthorize("@ss.hasPermission('iot:ota-upgrade-record:query')")  
62 - @Parameter(name = "id", description = "升级记录编号", required = true, example = "1024")  
63 - @TransMethodResult  
64 - public CommonResult<IotOtaUpgradeRecordRespVO> getUpgradeRecord(@RequestParam("id") Long id) {  
65 - IotOtaUpgradeRecordDO upgradeRecord = upgradeRecordService.getUpgradeRecord(id);  
66 - return success(BeanUtils.toBean(upgradeRecord, IotOtaUpgradeRecordRespVO.class));  
67 - }  
68 -  
69 - @PutMapping("/retry")  
70 - @Operation(summary = "重试升级记录")  
71 - @PreAuthorize("@ss.hasPermission('iot:ota-upgrade-record:retry')")  
72 - @Parameter(name = "id", description = "升级记录编号", required = true, example = "1024")  
73 - public CommonResult<Boolean> retryUpgradeRecord(@RequestParam("id") Long id) {  
74 - upgradeRecordService.retryUpgradeRecord(id);  
75 - return success(true);  
76 - }  
77 -  
78 -}  
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/ota/IotOtaUpgradeTaskController.java deleted
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
@@ -4,6 +4,7 @@ import io.swagger.v3.oas.annotations.media.Schema; @@ -4,6 +4,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
4 import jakarta.validation.constraints.NotEmpty; 4 import jakarta.validation.constraints.NotEmpty;
5 import jakarta.validation.constraints.NotNull; 5 import jakarta.validation.constraints.NotNull;
6 import lombok.Data; 6 import lombok.Data;
  7 +import org.hibernate.validator.constraints.URL;
7 8
8 @Schema(description = "管理后台 - IoT OTA 固件创建 Request VO") 9 @Schema(description = "管理后台 - IoT OTA 固件创建 Request VO")
9 @Data 10 @Data
@@ -22,17 +23,11 @@ public class IotOtaFirmwareCreateReqVO { @@ -22,17 +23,11 @@ public class IotOtaFirmwareCreateReqVO {
22 23
23 @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") 24 @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
24 @NotNull(message = "产品编号不能为空") 25 @NotNull(message = "产品编号不能为空")
25 - private String productId; 26 + private Long productId;
26 27
27 - @Schema(description = "签名方式", example = "MD5")  
28 - // TODO @li:是不是必传哈  
29 - private String signMethod;  
30 -  
31 - @Schema(description = "固件文件 URL", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/yudao-firmware.zip") 28 + @Schema(description = "固件文件 URL", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/1.zip")
32 @NotEmpty(message = "固件文件 URL 不能为空") 29 @NotEmpty(message = "固件文件 URL 不能为空")
  30 + @URL(message = "固件文件 URL 格式错误")
33 private String fileUrl; 31 private String fileUrl;
34 32
35 - @Schema(description = "自定义信息,建议使用 JSON 格式", example = "{\"key1\":\"value1\",\"key2\":\"value2\"}")  
36 - private String information;  
37 -  
38 } 33 }
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/ota/vo/firmware/IotOtaFirmwarePageReqVO.java
@@ -3,21 +3,24 @@ package cn.iocoder.yudao.module.iot.controller.admin.ota.vo.firmware; @@ -3,21 +3,24 @@ package cn.iocoder.yudao.module.iot.controller.admin.ota.vo.firmware;
3 import cn.iocoder.yudao.framework.common.pojo.PageParam; 3 import cn.iocoder.yudao.framework.common.pojo.PageParam;
4 import io.swagger.v3.oas.annotations.media.Schema; 4 import io.swagger.v3.oas.annotations.media.Schema;
5 import lombok.Data; 5 import lombok.Data;
  6 +import org.springframework.format.annotation.DateTimeFormat;
  7 +
  8 +import java.time.LocalDateTime;
  9 +
  10 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
6 11
7 -@Data  
8 @Schema(description = "管理后台 - IoT OTA 固件分页 Request VO") 12 @Schema(description = "管理后台 - IoT OTA 固件分页 Request VO")
  13 +@Data
9 public class IotOtaFirmwarePageReqVO extends PageParam { 14 public class IotOtaFirmwarePageReqVO extends PageParam {
10 15
11 - /**  
12 - * 固件名称  
13 - */  
14 @Schema(description = "固件名称", example = "智能开关固件") 16 @Schema(description = "固件名称", example = "智能开关固件")
15 private String name; 17 private String name;
16 18
17 - /**  
18 - * 产品标识  
19 - */  
20 @Schema(description = "产品标识", example = "1024") 19 @Schema(description = "产品标识", example = "1024")
21 private String productId; 20 private String productId;
22 21
  22 + @Schema(description = "创建时间", example = "[2022-07-01 00:00:00, 2022-07-01 23:59:59]")
  23 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  24 + private LocalDateTime[] createTime;
  25 +
23 } 26 }
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/ota/vo/firmware/IotOtaFirmwareRespVO.java
1 package cn.iocoder.yudao.module.iot.controller.admin.ota.vo.firmware; 1 package cn.iocoder.yudao.module.iot.controller.admin.ota.vo.firmware;
2 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; 3 import com.fhs.core.trans.vo.VO;
7 import io.swagger.v3.oas.annotations.media.Schema; 4 import io.swagger.v3.oas.annotations.media.Schema;
8 import lombok.Data; 5 import lombok.Data;
9 6
10 -@Data 7 +import java.time.LocalDateTime;
  8 +
11 @Schema(description = "管理后台 - IoT OTA 固件 Response VO") 9 @Schema(description = "管理后台 - IoT OTA 固件 Response VO")
  10 +@Data
12 public class IotOtaFirmwareRespVO implements VO { 11 public class IotOtaFirmwareRespVO implements VO {
13 12
14 - /**  
15 - * 固件编号  
16 - */  
17 @Schema(description = "固件编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") 13 @Schema(description = "固件编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
18 private Long id; 14 private Long id;
19 - /**  
20 - * 固件名称  
21 - */  
22 - @Schema(description = "固件名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "OTA固件") 15 +
  16 + @Schema(description = "固件名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "OTA 固件")
23 private String name; 17 private String name;
24 - /**  
25 - * 固件描述  
26 - */ 18 +
27 @Schema(description = "固件描述") 19 @Schema(description = "固件描述")
28 private String description; 20 private String description;
29 - /**  
30 - * 版本号  
31 - */ 21 +
32 @Schema(description = "版本号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1.0.0") 22 @Schema(description = "版本号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1.0.0")
33 private String version; 23 private String version;
34 24
35 - /**  
36 - * 产品编号  
37 - * <p>  
38 - * 关联 {@link cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO#getId()}  
39 - */  
40 @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") 25 @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
41 - @Trans(type = TransType.SIMPLE, target = IotProductDO.class, fields = {"name"}, refs = {"productName"})  
42 - private String productId;  
43 - /**  
44 - * 产品标识  
45 - * <p>  
46 - * 冗余 {@link cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO#getProductKey()}  
47 - */  
48 - @Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "iot-product-key")  
49 - private String productKey;  
50 - /**  
51 - * 产品名称  
52 - */  
53 - @Schema(description = "产品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "OTA产品") 26 + private Long productId;
  27 +
  28 + @Schema(description = "产品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "智能设备")
54 private String productName; 29 private String productName;
55 - /**  
56 - * 签名方式  
57 - * <p>  
58 - * 例如说:MD5、SHA256  
59 - */  
60 - @Schema(description = "签名方式", example = "MD5")  
61 - private String signMethod;  
62 - /**  
63 - * 固件文件签名  
64 - */  
65 - @Schema(description = "固件文件签名", example = "1024")  
66 - private String fileSign;  
67 - /**  
68 - * 固件文件大小  
69 - */ 30 +
  31 + @Schema(description = "固件文件 URL", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/firmware.bin")
  32 + private String fileUrl;
  33 +
70 @Schema(description = "固件文件大小", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") 34 @Schema(description = "固件文件大小", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
71 private Long fileSize; 35 private Long fileSize;
72 - /**  
73 - * 固件文件 URL  
74 - */  
75 - @Schema(description = "固件文件 URL", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn")  
76 - private String fileUrl;  
77 - /**  
78 - * 自定义信息,建议使用 JSON 格式  
79 - */  
80 - @Schema(description = "自定义信息,建议使用 JSON 格式")  
81 - private String information; 36 +
  37 + @Schema(description = "固件文件签名算法", example = "MD5")
  38 + private String fileDigestAlgorithm;
  39 +
  40 + @Schema(description = "固件文件签名结果", example = "d41d8cd98f00b204e9800998ecf8427e")
  41 + private String fileDigestValue;
  42 +
  43 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  44 + private LocalDateTime createTime;
  45 +
  46 + @Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED)
  47 + private LocalDateTime updateTime;
82 48
83 } 49 }
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/ota/vo/firmware/IotOtaFirmwareUpdateReqVO.java
1 package cn.iocoder.yudao.module.iot.controller.admin.ota.vo.firmware; 1 package cn.iocoder.yudao.module.iot.controller.admin.ota.vo.firmware;
2 2
3 import io.swagger.v3.oas.annotations.media.Schema; 3 import io.swagger.v3.oas.annotations.media.Schema;
4 -import jakarta.validation.constraints.NotEmpty;  
5 import jakarta.validation.constraints.NotNull; 4 import jakarta.validation.constraints.NotNull;
6 import lombok.Data; 5 import lombok.Data;
7 6
@@ -13,9 +12,7 @@ public class IotOtaFirmwareUpdateReqVO { @@ -13,9 +12,7 @@ public class IotOtaFirmwareUpdateReqVO {
13 @NotNull(message = "固件编号不能为空") 12 @NotNull(message = "固件编号不能为空")
14 private Long id; 13 private Long id;
15 14
16 - // TODO @li:name 是不是可以飞必传哈  
17 - @Schema(description = "固件名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "智能开关固件")  
18 - @NotEmpty(message = "固件名称不能为空") 15 + @Schema(description = "固件名称", example = "智能开关固件")
19 private String name; 16 private String name;
20 17
21 @Schema(description = "固件描述", example = "某品牌型号固件,测试用") 18 @Schema(description = "固件描述", example = "某品牌型号固件,测试用")
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/ota/vo/upgrade/task/IotOtaUpgradeTaskSaveReqVO.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/ota/vo/task/IotOtaTaskCreateReqVO.java
1 -package cn.iocoder.yudao.module.iot.controller.admin.ota.vo.upgrade.task; 1 +package cn.iocoder.yudao.module.iot.controller.admin.ota.vo.task;
2 2
3 import cn.iocoder.yudao.framework.common.validation.InEnum; 3 import cn.iocoder.yudao.framework.common.validation.InEnum;
4 -import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;  
5 -import cn.iocoder.yudao.module.iot.dal.dataobject.ota.IotOtaFirmwareDO;  
6 -import cn.iocoder.yudao.module.iot.enums.ota.IotOtaUpgradeTaskScopeEnum; 4 +import cn.iocoder.yudao.module.iot.enums.ota.IotOtaTaskDeviceScopeEnum;
7 import io.swagger.v3.oas.annotations.media.Schema; 5 import io.swagger.v3.oas.annotations.media.Schema;
8 import jakarta.validation.constraints.NotEmpty; 6 import jakarta.validation.constraints.NotEmpty;
9 import jakarta.validation.constraints.NotNull; 7 import jakarta.validation.constraints.NotNull;
@@ -11,51 +9,29 @@ import lombok.Data; @@ -11,51 +9,29 @@ import lombok.Data;
11 9
12 import java.util.List; 10 import java.util.List;
13 11
  12 +@Schema(description = "管理后台 - IoT OTA 升级任务创建 Request VO")
14 @Data 13 @Data
15 -@Schema(description = "管理后台 - IoT OTA 升级任务创建/修改 Request VO")  
16 -public class IotOtaUpgradeTaskSaveReqVO { 14 +public class IotOtaTaskCreateReqVO {
17 15
18 - // TODO @li:已经有注解,不用重复注释  
19 - // TODO @li: @Schema 写在参数校验前面。先有定义;其他的,也检查下;  
20 -  
21 - /**  
22 - * 任务名称  
23 - */  
24 @NotEmpty(message = "任务名称不能为空") 16 @NotEmpty(message = "任务名称不能为空")
25 @Schema(description = "任务名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "升级任务") 17 @Schema(description = "任务名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "升级任务")
26 private String name; 18 private String name;
27 19
28 - /**  
29 - * 任务描述  
30 - */  
31 @Schema(description = "任务描述", example = "升级任务") 20 @Schema(description = "任务描述", example = "升级任务")
32 private String description; 21 private String description;
33 22
34 - /**  
35 - * 固件编号  
36 - * <p>  
37 - * 关联 {@link IotOtaFirmwareDO#getId()}  
38 - */  
39 - @NotNull(message = "固件编号不能为空")  
40 @Schema(description = "固件编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") 23 @Schema(description = "固件编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  24 + @NotNull(message = "固件编号不能为空")
41 private Long firmwareId; 25 private Long firmwareId;
42 26
43 - /**  
44 - * 升级范围  
45 - * <p>  
46 - * 关联 {@link cn.iocoder.yudao.module.iot.enums.ota.IotOtaUpgradeTaskScopeEnum}  
47 - */  
48 - @NotNull(message = "升级范围不能为空")  
49 - @InEnum(value = IotOtaUpgradeTaskScopeEnum.class)  
50 @Schema(description = "升级范围", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") 27 @Schema(description = "升级范围", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
51 - private Integer scope;  
52 -  
53 - /**  
54 - * 选中的设备编号数组  
55 - * <p>  
56 - * 关联 {@link IotDeviceDO#getId()}  
57 - */  
58 - @Schema(description = "选中的设备编号数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1,2,3,4]") 28 + @NotNull(message = "升级范围不能为空")
  29 + @InEnum(value = IotOtaTaskDeviceScopeEnum.class)
  30 + private Integer deviceScope;
  31 +
  32 + @Schema(description = "选中的设备编号数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "1,2,3")
59 private List<Long> deviceIds; 33 private List<Long> deviceIds;
60 34
  35 + // TODO @li:如果 deviceScope 等于 2 时,deviceIds 校验非空;
  36 +
61 } 37 }
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/ota/vo/upgrade/task/IotOtaUpgradeTaskPageReqVO.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/ota/vo/task/IotOtaTaskPageReqVO.java
1 -package cn.iocoder.yudao.module.iot.controller.admin.ota.vo.upgrade.task; 1 +package cn.iocoder.yudao.module.iot.controller.admin.ota.vo.task;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.PageParam; 3 import cn.iocoder.yudao.framework.common.pojo.PageParam;
4 import io.swagger.v3.oas.annotations.media.Schema; 4 import io.swagger.v3.oas.annotations.media.Schema;
5 -import jakarta.validation.constraints.NotNull;  
6 import lombok.Data; 5 import lombok.Data;
7 6
8 -@Data  
9 @Schema(description = "管理后台 - IoT OTA 升级任务分页 Request VO") 7 @Schema(description = "管理后台 - IoT OTA 升级任务分页 Request VO")
10 -public class IotOtaUpgradeTaskPageReqVO extends PageParam { 8 +@Data
  9 +public class IotOtaTaskPageReqVO extends PageParam {
11 10
12 - /**  
13 - * 任务名称字段,用于描述任务的名称  
14 - */  
15 @Schema(description = "任务名称", example = "升级任务") 11 @Schema(description = "任务名称", example = "升级任务")
16 private String name; 12 private String name;
17 13
18 - /**  
19 - * 固件编号字段,用于唯一标识固件,不能为空  
20 - */  
21 - @NotNull(message = "固件编号不能为空")  
22 - @Schema(description = "固件编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") 14 + @Schema(description = "固件编号", example = "1024")
23 private Long firmwareId; 15 private Long firmwareId;
24 16
25 } 17 }
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/ota/vo/task/IotOtaTaskRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.controller.admin.ota.vo.task;
  2 +
  3 +import com.fhs.core.trans.vo.VO;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Data;
  6 +
  7 +import java.time.LocalDateTime;
  8 +
  9 +@Schema(description = "管理后台 - IoT OTA 升级任务 Response VO")
  10 +@Data
  11 +public class IotOtaTaskRespVO implements VO {
  12 +
  13 + @Schema(description = "任务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  14 + private Long id;
  15 +
  16 + @Schema(description = "任务名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "升级任务")
  17 + private String name;
  18 +
  19 + @Schema(description = "任务描述", example = "升级任务")
  20 + private String description;
  21 +
  22 + @Schema(description = "固件编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  23 + private Long firmwareId;
  24 +
  25 + @Schema(description = "任务状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
  26 + private Integer status;
  27 +
  28 + @Schema(description = "升级范围", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  29 + private Integer deviceScope;
  30 +
  31 + @Schema(description = "设备总共数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  32 + private Integer deviceTotalCount;
  33 +
  34 + @Schema(description = "设备成功数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "66")
  35 + private Integer deviceSuccessCount;
  36 +
  37 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2022-07-08 07:30:00")
  38 + private LocalDateTime createTime;
  39 +
  40 +}
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/ota/vo/task/record/IotOtaTaskRecordPageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.controller.admin.ota.vo.task.record;
  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.ota.IotOtaTaskRecordStatusEnum;
  6 +import io.swagger.v3.oas.annotations.media.Schema;
  7 +import lombok.Data;
  8 +
  9 +@Schema(description = "管理后台 - IoT OTA 升级记录分页 Request VO")
  10 +@Data
  11 +public class IotOtaTaskRecordPageReqVO extends PageParam {
  12 +
  13 + @Schema(description = "升级任务编号", example = "1024")
  14 + private Long taskId;
  15 +
  16 + @Schema(description = "升级记录状态", example = "5")
  17 + @InEnum(IotOtaTaskRecordStatusEnum.class)
  18 + private Integer status;
  19 +
  20 +}
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/ota/vo/task/record/IotOtaTaskRecordRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.controller.admin.ota.vo.task.record;
  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 OTA 升级任务记录 Response VO")
  9 +@Data
  10 +public class IotOtaTaskRecordRespVO {
  11 +
  12 + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  13 + private Long id;
  14 +
  15 + @Schema(description = "固件编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  16 + private Long firmwareId;
  17 +
  18 + @Schema(description = "任务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2048")
  19 + private Long taskId;
  20 +
  21 + @Schema(description = "设备编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  22 + private Long deviceId;
  23 +
  24 + @Schema(description = "设备名称", example = "智能开关")
  25 + private String deviceName;
  26 +
  27 + @Schema(description = "来源的固件编号", example = "1023")
  28 + private Long fromFirmwareId;
  29 +
  30 + @Schema(description = "来源固件版本", example = "1.0.0")
  31 + private String fromFirmwareVersion;
  32 +
  33 + @Schema(description = "升级状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  34 + private Integer status;
  35 +
  36 + @Schema(description = "升级进度,百分比", requiredMode = Schema.RequiredMode.REQUIRED, example = "50")
  37 + private Integer progress;
  38 +
  39 + @Schema(description = "升级进度描述", example = "正在下载固件...")
  40 + private String description;
  41 +
  42 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  43 + private LocalDateTime createTime;
  44 +
  45 + @Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED)
  46 + private LocalDateTime updateTime;
  47 +
  48 +}
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/ota/vo/upgrade/record/IotOtaUpgradeRecordPageReqVO.java deleted
1 -package cn.iocoder.yudao.module.iot.controller.admin.ota.vo.upgrade.record;  
2 -  
3 -import cn.iocoder.yudao.framework.common.pojo.PageParam;  
4 -import io.swagger.v3.oas.annotations.media.Schema;  
5 -import jakarta.validation.constraints.NotNull;  
6 -import lombok.Data;  
7 -  
8 -@Data  
9 -@Schema(description = "管理后台 - IoT OTA 升级记录分页 Request VO")  
10 -public class IotOtaUpgradeRecordPageReqVO extends PageParam {  
11 -  
12 - // TODO @li:已经有注解,不用重复注释  
13 - /**  
14 - * 升级任务编号字段。  
15 - * <p>  
16 - * 该字段用于标识升级任务的唯一编号,不能为空。  
17 - */  
18 - @Schema(description = "升级任务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")  
19 - @NotNull(message = "升级任务编号不能为空")  
20 - private Long taskId;  
21 -  
22 - /**  
23 - * 设备标识字段。  
24 - * <p>  
25 - * 该字段用于标识设备的名称,通常用于区分不同的设备。  
26 - */  
27 - @Schema(description = "设备标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "摄像头A1-1")  
28 - private String deviceName;  
29 -  
30 -}  
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/ota/vo/upgrade/record/IotOtaUpgradeRecordRespVO.java deleted
1 -package cn.iocoder.yudao.module.iot.controller.admin.ota.vo.upgrade.record;  
2 -  
3 -import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;  
4 -import cn.iocoder.yudao.module.iot.dal.dataobject.ota.IotOtaFirmwareDO;  
5 -import cn.iocoder.yudao.module.iot.dal.dataobject.ota.IotOtaUpgradeTaskDO;  
6 -import com.fhs.core.trans.anno.Trans;  
7 -import com.fhs.core.trans.constant.TransType;  
8 -import io.swagger.v3.oas.annotations.media.Schema;  
9 -import lombok.Data;  
10 -  
11 -import java.time.LocalDateTime;  
12 -  
13 -@Data  
14 -@Schema(description = "管理后台 - IoT OTA 升级记录 Response VO")  
15 -public class IotOtaUpgradeRecordRespVO {  
16 -  
17 - /**  
18 - * 升级记录编号  
19 - */  
20 - @Schema(description = "升级记录编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")  
21 - private Long id;  
22 - /**  
23 - * 固件编号  
24 - * <p>  
25 - * 关联 {@link IotOtaFirmwareDO#getId()}  
26 - */  
27 - @Schema(description = "固件编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")  
28 - @Trans(type = TransType.SIMPLE, target = IotOtaFirmwareDO.class, fields = {"version"}, refs = {"firmwareVersion"})  
29 - private Long firmwareId;  
30 - /**  
31 - * 固件版本  
32 - */  
33 - @Schema(description = "固件版本", requiredMode = Schema.RequiredMode.REQUIRED, example = "v1.0.0")  
34 - private String firmwareVersion;  
35 - /**  
36 - * 任务编号  
37 - * <p>  
38 - * 关联 {@link IotOtaUpgradeTaskDO#getId()}  
39 - */  
40 - @Schema(description = "任务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")  
41 - private Long taskId;  
42 - /**  
43 - * 产品标识  
44 - * <p>  
45 - * 关联 {@link cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO#getId()}  
46 - */  
47 - @Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "iot")  
48 - private String productKey;  
49 - /**  
50 - * 设备名称  
51 - * <p>  
52 - * 关联 {@link cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO#getId()}  
53 - */  
54 - @Schema(description = "设备名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "iot")  
55 - private String deviceName;  
56 - /**  
57 - * 设备编号  
58 - * <p>  
59 - * 关联 {@link cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO#getId()}  
60 - */  
61 - @Schema(description = "设备编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")  
62 - private String deviceId;  
63 - /**  
64 - * 来源的固件编号  
65 - * <p>  
66 - * 关联 {@link IotDeviceDO#getFirmwareId()}  
67 - */  
68 - @Schema(description = "来源的固件编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")  
69 - @Trans(type = TransType.SIMPLE, target = IotOtaFirmwareDO.class, fields = {"version"}, refs = {"fromFirmwareVersion"})  
70 - private Long fromFirmwareId;  
71 - /**  
72 - * 来源的固件版本  
73 - */  
74 - @Schema(description = "来源的固件版本", requiredMode = Schema.RequiredMode.REQUIRED, example = "v1.0.0")  
75 - private String fromFirmwareVersion;  
76 - /**  
77 - * 升级状态  
78 - * <p>  
79 - * 关联 {@link cn.iocoder.yudao.module.iot.enums.ota.IotOtaUpgradeRecordStatusEnum}  
80 - */  
81 - @Schema(description = "升级状态", requiredMode = Schema.RequiredMode.REQUIRED, allowableValues = {"0", "10", "20", "30", "40", "50"})  
82 - private Integer status;  
83 - /**  
84 - * 升级进度,百分比  
85 - */  
86 - @Schema(description = "升级进度,百分比", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")  
87 - private Integer progress;  
88 - /**  
89 - * 升级进度描述  
90 - * <p>  
91 - * 注意,只记录设备最后一次的升级进度描述  
92 - * 如果想看历史记录,可以查看 {@link cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceLogDO} 设备日志  
93 - */  
94 - @Schema(description = "升级进度描述", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")  
95 - private String description;  
96 - /**  
97 - * 升级开始时间  
98 - */  
99 - @Schema(description = "升级开始时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2022-07-08 07:30:00")  
100 - private LocalDateTime startTime;  
101 - /**  
102 - * 升级结束时间  
103 - */  
104 - @Schema(description = "升级结束时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2022-07-08 07:30:00")  
105 - private LocalDateTime endTime;  
106 -  
107 -}  
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/ota/vo/upgrade/task/IotOtaUpgradeTaskRespVO.java deleted
1 -package cn.iocoder.yudao.module.iot.controller.admin.ota.vo.upgrade.task;  
2 -  
3 -import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;  
4 -import cn.iocoder.yudao.module.iot.dal.dataobject.ota.IotOtaFirmwareDO;  
5 -import com.fhs.core.trans.vo.VO;  
6 -import io.swagger.v3.oas.annotations.media.Schema;  
7 -import lombok.Data;  
8 -  
9 -import java.time.LocalDateTime;  
10 -import java.util.List;  
11 -  
12 -@Data  
13 -@Schema(description = "管理后台 - IoT OTA 升级任务 Response VO")  
14 -public class IotOtaUpgradeTaskRespVO implements VO {  
15 -  
16 - /**  
17 - * 任务编号  
18 - */  
19 - @Schema(description = "任务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")  
20 - private Long id;  
21 - /**  
22 - * 任务名称  
23 - */  
24 - @Schema(description = "任务名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "升级任务")  
25 - private String name;  
26 - /**  
27 - * 任务描述  
28 - */  
29 - @Schema(description = "任务描述", example = "升级任务")  
30 - private String description;  
31 - /**  
32 - * 固件编号  
33 - * <p>  
34 - * 关联 {@link IotOtaFirmwareDO#getId()}  
35 - */  
36 - @Schema(description = "固件编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")  
37 - private Long firmwareId;  
38 - /**  
39 - * 任务状态  
40 - * <p>  
41 - * 关联 {@link cn.iocoder.yudao.module.iot.enums.ota.IotOtaUpgradeTaskStatusEnum}  
42 - */  
43 - @Schema(description = "任务状态", requiredMode = Schema.RequiredMode.REQUIRED, allowableValues = {"10", "20", "21", "30"})  
44 - private Integer status;  
45 - /**  
46 - * 任务状态名称  
47 - */  
48 - @Schema(description = "任务状态名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "进行中")  
49 - private String statusName;  
50 - /**  
51 - * 升级范围  
52 - * <p>  
53 - * 关联 {@link cn.iocoder.yudao.module.iot.enums.ota.IotOtaUpgradeTaskScopeEnum}  
54 - */  
55 - @Schema(description = "升级范围", requiredMode = Schema.RequiredMode.REQUIRED, allowableValues = {"1", "2"})  
56 - private Integer scope;  
57 - /**  
58 - * 设备数量  
59 - */  
60 - @Schema(description = "设备数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")  
61 - private Long deviceCount;  
62 - /**  
63 - * 选中的设备编号数组  
64 - * <p>  
65 - * 关联 {@link IotDeviceDO#getId()}  
66 - */  
67 - @Schema(description = "选中的设备编号数组", example = "1024")  
68 - private List<Long> deviceIds;  
69 - /**  
70 - * 选中的设备名字数组  
71 - * <p>  
72 - * 关联 {@link IotDeviceDO#getDeviceName()}  
73 - */  
74 - @Schema(description = "选中的设备名字数组", example = "1024")  
75 - private List<String> deviceNames;  
76 - /**  
77 - * 创建时间  
78 - */  
79 - @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2022-07-08 07:30:00")  
80 - private LocalDateTime createTime;  
81 -  
82 -}  
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/PluginConfigController.java deleted
1 -package cn.iocoder.yudao.module.iot.controller.admin.plugin;  
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.plugin.vo.config.PluginConfigImportReqVO;  
7 -import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config.PluginConfigPageReqVO;  
8 -import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config.PluginConfigRespVO;  
9 -import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config.PluginConfigSaveReqVO;  
10 -import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config.PluginConfigStatusReqVO;  
11 -import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginConfigDO;  
12 -import cn.iocoder.yudao.module.iot.service.plugin.IotPluginConfigService;  
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 static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;  
23 -  
24 -@Tag(name = "管理后台 - IoT 插件配置")  
25 -@RestController  
26 -@RequestMapping("/iot/plugin-config")  
27 -@Validated  
28 -public class PluginConfigController {  
29 -  
30 - @Resource  
31 - private IotPluginConfigService pluginConfigService;  
32 -  
33 - @PostMapping("/create")  
34 - @Operation(summary = "创建插件配置")  
35 - @PreAuthorize("@ss.hasPermission('iot:plugin-config:create')")  
36 - public CommonResult<Long> createPluginConfig(@Valid @RequestBody PluginConfigSaveReqVO createReqVO) {  
37 - return success(pluginConfigService.createPluginConfig(createReqVO));  
38 - }  
39 -  
40 - @PutMapping("/update")  
41 - @Operation(summary = "更新插件配置")  
42 - @PreAuthorize("@ss.hasPermission('iot:plugin-config:update')")  
43 - public CommonResult<Boolean> updatePluginConfig(@Valid @RequestBody PluginConfigSaveReqVO updateReqVO) {  
44 - pluginConfigService.updatePluginConfig(updateReqVO);  
45 - return success(true);  
46 - }  
47 -  
48 - @DeleteMapping("/delete")  
49 - @Operation(summary = "删除插件配置")  
50 - @Parameter(name = "id", description = "编号", required = true)  
51 - @PreAuthorize("@ss.hasPermission('iot:plugin-config:delete')")  
52 - public CommonResult<Boolean> deletePluginConfig(@RequestParam("id") Long id) {  
53 - pluginConfigService.deletePluginConfig(id);  
54 - return success(true);  
55 - }  
56 -  
57 - @GetMapping("/get")  
58 - @Operation(summary = "获得插件配置")  
59 - @Parameter(name = "id", description = "编号", required = true, example = "1024")  
60 - @PreAuthorize("@ss.hasPermission('iot:plugin-config:query')")  
61 - public CommonResult<PluginConfigRespVO> getPluginConfig(@RequestParam("id") Long id) {  
62 - IotPluginConfigDO pluginConfig = pluginConfigService.getPluginConfig(id);  
63 - return success(BeanUtils.toBean(pluginConfig, PluginConfigRespVO.class));  
64 - }  
65 -  
66 - @GetMapping("/page")  
67 - @Operation(summary = "获得插件配置分页")  
68 - @PreAuthorize("@ss.hasPermission('iot:plugin-config:query')")  
69 - public CommonResult<PageResult<PluginConfigRespVO>> getPluginConfigPage(@Valid PluginConfigPageReqVO pageReqVO) {  
70 - PageResult<IotPluginConfigDO> pageResult = pluginConfigService.getPluginConfigPage(pageReqVO);  
71 - return success(BeanUtils.toBean(pageResult, PluginConfigRespVO.class));  
72 - }  
73 -  
74 - @PostMapping("/upload-file")  
75 - @Operation(summary = "上传插件文件")  
76 - @PreAuthorize("@ss.hasPermission('iot:plugin-config:update')")  
77 - public CommonResult<Boolean> uploadFile(@Valid PluginConfigImportReqVO reqVO) {  
78 - pluginConfigService.uploadFile(reqVO.getId(), reqVO.getFile());  
79 - return success(true);  
80 - }  
81 -  
82 - @PutMapping("/update-status")  
83 - @Operation(summary = "修改插件状态")  
84 - @PreAuthorize("@ss.hasPermission('iot:plugin-config:update')")  
85 - public CommonResult<Boolean> updatePluginConfigStatus(@Valid @RequestBody PluginConfigStatusReqVO reqVO) {  
86 - pluginConfigService.updatePluginStatus(reqVO.getId(), reqVO.getStatus());  
87 - return success(true);  
88 - }  
89 -  
90 -}  
91 \ No newline at end of file 0 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/config/PluginConfigImportReqVO.java deleted
1 -package cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config;  
2 -  
3 -import io.swagger.v3.oas.annotations.media.Schema;  
4 -import jakarta.validation.constraints.NotNull;  
5 -import lombok.Data;  
6 -import org.springframework.web.multipart.MultipartFile;  
7 -  
8 -@Schema(description = "管理后台 - IoT 插件上传 Request VO")  
9 -@Data  
10 -public class PluginConfigImportReqVO {  
11 -  
12 - @Schema(description = "主键 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "11546")  
13 - private Long id;  
14 -  
15 - @Schema(description = "插件文件", requiredMode = Schema.RequiredMode.REQUIRED)  
16 - @NotNull(message = "插件文件不能为空")  
17 - private MultipartFile file;  
18 -  
19 -}  
20 \ No newline at end of file 0 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/config/PluginConfigPageReqVO.java deleted
1 -package cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config;  
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.plugin.IotPluginStatusEnum;  
6 -import io.swagger.v3.oas.annotations.media.Schema;  
7 -import lombok.Data;  
8 -  
9 -@Schema(description = "管理后台 - IoT 插件配置分页 Request VO")  
10 -@Data  
11 -public class PluginConfigPageReqVO extends PageParam {  
12 -  
13 - @Schema(description = "插件名称", example = "http")  
14 - private String name;  
15 -  
16 - @Schema(description = "状态", example = "1")  
17 - @InEnum(IotPluginStatusEnum.class)  
18 - private Integer status;  
19 -  
20 -}  
21 \ No newline at end of file 0 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/config/PluginConfigRespVO.java deleted
1 -package cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config;  
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 PluginConfigRespVO {  
11 -  
12 - @Schema(description = "主键 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "11546")  
13 - private Long id;  
14 -  
15 - @Schema(description = "插件包标识符", requiredMode = Schema.RequiredMode.REQUIRED, example = "24627")  
16 - private String pluginKey;  
17 -  
18 - @Schema(description = "插件名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")  
19 - private String name;  
20 -  
21 - @Schema(description = "描述", example = "你猜")  
22 - private String description;  
23 -  
24 - @Schema(description = "部署方式", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")  
25 - private Integer deployType;  
26 -  
27 - @Schema(description = "插件包文件名", requiredMode = Schema.RequiredMode.REQUIRED)  
28 - private String fileName;  
29 -  
30 - @Schema(description = "插件版本", requiredMode = Schema.RequiredMode.REQUIRED)  
31 - private String version;  
32 -  
33 - @Schema(description = "插件类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")  
34 - private Integer type;  
35 -  
36 - @Schema(description = "设备插件协议类型")  
37 - private String protocol;  
38 -  
39 - @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED)  
40 - private Integer status;  
41 -  
42 - @Schema(description = "插件配置项描述信息")  
43 - private String configSchema;  
44 -  
45 - @Schema(description = "插件配置信息")  
46 - private String config;  
47 -  
48 - @Schema(description = "插件脚本")  
49 - private String script;  
50 -  
51 - @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)  
52 - private LocalDateTime createTime;  
53 -  
54 -}  
55 \ No newline at end of file 0 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/config/PluginConfigSaveReqVO.java deleted
1 -package cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config;  
2 -  
3 -import cn.iocoder.yudao.framework.common.validation.InEnum;  
4 -import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginStatusEnum;  
5 -import io.swagger.v3.oas.annotations.media.Schema;  
6 -import lombok.Data;  
7 -  
8 -@Schema(description = "管理后台 - IoT 插件配置新增/修改 Request VO")  
9 -@Data  
10 -public class PluginConfigSaveReqVO {  
11 -  
12 - // TODO @haohao:新增的字段有点多,每个都需要哇?  
13 -  
14 - // TODO @haohao:一些枚举字段,需要加枚举校验。例如说,deployType、status、type 等  
15 -  
16 - @Schema(description = "主键编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11546")  
17 - private Long id;  
18 -  
19 - @Schema(description = "插件包标识符", requiredMode = Schema.RequiredMode.REQUIRED, example = "24627")  
20 - private String pluginKey;  
21 -  
22 - @Schema(description = "插件名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")  
23 - private String name;  
24 -  
25 - @Schema(description = "描述", example = "你猜")  
26 - private String description;  
27 -  
28 - @Schema(description = "部署方式", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")  
29 - private Integer deployType;  
30 -  
31 - @Schema(description = "插件包文件名", requiredMode = Schema.RequiredMode.REQUIRED)  
32 - private String fileName;  
33 -  
34 - @Schema(description = "插件版本", requiredMode = Schema.RequiredMode.REQUIRED)  
35 - private String version;  
36 -  
37 - @Schema(description = "插件类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")  
38 - private Integer type;  
39 -  
40 - @Schema(description = "设备插件协议类型")  
41 - private String protocol;  
42 -  
43 - @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED)  
44 - @InEnum(IotPluginStatusEnum.class)  
45 - private Integer status;  
46 -  
47 - @Schema(description = "插件配置项描述信息")  
48 - private String configSchema;  
49 -  
50 - @Schema(description = "插件配置信息")  
51 - private String config;  
52 -  
53 - @Schema(description = "插件脚本")  
54 - private String script;  
55 -  
56 -}  
57 \ No newline at end of file 0 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/config/PluginConfigStatusReqVO.java deleted
1 -package cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config;  
2 -  
3 -import cn.iocoder.yudao.framework.common.validation.InEnum;  
4 -import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginStatusEnum;  
5 -import io.swagger.v3.oas.annotations.media.Schema;  
6 -import lombok.Data;  
7 -  
8 -@Schema(description = "管理后台 - IoT 插件配置状态 Request VO")  
9 -@Data  
10 -public class PluginConfigStatusReqVO {  
11 -  
12 - @Schema(description = "主键编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11546")  
13 - private Long id;  
14 -  
15 - @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED)  
16 - @InEnum(IotPluginStatusEnum.class)  
17 - private Integer status;  
18 -  
19 -}  
20 \ No newline at end of file 0 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/instance/PluginInstancePageReqVO.java deleted
1 -package cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.instance;  
2 -  
3 -import lombok.*;  
4 -import io.swagger.v3.oas.annotations.media.Schema;  
5 -import cn.iocoder.yudao.framework.common.pojo.PageParam;  
6 -import org.springframework.format.annotation.DateTimeFormat;  
7 -import java.time.LocalDateTime;  
8 -  
9 -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;  
10 -  
11 -// TODO @haohao:后续需要使用下  
12 -@Schema(description = "管理后台 - IoT 插件实例分页 Request VO")  
13 -@Data  
14 -public class PluginInstancePageReqVO extends PageParam {  
15 -  
16 - @Schema(description = "插件主程序编号", example = "23738")  
17 - private String mainId;  
18 -  
19 - @Schema(description = "插件id", example = "26498")  
20 - private Long pluginId;  
21 -  
22 - @Schema(description = "插件主程序所在ip")  
23 - private String ip;  
24 -  
25 - @Schema(description = "插件主程序端口")  
26 - private Integer port;  
27 -  
28 - @Schema(description = "心跳时间,心路时间超过30秒需要剔除")  
29 - private Long heartbeatAt;  
30 -  
31 - @Schema(description = "创建时间")  
32 - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)  
33 - private LocalDateTime[] createTime;  
34 -  
35 -}  
36 \ No newline at end of file 0 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/instance/PluginInstanceRespVO.java deleted
1 -package cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.instance;  
2 -  
3 -import io.swagger.v3.oas.annotations.media.Schema;  
4 -import lombok.Data;  
5 -  
6 -import java.time.LocalDateTime;  
7 -  
8 -// TODO @haohao:后续需要使用下  
9 -@Schema(description = "管理后台 - IoT 插件实例 Response VO")  
10 -@Data  
11 -public class PluginInstanceRespVO {  
12 -  
13 - @Schema(description = "主键编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "23864")  
14 - private Long id;  
15 -  
16 - @Schema(description = "插件主程序id", requiredMode = Schema.RequiredMode.REQUIRED, example = "23738")  
17 - private String mainId;  
18 -  
19 - @Schema(description = "插件id", requiredMode = Schema.RequiredMode.REQUIRED, example = "26498")  
20 - private Long pluginId;  
21 -  
22 - @Schema(description = "插件主程序所在ip", requiredMode = Schema.RequiredMode.REQUIRED)  
23 - private String ip;  
24 -  
25 - @Schema(description = "插件主程序端口", requiredMode = Schema.RequiredMode.REQUIRED)  
26 - private Integer port;  
27 -  
28 - @Schema(description = "心跳时间,心路时间超过30秒需要剔除", requiredMode = Schema.RequiredMode.REQUIRED)  
29 - private Long heartbeatAt;  
30 -  
31 - @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)  
32 - private LocalDateTime createTime;  
33 -  
34 -}  
35 \ No newline at end of file 0 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/product/IotProductController.java
@@ -84,6 +84,27 @@ public class IotProductController { @@ -84,6 +84,27 @@ public class IotProductController {
84 @PreAuthorize("@ss.hasPermission('iot:product:query')") 84 @PreAuthorize("@ss.hasPermission('iot:product:query')")
85 public CommonResult<IotProductRespVO> getProduct(@RequestParam("id") Long id) { 85 public CommonResult<IotProductRespVO> getProduct(@RequestParam("id") Long id) {
86 IotProductDO product = productService.getProduct(id); 86 IotProductDO product = productService.getProduct(id);
  87 + if (product == null) {
  88 + return success(null);
  89 + }
  90 + // 拼接数据
  91 + IotProductCategoryDO category = categoryService.getProductCategory(product.getCategoryId());
  92 + return success(BeanUtils.toBean(product, IotProductRespVO.class, bean -> {
  93 + if (category != null) {
  94 + bean.setCategoryName(category.getName());
  95 + }
  96 + }));
  97 + }
  98 +
  99 + @GetMapping("/get-by-key")
  100 + @Operation(summary = "通过 ProductKey 获得产品")
  101 + @Parameter(name = "productKey", description = "产品Key", required = true, example = "abc123")
  102 + @PreAuthorize("@ss.hasPermission('iot:product:query')")
  103 + public CommonResult<IotProductRespVO> getProductByKey(@RequestParam("productKey") String productKey) {
  104 + IotProductDO product = productService.getProductByProductKey(productKey);
  105 + if (product == null) {
  106 + return success(null);
  107 + }
87 // 拼接数据 108 // 拼接数据
88 IotProductCategoryDO category = categoryService.getProductCategory(product.getCategoryId()); 109 IotProductCategoryDO category = categoryService.getProductCategory(product.getCategoryId());
89 return success(BeanUtils.toBean(product, IotProductRespVO.class, bean -> { 110 return success(BeanUtils.toBean(product, IotProductRespVO.class, bean -> {
@@ -122,11 +143,11 @@ public class IotProductController { @@ -122,11 +143,11 @@ public class IotProductController {
122 143
123 @GetMapping("/simple-list") 144 @GetMapping("/simple-list")
124 @Operation(summary = "获取产品的精简信息列表", description = "主要用于前端的下拉选项") 145 @Operation(summary = "获取产品的精简信息列表", description = "主要用于前端的下拉选项")
125 - public CommonResult<List<IotProductRespVO>> getSimpleProductList() { 146 + public CommonResult<List<IotProductRespVO>> getProductSimpleList() {
126 List<IotProductDO> list = productService.getProductList(); 147 List<IotProductDO> list = productService.getProductList();
127 return success(convertList(list, product -> // 只返回 id、name 字段 148 return success(convertList(list, product -> // 只返回 id、name 字段
128 new IotProductRespVO().setId(product.getId()).setName(product.getName()) 149 new IotProductRespVO().setId(product.getId()).setName(product.getName())
129 - .setDeviceType(product.getDeviceType()))); 150 + .setDeviceType(product.getDeviceType()).setLocationType(product.getLocationType())));
130 } 151 }
131 152
132 } 153 }
133 \ No newline at end of file 154 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/product/vo/product/IotProductRespVO.java
@@ -61,24 +61,15 @@ public class IotProductRespVO { @@ -61,24 +61,15 @@ public class IotProductRespVO {
61 @DictFormat(DictTypeConstants.NET_TYPE) 61 @DictFormat(DictTypeConstants.NET_TYPE)
62 private Integer netType; 62 private Integer netType;
63 63
64 - @Schema(description = "接入网关协议", example = "2")  
65 - @ExcelProperty(value = "接入网关协议", converter = DictConvert.class)  
66 - @DictFormat(DictTypeConstants.PROTOCOL_TYPE)  
67 - private Integer protocolType; 64 + @Schema(description = "定位方式", example = "2")
  65 + @ExcelProperty(value = "定位方式", converter = DictConvert.class)
  66 + @DictFormat(DictTypeConstants.LOCATION_TYPE)
  67 + private Integer locationType;
68 68
69 - @Schema(description = "协议编号(脚本解析 id)", requiredMode = Schema.RequiredMode.REQUIRED, example = "13177")  
70 - @ExcelProperty("协议编号(脚本解析 id)")  
71 - private Long protocolId;  
72 -  
73 - @Schema(description = "数据格式") 69 + @Schema(description = "数据格式", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
74 @ExcelProperty(value = "数据格式", converter = DictConvert.class) 70 @ExcelProperty(value = "数据格式", converter = DictConvert.class)
75 - @DictFormat(DictTypeConstants.DATA_FORMAT)  
76 - private Integer dataFormat;  
77 -  
78 - @Schema(description = "数据校验级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")  
79 - @ExcelProperty(value = "数据校验级别", converter = DictConvert.class)  
80 - @DictFormat(DictTypeConstants.VALIDATE_TYPE)  
81 - private Integer validateType; 71 + @DictFormat(DictTypeConstants.CODEC_TYPE)
  72 + private String codecType;
82 73
83 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) 74 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
84 @ExcelProperty("创建时间") 75 @ExcelProperty("创建时间")
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/product/vo/product/IotProductSaveReqVO.java
1 package cn.iocoder.yudao.module.iot.controller.admin.product.vo.product; 1 package cn.iocoder.yudao.module.iot.controller.admin.product.vo.product;
2 2
3 import cn.iocoder.yudao.framework.common.validation.InEnum; 3 import cn.iocoder.yudao.framework.common.validation.InEnum;
4 -import cn.iocoder.yudao.module.iot.enums.product.*; 4 +import cn.iocoder.yudao.module.iot.enums.product.IotLocationTypeEnum;
  5 +import cn.iocoder.yudao.module.iot.enums.product.IotNetTypeEnum;
  6 +import cn.iocoder.yudao.module.iot.enums.product.IotProductDeviceTypeEnum;
5 import io.swagger.v3.oas.annotations.media.Schema; 7 import io.swagger.v3.oas.annotations.media.Schema;
6 import jakarta.validation.constraints.NotEmpty; 8 import jakarta.validation.constraints.NotEmpty;
7 import jakarta.validation.constraints.NotNull; 9 import jakarta.validation.constraints.NotNull;
@@ -43,18 +45,12 @@ public class IotProductSaveReqVO { @@ -43,18 +45,12 @@ public class IotProductSaveReqVO {
43 @InEnum(value = IotNetTypeEnum.class, message = "联网方式必须是 {value}") 45 @InEnum(value = IotNetTypeEnum.class, message = "联网方式必须是 {value}")
44 private Integer netType; 46 private Integer netType;
45 47
46 - @Schema(description = "接入网关协议", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")  
47 - @InEnum(value = IotProtocolTypeEnum.class, message = "接入网关协议必须是 {value}")  
48 - private Integer protocolType; 48 + @Schema(description = "定位类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
  49 + @InEnum(value = IotLocationTypeEnum.class, message = "定位方式必须是 {value}")
  50 + private Integer locationType;
49 51
50 - @Schema(description = "数据格式", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")  
51 - @InEnum(value = IotDataFormatEnum.class, message = "数据格式必须是 {value}")  
52 - @NotNull(message = "数据格式不能为空")  
53 - private Integer dataFormat;  
54 -  
55 - @Schema(description = "数据校验级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")  
56 - @InEnum(value = IotValidateTypeEnum.class, message = "数据校验级别必须是 {value}")  
57 - @NotNull(message = "数据校验级别不能为空")  
58 - private Integer validateType; 52 + @Schema(description = "数据格式", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
  53 + @NotEmpty(message = "数据格式不能为空")
  54 + private String codecType;
59 55
60 } 56 }
61 \ No newline at end of file 57 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/IotDataBridgeController.java deleted
1 -package cn.iocoder.yudao.module.iot.controller.admin.rule;  
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.rule.vo.databridge.IotDataBridgePageReqVO;  
7 -import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.IotDataBridgeRespVO;  
8 -import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.IotDataBridgeSaveReqVO;  
9 -import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotDataBridgeDO;  
10 -import cn.iocoder.yudao.module.iot.service.rule.IotDataBridgeService;  
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 数据桥梁")  
23 -@RestController  
24 -@RequestMapping("/iot/data-bridge")  
25 -@Validated  
26 -public class IotDataBridgeController {  
27 -  
28 - @Resource  
29 - private IotDataBridgeService dataBridgeService;  
30 -  
31 - @PostMapping("/create")  
32 - @Operation(summary = "创建数据桥梁")  
33 - @PreAuthorize("@ss.hasPermission('iot:data-bridge:create')")  
34 - public CommonResult<Long> createDataBridge(@Valid @RequestBody IotDataBridgeSaveReqVO createReqVO) {  
35 - return success(dataBridgeService.createDataBridge(createReqVO));  
36 - }  
37 -  
38 - @PutMapping("/update")  
39 - @Operation(summary = "更新数据桥梁")  
40 - @PreAuthorize("@ss.hasPermission('iot:data-bridge:update')")  
41 - public CommonResult<Boolean> updateDataBridge(@Valid @RequestBody IotDataBridgeSaveReqVO updateReqVO) {  
42 - dataBridgeService.updateDataBridge(updateReqVO);  
43 - return success(true);  
44 - }  
45 -  
46 - @DeleteMapping("/delete")  
47 - @Operation(summary = "删除数据桥梁")  
48 - @Parameter(name = "id", description = "编号", required = true)  
49 - @PreAuthorize("@ss.hasPermission('iot:data-bridge:delete')")  
50 - public CommonResult<Boolean> deleteDataBridge(@RequestParam("id") Long id) {  
51 - dataBridgeService.deleteDataBridge(id);  
52 - return success(true);  
53 - }  
54 -  
55 - @GetMapping("/get")  
56 - @Operation(summary = "获得数据桥梁")  
57 - @Parameter(name = "id", description = "编号", required = true, example = "1024")  
58 - @PreAuthorize("@ss.hasPermission('iot:data-bridge:query')")  
59 - public CommonResult<IotDataBridgeRespVO> getDataBridge(@RequestParam("id") Long id) {  
60 - IotDataBridgeDO dataBridge = dataBridgeService.getDataBridge(id);  
61 - return success(BeanUtils.toBean(dataBridge, IotDataBridgeRespVO.class));  
62 - }  
63 -  
64 - @GetMapping("/page")  
65 - @Operation(summary = "获得数据桥梁分页")  
66 - @PreAuthorize("@ss.hasPermission('iot:data-bridge:query')")  
67 - public CommonResult<PageResult<IotDataBridgeRespVO>> getDataBridgePage(@Valid IotDataBridgePageReqVO pageReqVO) {  
68 - PageResult<IotDataBridgeDO> pageResult = dataBridgeService.getDataBridgePage(pageReqVO);  
69 - return success(BeanUtils.toBean(pageResult, IotDataBridgeRespVO.class));  
70 - }  
71 -  
72 -}  
73 \ No newline at end of file 0 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/IotDataRuleController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.controller.admin.rule;
  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.rule.vo.data.rule.IotDataRulePageReqVO;
  7 +import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.data.rule.IotDataRuleRespVO;
  8 +import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.data.rule.IotDataRuleSaveReqVO;
  9 +import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotDataRuleDO;
  10 +import cn.iocoder.yudao.module.iot.service.rule.data.IotDataRuleService;
  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 数据流转规则")
  23 +@RestController
  24 +@RequestMapping("/iot/data-rule")
  25 +@Validated
  26 +public class IotDataRuleController {
  27 +
  28 + @Resource
  29 + private IotDataRuleService dataRuleService;
  30 +
  31 + @PostMapping("/create")
  32 + @Operation(summary = "创建数据流转规则")
  33 + @PreAuthorize("@ss.hasPermission('iot:data-rule:create')")
  34 + public CommonResult<Long> createDataRule(@Valid @RequestBody IotDataRuleSaveReqVO createReqVO) {
  35 + return success(dataRuleService.createDataRule(createReqVO));
  36 + }
  37 +
  38 + @PutMapping("/update")
  39 + @Operation(summary = "更新数据流转规则")
  40 + @PreAuthorize("@ss.hasPermission('iot:data-rule:update')")
  41 + public CommonResult<Boolean> updateDataRule(@Valid @RequestBody IotDataRuleSaveReqVO updateReqVO) {
  42 + dataRuleService.updateDataRule(updateReqVO);
  43 + return success(true);
  44 + }
  45 +
  46 + @DeleteMapping("/delete")
  47 + @Operation(summary = "删除数据流转规则")
  48 + @Parameter(name = "id", description = "编号", required = true)
  49 + @PreAuthorize("@ss.hasPermission('iot:data-rule:delete')")
  50 + public CommonResult<Boolean> deleteDataRule(@RequestParam("id") Long id) {
  51 + dataRuleService.deleteDataRule(id);
  52 + return success(true);
  53 + }
  54 +
  55 + @GetMapping("/get")
  56 + @Operation(summary = "获得数据流转规则")
  57 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  58 + @PreAuthorize("@ss.hasPermission('iot:data-rule:query')")
  59 + public CommonResult<IotDataRuleRespVO> getDataRule(@RequestParam("id") Long id) {
  60 + IotDataRuleDO dataRule = dataRuleService.getDataRule(id);
  61 + return success(BeanUtils.toBean(dataRule, IotDataRuleRespVO.class));
  62 + }
  63 +
  64 + @GetMapping("/page")
  65 + @Operation(summary = "获得数据流转规则分页")
  66 + @PreAuthorize("@ss.hasPermission('iot:data-rule:query')")
  67 + public CommonResult<PageResult<IotDataRuleRespVO>> getDataRulePage(@Valid IotDataRulePageReqVO pageReqVO) {
  68 + PageResult<IotDataRuleDO> pageResult = dataRuleService.getDataRulePage(pageReqVO);
  69 + return success(BeanUtils.toBean(pageResult, IotDataRuleRespVO.class));
  70 + }
  71 +
  72 +}
0 \ No newline at end of file 73 \ No newline at end of file