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 24 <!-- <module>yudao-module-crm</module>-->
25 25 <!-- <module>yudao-module-erp</module>-->
26 26 <!-- <module>yudao-module-ai</module>-->
27   -<!-- <module>yudao-module-iot</module>-->
  27 + <module>yudao-module-iot</module>
28 28 </modules>
29 29  
30 30 <name>${project.artifactId}</name>
... ...
yudao-framework/yudao-spring-boot-starter-mybatis/pom.xml
... ... @@ -63,6 +63,10 @@
63 63 <artifactId>opengauss-jdbc</artifactId>
64 64 <optional>true</optional>
65 65 </dependency>
  66 + <dependency>
  67 + <groupId>com.taosdata.jdbc</groupId>
  68 + <artifactId>taos-jdbcdriver</artifactId>
  69 + </dependency>
66 70  
67 71 <dependency>
68 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 39 ErrorCode DEVICE_GROUP_NOT_EXISTS = new ErrorCode(1_050_005_000, "设备分组不存在");
40 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 44 ErrorCode PLUGIN_INSTALL_FAILED = new ErrorCode(1_050_006_001, "插件安装失败");
45 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 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 50 // ========== 插件实例 1-050-007-000 ==========
50 51  
... ...
yudao-module-iot/yudao-module-iot-biz/pom.xml
... ... @@ -52,11 +52,6 @@
52 52 <artifactId>yudao-spring-boot-starter-redis</artifactId>
53 53 </dependency>
54 54  
55   - <dependency>
56   - <groupId>com.taosdata.jdbc</groupId>
57   - <artifactId>taos-jdbcdriver</artifactId>
58   - </dependency>
59   -
60 55 <!-- Test 测试相关 -->
61 56 <dependency>
62 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 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 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 3 import io.swagger.v3.oas.annotations.media.Schema;
4 4 import jakarta.validation.constraints.NotNull;
... ... @@ -7,7 +7,7 @@ import org.springframework.web.multipart.MultipartFile;
7 7  
8 8 @Schema(description = "管理后台 - IoT 插件上传 Request VO")
9 9 @Data
10   -public class PluginInfoImportReqVO {
  10 +public class PluginConfigImportReqVO {
11 11  
12 12 @Schema(description = "主键 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "11546")
13 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 3 import cn.iocoder.yudao.framework.common.pojo.PageParam;
4 4 import cn.iocoder.yudao.framework.common.validation.InEnum;
... ... @@ -6,9 +6,9 @@ import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginStatusEnum;
6 6 import io.swagger.v3.oas.annotations.media.Schema;
7 7 import lombok.Data;
8 8  
9   -@Schema(description = "管理后台 - IoT 插件信息分页 Request VO")
  9 +@Schema(description = "管理后台 - IoT 插件配置分页 Request VO")
10 10 @Data
11   -public class PluginInfoPageReqVO extends PageParam {
  11 +public class PluginConfigPageReqVO extends PageParam {
12 12  
13 13 @Schema(description = "插件名称", example = "http")
14 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 3 import io.swagger.v3.oas.annotations.media.Schema;
4 4 import lombok.Data;
5 5  
6 6 import java.time.LocalDateTime;
7 7  
8   -@Schema(description = "管理后台 - IoT 插件信息 Response VO")
  8 +@Schema(description = "管理后台 - IoT 插件配置 Response VO")
9 9 @Data
10   -public class PluginInfoRespVO {
  10 +public class PluginConfigRespVO {
11 11  
12 12 @Schema(description = "主键 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "11546")
13 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 3 import cn.iocoder.yudao.framework.common.validation.InEnum;
4 4 import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginStatusEnum;
5 5 import io.swagger.v3.oas.annotations.media.Schema;
6 6 import lombok.Data;
7 7  
8   -@Schema(description = "管理后台 - IoT 插件信息新增/修改 Request VO")
  8 +@Schema(description = "管理后台 - IoT 插件配置新增/修改 Request VO")
9 9 @Data
10   -public class PluginInfoSaveReqVO {
  10 +public class PluginConfigSaveReqVO {
11 11  
12 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 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 1 package cn.iocoder.yudao.module.iot.dal.dataobject.plugin;
2 2  
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
3 4 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
4 5 import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginDeployTypeEnum;
5 6 import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginStatusEnum;
... ... @@ -9,21 +10,20 @@ import com.baomidou.mybatisplus.annotation.TableId;
9 10 import com.baomidou.mybatisplus.annotation.TableName;
10 11 import lombok.*;
11 12  
12   -// TODO @haohao:建议 IotPluginInfoDO 改成 IotPluginConfigDO,插件配置。项目里,暂时没有用 info 作为配置的哈。
13 13 /**
14   - * IoT 插件信息 DO
  14 + * IoT 插件配置 DO
15 15 *
16 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 20 @Data
21 21 @EqualsAndHashCode(callSuper = true)
22 22 @ToString(callSuper = true)
23 23 @Builder
24 24 @NoArgsConstructor
25 25 @AllArgsConstructor
26   -public class IotPluginInfoDO extends BaseDO {
  26 +public class IotPluginConfigDO extends BaseDO {
27 27  
28 28 /**
29 29 * 主键 ID
... ... @@ -73,7 +73,7 @@ public class IotPluginInfoDO extends BaseDO {
73 73 /**
74 74 * 状态
75 75 * <p>
76   - * 枚举 {@link IotPluginStatusEnum}
  76 + * 枚举 {@link CommonStatusEnum}
77 77 */
78 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 31 /**
32 32 * 插件编号
33 33 * <p>
34   - * 关联 {@link IotPluginInfoDO#getId()}
  34 + * 关联 {@link IotPluginConfigDO#getId()}
35 35 */
36 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 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 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 2  
3 3 import cn.iocoder.yudao.module.iot.framework.plugin.core.IotPluginStartRunner;
4 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 6 import lombok.extern.slf4j.Slf4j;
7 7 import org.pf4j.spring.SpringPluginManager;
8 8 import org.springframework.beans.factory.annotation.Value;
... ... @@ -22,8 +22,8 @@ public class IotPluginConfiguration {
22 22  
23 23 @Bean
24 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 29 // TODO @芋艿:需要 review 下
... ... @@ -31,7 +31,6 @@ public class IotPluginConfiguration {
31 31 public SpringPluginManager pluginManager(@Value("${pf4j.pluginsDir:pluginsDir}") String pluginsDir) {
32 32 log.info("[init][实例化 SpringPluginManager]");
33 33 SpringPluginManager springPluginManager = new SpringPluginManager(Paths.get(pluginsDir)) {
34   -// SpringPluginManager springPluginManager = new SpringPluginManager() {
35 34  
36 35 @Override
37 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 2  
3 3 import cn.hutool.core.collection.CollUtil;
4 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 6 import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginDeployTypeEnum;
7 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 9 import lombok.RequiredArgsConstructor;
10 10 import lombok.extern.slf4j.Slf4j;
11 11 import org.pf4j.spring.SpringPluginManager;
... ... @@ -25,28 +25,29 @@ public class IotPluginStartRunner implements ApplicationRunner {
25 25  
26 26 private final SpringPluginManager springPluginManager;
27 27  
28   - private final IotPluginInfoService pluginInfoService;
  28 + private final IotPluginConfigService pluginConfigService;
29 29  
30 30 @Override
31 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 37 log.info("[run][没有需要启动的插件]");
37 38 return;
38 39 }
39 40  
40 41 // 遍历插件列表,逐个启动
41   - pluginInfoList.forEach(pluginInfo -> {
  42 + pluginConfigList.forEach(pluginConfig -> {
42 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 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 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 1 package cn.iocoder.yudao.module.iot.service.plugin;
2 2  
3 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 8 import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginStatusEnum;
8 9 import jakarta.validation.Valid;
9 10 import jakarta.validation.constraints.NotEmpty;
... ... @@ -12,49 +13,49 @@ import org.springframework.web.multipart.MultipartFile;
12 13 import java.util.List;
13 14  
14 15 /**
15   - * IoT 插件信息 Service 接口
  16 + * IoT 插件配置 Service 接口
16 17 *
17 18 * @author haohao
18 19 */
19   -public interface IotPluginInfoService {
  20 +public interface IotPluginConfigService {
20 21  
21 22 /**
22   - * 创建插件信息
  23 + * 创建插件配置
23 24 *
24 25 * @param createReqVO 创建信息
25 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 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 40 * @param id 编号
40 41 */
41   - void deletePluginInfo(Long id);
  42 + void deletePluginConfig(Long id);
42 43  
43 44 /**
44   - * 获得插件信息
  45 + * 获得插件配置
45 46 *
46 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 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 61 * 上传插件的 JAR 包
... ... @@ -73,20 +74,27 @@ public interface IotPluginInfoService {
73 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 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 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 1 package cn.iocoder.yudao.module.iot.service.plugin;
2 2  
3 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 5 import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginInstanceDO;
6 6 import org.springframework.web.multipart.MultipartFile;
7 7  
... ... @@ -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 53 /**
54 54 * 更新插件状态
55 55 *
56   - * @param pluginInfoDo 插件信息
  56 + * @param pluginConfigDO 插件配置
57 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 4 import cn.hutool.core.io.FileUtil;
5 5 import cn.hutool.core.util.StrUtil;
6 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 8 import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginInstanceDO;
9 9 import cn.iocoder.yudao.module.iot.dal.mysql.plugin.IotPluginInstanceMapper;
10 10 import cn.iocoder.yudao.module.iot.dal.redis.plugin.DevicePluginProcessIdRedisDAO;
... ... @@ -45,7 +45,7 @@ public class IotPluginInstanceServiceImpl implements IotPluginInstanceService {
45 45  
46 46 @Resource
47 47 @Lazy // 延迟加载,避免循环依赖
48   - private IotPluginInfoService pluginInfoService;
  48 + private IotPluginConfigService pluginConfigService;
49 49  
50 50 @Resource
51 51 private IotPluginInstanceMapper pluginInstanceMapper;
... ... @@ -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 83 if (info == null) {
84 84 log.error("[heartbeatPluginInstance][心跳({}) 对应的插件不存在]", heartbeatReqDTO);
85 85 return;
... ... @@ -129,18 +129,18 @@ public class IotPluginInstanceServiceImpl implements IotPluginInstanceService {
129 129 }
130 130  
131 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 134 if (!file.exists()) {
135 135 return;
136 136 }
137 137 try {
138 138 TimeUnit.SECONDS.sleep(1); // 等待 1 秒,避免插件未卸载完毕
139 139 if (!file.delete()) {
140   - log.error("[deletePluginInfo][删除插件文件({}) 失败]", pluginInfoDO.getFileName());
  140 + log.error("[deletePluginFile][删除插件文件({}) 失败]", pluginConfigDO.getFileName());
141 141 }
142 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 171 }
172 172  
173 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 176 PluginWrapper plugin = pluginManager.getPlugin(pluginKey);
177 177  
178 178 if (plugin == null) {
179 179 // 插件不存在且状态为停止,抛出异常
180   - if (IotPluginStatusEnum.STOPPED.getStatus().equals(pluginInfoDo.getStatus())) {
  180 + if (IotPluginStatusEnum.STOPPED.getStatus().equals(pluginConfigDO.getStatus())) {
181 181 throw exception(ErrorCodeConstants.PLUGIN_STATUS_INVALID);
182 182 }
183 183 return;
... ...
yudao-server/pom.xml
... ... @@ -109,11 +109,11 @@
109 109 <!-- </dependency>-->
110 110  
111 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 118 <!-- spring boot 配置所需依赖 -->
119 119 <dependency>
... ...