update:迁移数据大屏模块
parent
7d59858c53
commit
2779fc269a
|
@ -46,10 +46,23 @@ public enum ErrCode implements IEnum {
|
||||||
INIT_PRODUCER_ERROR(00000000, "初始化MQ生产者失败"),
|
INIT_PRODUCER_ERROR(00000000, "初始化MQ生产者失败"),
|
||||||
SEND_MSG_ERROR(00000000, "发送消息失败"),
|
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, "任务不支持续订"),
|
TASK_NOT_SUPPORT_RENEW(00000000, "任务不支持续订"),
|
||||||
GROUP_ALREADY(00000000, "分组已经存在"),
|
GROUP_ALREADY(00000000, "分组已经存在"),
|
||||||
GROUP_NOT_FOUND(00000000, "分组不存在"),
|
GROUP_NOT_FOUND(00000000, "分组不存在"),
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -59,6 +59,11 @@
|
||||||
<artifactId>iot-rule-engine</artifactId>
|
<artifactId>iot-rule-engine</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>cc.iotkit</groupId>
|
||||||
|
<artifactId>iot-screen</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>cc.iotkit</groupId>
|
<groupId>cc.iotkit</groupId>
|
||||||
<artifactId>iot-component-oss</artifactId>
|
<artifactId>iot-component-oss</artifactId>
|
||||||
|
|
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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>
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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"));
|
||||||
|
}
|
||||||
|
}
|
|
@ -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..."));
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,6 +18,7 @@
|
||||||
<module>iot-rule-engine</module>
|
<module>iot-rule-engine</module>
|
||||||
<module>iot-message-notify</module>
|
<module>iot-message-notify</module>
|
||||||
<module>iot-generator</module>
|
<module>iot-generator</module>
|
||||||
|
<module>iot-screen</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
|
|
||||||
|
|
6
pom.xml
6
pom.xml
|
@ -527,6 +527,12 @@
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>cc.iotkit</groupId>
|
||||||
|
<artifactId>iot-screen</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>cc.iotkit</groupId>
|
<groupId>cc.iotkit</groupId>
|
||||||
<artifactId>iot-system</artifactId>
|
<artifactId>iot-system</artifactId>
|
||||||
|
|
Loading…
Reference in New Issue