Commit 6eadbba34554f2364f7bb77daed829bec8945637

Authored by 安浩浩
1 parent b46e6309

【代码重构】IoT:重构插件配置管理,替换 PluginInfo 为 PluginConfig

Showing 23 changed files with 427 additions and 369 deletions
@@ -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-spring-boot-starter-mybatis/pom.xml
@@ -63,6 +63,10 @@ @@ -63,6 +63,10 @@
63 <artifactId>opengauss-jdbc</artifactId> 63 <artifactId>opengauss-jdbc</artifactId>
64 <optional>true</optional> 64 <optional>true</optional>
65 </dependency> 65 </dependency>
  66 + <dependency>
  67 + <groupId>com.taosdata.jdbc</groupId>
  68 + <artifactId>taos-jdbcdriver</artifactId>
  69 + </dependency>
66 70
67 <dependency> 71 <dependency>
68 <groupId>com.alibaba</groupId> 72 <groupId>com.alibaba</groupId>
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java
@@ -39,12 +39,13 @@ public interface ErrorCodeConstants { @@ -39,12 +39,13 @@ public interface ErrorCodeConstants {
39 ErrorCode DEVICE_GROUP_NOT_EXISTS = new ErrorCode(1_050_005_000, "设备分组不存在"); 39 ErrorCode DEVICE_GROUP_NOT_EXISTS = new ErrorCode(1_050_005_000, "设备分组不存在");
40 ErrorCode DEVICE_GROUP_DELETE_FAIL_DEVICE_EXISTS = new ErrorCode(1_050_005_001, "设备分组下存在设备,不允许删除"); 40 ErrorCode DEVICE_GROUP_DELETE_FAIL_DEVICE_EXISTS = new ErrorCode(1_050_005_001, "设备分组下存在设备,不允许删除");
41 41
42 - // ========== 插件信息 1-050-006-000 ==========  
43 - ErrorCode PLUGIN_INFO_NOT_EXISTS = new ErrorCode(1_050_006_000, "插件信息不存在"); 42 + // ========== 插件配置 1-050-006-000 ==========
  43 + ErrorCode PLUGIN_CONFIG_NOT_EXISTS = new ErrorCode(1_050_006_000, "插件配置不存在");
44 ErrorCode PLUGIN_INSTALL_FAILED = new ErrorCode(1_050_006_001, "插件安装失败"); 44 ErrorCode PLUGIN_INSTALL_FAILED = new ErrorCode(1_050_006_001, "插件安装失败");
45 ErrorCode PLUGIN_INSTALL_FAILED_FILE_NAME_NOT_MATCH = new ErrorCode(1_050_006_002, "插件安装失败,文件名与原插件id不匹配"); 45 ErrorCode PLUGIN_INSTALL_FAILED_FILE_NAME_NOT_MATCH = new ErrorCode(1_050_006_002, "插件安装失败,文件名与原插件id不匹配");
46 - ErrorCode PLUGIN_INFO_DELETE_FAILED_RUNNING = new ErrorCode(1_050_006_003, "请先停止插件"); 46 + ErrorCode PLUGIN_CONFIG_DELETE_FAILED_RUNNING = new ErrorCode(1_050_006_003, "请先停止插件");
47 ErrorCode PLUGIN_STATUS_INVALID = new ErrorCode(1_050_006_004, "插件状态无效"); 47 ErrorCode PLUGIN_STATUS_INVALID = new ErrorCode(1_050_006_004, "插件状态无效");
  48 + ErrorCode PLUGIN_CONFIG_KEY_DUPLICATE = new ErrorCode(1_050_006_005, "插件标识已存在");
48 49
49 // ========== 插件实例 1-050-007-000 ========== 50 // ========== 插件实例 1-050-007-000 ==========
50 51
yudao-module-iot/yudao-module-iot-biz/pom.xml
@@ -52,11 +52,6 @@ @@ -52,11 +52,6 @@
52 <artifactId>yudao-spring-boot-starter-redis</artifactId> 52 <artifactId>yudao-spring-boot-starter-redis</artifactId>
53 </dependency> 53 </dependency>
54 54
55 - <dependency>  
56 - <groupId>com.taosdata.jdbc</groupId>  
57 - <artifactId>taos-jdbcdriver</artifactId>  
58 - </dependency>  
59 -  
60 <!-- Test 测试相关 --> 55 <!-- Test 测试相关 -->
61 <dependency> 56 <dependency>
62 <groupId>cn.iocoder.boot</groupId> 57 <groupId>cn.iocoder.boot</groupId>
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/PluginConfigController.java 0 → 100644
  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 +}
0 \ No newline at end of file 91 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/PluginInfoController.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.info.PluginInfoImportReqVO;  
7 -import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.info.PluginInfoPageReqVO;  
8 -import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.info.PluginInfoRespVO;  
9 -import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.info.PluginInfoSaveReqVO;  
10 -import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginInfoDO;  
11 -import cn.iocoder.yudao.module.iot.service.plugin.IotPluginInfoService;  
12 -import io.swagger.v3.oas.annotations.Operation;  
13 -import io.swagger.v3.oas.annotations.Parameter;  
14 -import io.swagger.v3.oas.annotations.tags.Tag;  
15 -import jakarta.annotation.Resource;  
16 -import jakarta.validation.Valid;  
17 -import org.springframework.security.access.prepost.PreAuthorize;  
18 -import org.springframework.validation.annotation.Validated;  
19 -import org.springframework.web.bind.annotation.*;  
20 -  
21 -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;  
22 -  
23 -@Tag(name = "管理后台 - IoT 插件信息")  
24 -@RestController  
25 -@RequestMapping("/iot/plugin-info")  
26 -@Validated  
27 -public class PluginInfoController {  
28 -  
29 - @Resource  
30 - private IotPluginInfoService pluginInfoService;  
31 -  
32 - @PostMapping("/create")  
33 - @Operation(summary = "创建插件信息")  
34 - @PreAuthorize("@ss.hasPermission('iot:plugin-info:create')")  
35 - public CommonResult<Long> createPluginInfo(@Valid @RequestBody PluginInfoSaveReqVO createReqVO) {  
36 - return success(pluginInfoService.createPluginInfo(createReqVO));  
37 - }  
38 -  
39 - @PutMapping("/update")  
40 - @Operation(summary = "更新插件信息")  
41 - @PreAuthorize("@ss.hasPermission('iot:plugin-info:update')")  
42 - public CommonResult<Boolean> updatePluginInfo(@Valid @RequestBody PluginInfoSaveReqVO updateReqVO) {  
43 - pluginInfoService.updatePluginInfo(updateReqVO);  
44 - return success(true);  
45 - }  
46 -  
47 - @DeleteMapping("/delete")  
48 - @Operation(summary = "删除插件信息")  
49 - @Parameter(name = "id", description = "编号", required = true)  
50 - @PreAuthorize("@ss.hasPermission('iot:plugin-info:delete')")  
51 - public CommonResult<Boolean> deletePluginInfo(@RequestParam("id") Long id) {  
52 - pluginInfoService.deletePluginInfo(id);  
53 - return success(true);  
54 - }  
55 -  
56 - @GetMapping("/get")  
57 - @Operation(summary = "获得插件信息")  
58 - @Parameter(name = "id", description = "编号", required = true, example = "1024")  
59 - @PreAuthorize("@ss.hasPermission('iot:plugin-info:query')")  
60 - public CommonResult<PluginInfoRespVO> getPluginInfo(@RequestParam("id") Long id) {  
61 - IotPluginInfoDO pluginInfo = pluginInfoService.getPluginInfo(id);  
62 - return success(BeanUtils.toBean(pluginInfo, PluginInfoRespVO.class));  
63 - }  
64 -  
65 - @GetMapping("/page")  
66 - @Operation(summary = "获得插件信息分页")  
67 - @PreAuthorize("@ss.hasPermission('iot:plugin-info:query')")  
68 - public CommonResult<PageResult<PluginInfoRespVO>> getPluginInfoPage(@Valid PluginInfoPageReqVO pageReqVO) {  
69 - PageResult<IotPluginInfoDO> pageResult = pluginInfoService.getPluginInfoPage(pageReqVO);  
70 - return success(BeanUtils.toBean(pageResult, PluginInfoRespVO.class));  
71 - }  
72 -  
73 - @PostMapping("/upload-file")  
74 - @Operation(summary = "上传插件文件")  
75 - @PreAuthorize("@ss.hasPermission('iot:plugin-info:update')")  
76 - public CommonResult<Boolean> uploadFile(@Valid PluginInfoImportReqVO reqVO) {  
77 - pluginInfoService.uploadFile(reqVO.getId(), reqVO.getFile());  
78 - return success(true);  
79 - }  
80 -  
81 - // TODO @haohao:要不独立一个 VO,不用 PluginInfoSaveReqVO  
82 - @PutMapping("/update-status")  
83 - @Operation(summary = "修改插件状态")  
84 - @PreAuthorize("@ss.hasPermission('iot:plugin-info:update')")  
85 - public CommonResult<Boolean> updateUserStatus(@Valid @RequestBody PluginInfoSaveReqVO reqVO) {  
86 - pluginInfoService.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/info/PluginInfoImportReqVO.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/config/PluginConfigImportReqVO.java
1 -package cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.info; 1 +package cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config;
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.NotNull; 4 import jakarta.validation.constraints.NotNull;
@@ -7,7 +7,7 @@ import org.springframework.web.multipart.MultipartFile; @@ -7,7 +7,7 @@ import org.springframework.web.multipart.MultipartFile;
7 7
8 @Schema(description = "管理后台 - IoT 插件上传 Request VO") 8 @Schema(description = "管理后台 - IoT 插件上传 Request VO")
9 @Data 9 @Data
10 -public class PluginInfoImportReqVO { 10 +public class PluginConfigImportReqVO {
11 11
12 @Schema(description = "主键 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "11546") 12 @Schema(description = "主键 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "11546")
13 private Long id; 13 private Long id;
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/info/PluginInfoPageReqVO.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/config/PluginConfigPageReqVO.java
1 -package cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.info; 1 +package cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config;
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;
@@ -6,9 +6,9 @@ import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginStatusEnum; @@ -6,9 +6,9 @@ import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginStatusEnum;
6 import io.swagger.v3.oas.annotations.media.Schema; 6 import io.swagger.v3.oas.annotations.media.Schema;
7 import lombok.Data; 7 import lombok.Data;
8 8
9 -@Schema(description = "管理后台 - IoT 插件信息分页 Request VO") 9 +@Schema(description = "管理后台 - IoT 插件配置分页 Request VO")
10 @Data 10 @Data
11 -public class PluginInfoPageReqVO extends PageParam { 11 +public class PluginConfigPageReqVO extends PageParam {
12 12
13 @Schema(description = "插件名称", example = "http") 13 @Schema(description = "插件名称", example = "http")
14 private String name; 14 private String name;
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/info/PluginInfoRespVO.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/config/PluginConfigRespVO.java
1 -package cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.info; 1 +package cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config;
2 2
3 import io.swagger.v3.oas.annotations.media.Schema; 3 import io.swagger.v3.oas.annotations.media.Schema;
4 import lombok.Data; 4 import lombok.Data;
5 5
6 import java.time.LocalDateTime; 6 import java.time.LocalDateTime;
7 7
8 -@Schema(description = "管理后台 - IoT 插件信息 Response VO") 8 +@Schema(description = "管理后台 - IoT 插件配置 Response VO")
9 @Data 9 @Data
10 -public class PluginInfoRespVO { 10 +public class PluginConfigRespVO {
11 11
12 @Schema(description = "主键 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "11546") 12 @Schema(description = "主键 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "11546")
13 private Long id; 13 private Long id;
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/info/PluginInfoSaveReqVO.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/config/PluginConfigSaveReqVO.java
1 -package cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.info; 1 +package cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config;
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.plugin.IotPluginStatusEnum; 4 import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginStatusEnum;
5 import io.swagger.v3.oas.annotations.media.Schema; 5 import io.swagger.v3.oas.annotations.media.Schema;
6 import lombok.Data; 6 import lombok.Data;
7 7
8 -@Schema(description = "管理后台 - IoT 插件信息新增/修改 Request VO") 8 +@Schema(description = "管理后台 - IoT 插件配置新增/修改 Request VO")
9 @Data 9 @Data
10 -public class PluginInfoSaveReqVO { 10 +public class PluginConfigSaveReqVO {
11 11
12 // TODO @haohao:新增的字段有点多,每个都需要哇? 12 // TODO @haohao:新增的字段有点多,每个都需要哇?
13 13
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/config/PluginConfigStatusReqVO.java 0 → 100644
  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 +}
0 \ No newline at end of file 20 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/plugin/IotPluginInfoDO.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/plugin/IotPluginConfigDO.java
1 package cn.iocoder.yudao.module.iot.dal.dataobject.plugin; 1 package cn.iocoder.yudao.module.iot.dal.dataobject.plugin;
2 2
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; 4 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
4 import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginDeployTypeEnum; 5 import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginDeployTypeEnum;
5 import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginStatusEnum; 6 import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginStatusEnum;
@@ -9,21 +10,20 @@ import com.baomidou.mybatisplus.annotation.TableId; @@ -9,21 +10,20 @@ import com.baomidou.mybatisplus.annotation.TableId;
9 import com.baomidou.mybatisplus.annotation.TableName; 10 import com.baomidou.mybatisplus.annotation.TableName;
10 import lombok.*; 11 import lombok.*;
11 12
12 -// TODO @haohao:建议 IotPluginInfoDO 改成 IotPluginConfigDO,插件配置。项目里,暂时没有用 info 作为配置的哈。  
13 /** 13 /**
14 - * IoT 插件信息 DO 14 + * IoT 插件配置 DO
15 * 15 *
16 * @author 芋道源码 16 * @author 芋道源码
17 */ 17 */
18 -@TableName("iot_plugin_info")  
19 -@KeySequence("iot_plugin_info_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 18 +@TableName("iot_plugin_config")
  19 +@KeySequence("iot_plugin_config_seq")
20 @Data 20 @Data
21 @EqualsAndHashCode(callSuper = true) 21 @EqualsAndHashCode(callSuper = true)
22 @ToString(callSuper = true) 22 @ToString(callSuper = true)
23 @Builder 23 @Builder
24 @NoArgsConstructor 24 @NoArgsConstructor
25 @AllArgsConstructor 25 @AllArgsConstructor
26 -public class IotPluginInfoDO extends BaseDO { 26 +public class IotPluginConfigDO extends BaseDO {
27 27
28 /** 28 /**
29 * 主键 ID 29 * 主键 ID
@@ -73,7 +73,7 @@ public class IotPluginInfoDO extends BaseDO { @@ -73,7 +73,7 @@ public class IotPluginInfoDO extends BaseDO {
73 /** 73 /**
74 * 状态 74 * 状态
75 * <p> 75 * <p>
76 - * 枚举 {@link IotPluginStatusEnum} 76 + * 枚举 {@link CommonStatusEnum}
77 */ 77 */
78 private Integer status; 78 private Integer status;
79 79
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/plugin/IotPluginInstanceDO.java
@@ -31,7 +31,7 @@ public class IotPluginInstanceDO extends BaseDO { @@ -31,7 +31,7 @@ public class IotPluginInstanceDO extends BaseDO {
31 /** 31 /**
32 * 插件编号 32 * 插件编号
33 * <p> 33 * <p>
34 - * 关联 {@link IotPluginInfoDO#getId()} 34 + * 关联 {@link IotPluginConfigDO#getId()}
35 */ 35 */
36 private Long pluginId; 36 private Long pluginId;
37 /** 37 /**
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/plugin/IotPluginConfigMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.dal.mysql.plugin;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  5 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  6 +import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config.PluginConfigPageReqVO;
  7 +import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginConfigDO;
  8 +import org.apache.ibatis.annotations.Mapper;
  9 +
  10 +import java.util.List;
  11 +
  12 +@Mapper
  13 +public interface IotPluginConfigMapper extends BaseMapperX<IotPluginConfigDO> {
  14 +
  15 + default PageResult<IotPluginConfigDO> selectPage(PluginConfigPageReqVO reqVO) {
  16 + return selectPage(reqVO, new LambdaQueryWrapperX<IotPluginConfigDO>()
  17 + .likeIfPresent(IotPluginConfigDO::getName, reqVO.getName())
  18 + .eqIfPresent(IotPluginConfigDO::getStatus, reqVO.getStatus())
  19 + .orderByDesc(IotPluginConfigDO::getId));
  20 + }
  21 +
  22 + default List<IotPluginConfigDO> selectListByStatusAndDeployType(Integer status, Integer deployType) {
  23 + return selectList(new LambdaQueryWrapperX<IotPluginConfigDO>()
  24 + .eq(IotPluginConfigDO::getStatus, status)
  25 + .eq(IotPluginConfigDO::getDeployType, deployType)
  26 + .orderByAsc(IotPluginConfigDO::getId));
  27 + }
  28 +
  29 + default IotPluginConfigDO selectByPluginKey(String pluginKey) {
  30 + return selectOne(IotPluginConfigDO::getPluginKey, pluginKey);
  31 + }
  32 +
  33 +}
0 \ No newline at end of file 34 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/plugin/IotPluginInfoMapper.java deleted
1 -package cn.iocoder.yudao.module.iot.dal.mysql.plugin;  
2 -  
3 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
4 -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;  
5 -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;  
6 -import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.info.PluginInfoPageReqVO;  
7 -import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginInfoDO;  
8 -import org.apache.ibatis.annotations.Mapper;  
9 -  
10 -import java.util.List;  
11 -  
12 -@Mapper  
13 -public interface IotPluginInfoMapper extends BaseMapperX<IotPluginInfoDO> {  
14 -  
15 - default PageResult<IotPluginInfoDO> selectPage(PluginInfoPageReqVO reqVO) {  
16 - return selectPage(reqVO, new LambdaQueryWrapperX<IotPluginInfoDO>()  
17 - .likeIfPresent(IotPluginInfoDO::getName, reqVO.getName())  
18 - .eqIfPresent(IotPluginInfoDO::getStatus, reqVO.getStatus())  
19 - .orderByDesc(IotPluginInfoDO::getId));  
20 - }  
21 -  
22 - default List<IotPluginInfoDO> selectListByStatus(Integer status) {  
23 - return selectList(new LambdaQueryWrapperX<IotPluginInfoDO>()  
24 - .eq(IotPluginInfoDO::getStatus, status)  
25 - .orderByAsc(IotPluginInfoDO::getId));  
26 - }  
27 -  
28 - default IotPluginInfoDO selectByPluginKey(String pluginKey) {  
29 - return selectOne(IotPluginInfoDO::getPluginKey, pluginKey);  
30 - }  
31 -  
32 -}  
33 \ 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/framework/plugin/config/IotPluginConfiguration.java
@@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.iot.framework.plugin.config; @@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.iot.framework.plugin.config;
2 2
3 import cn.iocoder.yudao.module.iot.framework.plugin.core.IotPluginStartRunner; 3 import cn.iocoder.yudao.module.iot.framework.plugin.core.IotPluginStartRunner;
4 import cn.iocoder.yudao.module.iot.framework.plugin.core.IotPluginStateListener; 4 import cn.iocoder.yudao.module.iot.framework.plugin.core.IotPluginStateListener;
5 -import cn.iocoder.yudao.module.iot.service.plugin.IotPluginInfoService; 5 +import cn.iocoder.yudao.module.iot.service.plugin.IotPluginConfigService;
6 import lombok.extern.slf4j.Slf4j; 6 import lombok.extern.slf4j.Slf4j;
7 import org.pf4j.spring.SpringPluginManager; 7 import org.pf4j.spring.SpringPluginManager;
8 import org.springframework.beans.factory.annotation.Value; 8 import org.springframework.beans.factory.annotation.Value;
@@ -22,8 +22,8 @@ public class IotPluginConfiguration { @@ -22,8 +22,8 @@ public class IotPluginConfiguration {
22 22
23 @Bean 23 @Bean
24 public IotPluginStartRunner pluginStartRunner(SpringPluginManager pluginManager, 24 public IotPluginStartRunner pluginStartRunner(SpringPluginManager pluginManager,
25 - IotPluginInfoService pluginInfoService) {  
26 - return new IotPluginStartRunner(pluginManager, pluginInfoService); 25 + IotPluginConfigService pluginConfigService) {
  26 + return new IotPluginStartRunner(pluginManager, pluginConfigService);
27 } 27 }
28 28
29 // TODO @芋艿:需要 review 下 29 // TODO @芋艿:需要 review 下
@@ -31,7 +31,6 @@ public class IotPluginConfiguration { @@ -31,7 +31,6 @@ public class IotPluginConfiguration {
31 public SpringPluginManager pluginManager(@Value("${pf4j.pluginsDir:pluginsDir}") String pluginsDir) { 31 public SpringPluginManager pluginManager(@Value("${pf4j.pluginsDir:pluginsDir}") String pluginsDir) {
32 log.info("[init][实例化 SpringPluginManager]"); 32 log.info("[init][实例化 SpringPluginManager]");
33 SpringPluginManager springPluginManager = new SpringPluginManager(Paths.get(pluginsDir)) { 33 SpringPluginManager springPluginManager = new SpringPluginManager(Paths.get(pluginsDir)) {
34 -// SpringPluginManager springPluginManager = new SpringPluginManager() {  
35 34
36 @Override 35 @Override
37 public void startPlugins() { 36 public void startPlugins() {
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/framework/plugin/core/IotPluginStartRunner.java
@@ -2,10 +2,10 @@ package cn.iocoder.yudao.module.iot.framework.plugin.core; @@ -2,10 +2,10 @@ package cn.iocoder.yudao.module.iot.framework.plugin.core;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils; 4 import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
5 -import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginInfoDO; 5 +import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginConfigDO;
6 import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginDeployTypeEnum; 6 import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginDeployTypeEnum;
7 import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginStatusEnum; 7 import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginStatusEnum;
8 -import cn.iocoder.yudao.module.iot.service.plugin.IotPluginInfoService; 8 +import cn.iocoder.yudao.module.iot.service.plugin.IotPluginConfigService;
9 import lombok.RequiredArgsConstructor; 9 import lombok.RequiredArgsConstructor;
10 import lombok.extern.slf4j.Slf4j; 10 import lombok.extern.slf4j.Slf4j;
11 import org.pf4j.spring.SpringPluginManager; 11 import org.pf4j.spring.SpringPluginManager;
@@ -25,28 +25,29 @@ public class IotPluginStartRunner implements ApplicationRunner { @@ -25,28 +25,29 @@ public class IotPluginStartRunner implements ApplicationRunner {
25 25
26 private final SpringPluginManager springPluginManager; 26 private final SpringPluginManager springPluginManager;
27 27
28 - private final IotPluginInfoService pluginInfoService; 28 + private final IotPluginConfigService pluginConfigService;
29 29
30 @Override 30 @Override
31 public void run(ApplicationArguments args) { 31 public void run(ApplicationArguments args) {
32 - List<IotPluginInfoDO> pluginInfoList = TenantUtils.executeIgnore(  
33 - // TODO @haohao:需要查询部署类型哈  
34 - () -> pluginInfoService.getPluginInfoListByStatus(IotPluginStatusEnum.RUNNING.getStatus()));  
35 - if (CollUtil.isEmpty(pluginInfoList)) { 32 + List<IotPluginConfigDO> pluginConfigList = TenantUtils.executeIgnore(
  33 + // 查询运行中且部署类型为 JAR 的插件
  34 + () -> pluginConfigService.getPluginConfigListByStatusAndDeployType(
  35 + IotPluginStatusEnum.RUNNING.getStatus(), IotPluginDeployTypeEnum.JAR.getDeployType()));
  36 + if (CollUtil.isEmpty(pluginConfigList)) {
36 log.info("[run][没有需要启动的插件]"); 37 log.info("[run][没有需要启动的插件]");
37 return; 38 return;
38 } 39 }
39 40
40 // 遍历插件列表,逐个启动 41 // 遍历插件列表,逐个启动
41 - pluginInfoList.forEach(pluginInfo -> { 42 + pluginConfigList.forEach(pluginConfig -> {
42 try { 43 try {
43 - log.info("[run][插件({}) 启动开始]", pluginInfo.getPluginKey());  
44 - springPluginManager.startPlugin(pluginInfo.getPluginKey());  
45 - log.info("[run][插件({}) 启动完成]", pluginInfo.getPluginKey()); 44 + log.info("[run][插件({}) 启动开始]", pluginConfig.getPluginKey());
  45 + springPluginManager.startPlugin(pluginConfig.getPluginKey());
  46 + log.info("[run][插件({}) 启动完成]", pluginConfig.getPluginKey());
46 } catch (Exception e) { 47 } catch (Exception e) {
47 - log.error("[run][插件({}) 启动异常]", pluginInfo.getPluginKey(), e); 48 + log.error("[run][插件({}) 启动异常]", pluginConfig.getPluginKey(), e);
48 } 49 }
49 }); 50 });
50 } 51 }
51 52
52 -} 53 -}
  54 +}
53 \ No newline at end of file 55 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/plugin/IotPluginInfoService.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/plugin/IotPluginConfigService.java
1 package cn.iocoder.yudao.module.iot.service.plugin; 1 package cn.iocoder.yudao.module.iot.service.plugin;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 -import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.info.PluginInfoPageReqVO;  
5 -import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.info.PluginInfoSaveReqVO;  
6 -import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginInfoDO; 4 +import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config.PluginConfigPageReqVO;
  5 +import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config.PluginConfigSaveReqVO;
  6 +import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginConfigDO;
  7 +import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginDeployTypeEnum;
7 import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginStatusEnum; 8 import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginStatusEnum;
8 import jakarta.validation.Valid; 9 import jakarta.validation.Valid;
9 import jakarta.validation.constraints.NotEmpty; 10 import jakarta.validation.constraints.NotEmpty;
@@ -12,49 +13,49 @@ import org.springframework.web.multipart.MultipartFile; @@ -12,49 +13,49 @@ import org.springframework.web.multipart.MultipartFile;
12 import java.util.List; 13 import java.util.List;
13 14
14 /** 15 /**
15 - * IoT 插件信息 Service 接口 16 + * IoT 插件配置 Service 接口
16 * 17 *
17 * @author haohao 18 * @author haohao
18 */ 19 */
19 -public interface IotPluginInfoService { 20 +public interface IotPluginConfigService {
20 21
21 /** 22 /**
22 - * 创建插件信息 23 + * 创建插件配置
23 * 24 *
24 * @param createReqVO 创建信息 25 * @param createReqVO 创建信息
25 * @return 编号 26 * @return 编号
26 */ 27 */
27 - Long createPluginInfo(@Valid PluginInfoSaveReqVO createReqVO); 28 + Long createPluginConfig(@Valid PluginConfigSaveReqVO createReqVO);
28 29
29 /** 30 /**
30 - * 更新插件信息 31 + * 更新插件配置
31 * 32 *
32 * @param updateReqVO 更新信息 33 * @param updateReqVO 更新信息
33 */ 34 */
34 - void updatePluginInfo(@Valid PluginInfoSaveReqVO updateReqVO); 35 + void updatePluginConfig(@Valid PluginConfigSaveReqVO updateReqVO);
35 36
36 /** 37 /**
37 - * 删除插件信息 38 + * 删除插件配置
38 * 39 *
39 * @param id 编号 40 * @param id 编号
40 */ 41 */
41 - void deletePluginInfo(Long id); 42 + void deletePluginConfig(Long id);
42 43
43 /** 44 /**
44 - * 获得插件信息 45 + * 获得插件配置
45 * 46 *
46 * @param id 编号 47 * @param id 编号
47 - * @return 插件信息 48 + * @return 插件配置
48 */ 49 */
49 - IotPluginInfoDO getPluginInfo(Long id); 50 + IotPluginConfigDO getPluginConfig(Long id);
50 51
51 /** 52 /**
52 - * 获得插件信息分页 53 + * 获得插件配置分页
53 * 54 *
54 * @param pageReqVO 分页查询 55 * @param pageReqVO 分页查询
55 - * @return 插件信息分页 56 + * @return 插件配置分页
56 */ 57 */
57 - PageResult<IotPluginInfoDO> getPluginInfoPage(PluginInfoPageReqVO pageReqVO); 58 + PageResult<IotPluginConfigDO> getPluginConfigPage(PluginConfigPageReqVO pageReqVO);
58 59
59 /** 60 /**
60 * 上传插件的 JAR 包 61 * 上传插件的 JAR 包
@@ -73,20 +74,27 @@ public interface IotPluginInfoService { @@ -73,20 +74,27 @@ public interface IotPluginInfoService {
73 void updatePluginStatus(Long id, Integer status); 74 void updatePluginStatus(Long id, Integer status);
74 75
75 /** 76 /**
76 - * 获得插件信息列表 77 + * 获得插件配置列表
77 * 78 *
78 - * @return 插件信息列表 79 + * @return 插件配置列表
79 */ 80 */
80 - List<IotPluginInfoDO> getPluginInfoList(); 81 + List<IotPluginConfigDO> getPluginConfigList();
81 82
82 /** 83 /**
83 - * 根据状态获得插件信息列表 84 + * 根据状态和部署类型获得插件配置列表
84 * 85 *
85 - * @param status 状态 {@link IotPluginStatusEnum}  
86 - * @return 插件信息列表 86 + * @param status 状态 {@link IotPluginStatusEnum}
  87 + * @param deployType 部署类型 {@link IotPluginDeployTypeEnum}
  88 + * @return 插件配置列表
87 */ 89 */
88 - List<IotPluginInfoDO> getPluginInfoListByStatus(Integer status); 90 + List<IotPluginConfigDO> getPluginConfigListByStatusAndDeployType(Integer status, Integer deployType);
89 91
90 - IotPluginInfoDO getPluginInfoByPluginKey(@NotEmpty(message = "插件包标识符不能为空") String pluginKey); 92 + /**
  93 + * 根据插件包标识符获取插件配置
  94 + *
  95 + * @param pluginKey 插件包标识符
  96 + * @return 插件配置
  97 + */
  98 + IotPluginConfigDO getPluginConfigByPluginKey(@NotEmpty(message = "插件包标识符不能为空") String pluginKey);
91 99
92 } 100 }
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/plugin/IotPluginConfigServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.service.plugin;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  5 +import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config.PluginConfigPageReqVO;
  6 +import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config.PluginConfigSaveReqVO;
  7 +import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginConfigDO;
  8 +import cn.iocoder.yudao.module.iot.dal.mysql.plugin.IotPluginConfigMapper;
  9 +import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginStatusEnum;
  10 +import jakarta.annotation.Resource;
  11 +import lombok.extern.slf4j.Slf4j;
  12 +import org.pf4j.PluginWrapper;
  13 +import org.pf4j.spring.SpringPluginManager;
  14 +import org.springframework.stereotype.Service;
  15 +import org.springframework.validation.annotation.Validated;
  16 +import org.springframework.web.multipart.MultipartFile;
  17 +
  18 +import java.util.List;
  19 +
  20 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  21 +import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*;
  22 +/**
  23 + * IoT 插件配置 Service 实现类
  24 + *
  25 + * @author haohao
  26 + */
  27 +@Service
  28 +@Validated
  29 +@Slf4j
  30 +public class IotPluginConfigServiceImpl implements IotPluginConfigService {
  31 +
  32 + @Resource
  33 + private IotPluginConfigMapper pluginConfigMapper;
  34 +
  35 + @Resource
  36 + private IotPluginInstanceService pluginInstanceService;
  37 +
  38 + @Resource
  39 + private SpringPluginManager springPluginManager;
  40 +
  41 + @Override
  42 + public Long createPluginConfig(PluginConfigSaveReqVO createReqVO) {
  43 + // 1. 校验插件标识唯一性:确保没有其他配置使用相同的 pluginKey(新建时 id 为 null)
  44 + validatePluginKeyUnique(null, createReqVO.getPluginKey());
  45 + IotPluginConfigDO pluginConfig = BeanUtils.toBean(createReqVO, IotPluginConfigDO.class);
  46 + // 2. 插入插件配置到数据库
  47 + pluginConfigMapper.insert(pluginConfig);
  48 + return pluginConfig.getId();
  49 + }
  50 +
  51 + @Override
  52 + public void updatePluginConfig(PluginConfigSaveReqVO updateReqVO) {
  53 + // 1. 校验插件配置是否存在:根据传入 ID 判断记录是否存在
  54 + validatePluginConfigExists(updateReqVO.getId());
  55 + // 2. 校验插件标识唯一性:确保更新后的 pluginKey 没有被其他记录占用
  56 + validatePluginKeyUnique(updateReqVO.getId(), updateReqVO.getPluginKey());
  57 + // 3. 将更新请求对象转换为插件配置数据对象
  58 + IotPluginConfigDO updateObj = BeanUtils.toBean(updateReqVO, IotPluginConfigDO.class);
  59 + pluginConfigMapper.updateById(updateObj);
  60 + }
  61 +
  62 + /**
  63 + * 校验插件标识唯一性
  64 + *
  65 + * @param id 当前插件配置的 ID(如果为 null 则说明为新建操作)
  66 + * @param pluginKey 待校验的插件标识
  67 + */
  68 + private void validatePluginKeyUnique(Long id, String pluginKey) {
  69 + // 1. 根据 pluginKey 从数据库中查询已有的插件配置
  70 + IotPluginConfigDO pluginConfig = pluginConfigMapper.selectByPluginKey(pluginKey);
  71 + // 2. 如果查询到记录且记录的 ID 与当前 ID 不相同,则认为存在重复,抛出异常
  72 + if (pluginConfig != null && !pluginConfig.getId().equals(id)) {
  73 + throw exception(PLUGIN_CONFIG_KEY_DUPLICATE);
  74 + }
  75 + }
  76 +
  77 + @Override
  78 + public void deletePluginConfig(Long id) {
  79 + // 1. 校验存在
  80 + IotPluginConfigDO pluginConfigDO = validatePluginConfigExists(id);
  81 + // 2. 未开启状态,才允许删除
  82 + if (IotPluginStatusEnum.RUNNING.getStatus().equals(pluginConfigDO.getStatus())) {
  83 + throw exception(PLUGIN_CONFIG_DELETE_FAILED_RUNNING);
  84 + }
  85 +
  86 + // 3. 卸载插件
  87 + pluginInstanceService.stopAndUnloadPlugin(pluginConfigDO.getPluginKey());
  88 + // 4. 删除插件文件
  89 + pluginInstanceService.deletePluginFile(pluginConfigDO);
  90 +
  91 + // 5. 删除插件配置
  92 + pluginConfigMapper.deleteById(id);
  93 + }
  94 +
  95 + /**
  96 + * 校验插件配置是否存在
  97 + *
  98 + * @param id 插件配置编号
  99 + * @return 插件配置
  100 + */
  101 + private IotPluginConfigDO validatePluginConfigExists(Long id) {
  102 + IotPluginConfigDO pluginConfig = pluginConfigMapper.selectById(id);
  103 + if (pluginConfig == null) {
  104 + throw exception(PLUGIN_CONFIG_NOT_EXISTS);
  105 + }
  106 + return pluginConfig;
  107 + }
  108 +
  109 + @Override
  110 + public IotPluginConfigDO getPluginConfig(Long id) {
  111 + return pluginConfigMapper.selectById(id);
  112 + }
  113 +
  114 + @Override
  115 + public PageResult<IotPluginConfigDO> getPluginConfigPage(PluginConfigPageReqVO pageReqVO) {
  116 + return pluginConfigMapper.selectPage(pageReqVO);
  117 + }
  118 +
  119 + @Override
  120 + public void uploadFile(Long id, MultipartFile file) {
  121 + // 1. 校验插件配置是否存在
  122 + IotPluginConfigDO pluginConfigDO = validatePluginConfigExists(id);
  123 +
  124 + // 2.1 停止并卸载旧的插件
  125 + pluginInstanceService.stopAndUnloadPlugin(pluginConfigDO.getPluginKey());
  126 + // 2.2 上传新的插件文件,更新插件启用状态文件
  127 + String pluginKeyNew = pluginInstanceService.uploadAndLoadNewPlugin(file);
  128 +
  129 + // 3. 校验 file 相关参数,是否完整
  130 + validatePluginConfigFile(pluginKeyNew);
  131 +
  132 + // 4. 更新插件配置
  133 + IotPluginConfigDO updatedPluginConfig = new IotPluginConfigDO()
  134 + .setId(pluginConfigDO.getId())
  135 + .setPluginKey(pluginKeyNew)
  136 + .setStatus(IotPluginStatusEnum.STOPPED.getStatus()) // TODO @haohao:这个状态,是不是非 stop 哈?
  137 + .setFileName(file.getOriginalFilename())
  138 + .setScript("") // TODO @haohao:这个设置为 "" 会不会覆盖数据里的哈?应该从插件里读取?未来?
  139 + .setConfigSchema(springPluginManager.getPlugin(pluginKeyNew).getDescriptor().getPluginDescription())
  140 + .setVersion(springPluginManager.getPlugin(pluginKeyNew).getDescriptor().getVersion())
  141 + .setDescription(springPluginManager.getPlugin(pluginKeyNew).getDescriptor().getPluginDescription());
  142 + pluginConfigMapper.updateById(updatedPluginConfig);
  143 + }
  144 +
  145 + /**
  146 + * 校验 file 相关参数
  147 + *
  148 + * @param pluginKeyNew 插件标识符
  149 + */
  150 + private void validatePluginConfigFile(String pluginKeyNew) {
  151 + // TODO @haohao:校验 file 相关参数,是否完整,类似:version 之类是不是可以解析到
  152 + PluginWrapper plugin = springPluginManager.getPlugin(pluginKeyNew);
  153 + if (plugin == null) {
  154 + throw exception(PLUGIN_INSTALL_FAILED);
  155 + }
  156 + if (plugin.getDescriptor().getVersion() == null) {
  157 + throw exception(PLUGIN_INSTALL_FAILED);
  158 + }
  159 + }
  160 +
  161 + @Override
  162 + public void updatePluginStatus(Long id, Integer status) {
  163 + // 1. 校验插件配置是否存在
  164 + IotPluginConfigDO pluginConfigDo = validatePluginConfigExists(id);
  165 +
  166 + // 2. 更新插件状态
  167 + pluginInstanceService.updatePluginStatus(pluginConfigDo, status);
  168 +
  169 + // 3. 更新数据库中的插件状态
  170 + pluginConfigMapper.updateById(new IotPluginConfigDO().setId(id).setStatus(status));
  171 + }
  172 +
  173 + @Override
  174 + public List<IotPluginConfigDO> getPluginConfigList() {
  175 + return pluginConfigMapper.selectList();
  176 + }
  177 +
  178 + @Override
  179 + public List<IotPluginConfigDO> getPluginConfigListByStatusAndDeployType(Integer status, Integer deployType) {
  180 + return pluginConfigMapper.selectListByStatusAndDeployType(status, deployType);
  181 + }
  182 +
  183 + @Override
  184 + public IotPluginConfigDO getPluginConfigByPluginKey(String pluginKey) {
  185 + return pluginConfigMapper.selectByPluginKey(pluginKey);
  186 + }
  187 +
  188 +}
0 \ No newline at end of file 189 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/plugin/IotPluginInfoServiceImpl.java deleted
1 -package cn.iocoder.yudao.module.iot.service.plugin;  
2 -  
3 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
4 -import cn.iocoder.yudao.framework.common.util.object.BeanUtils;  
5 -import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.info.PluginInfoPageReqVO;  
6 -import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.info.PluginInfoSaveReqVO;  
7 -import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginInfoDO;  
8 -import cn.iocoder.yudao.module.iot.dal.mysql.plugin.IotPluginInfoMapper;  
9 -import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginStatusEnum;  
10 -import jakarta.annotation.Resource;  
11 -import lombok.extern.slf4j.Slf4j;  
12 -import org.pf4j.spring.SpringPluginManager;  
13 -import org.springframework.stereotype.Service;  
14 -import org.springframework.validation.annotation.Validated;  
15 -import org.springframework.web.multipart.MultipartFile;  
16 -  
17 -import java.util.List;  
18 -  
19 -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;  
20 -import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.PLUGIN_INFO_DELETE_FAILED_RUNNING;  
21 -import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.PLUGIN_INFO_NOT_EXISTS;  
22 -  
23 -/**  
24 - * IoT 插件信息 Service 实现类  
25 - *  
26 - * @author haohao  
27 - */  
28 -@Service  
29 -@Validated  
30 -@Slf4j  
31 -public class IotPluginInfoServiceImpl implements IotPluginInfoService {  
32 -  
33 - @Resource  
34 - private IotPluginInfoMapper pluginInfoMapper;  
35 -  
36 - @Resource  
37 - private IotPluginInstanceService pluginInstanceService;  
38 -  
39 - @Resource  
40 - private SpringPluginManager springPluginManager;  
41 -  
42 - @Override  
43 - public Long createPluginInfo(PluginInfoSaveReqVO createReqVO) {  
44 - // TODO @haohao:pluginKey 唯一值  
45 - IotPluginInfoDO pluginInfo = BeanUtils.toBean(createReqVO, IotPluginInfoDO.class);  
46 - pluginInfoMapper.insert(pluginInfo);  
47 - return pluginInfo.getId();  
48 - }  
49 -  
50 - @Override  
51 - public void updatePluginInfo(PluginInfoSaveReqVO updateReqVO) {  
52 - // 校验存在  
53 - validatePluginInfoExists(updateReqVO.getId());  
54 - // 更新  
55 - IotPluginInfoDO updateObj = BeanUtils.toBean(updateReqVO, IotPluginInfoDO.class);  
56 - pluginInfoMapper.updateById(updateObj);  
57 - }  
58 -  
59 - @Override  
60 - public void deletePluginInfo(Long id) {  
61 - // 1.1 校验存在  
62 - IotPluginInfoDO pluginInfoDO = validatePluginInfoExists(id);  
63 - // 1.2 未开启状态,才允许删除  
64 - if (IotPluginStatusEnum.RUNNING.getStatus().equals(pluginInfoDO.getStatus())) {  
65 - throw exception(PLUGIN_INFO_DELETE_FAILED_RUNNING);  
66 - }  
67 -  
68 - // 2.1 卸载插件  
69 - pluginInstanceService.stopAndUnloadPlugin(pluginInfoDO.getPluginKey());  
70 - // 2.2 删除插件文件  
71 - pluginInstanceService.deletePluginFile(pluginInfoDO);  
72 -  
73 - // 3. 删除插件信息  
74 - pluginInfoMapper.deleteById(id);  
75 - }  
76 -  
77 - private IotPluginInfoDO validatePluginInfoExists(Long id) {  
78 - IotPluginInfoDO pluginInfo = pluginInfoMapper.selectById(id);  
79 - if (pluginInfo == null) {  
80 - throw exception(PLUGIN_INFO_NOT_EXISTS);  
81 - }  
82 - return pluginInfo;  
83 - }  
84 -  
85 - @Override  
86 - public IotPluginInfoDO getPluginInfo(Long id) {  
87 - return pluginInfoMapper.selectById(id);  
88 - }  
89 -  
90 - @Override  
91 - public PageResult<IotPluginInfoDO> getPluginInfoPage(PluginInfoPageReqVO pageReqVO) {  
92 - return pluginInfoMapper.selectPage(pageReqVO);  
93 - }  
94 -  
95 - @Override  
96 - public void uploadFile(Long id, MultipartFile file) {  
97 - // 1. 校验插件信息是否存在  
98 - IotPluginInfoDO pluginInfoDo = validatePluginInfoExists(id);  
99 - // TODO @haohao:最好校验下 file 相关参数,是否完整,类似:version 之类是不是可以解析到  
100 -  
101 - // 2.1 停止并卸载旧的插件  
102 - pluginInstanceService.stopAndUnloadPlugin(pluginInfoDo.getPluginKey());  
103 - // 2.2 上传新的插件文件,更新插件启用状态文件  
104 - String pluginKeyNew = pluginInstanceService.uploadAndLoadNewPlugin(file);  
105 -  
106 - // 3. 更新插件信息  
107 - updatePluginInfo(pluginInfoDo, pluginKeyNew, file);  
108 - }  
109 -  
110 - // TODO @haohao:这个方法,要不合并到 uploadFile 里;  
111 - /**  
112 - * 更新插件信息  
113 - *  
114 - * @param pluginInfoDo 插件信息  
115 - * @param pluginKeyNew 插件标识符  
116 - * @param file 文件  
117 - */  
118 - private void updatePluginInfo(IotPluginInfoDO pluginInfoDo, String pluginKeyNew, MultipartFile file) {  
119 - IotPluginInfoDO updatedPluginInfo = new IotPluginInfoDO()  
120 - .setId(pluginInfoDo.getId())  
121 - .setPluginKey(pluginKeyNew)  
122 - .setStatus(IotPluginStatusEnum.STOPPED.getStatus()) // TODO @haohao:这个状态,是不是非 stop 哈?  
123 - .setFileName(file.getOriginalFilename())  
124 - .setScript("") // TODO @haohao:这个设置为 "" 会不会覆盖数据里的哈?应该从插件里读取?未来?  
125 - .setConfigSchema(springPluginManager.getPlugin(pluginKeyNew).getDescriptor().getPluginDescription())  
126 - .setVersion(springPluginManager.getPlugin(pluginKeyNew).getDescriptor().getVersion())  
127 - .setDescription(springPluginManager.getPlugin(pluginKeyNew).getDescriptor().getPluginDescription());  
128 - pluginInfoMapper.updateById(updatedPluginInfo);  
129 - }  
130 -  
131 - @Override  
132 - public void updatePluginStatus(Long id, Integer status) {  
133 - // 1. 校验插件信息是否存在  
134 - IotPluginInfoDO pluginInfoDo = validatePluginInfoExists(id);  
135 -  
136 - // 2. 更新插件状态  
137 - pluginInstanceService.updatePluginStatus(pluginInfoDo, status);  
138 -  
139 - // 3. 更新数据库中的插件状态  
140 - pluginInfoMapper.updateById(new IotPluginInfoDO().setId(id).setStatus(status));  
141 - }  
142 -  
143 - @Override  
144 - public List<IotPluginInfoDO> getPluginInfoList() {  
145 - return pluginInfoMapper.selectList();  
146 - }  
147 -  
148 - @Override  
149 - public List<IotPluginInfoDO> getPluginInfoListByStatus(Integer status) {  
150 - return pluginInfoMapper.selectListByStatus(status);  
151 - }  
152 -  
153 - @Override  
154 - public IotPluginInfoDO getPluginInfoByPluginKey(String pluginKey) {  
155 - return pluginInfoMapper.selectByPluginKey(pluginKey);  
156 - }  
157 -  
158 -}  
159 \ 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/service/plugin/IotPluginInstanceService.java
1 package cn.iocoder.yudao.module.iot.service.plugin; 1 package cn.iocoder.yudao.module.iot.service.plugin;
2 2
3 import cn.iocoder.yudao.module.iot.api.device.dto.control.upstream.IotPluginInstanceHeartbeatReqDTO; 3 import cn.iocoder.yudao.module.iot.api.device.dto.control.upstream.IotPluginInstanceHeartbeatReqDTO;
4 -import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginInfoDO; 4 +import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginConfigDO;
5 import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginInstanceDO; 5 import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginInstanceDO;
6 import org.springframework.web.multipart.MultipartFile; 6 import org.springframework.web.multipart.MultipartFile;
7 7
@@ -38,9 +38,9 @@ public interface IotPluginInstanceService { @@ -38,9 +38,9 @@ public interface IotPluginInstanceService {
38 /** 38 /**
39 * 删除插件文件 39 * 删除插件文件
40 * 40 *
41 - * @param pluginInfoDo 插件信息 41 + * @param pluginConfigDO 插件配置
42 */ 42 */
43 - void deletePluginFile(IotPluginInfoDO pluginInfoDo); 43 + void deletePluginFile(IotPluginConfigDO pluginConfigDO);
44 44
45 /** 45 /**
46 * 上传并加载新的插件文件 46 * 上传并加载新的插件文件
@@ -53,10 +53,10 @@ public interface IotPluginInstanceService { @@ -53,10 +53,10 @@ public interface IotPluginInstanceService {
53 /** 53 /**
54 * 更新插件状态 54 * 更新插件状态
55 * 55 *
56 - * @param pluginInfoDo 插件信息 56 + * @param pluginConfigDO 插件配置
57 * @param status 新状态 57 * @param status 新状态
58 */ 58 */
59 - void updatePluginStatus(IotPluginInfoDO pluginInfoDo, Integer status); 59 + void updatePluginStatus(IotPluginConfigDO pluginConfigDO, Integer status);
60 60
61 // ========== 设备与插件的映射操作 ========== 61 // ========== 设备与插件的映射操作 ==========
62 62
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/plugin/IotPluginInstanceServiceImpl.java
@@ -4,7 +4,7 @@ import cn.hutool.core.collection.CollUtil; @@ -4,7 +4,7 @@ import cn.hutool.core.collection.CollUtil;
4 import cn.hutool.core.io.FileUtil; 4 import cn.hutool.core.io.FileUtil;
5 import cn.hutool.core.util.StrUtil; 5 import cn.hutool.core.util.StrUtil;
6 import cn.iocoder.yudao.module.iot.api.device.dto.control.upstream.IotPluginInstanceHeartbeatReqDTO; 6 import cn.iocoder.yudao.module.iot.api.device.dto.control.upstream.IotPluginInstanceHeartbeatReqDTO;
7 -import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginInfoDO; 7 +import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginConfigDO;
8 import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginInstanceDO; 8 import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginInstanceDO;
9 import cn.iocoder.yudao.module.iot.dal.mysql.plugin.IotPluginInstanceMapper; 9 import cn.iocoder.yudao.module.iot.dal.mysql.plugin.IotPluginInstanceMapper;
10 import cn.iocoder.yudao.module.iot.dal.redis.plugin.DevicePluginProcessIdRedisDAO; 10 import cn.iocoder.yudao.module.iot.dal.redis.plugin.DevicePluginProcessIdRedisDAO;
@@ -45,7 +45,7 @@ public class IotPluginInstanceServiceImpl implements IotPluginInstanceService { @@ -45,7 +45,7 @@ public class IotPluginInstanceServiceImpl implements IotPluginInstanceService {
45 45
46 @Resource 46 @Resource
47 @Lazy // 延迟加载,避免循环依赖 47 @Lazy // 延迟加载,避免循环依赖
48 - private IotPluginInfoService pluginInfoService; 48 + private IotPluginConfigService pluginConfigService;
49 49
50 @Resource 50 @Resource
51 private IotPluginInstanceMapper pluginInstanceMapper; 51 private IotPluginInstanceMapper pluginInstanceMapper;
@@ -79,7 +79,7 @@ public class IotPluginInstanceServiceImpl implements IotPluginInstanceService { @@ -79,7 +79,7 @@ public class IotPluginInstanceServiceImpl implements IotPluginInstanceService {
79 } 79 }
80 80
81 // 情况二:不存在,则创建 81 // 情况二:不存在,则创建
82 - IotPluginInfoDO info = pluginInfoService.getPluginInfoByPluginKey(heartbeatReqDTO.getPluginKey()); 82 + IotPluginConfigDO info = pluginConfigService.getPluginConfigByPluginKey(heartbeatReqDTO.getPluginKey());
83 if (info == null) { 83 if (info == null) {
84 log.error("[heartbeatPluginInstance][心跳({}) 对应的插件不存在]", heartbeatReqDTO); 84 log.error("[heartbeatPluginInstance][心跳({}) 对应的插件不存在]", heartbeatReqDTO);
85 return; 85 return;
@@ -129,18 +129,18 @@ public class IotPluginInstanceServiceImpl implements IotPluginInstanceService { @@ -129,18 +129,18 @@ public class IotPluginInstanceServiceImpl implements IotPluginInstanceService {
129 } 129 }
130 130
131 @Override 131 @Override
132 - public void deletePluginFile(IotPluginInfoDO pluginInfoDO) {  
133 - File file = new File(pluginsDir, pluginInfoDO.getFileName()); 132 + public void deletePluginFile(IotPluginConfigDO pluginConfigDO) {
  133 + File file = new File(pluginsDir, pluginConfigDO.getFileName());
134 if (!file.exists()) { 134 if (!file.exists()) {
135 return; 135 return;
136 } 136 }
137 try { 137 try {
138 TimeUnit.SECONDS.sleep(1); // 等待 1 秒,避免插件未卸载完毕 138 TimeUnit.SECONDS.sleep(1); // 等待 1 秒,避免插件未卸载完毕
139 if (!file.delete()) { 139 if (!file.delete()) {
140 - log.error("[deletePluginInfo][删除插件文件({}) 失败]", pluginInfoDO.getFileName()); 140 + log.error("[deletePluginFile][删除插件文件({}) 失败]", pluginConfigDO.getFileName());
141 } 141 }
142 } catch (InterruptedException e) { 142 } catch (InterruptedException e) {
143 - log.error("[deletePluginInfo][删除插件文件({}) 失败]", pluginInfoDO.getFileName(), e); 143 + log.error("[deletePluginFile][删除插件文件({}) 失败]", pluginConfigDO.getFileName(), e);
144 } 144 }
145 } 145 }
146 146
@@ -171,13 +171,13 @@ public class IotPluginInstanceServiceImpl implements IotPluginInstanceService { @@ -171,13 +171,13 @@ public class IotPluginInstanceServiceImpl implements IotPluginInstanceService {
171 } 171 }
172 172
173 @Override 173 @Override
174 - public void updatePluginStatus(IotPluginInfoDO pluginInfoDo, Integer status) {  
175 - String pluginKey = pluginInfoDo.getPluginKey(); 174 + public void updatePluginStatus(IotPluginConfigDO pluginConfigDO, Integer status) {
  175 + String pluginKey = pluginConfigDO.getPluginKey();
176 PluginWrapper plugin = pluginManager.getPlugin(pluginKey); 176 PluginWrapper plugin = pluginManager.getPlugin(pluginKey);
177 177
178 if (plugin == null) { 178 if (plugin == null) {
179 // 插件不存在且状态为停止,抛出异常 179 // 插件不存在且状态为停止,抛出异常
180 - if (IotPluginStatusEnum.STOPPED.getStatus().equals(pluginInfoDo.getStatus())) { 180 + if (IotPluginStatusEnum.STOPPED.getStatus().equals(pluginConfigDO.getStatus())) {
181 throw exception(ErrorCodeConstants.PLUGIN_STATUS_INVALID); 181 throw exception(ErrorCodeConstants.PLUGIN_STATUS_INVALID);
182 } 182 }
183 return; 183 return;
yudao-server/pom.xml
@@ -109,11 +109,11 @@ @@ -109,11 +109,11 @@
109 <!-- </dependency>--> 109 <!-- </dependency>-->
110 110
111 <!-- IoT 物联网相关模块。默认注释,保证编译速度 --> 111 <!-- IoT 物联网相关模块。默认注释,保证编译速度 -->
112 -<!-- <dependency>-->  
113 -<!-- <groupId>cn.iocoder.boot</groupId>-->  
114 -<!-- <artifactId>yudao-module-iot-biz</artifactId>-->  
115 -<!-- <version>${revision}</version>-->  
116 -<!-- </dependency>--> 112 + <dependency>
  113 + <groupId>cn.iocoder.boot</groupId>
  114 + <artifactId>yudao-module-iot-biz</artifactId>
  115 + <version>${revision}</version>
  116 + </dependency>
117 117
118 <!-- spring boot 配置所需依赖 --> 118 <!-- spring boot 配置所需依赖 -->
119 <dependency> 119 <dependency>