diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/IotRuleSceneController.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/IotRuleSceneController.java index 36559a5f19..7e582bdb77 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/IotRuleSceneController.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/IotRuleSceneController.java @@ -14,7 +14,6 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; -import jakarta.annotation.security.PermitAll; import jakarta.validation.Valid; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; @@ -91,10 +90,4 @@ public class IotRuleSceneController { new IotRuleSceneRespVO().setId(scene.getId()).setName(scene.getName()))); } - @GetMapping("/test") - @PermitAll - public void test() { - ruleSceneService.test(); - } - } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/IotRuleSceneService.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/IotRuleSceneService.java index e565c59c3f..62225e64eb 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/IotRuleSceneService.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/IotRuleSceneService.java @@ -103,9 +103,4 @@ public interface IotRuleSceneService { */ void executeRuleSceneByTimer(Long id); - /** - * TODO 芋艿:测试方法,需要删除 - */ - void test(); - } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/IotRuleSceneServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/IotRuleSceneServiceImpl.java index e3762fa9ef..8a03e58cfc 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/IotRuleSceneServiceImpl.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/IotRuleSceneServiceImpl.java @@ -27,18 +27,11 @@ import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneConditionOperatorEnum; import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneConditionTypeEnum; import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneTriggerTypeEnum; import cn.iocoder.yudao.module.iot.framework.job.core.IotSchedulerManager; -import cn.iocoder.yudao.module.iot.job.rule.IotRuleSceneJob; import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; import cn.iocoder.yudao.module.iot.service.product.IotProductService; import cn.iocoder.yudao.module.iot.service.rule.scene.action.IotSceneRuleAction; import jakarta.annotation.Resource; -import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; -import org.quartz.JobKey; -import org.quartz.Scheduler; -import org.quartz.SchedulerException; -import org.quartz.TriggerKey; -import org.quartz.impl.StdSchedulerFactory; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @@ -556,50 +549,4 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService { }); } - @Override - @SneakyThrows - public void test() { - // TODO @芋艿:测试思路代码,记得删除!!! - // 1. Job 类:IotRuleSceneJob DONE - // 2. 参数:id DONE - // 3. jobHandlerName:IotRuleSceneJob + id DONE - - // 新增:addJob - // 修改:不存在 addJob、存在 updateJob - // 有 + 禁用:1)存在、停止;2)不存在:不处理;TODO 测试:直接暂停,是否可以???(结论:可以)pauseJob - // 有 + 开启:1)存在,更新;2)不存在,新增;结论:使用 save(addOrUpdateJob) - // 无 + 禁用、开启:1)存在,删除;TODO 测试:直接删除???(结论:可以)deleteJob - - // - if (false) { - Long id = 1L; - Map jobDataMap = IotRuleSceneJob.buildJobDataMap(id); - schedulerManager.addOrUpdateJob(IotRuleSceneJob.class, - IotRuleSceneJob.buildJobName(id), - "0/10 * * * * ?", - jobDataMap); - } - if (false) { - Long id = 1L; - schedulerManager.pauseJob(IotRuleSceneJob.buildJobName(id)); - } - if (true) { - Long id = 1L; - schedulerManager.deleteJob(IotRuleSceneJob.buildJobName(id)); - } - } - - public static void main2(String[] args) throws SchedulerException { -// System.out.println(QuartzJobBean.class); - Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); - scheduler.start(); - - String jobHandlerName = "123"; - // 暂停 Trigger 对象 - scheduler.pauseTrigger(new TriggerKey(jobHandlerName)); - // 取消并删除 Job 调度 - scheduler.unscheduleJob(new TriggerKey(jobHandlerName)); - scheduler.deleteJob(new JobKey(jobHandlerName)); - } - } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/rule/scene/IotRuleSceneServiceSimpleTest.java b/yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/rule/scene/IotRuleSceneServiceSimpleTest.java new file mode 100644 index 0000000000..e2735f5bce --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/rule/scene/IotRuleSceneServiceSimpleTest.java @@ -0,0 +1,211 @@ +package cn.iocoder.yudao.module.iot.service.rule.scene; + +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; +import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.IotRuleSceneSaveReqVO; +import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO; +import cn.iocoder.yudao.module.iot.dal.mysql.rule.IotRuleSceneMapper; +import cn.iocoder.yudao.module.iot.framework.job.core.IotSchedulerManager; +import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; +import cn.iocoder.yudao.module.iot.service.product.IotProductService; +import cn.iocoder.yudao.module.iot.service.rule.scene.action.IotSceneRuleAction; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; + +import java.util.Collections; +import java.util.List; + +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; + +/** + * {@link IotRuleSceneServiceImpl} 的简化单元测试类 + * 使用 Mockito 进行纯单元测试,不依赖 Spring 容器 + * + * @author 芋道源码 + */ +public class IotRuleSceneServiceSimpleTest extends BaseMockitoUnitTest { + + @InjectMocks + private IotRuleSceneServiceImpl ruleSceneService; + + @Mock + private IotRuleSceneMapper ruleSceneMapper; + + @Mock + private List ruleSceneActions; + + @Mock + private IotSchedulerManager schedulerManager; + + @Mock + private IotProductService productService; + + @Mock + private IotDeviceService deviceService; + + @Test + public void testCreateRuleScene_success() { + // 准备参数 + IotRuleSceneSaveReqVO createReqVO = randomPojo(IotRuleSceneSaveReqVO.class, o -> { + o.setId(null); + o.setStatus(CommonStatusEnum.ENABLE.getStatus()); + o.setTriggers(Collections.singletonList(randomPojo(IotSceneRuleDO.Trigger.class))); + o.setActions(Collections.singletonList(randomPojo(IotSceneRuleDO.Action.class))); + }); + + // Mock 行为 + Long expectedId = randomLongId(); + when(ruleSceneMapper.insert(any(IotSceneRuleDO.class))).thenAnswer(invocation -> { + IotSceneRuleDO ruleScene = invocation.getArgument(0); + ruleScene.setId(expectedId); + return 1; + }); + + // 调用 + Long ruleSceneId = ruleSceneService.createRuleScene(createReqVO); + + // 断言 + assertEquals(expectedId, ruleSceneId); + verify(ruleSceneMapper, times(1)).insert(any(IotSceneRuleDO.class)); + } + + @Test + public void testUpdateRuleScene_success() { + // 准备参数 + Long id = randomLongId(); + IotRuleSceneSaveReqVO updateReqVO = randomPojo(IotRuleSceneSaveReqVO.class, o -> { + o.setId(id); + o.setStatus(CommonStatusEnum.ENABLE.getStatus()); + o.setTriggers(Collections.singletonList(randomPojo(IotSceneRuleDO.Trigger.class))); + o.setActions(Collections.singletonList(randomPojo(IotSceneRuleDO.Action.class))); + }); + + // Mock 行为 + IotSceneRuleDO existingRuleScene = randomPojo(IotSceneRuleDO.class, o -> o.setId(id)); + when(ruleSceneMapper.selectById(id)).thenReturn(existingRuleScene); + when(ruleSceneMapper.updateById(any(IotSceneRuleDO.class))).thenReturn(1); + + // 调用 + assertDoesNotThrow(() -> ruleSceneService.updateRuleScene(updateReqVO)); + + // 验证 + verify(ruleSceneMapper, times(1)).selectById(id); + verify(ruleSceneMapper, times(1)).updateById(any(IotSceneRuleDO.class)); + } + + @Test + public void testDeleteRuleScene_success() { + // 准备参数 + Long id = randomLongId(); + + // Mock 行为 + IotSceneRuleDO existingRuleScene = randomPojo(IotSceneRuleDO.class, o -> o.setId(id)); + when(ruleSceneMapper.selectById(id)).thenReturn(existingRuleScene); + when(ruleSceneMapper.deleteById(id)).thenReturn(1); + + // 调用 + assertDoesNotThrow(() -> ruleSceneService.deleteRuleScene(id)); + + // 验证 + verify(ruleSceneMapper, times(1)).selectById(id); + verify(ruleSceneMapper, times(1)).deleteById(id); + } + + @Test + public void testGetRuleScene() { + // 准备参数 + Long id = randomLongId(); + IotSceneRuleDO expectedRuleScene = randomPojo(IotSceneRuleDO.class, o -> o.setId(id)); + + // Mock 行为 + when(ruleSceneMapper.selectById(id)).thenReturn(expectedRuleScene); + + // 调用 + IotSceneRuleDO result = ruleSceneService.getRuleScene(id); + + // 断言 + assertEquals(expectedRuleScene, result); + verify(ruleSceneMapper, times(1)).selectById(id); + } + + @Test + public void testUpdateRuleSceneStatus_success() { + // 准备参数 + Long id = randomLongId(); + Integer status = CommonStatusEnum.DISABLE.getStatus(); + + // Mock 行为 + IotSceneRuleDO existingRuleScene = randomPojo(IotSceneRuleDO.class, o -> { + o.setId(id); + o.setStatus(CommonStatusEnum.ENABLE.getStatus()); + }); + when(ruleSceneMapper.selectById(id)).thenReturn(existingRuleScene); + when(ruleSceneMapper.updateById(any(IotSceneRuleDO.class))).thenReturn(1); + + // 调用 + assertDoesNotThrow(() -> ruleSceneService.updateRuleSceneStatus(id, status)); + + // 验证 + verify(ruleSceneMapper, times(1)).selectById(id); + verify(ruleSceneMapper, times(1)).updateById(any(IotSceneRuleDO.class)); + } + + @Test + public void testExecuteRuleSceneByTimer_success() { + // 准备参数 + Long id = randomLongId(); + + // Mock 行为 + IotSceneRuleDO ruleScene = randomPojo(IotSceneRuleDO.class, o -> { + o.setId(id); + o.setStatus(CommonStatusEnum.ENABLE.getStatus()); + }); + when(ruleSceneMapper.selectById(id)).thenReturn(ruleScene); + + // 调用 + assertDoesNotThrow(() -> ruleSceneService.executeRuleSceneByTimer(id)); + + // 验证 + verify(ruleSceneMapper, times(1)).selectById(id); + } + + @Test + public void testExecuteRuleSceneByTimer_notExists() { + // 准备参数 + Long id = randomLongId(); + + // Mock 行为 + when(ruleSceneMapper.selectById(id)).thenReturn(null); + + // 调用 - 不存在的场景规则应该不会抛异常,只是记录日志 + assertDoesNotThrow(() -> ruleSceneService.executeRuleSceneByTimer(id)); + + // 验证 + verify(ruleSceneMapper, times(1)).selectById(id); + } + + @Test + public void testExecuteRuleSceneByTimer_disabled() { + // 准备参数 + Long id = randomLongId(); + + // Mock 行为 + IotSceneRuleDO ruleScene = randomPojo(IotSceneRuleDO.class, o -> { + o.setId(id); + o.setStatus(CommonStatusEnum.DISABLE.getStatus()); + }); + when(ruleSceneMapper.selectById(id)).thenReturn(ruleScene); + + // 调用 - 禁用的场景规则应该不会执行,只是记录日志 + assertDoesNotThrow(() -> ruleSceneService.executeRuleSceneByTimer(id)); + + // 验证 + verify(ruleSceneMapper, times(1)).selectById(id); + } +} diff --git a/yudao-module-iot/yudao-module-iot-biz/src/test/resources/application-unit-test.yaml b/yudao-module-iot/yudao-module-iot-biz/src/test/resources/application-unit-test.yaml new file mode 100644 index 0000000000..7eecc88a4b --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/test/resources/application-unit-test.yaml @@ -0,0 +1,43 @@ +spring: + main: + lazy-initialization: true # 开启懒加载,加快速度 + banner-mode: off # 单元测试,禁用 Banner + # 数据源配置项 + datasource: + name: ruoyi-vue-pro + url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false;NON_KEYWORDS=value; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写 + driver-class-name: org.h2.Driver + username: sa + password: + druid: + async-init: true # 单元测试,异步初始化 Druid 连接池,提升启动速度 + initial-size: 1 # 单元测试,配置为 1,提升启动速度 + sql: + init: + schema-locations: classpath:/sql/create_tables.sql + +mybatis-plus: + lazy-initialization: true # 单元测试,设置 MyBatis Mapper 延迟加载,加速每个单元测试 + type-aliases-package: ${yudao.info.base-package}.module.*.dal.dataobject + +--- #################### 定时任务相关配置 #################### + +--- #################### 配置中心相关配置 #################### + +--- #################### 服务保障相关配置 #################### + +# Lock4j 配置项(单元测试,禁用 Lock4j) + +--- #################### 监控相关配置 #################### + +--- #################### 芋道相关配置 #################### + +# 芋道配置项,设置当前项目所有自定义的配置 +yudao: + info: + base-package: cn.iocoder.yudao + tenant: # 多租户相关配置项 + enable: true + xss: + enable: false + demo: false # 关闭演示模式 diff --git a/yudao-module-iot/yudao-module-iot-biz/src/test/resources/logback.xml b/yudao-module-iot/yudao-module-iot-biz/src/test/resources/logback.xml new file mode 100644 index 0000000000..1d071e4799 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/test/resources/logback.xml @@ -0,0 +1,4 @@ + + + + diff --git a/yudao-module-iot/yudao-module-iot-biz/src/test/resources/sql/clean.sql b/yudao-module-iot/yudao-module-iot-biz/src/test/resources/sql/clean.sql new file mode 100644 index 0000000000..79047d1697 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/test/resources/sql/clean.sql @@ -0,0 +1,21 @@ +-- IoT 模块测试数据清理脚本 +DELETE +FROM "iot_scene_rule"; +DELETE +FROM "iot_product"; +DELETE +FROM "iot_device"; +DELETE +FROM "iot_thing_model"; +DELETE +FROM "iot_device_data"; +DELETE +FROM "iot_alert_config"; +DELETE +FROM "iot_alert_record"; +DELETE +FROM "iot_ota_firmware"; +DELETE +FROM "iot_ota_task"; +DELETE +FROM "iot_ota_record"; diff --git a/yudao-module-iot/yudao-module-iot-biz/src/test/resources/sql/create_tables.sql b/yudao-module-iot/yudao-module-iot-biz/src/test/resources/sql/create_tables.sql new file mode 100644 index 0000000000..a63bd3ed3a --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/test/resources/sql/create_tables.sql @@ -0,0 +1,472 @@ +-- IoT 模块测试数据库表结构 +-- 基于 H2 数据库语法,兼容 MySQL 模式 + +-- IoT 场景联动规则表 +CREATE TABLE IF NOT EXISTS "iot_scene_rule" +( + "id" + bigint + NOT + NULL + GENERATED + BY + DEFAULT AS + IDENTITY, + "name" + varchar +( + 255 +) NOT NULL DEFAULT '', + "description" varchar +( + 500 +) DEFAULT NULL, + "status" tinyint NOT NULL DEFAULT '0', + "triggers" text, + "actions" text, + "creator" varchar +( + 64 +) DEFAULT '', + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar +( + 64 +) DEFAULT '', + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + "tenant_id" bigint NOT NULL DEFAULT '0', + PRIMARY KEY +( + "id" +) + ) COMMENT 'IoT 场景联动规则表'; + +-- IoT 产品表 +CREATE TABLE IF NOT EXISTS "iot_product" +( + "id" + bigint + NOT + NULL + GENERATED + BY + DEFAULT AS + IDENTITY, + "name" + varchar +( + 255 +) NOT NULL DEFAULT '', + "product_key" varchar +( + 100 +) NOT NULL DEFAULT '', + "protocol_type" tinyint NOT NULL DEFAULT '0', + "category_id" bigint DEFAULT NULL, + "description" varchar +( + 500 +) DEFAULT NULL, + "data_format" tinyint NOT NULL DEFAULT '0', + "device_type" tinyint NOT NULL DEFAULT '0', + "net_type" tinyint NOT NULL DEFAULT '0', + "validate_type" tinyint NOT NULL DEFAULT '0', + "status" tinyint NOT NULL DEFAULT '0', + "creator" varchar +( + 64 +) DEFAULT '', + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar +( + 64 +) DEFAULT '', + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + "tenant_id" bigint NOT NULL DEFAULT '0', + PRIMARY KEY +( + "id" +) + ) COMMENT 'IoT 产品表'; + +-- IoT 设备表 +CREATE TABLE IF NOT EXISTS "iot_device" +( + "id" + bigint + NOT + NULL + GENERATED + BY + DEFAULT AS + IDENTITY, + "device_name" + varchar +( + 255 +) NOT NULL DEFAULT '', + "product_id" bigint NOT NULL, + "device_key" varchar +( + 100 +) NOT NULL DEFAULT '', + "device_secret" varchar +( + 100 +) NOT NULL DEFAULT '', + "nickname" varchar +( + 255 +) DEFAULT NULL, + "status" tinyint NOT NULL DEFAULT '0', + "status_last_update_time" timestamp DEFAULT NULL, + "last_online_time" timestamp DEFAULT NULL, + "last_offline_time" timestamp DEFAULT NULL, + "active_time" timestamp DEFAULT NULL, + "ip" varchar +( + 50 +) DEFAULT NULL, + "firmware_version" varchar +( + 50 +) DEFAULT NULL, + "device_type" tinyint NOT NULL DEFAULT '0', + "gateway_id" bigint DEFAULT NULL, + "sub_device_count" int NOT NULL DEFAULT '0', + "creator" varchar +( + 64 +) DEFAULT '', + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar +( + 64 +) DEFAULT '', + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + "tenant_id" bigint NOT NULL DEFAULT '0', + PRIMARY KEY +( + "id" +) + ) COMMENT 'IoT 设备表'; + +-- IoT 物模型表 +CREATE TABLE IF NOT EXISTS "iot_thing_model" +( + "id" + bigint + NOT + NULL + GENERATED + BY + DEFAULT AS + IDENTITY, + "product_id" + bigint + NOT + NULL, + "identifier" + varchar +( + 100 +) NOT NULL DEFAULT '', + "name" varchar +( + 255 +) NOT NULL DEFAULT '', + "description" varchar +( + 500 +) DEFAULT NULL, + "type" tinyint NOT NULL DEFAULT '1', + "property" text, + "creator" varchar +( + 64 +) DEFAULT '', + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar +( + 64 +) DEFAULT '', + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + "tenant_id" bigint NOT NULL DEFAULT '0', + PRIMARY KEY +( + "id" +) + ) COMMENT 'IoT 物模型表'; + +-- IoT 设备数据表 +CREATE TABLE IF NOT EXISTS "iot_device_data" +( + "id" + bigint + NOT + NULL + GENERATED + BY + DEFAULT AS + IDENTITY, + "device_id" + bigint + NOT + NULL, + "product_id" + bigint + NOT + NULL, + "identifier" + varchar +( + 100 +) NOT NULL DEFAULT '', + "type" tinyint NOT NULL DEFAULT '1', + "data" text, + "ts" bigint NOT NULL DEFAULT '0', + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY +( + "id" +) + ) COMMENT 'IoT 设备数据表'; + +-- IoT 告警配置表 +CREATE TABLE IF NOT EXISTS "iot_alert_config" +( + "id" + bigint + NOT + NULL + GENERATED + BY + DEFAULT AS + IDENTITY, + "name" + varchar +( + 255 +) NOT NULL DEFAULT '', + "product_id" bigint NOT NULL, + "device_id" bigint DEFAULT NULL, + "rule_id" bigint DEFAULT NULL, + "status" tinyint NOT NULL DEFAULT '0', + "creator" varchar +( + 64 +) DEFAULT '', + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar +( + 64 +) DEFAULT '', + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + "tenant_id" bigint NOT NULL DEFAULT '0', + PRIMARY KEY +( + "id" +) + ) COMMENT 'IoT 告警配置表'; + +-- IoT 告警记录表 +CREATE TABLE IF NOT EXISTS "iot_alert_record" +( + "id" + bigint + NOT + NULL + GENERATED + BY + DEFAULT AS + IDENTITY, + "alert_config_id" + bigint + NOT + NULL, + "alert_name" + varchar +( + 255 +) NOT NULL DEFAULT '', + "product_id" bigint NOT NULL, + "device_id" bigint DEFAULT NULL, + "rule_id" bigint DEFAULT NULL, + "alert_data" text, + "alert_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "deal_status" tinyint NOT NULL DEFAULT '0', + "deal_time" timestamp DEFAULT NULL, + "deal_user_id" bigint DEFAULT NULL, + "deal_remark" varchar +( + 500 +) DEFAULT NULL, + "creator" varchar +( + 64 +) DEFAULT '', + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar +( + 64 +) DEFAULT '', + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + "tenant_id" bigint NOT NULL DEFAULT '0', + PRIMARY KEY +( + "id" +) + ) COMMENT 'IoT 告警记录表'; + +-- IoT OTA 固件表 +CREATE TABLE IF NOT EXISTS "iot_ota_firmware" +( + "id" + bigint + NOT + NULL + GENERATED + BY + DEFAULT AS + IDENTITY, + "name" + varchar +( + 255 +) NOT NULL DEFAULT '', + "product_id" bigint NOT NULL, + "version" varchar +( + 50 +) NOT NULL DEFAULT '', + "description" varchar +( + 500 +) DEFAULT NULL, + "file_url" varchar +( + 500 +) DEFAULT NULL, + "file_size" bigint NOT NULL DEFAULT '0', + "status" tinyint NOT NULL DEFAULT '0', + "creator" varchar +( + 64 +) DEFAULT '', + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar +( + 64 +) DEFAULT '', + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + "tenant_id" bigint NOT NULL DEFAULT '0', + PRIMARY KEY +( + "id" +) + ) COMMENT 'IoT OTA 固件表'; + +-- IoT OTA 升级任务表 +CREATE TABLE IF NOT EXISTS "iot_ota_task" +( + "id" + bigint + NOT + NULL + GENERATED + BY + DEFAULT AS + IDENTITY, + "name" + varchar +( + 255 +) NOT NULL DEFAULT '', + "firmware_id" bigint NOT NULL, + "product_id" bigint NOT NULL, + "upgrade_type" tinyint NOT NULL DEFAULT '0', + "status" tinyint NOT NULL DEFAULT '0', + "creator" varchar +( + 64 +) DEFAULT '', + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar +( + 64 +) DEFAULT '', + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + "tenant_id" bigint NOT NULL DEFAULT '0', + PRIMARY KEY +( + "id" +) + ) COMMENT 'IoT OTA 升级任务表'; + +-- IoT OTA 升级记录表 +CREATE TABLE IF NOT EXISTS "iot_ota_record" +( + "id" + bigint + NOT + NULL + GENERATED + BY + DEFAULT AS + IDENTITY, + "task_id" + bigint + NOT + NULL, + "firmware_id" + bigint + NOT + NULL, + "device_id" + bigint + NOT + NULL, + "status" + tinyint + NOT + NULL + DEFAULT + '0', + "progress" + int + NOT + NULL + DEFAULT + '0', + "error_msg" + varchar +( + 500 +) DEFAULT NULL, + "start_time" timestamp DEFAULT NULL, + "end_time" timestamp DEFAULT NULL, + "creator" varchar +( + 64 +) DEFAULT '', + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar +( + 64 +) DEFAULT '', + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + "tenant_id" bigint NOT NULL DEFAULT '0', + PRIMARY KEY +( + "id" +) + ) COMMENT 'IoT OTA 升级记录表';