Kaynağa Gözat

update:迁移数据大屏模块

tangfudong 1 yıl önce
ebeveyn
işleme
2779fc269a
26 değiştirilmiş dosya ile 1388 ekleme ve 0 silme
  1. 13 0
      iot-common/iot-common-core/src/main/java/cc/iotkit/common/enums/ErrCode.java
  2. 47 0
      iot-common/iot-common-dao/iot-common-model/src/main/java/cc/iotkit/model/screen/Screen.java
  3. 49 0
      iot-common/iot-common-dao/iot-common-model/src/main/java/cc/iotkit/model/screen/ScreenApi.java
  4. 16 0
      iot-common/iot-common-dao/iot-data-service/src/main/java/cc/iotkit/data/manager/IScreenApiData.java
  5. 16 0
      iot-common/iot-common-dao/iot-data-service/src/main/java/cc/iotkit/data/manager/IScreenData.java
  6. 18 0
      iot-common/iot-common-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/ScreenApiRepository.java
  7. 18 0
      iot-common/iot-common-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/ScreenRepository.java
  8. 56 0
      iot-common/iot-common-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/model/TbScreen.java
  9. 59 0
      iot-common/iot-common-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/model/TbScreenApi.java
  10. 51 0
      iot-common/iot-common-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/ScreenApiDataImpl.java
  11. 56 0
      iot-common/iot-common-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/ScreenDataImpl.java
  12. 5 0
      iot-module/iot-manager/pom.xml
  13. 137 0
      iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/ScreenController.java
  14. 23 0
      iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/bo/screen/DebugChangeBo.java
  15. 29 0
      iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/bo/screen/PublishChangeBo.java
  16. 43 0
      iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/IScreenService.java
  17. 214 0
      iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/impl/ScreenServiceImpl.java
  18. 85 0
      iot-module/iot-screen/pom.xml
  19. 119 0
      iot-module/iot-screen/src/main/java/cc/iotkit/screen/ScreenManager.java
  20. 18 0
      iot-module/iot-screen/src/main/java/cc/iotkit/screen/api/HttpContent.java
  21. 138 0
      iot-module/iot-screen/src/main/java/cc/iotkit/screen/api/ScreenApiHandle.java
  22. 27 0
      iot-module/iot-screen/src/main/java/cc/iotkit/screen/config/ScreenConfig.java
  23. 76 0
      iot-module/iot-screen/src/main/java/cc/iotkit/screen/staticres/ScreenComponent.java
  24. 68 0
      iot-module/iot-screen/src/main/java/cc/iotkit/screen/staticres/ScreenVerticle.java
  25. 1 0
      iot-module/pom.xml
  26. 6 0
      pom.xml

+ 13 - 0
iot-common/iot-common-core/src/main/java/cc/iotkit/common/enums/ErrCode.java

@@ -46,10 +46,23 @@ public enum ErrCode implements IEnum {
     INIT_PRODUCER_ERROR(00000000, "初始化MQ生产者失败"),
     SEND_MSG_ERROR(00000000, "发送消息失败"),
 
+    /**
+     * 大屏通用异常段
+     * */
+    RESOURCE_FILE_NOT_FOUND(00000000, "资源包为空"),
+    BIG_SCREEN_NOT_FOUND(00000000, "大屏不存在"),
+    BIG_SCREEN_ALREADY(00000000, "大屏已存在"),
+    ADD_BIG_SCREEN_ERROR(00000000, "保存大屏失败"),
+    DELETE_BIG_SCREEN_ERROR(00000000, "删除大屏资源失败"),
+    SCREEN_API_NOT_FOUND(00000000, "大屏接口不存在"),
+    ADD_SCREEN_API_ERROR(00000000, "添加大屏接口失败"),
+    SCREEN_PUBLISH_ERROR(00000000, "大屏发布失败"),
+    API_LIST_BLANK(00000000, "接口列表为空"),
 
     /**
      * 业务通用异常段
      */
+    ID_BLANK(00000000, "ID为空"),
     TASK_NOT_SUPPORT_RENEW(00000000, "任务不支持续订"),
     GROUP_ALREADY(00000000, "分组已经存在"),
     GROUP_NOT_FOUND(00000000, "分组不存在"),

+ 47 - 0
iot-common/iot-common-dao/iot-common-model/src/main/java/cc/iotkit/model/screen/Screen.java

@@ -0,0 +1,47 @@
+package cc.iotkit.model.screen;
+
+import cc.iotkit.model.Owned;
+import lombok.Data;
+
+/**
+ * @Author:tfd
+ * @Date:2023/6/25 15:04
+ */
+@Data
+public class Screen implements Owned<Long> {
+
+    public static final String STATE_STOPPED = "stopped";
+    public static final String STATE_RUNNING = "running";
+
+    private Long id;
+    private String uid;
+    /**
+     * 大屏名称
+     */
+    private String name;
+
+    /**
+     * 资源文件
+     */
+    private String resourceFile;
+
+    /**
+     * 端口
+     */
+    private Integer port;
+
+    /**
+     * 发布状态
+     */
+    private String state;
+
+    /**
+     * 创建时间
+     */
+    private Long createAt;
+
+    /**
+     * 是否为默认大屏
+     */
+    private Boolean isDefault;
+}

+ 49 - 0
iot-common/iot-common-dao/iot-common-model/src/main/java/cc/iotkit/model/screen/ScreenApi.java

@@ -0,0 +1,49 @@
+package cc.iotkit.model.screen;
+
+import cc.iotkit.model.Owned;
+import lombok.Data;
+
+/**
+ * @Author:tfd
+ * @Date:2023/6/25 15:04
+ */
+@Data
+public class ScreenApi implements Owned<Long> {
+
+    private Long id;
+    private String uid;
+    /**
+     * 大屏id
+     */
+    private Long screenId;
+
+    /**
+     * 接口路径
+     */
+    private String apiPath;
+
+    /**
+     * 接口参数
+     */
+    private String apiParams;
+
+    /**
+     * 请求方法
+     */
+    private String httpMethod;
+
+    /**
+     * 数据源
+     */
+    private String dataSource;
+
+    /**
+     * 创建时间
+     */
+    private Long createAt;
+
+    /**
+     * 转换脚本
+     */
+    private String script;
+}

+ 16 - 0
iot-common/iot-common-dao/iot-data-service/src/main/java/cc/iotkit/data/manager/IScreenApiData.java

@@ -0,0 +1,16 @@
+package cc.iotkit.data.manager;
+
+import cc.iotkit.data.IOwnedData;
+import cc.iotkit.model.screen.ScreenApi;
+
+import java.util.List;
+
+/**
+ * @Author:tfd
+ * @Date:2023/6/25 15:34
+ */
+public interface IScreenApiData extends IOwnedData<ScreenApi, Long> {
+    List<ScreenApi> findByScreenId(Long id);
+
+    void deleteByScreenId(Long id);
+}

+ 16 - 0
iot-common/iot-common-dao/iot-data-service/src/main/java/cc/iotkit/data/manager/IScreenData.java

@@ -0,0 +1,16 @@
+package cc.iotkit.data.manager;
+
+import cc.iotkit.data.IOwnedData;
+import cc.iotkit.model.screen.Screen;
+
+import java.util.List;
+
+/**
+ * @Author:tfd
+ * @Date:2023/6/25 15:34
+ */
+public interface IScreenData extends IOwnedData<Screen, Long> {
+    Screen findByIsDefault(boolean isDefault);
+
+    List<Screen> findByState(String state);
+}

+ 18 - 0
iot-common/iot-common-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/ScreenApiRepository.java

@@ -0,0 +1,18 @@
+package cc.iotkit.data.dao;
+
+import cc.iotkit.data.model.TbScreenApi;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.querydsl.QuerydslPredicateExecutor;
+
+import java.util.List;
+
+/**
+ * @Author:tfd
+ * @Date:2023/6/25 15:23
+ */
+public interface ScreenApiRepository extends JpaRepository<TbScreenApi, Long>, QuerydslPredicateExecutor<TbScreenApi> {
+
+    List<TbScreenApi> findByScreenId(Long screenId);
+
+    void deleteByScreenId(Long screenId);
+}

+ 18 - 0
iot-common/iot-common-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/ScreenRepository.java

@@ -0,0 +1,18 @@
+package cc.iotkit.data.dao;
+
+import cc.iotkit.data.model.TbScreen;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.querydsl.QuerydslPredicateExecutor;
+
+import java.util.List;
+
+/**
+ * @Author:tfd
+ * @Date:2023/6/25 15:23
+ */
+public interface ScreenRepository extends JpaRepository<TbScreen, Long>, QuerydslPredicateExecutor<TbScreen> {
+
+    TbScreen findByIsDefault(boolean isDefault);
+
+    List<TbScreen> findByState(String state);
+}

+ 56 - 0
iot-common/iot-common-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/model/TbScreen.java

@@ -0,0 +1,56 @@
+package cc.iotkit.data.model;
+
+import cc.iotkit.model.screen.Screen;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import org.hibernate.annotations.GenericGenerator;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+/**
+ * @Author:tfd
+ * @Date:2023/6/25 15:02
+ */
+@Data
+@Entity
+@Table(name = "screen")
+@AutoMapper(target = Screen.class)
+public class TbScreen {
+
+    @Id
+    @GeneratedValue(generator = "SnowflakeIdGenerator")
+    @GenericGenerator(name = "SnowflakeIdGenerator", strategy = "cc.iotkit.data.config.id.SnowflakeIdGenerator")
+    private Long id;
+    /**
+     * 大屏名称
+     */
+    private String name;
+
+    /**
+     * 资源文件
+     */
+    private String resourceFile;
+
+    /**
+     * 端口
+     */
+    private Integer port;
+
+    /**
+     * 发布状态
+     */
+    private String state;
+
+    /**
+     * 创建时间
+     */
+    private Long createAt;
+
+    /**
+     * 是否为默认大屏
+     */
+    private Boolean isDefault;
+}

+ 59 - 0
iot-common/iot-common-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/model/TbScreenApi.java

@@ -0,0 +1,59 @@
+package cc.iotkit.data.model;
+
+import cc.iotkit.model.screen.ScreenApi;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import org.hibernate.annotations.GenericGenerator;
+
+import javax.persistence.*;
+
+/**
+ * @Author:tfd
+ * @Date:2023/6/25 15:02
+ */
+@Data
+@Entity
+@Table(name = "screen_api")
+@AutoMapper(target = ScreenApi.class)
+public class TbScreenApi {
+
+    @Id
+    @GeneratedValue(generator = "SnowflakeIdGenerator")
+    @GenericGenerator(name = "SnowflakeIdGenerator", strategy = "cc.iotkit.data.config.id.SnowflakeIdGenerator")
+    private Long id;
+    /**
+     * 大屏id
+     */
+    private Long screenId;
+
+    /**
+     * 接口路径
+     */
+    private String apiPath;
+
+    /**
+     * 接口参数
+     */
+    private String apiParams;
+
+    /**
+     * 请求方法
+     */
+    private String httpMethod;
+
+    /**
+     * 数据源
+     */
+    private String dataSource;
+
+    /**
+     * 创建时间
+     */
+    private Long createAt;
+
+    /**
+     * 转换脚本
+     */
+    @Column(columnDefinition = "text")
+    private String script;
+}

+ 51 - 0
iot-common/iot-common-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/ScreenApiDataImpl.java

@@ -0,0 +1,51 @@
+package cc.iotkit.data.service;
+
+import cc.iotkit.common.utils.MapstructUtils;
+import cc.iotkit.data.dao.IJPACommData;
+import cc.iotkit.data.dao.ScreenApiRepository;
+import cc.iotkit.data.manager.IScreenApiData;
+import cc.iotkit.data.model.TbScreenApi;
+import cc.iotkit.model.screen.ScreenApi;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Primary;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @Author:tfd
+ * @Date:2023/6/25 15:21
+ */
+@Primary
+@Service
+public class ScreenApiDataImpl implements IScreenApiData,IJPACommData<ScreenApi,Long> {
+
+    @Autowired
+    private ScreenApiRepository screenApiRepository;
+
+    @Override
+    public JpaRepository getBaseRepository() {
+        return screenApiRepository;
+    }
+
+    @Override
+    public Class getJpaRepositoryClass() {
+        return TbScreenApi.class;
+    }
+
+    @Override
+    public Class getTClass() {
+        return ScreenApi.class;
+    }
+
+    @Override
+    public List<ScreenApi> findByScreenId(Long id) {
+        return MapstructUtils.convert(screenApiRepository.findByScreenId(id),ScreenApi.class);
+    }
+
+    @Override
+    public void deleteByScreenId(Long id) {
+        screenApiRepository.deleteByScreenId(id);
+    }
+}

+ 56 - 0
iot-common/iot-common-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/ScreenDataImpl.java

@@ -0,0 +1,56 @@
+package cc.iotkit.data.service;
+
+import cc.iotkit.common.utils.MapstructUtils;
+import cc.iotkit.data.dao.IJPACommData;
+import cc.iotkit.data.dao.ScreenRepository;
+import cc.iotkit.data.manager.IScreenData;
+import cc.iotkit.data.model.TbScreen;
+import cc.iotkit.model.screen.Screen;
+import com.querydsl.jpa.impl.JPAQueryFactory;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Primary;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @Author:tfd
+ * @Date:2023/6/25 15:21
+ */
+@Primary
+@Service
+@RequiredArgsConstructor
+public class ScreenDataImpl implements IScreenData,IJPACommData<Screen,Long> {
+
+    @Autowired
+    private ScreenRepository screenRepository;
+
+    private final JPAQueryFactory jpaQueryFactory;
+
+    @Override
+    public JpaRepository getBaseRepository() {
+        return screenRepository;
+    }
+
+    @Override
+    public Class getJpaRepositoryClass() {
+        return TbScreen.class;
+    }
+
+    @Override
+    public Class getTClass() {
+        return Screen.class;
+    }
+
+    @Override
+    public Screen findByIsDefault(boolean isDefault) {
+        return MapstructUtils.convert(screenRepository.findByIsDefault(isDefault),Screen.class);
+    }
+
+    @Override
+    public List<Screen> findByState(String state) {
+        return MapstructUtils.convert(screenRepository.findByState(state),Screen.class);
+    }
+}

+ 5 - 0
iot-module/iot-manager/pom.xml

@@ -59,6 +59,11 @@
             <artifactId>iot-rule-engine</artifactId>
         </dependency>
 
+        <dependency>
+            <groupId>cc.iotkit</groupId>
+            <artifactId>iot-screen</artifactId>
+        </dependency>
+
         <dependency>
             <groupId>cc.iotkit</groupId>
             <artifactId>iot-component-oss</artifactId>

+ 137 - 0
iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/ScreenController.java

@@ -0,0 +1,137 @@
+package cc.iotkit.manager.controller;
+
+import cc.iotkit.common.api.PageRequest;
+import cc.iotkit.common.api.Paging;
+import cc.iotkit.common.api.Request;
+import cc.iotkit.common.enums.ErrCode;
+import cc.iotkit.common.exception.BizException;
+import cc.iotkit.manager.dto.bo.screen.DebugChangeBo;
+import cc.iotkit.manager.dto.bo.screen.PublishChangeBo;
+import cc.iotkit.manager.service.IScreenService;
+import cc.iotkit.model.screen.Screen;
+import cc.iotkit.model.screen.ScreenApi;
+import cn.hutool.core.util.ObjectUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.List;
+
+/**
+ * @Author:tfd
+ * @Date:2023/6/25 14:56
+ */
+@Api(tags = {"大屏接口"})
+@Slf4j
+@RestController
+@RequestMapping("/screen")
+public class ScreenController {
+
+    @Autowired
+    private IScreenService screenService;
+
+    @ApiOperation(value = "获取大屏列表", httpMethod = "POST")
+    @PostMapping("/getScreens")
+    public Paging<Screen> getBigScreens(@Validated @RequestBody PageRequest<Screen> request) {
+        return screenService.getBigScreens(request);
+    }
+
+    @ApiOperation(value = "上传大屏资源包")
+    @PostMapping("/uploadResourceFile")
+    public Long uploadResourceFile(@RequestParam("file") MultipartFile file,
+                                   @RequestBody @Validated Request<Long> id){
+        if (file == null) {
+            throw new BizException(ErrCode.PARAMS_EXCEPTION);
+        }
+        log.info("saving upload resource file:{}", file.getName());
+        return screenService.uploadResourceFile(file,id.getData());
+    }
+
+    @ApiOperation(value = "获取大屏接口")
+    @PostMapping("/getScreenApis")
+    public List<ScreenApi> getScreenApis(@RequestBody @Validated Request<Long> id) {
+        if (ObjectUtil.isEmpty(id.getData())) {
+            throw new BizException(ErrCode.ID_BLANK);
+        }
+        return screenService.findByScreenId(id.getData());
+    }
+
+    @ApiOperation(value = "获取默认大屏")
+    @PostMapping("/getDefaultScreen")
+    public Screen getDefaultScreen() {
+        return screenService.getDefaultScreen();
+    }
+
+    @ApiOperation(value = "同步资源包接口")
+    @PostMapping("/syncResourceApis")
+    public List<ScreenApi> syncResourceApis(@RequestBody @Validated Request<Long> id) {
+        if (ObjectUtil.isEmpty(id.getData())) {
+            throw new BizException(ErrCode.ID_BLANK);
+        }
+        return screenService.syncResourceApis(id.getData());
+    }
+
+    @ApiOperation(value = "预览接口")
+    @PostMapping("/previewApis")
+    public void previewApis(@RequestBody  @Validated Request<List<ScreenApi>> screenApis) {
+        if (ObjectUtil.isNull(screenApis.getData())||screenApis.getData().size()==0) {
+            throw new BizException(ErrCode.API_LIST_BLANK);
+        }
+        screenService.previewApis(screenApis.getData());
+    }
+
+    @ApiOperation(value = "保存大屏接口")
+    @PostMapping("/saveScreenApis")
+    public void saveScreenApis(@RequestBody @Validated Request<List<ScreenApi>> screenApis) {
+        if (ObjectUtil.isNull(screenApis.getData())||screenApis.getData().size()==0) {
+            throw new BizException(ErrCode.API_LIST_BLANK);
+        }
+        screenService.saveScreenApis(screenApis.getData());
+    }
+
+    @ApiOperation(value = "调试模式转换")
+    @PostMapping("/debugModeChange")
+    public void debugMode(@RequestBody @Validated Request<DebugChangeBo> debugChange) {
+        screenService.debugModeChange(debugChange.getData());
+    }
+
+    @ApiOperation(value = "添加大屏")
+    @PostMapping("/addScreen")
+    public void addScreen(@RequestBody @Validated Request<Screen> screen) {
+        screenService.addBigScreen(screen.getData());
+    }
+
+    @ApiOperation(value = "保存大屏")
+    @PostMapping("/saveScreen")
+    public void saveScreen(@RequestBody @Validated Request<Screen> screen) {
+        screenService.saveBigScreen(screen.getData());
+    }
+
+    @ApiOperation(value = "发布状态改变")
+    @PostMapping("/publishStatusChange")
+    public void publishStatusChange(@RequestBody @Validated Request<PublishChangeBo> req) {
+        screenService.publishStatusChange(req.getData());
+    }
+
+    @ApiOperation(value = "设置默认大屏")
+    @PostMapping("/setDefaultScreen")
+    public void setDefaultScreen(@RequestBody @Validated Request<Long> id) {
+        if (ObjectUtil.isEmpty(id.getData())) {
+            throw new BizException(ErrCode.ID_BLANK);
+        }
+        screenService.setDefaultScreen(id.getData());
+    }
+
+    @ApiOperation(value = "删除大屏", httpMethod = "POST")
+    @PostMapping("/deleteScreen")
+    public void deleteScreen(@RequestBody @Validated Request<Long> id) {
+        if (ObjectUtil.isEmpty(id.getData())) {
+            throw new BizException(ErrCode.ID_BLANK);
+        }
+        screenService.deleteScreen(id.getData());
+    }
+}

+ 23 - 0
iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/bo/screen/DebugChangeBo.java

@@ -0,0 +1,23 @@
+package cc.iotkit.manager.dto.bo.screen;
+
+import io.swagger.annotations.ApiModelProperty;
+import jakarta.validation.constraints.NotBlank;
+import lombok.Data;
+
+/**
+ * @Author:tfd
+ * @Date:2023/6/26 11:23
+ */
+@Data
+public class DebugChangeBo {
+
+    private static final long serialVersionUID = -1L;
+
+    @NotBlank(message = "id不能为空")
+    @ApiModelProperty(value = "id")
+    private Long id;
+
+    @NotBlank(message = "转换状态不能为空")
+    @ApiModelProperty(value = "转换状态")
+    private Boolean state;
+}

+ 29 - 0
iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/bo/screen/PublishChangeBo.java

@@ -0,0 +1,29 @@
+package cc.iotkit.manager.dto.bo.screen;
+
+import cc.iotkit.common.api.BaseDto;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.Size;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+
+@ApiModel(value = "ChangeStateBo")
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class PublishChangeBo extends BaseDto {
+    private static final long serialVersionUID = -1L;
+
+    @NotBlank(message = "id不能为空")
+    @ApiModelProperty(value = "")
+    private Long id;
+
+
+    @NotBlank(message = "state不能为空")
+    @ApiModelProperty(value = "运行状态")
+    @Size(max = 255, message = "运行状态长度不正确")
+    private String state;
+
+
+}

+ 43 - 0
iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/IScreenService.java

@@ -0,0 +1,43 @@
+package cc.iotkit.manager.service;
+
+import cc.iotkit.common.api.PageRequest;
+import cc.iotkit.common.api.Paging;
+import cc.iotkit.manager.dto.bo.screen.DebugChangeBo;
+import cc.iotkit.manager.dto.bo.screen.PublishChangeBo;
+import cc.iotkit.model.screen.Screen;
+import cc.iotkit.model.screen.ScreenApi;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.List;
+
+/**
+ * @Author:tfd
+ * @Date:2023/6/25 15:14
+ */
+public interface IScreenService {
+    Long uploadResourceFile(MultipartFile file, Long id);
+
+    List<ScreenApi> findByScreenId(Long id);
+
+    Screen getDefaultScreen();
+
+    List<ScreenApi> syncResourceApis(Long id);
+
+    void previewApis(List<ScreenApi> screenApis);
+
+    void saveScreenApis(List<ScreenApi> screenApis);
+
+    void debugModeChange(DebugChangeBo debugChange);
+
+    void addBigScreen(Screen screen);
+
+    void saveBigScreen(Screen screen);
+
+    void publishStatusChange(PublishChangeBo data);
+
+    void setDefaultScreen(Long id);
+
+    void deleteScreen(Long id);
+
+    Paging<Screen> getBigScreens(PageRequest<Screen> request);
+}

+ 214 - 0
iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/impl/ScreenServiceImpl.java

@@ -0,0 +1,214 @@
+package cc.iotkit.manager.service.impl;
+
+import cc.iotkit.common.api.PageRequest;
+import cc.iotkit.common.api.Paging;
+import cc.iotkit.common.enums.ErrCode;
+import cc.iotkit.common.exception.BizException;
+import cc.iotkit.common.utils.ReflectUtil;
+import cc.iotkit.data.manager.IScreenApiData;
+import cc.iotkit.data.manager.IScreenData;
+import cc.iotkit.manager.dto.bo.screen.DebugChangeBo;
+import cc.iotkit.manager.dto.bo.screen.PublishChangeBo;
+import cc.iotkit.manager.service.DataOwnerService;
+import cc.iotkit.manager.service.IScreenService;
+import cc.iotkit.model.screen.Screen;
+import cc.iotkit.model.screen.ScreenApi;
+import cc.iotkit.screen.ScreenManager;
+import cc.iotkit.screen.config.ScreenConfig;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.ZipUtil;
+import com.github.yitter.idgen.YitIdHelper;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.io.FileUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.*;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * @Author:tfd
+ * @Date:2023/6/25 15:15
+ */
+@Service
+@Slf4j
+public class ScreenServiceImpl implements IScreenService {
+    @Autowired
+    private IScreenData screenData;
+    @Autowired
+    private IScreenApiData screenApiData;
+    @Autowired
+    private DataOwnerService dataOwnerService;
+    @Autowired
+    private ScreenConfig screenConfig;
+    @Autowired
+    private ScreenManager screenManager;
+
+    @Override
+    public Long uploadResourceFile(MultipartFile file, Long id) {
+        String fileName = StringUtils.cleanPath(Objects.requireNonNull(file.getOriginalFilename()));
+        try {
+            if (ObjectUtil.isNotNull(id)) {
+                getAndCheckBigScreen(id);
+            } else {
+                id = YitIdHelper.nextId();
+            }
+            Path filePath = screenConfig.getBigScreenFilePath(String.valueOf(id));
+            Files.createDirectories(filePath);
+            Path targetLocation = filePath.resolve(fileName);
+            Files.copy(file.getInputStream(), targetLocation, StandardCopyOption.REPLACE_EXISTING);
+            ZipUtil.unzip(filePath.toString()+"/"+fileName);
+            return id;
+        } catch (IOException ex) {
+            throw new BizException(ErrCode.UPLOAD_FILE_ERROR, ex);
+        }
+    }
+
+    @Override
+    public List<ScreenApi> findByScreenId(Long id) {
+        return screenApiData.findByScreenId(id);
+    }
+
+    @Override
+    public Screen getDefaultScreen() {
+        return screenData.findByIsDefault(true);
+    }
+
+    @Override
+    public List<ScreenApi> syncResourceApis(Long id) {
+        Screen screen = getAndCheckBigScreen(id);
+        return screenManager.getScreenApis(screen);
+    }
+
+    @Override
+    public void previewApis(List<ScreenApi> screenApis) {
+        Screen screen = getAndCheckBigScreen(screenApis.get(0).getScreenId());
+        screenManager.previewApis(screen,screenApis);
+    }
+
+    @Override
+    public void saveScreenApis(List<ScreenApi> screenApis) {
+        Screen screen = getAndCheckBigScreen(screenApis.get(0).getScreenId());
+        screenApiData.deleteByScreenId(screen.getId());
+        screenApiData.batchSave(screenApis);
+    }
+
+    @Override
+    public void debugModeChange(DebugChangeBo debugChange) {
+        Screen screen = getAndCheckBigScreen(debugChange.getId());
+        screenManager.debugMode(screen,debugChange.getState());
+    }
+
+    @Override
+    public void addBigScreen(Screen screen) {
+        String id = String.valueOf(screen.getId());
+        if (!StringUtils.hasLength(id)) {
+            throw new BizException(ErrCode.ID_BLANK);
+        }
+        Path resPath = screenConfig.getBigScreenFilePath(id);
+        if (!resPath.resolve(screen.getResourceFile()).toFile().exists()) {
+            throw new BizException(ErrCode.RESOURCE_FILE_NOT_FOUND);
+        }
+        Screen s = screenData.findById(screen.getId());
+        if (s != null) {
+            throw new BizException(ErrCode.BIG_SCREEN_ALREADY);
+        }
+        try {
+            screen.setCreateAt(System.currentTimeMillis());
+            screen.setIsDefault(false);
+            screenData.save(screen);
+        } catch (Throwable e) {
+            throw new BizException(ErrCode.ADD_BIG_SCREEN_ERROR, e);
+        }
+    }
+
+    @Override
+    public void saveBigScreen(Screen screen) {
+        String id = String.valueOf(screen.getId());
+        if (!StringUtils.hasLength(id)) {
+            throw new BizException(ErrCode.ID_BLANK);
+        }
+        Path jarPath = screenConfig.getBigScreenFilePath(id);
+        if (!jarPath.resolve(screen.getResourceFile()).toFile().exists()) {
+            throw new BizException(ErrCode.RESOURCE_FILE_NOT_FOUND);
+        }
+        Screen oldScreen = getAndCheckBigScreen(screen.getId());
+        screen = ReflectUtil.copyNoNulls(screen, oldScreen);
+        try {
+            screenData.save(screen);
+        } catch (Throwable e) {
+            throw new BizException(ErrCode.ADD_BIG_SCREEN_ERROR, e);
+        }
+    }
+
+    @Override
+    public void publishStatusChange(PublishChangeBo data) {
+        Screen screen = getAndCheckBigScreen(data.getId());
+        if (screen.STATE_RUNNING.equals(data.getState())) {//发布状态
+            List<ScreenApi> screenApis=screenApiData.findByScreenId(screen.getId());
+            if(screenApis==null||screenApis.size()==0){
+                throw new BizException(ErrCode.API_LIST_BLANK);
+            }
+            screen.setState(screen.STATE_RUNNING);
+            screenManager.register(screen);
+            screenManager.publish(screen);
+        } else {//取消发布
+            screen.setState(screen.STATE_STOPPED);
+            screenManager.unpublish(screen);
+        }
+        screenData.save(screen);
+    }
+
+    @Override
+    public void setDefaultScreen(Long id) {
+        Screen screen = getAndCheckBigScreen(id);
+        Screen oldScreen=screenData.findByIsDefault(true);
+        if(oldScreen!=null){
+            oldScreen.setIsDefault(false);
+        }
+        screenData.save(oldScreen);
+        screen.setIsDefault(true);
+        screenData.save(screen);
+    }
+
+    @Override
+    public void deleteScreen(Long id) {
+        Screen screen = getAndCheckBigScreen(id);
+        try {
+            Path path = Paths.get(String.format("%s/%s", screenConfig.getScreenDir(), id))
+                    .toAbsolutePath().normalize();
+            File file = path.toFile();
+            try {
+                if (file.isDirectory()) {
+                    FileUtils.deleteDirectory(file);
+                } else {
+                    FileUtils.delete(file);
+                }
+            } catch (NoSuchFileException e) {
+                log.warn("delete big screen resource error", e);
+            }
+            screenData.deleteById(screen.getId());
+        } catch (Throwable e) {
+            throw new BizException(ErrCode.DELETE_BIG_SCREEN_ERROR, e);
+        }
+    }
+
+    @Override
+    public Paging<Screen> getBigScreens(PageRequest<Screen> request) {
+        return screenData.findAll(request);
+    }
+
+    private Screen getAndCheckBigScreen(Long id) {
+        Screen oldBigScreen = screenData.findById(id);
+        if (oldBigScreen == null) {
+            throw new BizException(ErrCode.BIG_SCREEN_NOT_FOUND);
+        }
+        dataOwnerService.checkOwner(oldBigScreen);
+        return oldBigScreen;
+    }
+}

+ 85 - 0
iot-module/iot-screen/pom.xml

@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>iot-module</artifactId>
+        <groupId>cc.iotkit</groupId>
+        <version>${revision}</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>iot-screen</artifactId>
+    <description>
+        数据大屏模块
+    </description>
+
+    <dependencies>
+
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-context-support</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>io.vertx</groupId>
+            <artifactId>vertx-core</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>io.vertx</groupId>
+            <artifactId>vertx-web-proxy</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>cc.iotkit</groupId>
+            <artifactId>iot-common-core</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>cc.iotkit</groupId>
+            <artifactId>iot-script-engine</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-context</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>cc.iotkit</groupId>
+            <artifactId>iot-data-service</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>cc.iotkit</groupId>
+            <artifactId>iot-component-server</artifactId>
+        </dependency>
+
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>${java.version}</source>
+                    <target>${java.version}</target>
+                    <encoding>utf8</encoding>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 119 - 0
iot-module/iot-screen/src/main/java/cc/iotkit/screen/ScreenManager.java

@@ -0,0 +1,119 @@
+package cc.iotkit.screen;
+
+import cc.iotkit.comps.ApiTool;
+import cc.iotkit.data.manager.IScreenApiData;
+import cc.iotkit.data.manager.IScreenData;
+import cc.iotkit.model.screen.Screen;
+import cc.iotkit.model.screen.ScreenApi;
+import cc.iotkit.screen.api.ScreenApiHandle;
+import cc.iotkit.screen.config.ScreenConfig;
+import cc.iotkit.screen.staticres.ScreenComponent;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Author:tfd
+ * @Date:2023/6/25 17:03
+ */
+@Slf4j
+@Component
+public class ScreenManager {
+
+    @Autowired
+    private IScreenApiData screenApiData;
+
+    @Autowired
+    private IScreenData screenData;
+
+    @Autowired
+    private ScreenConfig screenConfig;
+
+    private final Map<Long, ScreenComponent> screens = new HashMap<>();
+    private final Map<Long, Boolean> states = new HashMap<>();
+
+    @PostConstruct
+    public void init() {
+        List<Screen> screenList = screenData.findByState(
+                Screen.STATE_RUNNING);
+        for (Screen screen : screenList) {
+            try {
+                register(screen);
+                publish(screen);
+            } catch (Throwable e) {
+                log.error("init screen error", e);
+            }
+        }
+    }
+
+    public void register(Screen screen) {
+        Long id = screen.getId();
+        if (screens.containsKey(id)) {
+            return;
+        }
+        ScreenComponent screenComponent=new ScreenComponent();
+        String[] pathNames=screen.getResourceFile().split("\\.");
+        screenComponent.create(screen.getPort(),pathNames.length>1?pathNames[0]:"",screenConfig);
+        screens.put(id,screenComponent);
+    }
+
+    public void publish(Screen screen) {
+        Long id = screen.getId();
+        ScreenComponent screenComponent = screens.get(id);
+        if (screenComponent == null) {
+            return;
+        }
+        ScreenApiHandle screenApiHandle=new ScreenApiHandle(id,screenApiData.findByScreenId(id));
+        screenApiHandle.putScriptEnv("apiTool", new ApiTool());
+        screenComponent.setApiHandle(screenApiHandle);
+        screenComponent.publish();
+        states.put(id, true);
+    }
+
+    public void unpublish(Screen screen) {
+        Long id = screen.getId();
+        ScreenComponent screenComponent = screens.get(id);
+        if (screenComponent == null) {
+            return;
+        }
+        screens.remove(id);
+        states.remove(id);
+        screenComponent.unpublish();
+    }
+
+    public void previewApis(Screen screen,List<ScreenApi> screenApis) {
+        Long id = screen.getId();
+        ScreenComponent screenComponent = screens.get(id);
+        if (screenComponent == null) {
+            return;
+        }
+        screenComponent.previewApis(screenApis);
+    }
+
+    public List<ScreenApi> getScreenApis(Screen screen) {
+        Long id = screen.getId();
+        ScreenComponent screenComponent = screens.get(id);
+        if (screenComponent == null) {
+            return null;
+        }
+        return screenComponent.getScreenApis();
+    }
+
+    public void debugMode(Screen screen,boolean state) {
+        Long id = screen.getId();
+        ScreenComponent screenComponent = screens.get(id);
+        if (screenComponent == null) {
+            return;
+        }
+        screenComponent.debugMode(state);
+    }
+
+    public boolean isRunning(String id) {
+        return states.containsKey(id) && states.get(id);
+    }
+}

+ 18 - 0
iot-module/iot-screen/src/main/java/cc/iotkit/screen/api/HttpContent.java

@@ -0,0 +1,18 @@
+package cc.iotkit.screen.api;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @Author:tfd
+ * @Date:2023/6/25 15:57
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+public class HttpContent {
+    private String content;
+}

+ 138 - 0
iot-module/iot-screen/src/main/java/cc/iotkit/screen/api/ScreenApiHandle.java

@@ -0,0 +1,138 @@
+package cc.iotkit.screen.api;
+
+import cc.iotkit.common.utils.JsonUtils;
+import cc.iotkit.common.utils.StringUtils;
+import cc.iotkit.model.screen.ScreenApi;
+import cc.iotkit.script.IScriptEngine;
+import cc.iotkit.script.ScriptEngineFactory;
+import com.fasterxml.jackson.core.type.TypeReference;
+import io.vertx.core.MultiMap;
+import io.vertx.core.http.HttpMethod;
+import io.vertx.core.http.HttpServerRequest;
+import io.vertx.core.http.HttpServerResponse;
+import io.vertx.core.json.JsonObject;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * @Author:tfd
+ * @Date:2023/6/25 15:54
+ */
+@Slf4j
+@Data
+public class ScreenApiHandle {
+    private final Long screenId;
+
+    public List<ScreenApi> screenApis;
+
+    public boolean debugMode=false;
+
+    private final IScriptEngine scriptEngine = ScriptEngineFactory.getScriptEngine("js");
+
+    public ScreenApiHandle(Long screenId, List<ScreenApi> screenApis) {
+        this.screenId = screenId;
+        this.screenApis = screenApis;
+    }
+
+    public void putScriptEnv(String key, Object value) {
+        this.scriptEngine.putScriptEnv(key, value);
+    }
+
+    /**
+     * 每个请求的处理方法要执行对应的请求脚本然后将结果返回给http服务器
+     *
+     */
+    public String httpReq(HttpServerRequest req, HttpServerResponse res) {
+        String response="";
+        try {
+            Map<String, Object> httpHeader = getData(req.headers());
+            log.info("request header:{}", JsonUtils.toJsonString(httpHeader));
+            String path=req.path();
+            String params="";
+            log.info("接收到请求:"+path);
+            if(HttpMethod.GET.name().equals(req.method().name())){
+                String[] getParams=req.absoluteURI().split("\\?");
+                if(getParams.length>1){
+                    params=getParams[1];
+                }
+            }else if(HttpMethod.POST.name().equals(req.method().name())){
+                MultiMap postParams=req.params();
+                JsonObject jsonObject = new JsonObject();
+                if(!postParams.isEmpty()){
+                    for (String paramName : postParams.names()) {
+                        jsonObject.put(paramName, postParams.get(paramName));
+                    }
+                    params=jsonObject.encode();
+                }
+            }
+            log.info("参数:"+params);
+            if(debugMode){
+                if(screenApis.stream().anyMatch(m -> m.getApiPath().equals(path))){
+                    String finalParams = params;
+                    screenApis.stream().map(s -> {
+                        s.setApiPath(path);
+                        s.setApiParams(finalParams);
+                        s.setHttpMethod(req.method().name());
+                        return s;
+                    }).collect(Collectors.toList());
+                }else{
+                    ScreenApi sai=new ScreenApi();
+                    sai.setApiPath(path);
+                    sai.setApiParams(params);
+                    sai.setHttpMethod(req.method().name());
+                    screenApis.add(sai);
+                }
+                response="PREVIEW API";
+            }else{
+                for (ScreenApi screenApi:screenApis) {
+                    if(screenApi.getApiPath().equals(path)){
+                        String script=screenApi.getScript();
+                        if(StringUtils.isBlank(script)){
+                            response="转换脚本为空";
+                            return response;
+                        }
+                        scriptEngine.setScript(script);
+                        try {
+                            HttpContent content =
+                                    scriptEngine.invokeMethod(
+                                            new TypeReference<>() {
+                                            },
+                                            "messageConver",
+                                            httpHeader,
+                                            params);
+                            response = content.getContent();
+                            response = response == null ? "" : response;
+                        } catch (Throwable e) {
+                            log.error("invokeMethod messageConver error", e);
+                            response = e.getMessage();
+                            return response;
+                        }
+                        log.info("response,content:{}", response);
+                    }else if("/favicon.ico".equals(path)){
+                        response="NOT FOUND";
+                    }else{
+                        response="NOT FOUND";
+                    }
+                }
+            }
+        } catch (Throwable e) {
+            log.error("handle request error", e);
+            response="server error:" + e.getMessage();
+            return response;
+        }
+        return response;
+    }
+
+    private static Map<String, Object> getData(MultiMap multiMap) {
+        Map<String, Object> data = new HashMap<>();
+        for (Map.Entry<String, String> entry : multiMap.entries()) {
+            data.put(entry.getKey(), entry.getValue());
+        }
+        return data;
+    }
+}

+ 27 - 0
iot-module/iot-screen/src/main/java/cc/iotkit/screen/config/ScreenConfig.java

@@ -0,0 +1,27 @@
+package cc.iotkit.screen.config;
+
+import lombok.Data;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+/**
+ * @Author:tfd
+ * @Date:2023/6/25 16:04
+ */
+@Configuration
+@Data
+public class ScreenConfig {
+
+    @Value("${bigScreen.dir:./data/screens}")
+    private String screenDir;
+    @Value("${bigScreen.admin:/iotkit/screen}")
+    public String screenAdmin;
+
+    public Path getBigScreenFilePath(String screenId) {
+        return Paths.get(screenDir, screenId)
+                .toAbsolutePath().normalize();
+    }
+}

+ 76 - 0
iot-module/iot-screen/src/main/java/cc/iotkit/screen/staticres/ScreenComponent.java

@@ -0,0 +1,76 @@
+package cc.iotkit.screen.staticres;
+
+import cc.iotkit.common.enums.ErrCode;
+import cc.iotkit.common.exception.BizException;
+import cc.iotkit.model.screen.ScreenApi;
+import cc.iotkit.screen.api.ScreenApiHandle;
+import cc.iotkit.screen.config.ScreenConfig;
+import io.vertx.core.Future;
+import io.vertx.core.Vertx;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * @Author:tfd
+ * @Date:2023/6/25 16:01
+ */
+@Slf4j
+public class ScreenComponent {
+
+    private Vertx vertx;
+    private CountDownLatch countDownLatch;
+    private String deployedId;
+    private ScreenApiHandle apiHandle;
+    private ScreenVerticle screenVerticle;
+
+    public List<ScreenApi> getScreenApis() {
+        return apiHandle.screenApis;
+    }
+
+    public void debugMode(boolean state) {
+        apiHandle.debugMode=state;
+    }
+
+    public void create(int port, String packageName, ScreenConfig screenConfig) {
+        vertx = Vertx.vertx();
+        screenVerticle = new ScreenVerticle(port,packageName,screenConfig);
+    }
+
+    public void setApiHandle(ScreenApiHandle screenApiHandle) {
+        this.apiHandle=screenApiHandle;
+    }
+
+    public void previewApis(List<ScreenApi> screenApis) {
+        this.apiHandle.setScreenApis(screenApis);
+    }
+
+    public void publish() {
+        try {
+            screenVerticle.setApiHandler(apiHandle);
+            countDownLatch = new CountDownLatch(1);
+            Future<String> future = vertx.deployVerticle(screenVerticle);
+            future.onSuccess((s -> {
+                deployedId = s;
+                countDownLatch.countDown();
+            }));
+            future.onFailure((e) -> {
+                countDownLatch.countDown();
+                log.error("publish screen failed", e);
+            });
+            countDownLatch.await();
+            future.succeeded();
+        } catch (Throwable e) {
+            throw new BizException(ErrCode.SCREEN_PUBLISH_ERROR, e);
+        }
+    }
+
+    @SneakyThrows
+    public void unpublish() {
+        screenVerticle.stop();
+        Future<Void> future = vertx.undeploy(deployedId);
+        future.onSuccess(unused -> log.info("unpublish screen success"));
+    }
+}

+ 68 - 0
iot-module/iot-screen/src/main/java/cc/iotkit/screen/staticres/ScreenVerticle.java

@@ -0,0 +1,68 @@
+package cc.iotkit.screen.staticres;
+
+import cc.iotkit.screen.api.ScreenApiHandle;
+import cc.iotkit.screen.config.ScreenConfig;
+import io.vertx.core.AbstractVerticle;
+import io.vertx.core.http.HttpServer;
+import io.vertx.ext.web.Router;
+import io.vertx.ext.web.handler.BodyHandler;
+import io.vertx.ext.web.handler.StaticHandler;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * @Author:tfd
+ * @Date:2023/6/25 16:03
+ */
+@Slf4j
+public class ScreenVerticle extends AbstractVerticle {
+
+    private HttpServer httpServer;
+
+    private int port;
+
+    private String packageName;
+
+    private ScreenApiHandle apiHandler;
+
+    private ScreenConfig screenConfig;
+
+    public ScreenVerticle(int port,String packageName,ScreenConfig screenConfig) {
+        this.port = port;
+        this.packageName = packageName;
+        this.screenConfig = screenConfig;
+    }
+
+    public void setApiHandler(ScreenApiHandle apiHandler) {
+        this.apiHandler = apiHandler;
+    }
+
+    @Override
+    public void start() throws Exception {
+        httpServer = vertx.createHttpServer();
+        Router router = Router.router(vertx);
+        router.route(screenConfig.screenAdmin + "/*").handler(StaticHandler.create(screenConfig.getScreenDir()+"/"+apiHandler.getScreenId()+"/"+packageName));
+        router.get(screenConfig.screenAdmin).handler(ctx -> {
+            ctx.response().sendFile(screenConfig.getScreenDir()+"/"+apiHandler.getScreenId() +"/"+packageName+ "/index.html");
+        });
+        router.get("/*").handler(ctx -> {
+            String res = apiHandler.httpReq(ctx.request(), ctx.response());
+            ctx.response().end(res);
+        });
+        router.post("/*").handler(BodyHandler.create()).handler(ctx -> {
+            String res = apiHandler.httpReq(ctx.request(), ctx.response());
+            ctx.response().end(res);
+        });
+        httpServer.requestHandler(router).listen(port, (http) -> {
+            if (http.succeeded()) {
+                log.info("screen server create succeed,port:{}", port);
+            } else {
+                log.error("screen server create failed", http.cause());
+            }
+        });
+    }
+
+    @Override
+    public void stop() throws Exception {
+        httpServer.close(voidAsyncResult -> log.info("close screen server..."));
+    }
+}

+ 1 - 0
iot-module/pom.xml

@@ -18,6 +18,7 @@
         <module>iot-rule-engine</module>
         <module>iot-message-notify</module>
         <module>iot-generator</module>
+        <module>iot-screen</module>
     </modules>
 
 

+ 6 - 0
pom.xml

@@ -527,6 +527,12 @@
                 <version>${project.version}</version>
             </dependency>
 
+            <dependency>
+                <groupId>cc.iotkit</groupId>
+                <artifactId>iot-screen</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+
             <dependency>
                 <groupId>cc.iotkit</groupId>
                 <artifactId>iot-system</artifactId>