mirror of
https://gitee.com/beecue/fastbee.git
synced 2025-12-17 00:15:55 +08:00
开源版新增规则脚本
This commit is contained in:
@@ -163,6 +163,11 @@ public interface FastBeeConstant {
|
||||
/**固件版本key*/
|
||||
String FIRMWARE_VERSION = "device:firmware:";
|
||||
|
||||
/**
|
||||
* 设备信息
|
||||
*/
|
||||
String DEVICE_MSG = "device:msg:";
|
||||
|
||||
/**采集点变更记录缓存key*/
|
||||
String COLLECT_POINT_CHANGE = "collect:point:change:";
|
||||
/**属性下发回调*/
|
||||
|
||||
@@ -81,4 +81,11 @@ public class RedisKeyBuilder {
|
||||
return FastBeeConstant.REDIS.DEVICE_MESSAGE_ID;
|
||||
}
|
||||
|
||||
/**
|
||||
* 缓存产品id,设备编号,协议编号
|
||||
*/
|
||||
public static String buildDeviceMsgCacheKey(String serialNumber){
|
||||
return FastBeeConstant.REDIS.DEVICE_MSG + serialNumber;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.fastbee.common.core.thingsModel;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 物模型值的项
|
||||
*
|
||||
* @author kerwincui
|
||||
* @date 2021-12-16
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@Builder
|
||||
@Data
|
||||
public class SceneThingsModelItem
|
||||
{
|
||||
/** 物模型唯一标识符 */
|
||||
private String id;
|
||||
|
||||
/** 物模型值 */
|
||||
private String value;
|
||||
|
||||
/** 类型:1=属性, 2=功能,3=事件, 4=设备升级,5=设备上线,6=设备下线 ,*/
|
||||
private int type;
|
||||
|
||||
/** 脚本ID */
|
||||
private String stripId;
|
||||
|
||||
/** 场景ID*/
|
||||
private Long sceneId;
|
||||
|
||||
/** 产品ID */
|
||||
private Long productId;
|
||||
|
||||
/** 设备编号 */
|
||||
private String DeviceNumber;
|
||||
}
|
||||
@@ -4,8 +4,11 @@ import com.fastbee.common.constant.FastBeeConstant;
|
||||
import com.fastbee.common.core.mq.DeviceReportBo;
|
||||
import com.fastbee.common.enums.ServerType;
|
||||
import com.fastbee.common.utils.DateUtils;
|
||||
import com.fastbee.common.utils.StringUtils;
|
||||
import com.fastbee.common.utils.gateway.mq.TopicsPost;
|
||||
import com.fastbee.common.utils.gateway.mq.TopicsUtils;
|
||||
import com.fastbee.iot.ruleEngine.MsgContext;
|
||||
import com.fastbee.iot.ruleEngine.RuleProcess;
|
||||
import com.fastbee.mq.redischannel.producer.MessageProducer;
|
||||
import com.fastbee.mq.service.IDeviceReportMessageService;
|
||||
import com.fastbee.mq.service.IMessagePublishService;
|
||||
@@ -17,6 +20,7 @@ import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
|
||||
@Component
|
||||
@@ -28,6 +32,9 @@ public class MqttService {
|
||||
@Resource
|
||||
private IDeviceReportMessageService deviceReportMessageService;
|
||||
|
||||
@Resource
|
||||
private RuleProcess ruleProcess;
|
||||
|
||||
|
||||
|
||||
public void subscribe(MqttAsyncClient client) throws MqttException {
|
||||
@@ -48,6 +55,18 @@ public class MqttService {
|
||||
log.info("接收消息主题 : " + topic);
|
||||
log.info("接收消息Qos : " + mqttMessage.getQos());
|
||||
log.info("接收消息内容 : " + message);
|
||||
|
||||
//这里默认设备编号长度超过9位
|
||||
String[] split = topic.split("/");
|
||||
String clientId = Arrays.stream(split).filter(imei -> imei.length() > 9).findFirst().get();
|
||||
// 规则引擎脚本处理,完成后返回结果
|
||||
MsgContext context = ruleProcess.processRuleScript(clientId, 1, topic, message);
|
||||
if (!Objects.isNull(context) && StringUtils.isNotEmpty(context.getPayload())
|
||||
&& StringUtils.isNotEmpty(context.getTopic())) {
|
||||
topic = context.getTopic();
|
||||
message = context.getPayload();
|
||||
}
|
||||
|
||||
String serialNumber = topicsUtils.parseSerialNumber(topic);
|
||||
Long productId = topicsUtils.parseProductId(topic);
|
||||
String name = topicsUtils.parseTopicName(topic);
|
||||
|
||||
@@ -0,0 +1,553 @@
|
||||
package com.fastbee.mq.ruleEngine;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.fastbee.common.core.mq.InvokeReqDto;
|
||||
import com.fastbee.common.core.redis.RedisCache;
|
||||
import com.fastbee.common.core.redis.RedisKeyBuilder;
|
||||
import com.fastbee.common.core.thingsModel.SceneThingsModelItem;
|
||||
import com.fastbee.common.core.thingsModel.ThingsModelSimpleItem;
|
||||
import com.fastbee.common.exception.ServiceException;
|
||||
import com.fastbee.common.utils.DateUtils;
|
||||
import com.fastbee.common.utils.StringUtils;
|
||||
import com.fastbee.common.utils.spring.SpringUtils;
|
||||
import com.fastbee.iot.model.ScriptTemplate;
|
||||
import com.fastbee.iot.model.ThingsModels.ValueItem;
|
||||
import com.fastbee.iot.service.IDeviceService;
|
||||
import com.fastbee.iot.service.IDeviceUserService;
|
||||
import com.fastbee.mq.service.IFunctionInvoke;
|
||||
import lombok.Data;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.util.regex.Pattern.compile;
|
||||
|
||||
@Data
|
||||
public class SceneContext {
|
||||
|
||||
/**
|
||||
* 上报信息的设备编号
|
||||
*/
|
||||
private String deviceNum;
|
||||
|
||||
/**
|
||||
* 上报信息的设备所属产品ID
|
||||
*/
|
||||
private Long productId;
|
||||
|
||||
/**
|
||||
* 上报信息的设备信息类型 1=属性, 2=功能,3=事件,4=设备升级,5=设备上线,6=设备下线
|
||||
*/
|
||||
private int type;
|
||||
|
||||
/**
|
||||
* 上报的物模型集合
|
||||
*/
|
||||
private List<ThingsModelSimpleItem> thingsModelSimpleItems;
|
||||
|
||||
/**
|
||||
* 触发成功的物模型集合,保留给告警记录
|
||||
*/
|
||||
private List<SceneThingsModelItem> sceneThingsModelItems;
|
||||
|
||||
|
||||
private static IFunctionInvoke functionInvoke = SpringUtils.getBean(IFunctionInvoke.class);
|
||||
|
||||
private static IDeviceService deviceService = SpringUtils.getBean(IDeviceService.class);
|
||||
|
||||
// private static IAlertService alertService = SpringUtils.getBean(IAlertService.class);
|
||||
|
||||
// private static NotifySendService notifySendService = SpringUtils.getBean(NotifySendService.class);
|
||||
|
||||
private static RedisCache redisCache = SpringUtils.getBean(RedisCache.class);
|
||||
|
||||
// private static AlertLogMapper alertLogMapper = SpringUtils.getBean(AlertLogMapper.class);
|
||||
|
||||
private static IDeviceUserService deviceUserService = SpringUtils.getBean(IDeviceUserService.class);
|
||||
|
||||
public SceneContext(String deviceNum, Long productId, int type, List<ThingsModelSimpleItem> thingsModelSimpleItems) {
|
||||
this.deviceNum = deviceNum;
|
||||
this.productId = productId;
|
||||
this.type = type;
|
||||
this.thingsModelSimpleItems = thingsModelSimpleItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理规则脚本
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private boolean process(String json) throws InterruptedException {
|
||||
System.out.println("------------------[规则引擎执行...]---------------------");
|
||||
ScriptTemplate scriptTemplate = JSON.parseObject(json, ScriptTemplate.class);
|
||||
if (scriptTemplate.getPurpose() == 2) {
|
||||
// 触发器,检查静默时间
|
||||
if (!checkSilent(scriptTemplate.getSilent(), scriptTemplate.getSceneId())) {
|
||||
// 触发条件为不满足时,返回true
|
||||
if (scriptTemplate.getCond() == 3) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// 触发器
|
||||
if (scriptTemplate.getSource() == 1) {
|
||||
// 设备触发
|
||||
return deviceTrigger(scriptTemplate);
|
||||
} else if (scriptTemplate.getSource() == 3) {
|
||||
// 产品触发
|
||||
return productTrigger(scriptTemplate);
|
||||
}
|
||||
|
||||
} /*else if (scriptTemplate.getPurpose() == 3) {
|
||||
// 执行动作,延迟执行,线程休眠 delay x 1000毫秒
|
||||
Thread.sleep(scriptTemplate.getDelay() * 1000);
|
||||
|
||||
if (scriptTemplate.getSource() == 4) {
|
||||
// 告警
|
||||
this.alert(scriptTemplate.getDelay(), scriptTemplate.getSceneId());
|
||||
} else if (scriptTemplate.getSource() == 1 || scriptTemplate.getSource() == 3) {
|
||||
// 下发指令
|
||||
this.send(scriptTemplate);
|
||||
}
|
||||
|
||||
// 更新静默时间
|
||||
this.updateSilent(scriptTemplate.getSilent(), scriptTemplate.getSceneId());
|
||||
}*/
|
||||
return false;
|
||||
}
|
||||
|
||||
/***
|
||||
* 设备触发脚本处理
|
||||
* @param scriptTemplate 解析后的Json脚本数据
|
||||
* @return
|
||||
*/
|
||||
private boolean deviceTrigger(ScriptTemplate scriptTemplate) {
|
||||
// 判断定制触发(执行一次)或设备上报
|
||||
boolean isDeviceReport = StringUtils.isEmpty(deviceNum) ? false : true;
|
||||
if (isDeviceReport) {
|
||||
// 1. 匹配设备编号
|
||||
boolean matchDeviceNum = Arrays.asList(scriptTemplate.getDeviceNums().split(",")).contains(deviceNum);
|
||||
if (scriptTemplate.getType() < 4) {
|
||||
// 2.匹配物模型标识符
|
||||
ThingsModelSimpleItem matchItem = null;
|
||||
if (thingsModelSimpleItems != null) {
|
||||
for (ThingsModelSimpleItem item : thingsModelSimpleItems) {
|
||||
if (item.getId().equals(scriptTemplate.getId())) {
|
||||
matchItem = item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (matchDeviceNum && matchItem != null) {
|
||||
// 记录结果
|
||||
if (sceneThingsModelItems == null) {
|
||||
sceneThingsModelItems = new ArrayList<>();
|
||||
}
|
||||
SceneThingsModelItem sceneItem = new SceneThingsModelItem(scriptTemplate.getId(), matchItem.getValue(), type,
|
||||
scriptTemplate.getScriptId(), scriptTemplate.getSceneId(), scriptTemplate.getProductId(), deviceNum);
|
||||
sceneThingsModelItems.add(sceneItem);
|
||||
// 3.设备上报值匹配
|
||||
boolean isMatch = matchValue(scriptTemplate.getOperator(), scriptTemplate.getValue(), matchItem.getValue());
|
||||
if (isMatch) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// 上线,下线
|
||||
if (matchDeviceNum && scriptTemplate.getType() == type) {
|
||||
// 记录结果
|
||||
if (sceneThingsModelItems == null) {
|
||||
sceneThingsModelItems = new ArrayList<>();
|
||||
}
|
||||
SceneThingsModelItem sceneItem = new SceneThingsModelItem(type == 5 ? "online" : "offline", type == 5 ? "1" : "0", type,
|
||||
scriptTemplate.getScriptId(), scriptTemplate.getSceneId(), scriptTemplate.getProductId(), deviceNum);
|
||||
sceneThingsModelItems.add(sceneItem);
|
||||
// 记录结果
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 定时触发/执行一次
|
||||
int resultCount = 0;
|
||||
// 3.查询设备最新上报值去匹配
|
||||
for (String num : Arrays.asList(scriptTemplate.getDeviceNums().split(","))) {
|
||||
// 数组类型,key去除前缀,值从逗号分隔的字符串获取
|
||||
String id = "";
|
||||
String value = "";
|
||||
int index = 0;
|
||||
if (scriptTemplate.getId().startsWith("array_")) {
|
||||
id = scriptTemplate.getId().substring(9);
|
||||
index = Integer.parseInt(scriptTemplate.getId().substring(6, 8));
|
||||
} else {
|
||||
id = scriptTemplate.getId();
|
||||
}
|
||||
String key = RedisKeyBuilder.buildTSLVCacheKey(scriptTemplate.getProductId(), num);
|
||||
String cacheValue = redisCache.getCacheMapValue(key, id);
|
||||
if (StringUtils.isEmpty(cacheValue)) {
|
||||
continue;
|
||||
}
|
||||
ValueItem valueItem = JSON.parseObject(cacheValue, ValueItem.class);
|
||||
if (scriptTemplate.getId().startsWith("array_")) {
|
||||
String[] values = valueItem.getValue().split(",");
|
||||
value = values[index];
|
||||
} else {
|
||||
value = valueItem.getValue();
|
||||
}
|
||||
boolean isMatch = matchValue(scriptTemplate.getOperator(), scriptTemplate.getValue(), value);
|
||||
if (isMatch) {
|
||||
// 记录结果
|
||||
if (sceneThingsModelItems == null) {
|
||||
sceneThingsModelItems = new ArrayList<>();
|
||||
}
|
||||
SceneThingsModelItem sceneItem = new SceneThingsModelItem(scriptTemplate.getId(), value, type,
|
||||
scriptTemplate.getScriptId(), scriptTemplate.getSceneId(), scriptTemplate.getProductId(), num);
|
||||
sceneThingsModelItems.add(sceneItem);
|
||||
resultCount++;
|
||||
}
|
||||
}
|
||||
// 任意设备匹配成功返回true
|
||||
return resultCount > 0 ? true : false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/***
|
||||
* 产品触发脚本处理
|
||||
* @param scriptTemplate
|
||||
* @return
|
||||
*/
|
||||
private boolean productTrigger(ScriptTemplate scriptTemplate) {
|
||||
// 判断定制触发(执行一次)或设备上报
|
||||
boolean isDeviceReport = StringUtils.isEmpty(deviceNum) ? false : true;
|
||||
if (isDeviceReport) {
|
||||
// 匹配产品编号
|
||||
boolean matchProductId = scriptTemplate.getProductId().equals(productId);
|
||||
if (scriptTemplate.getType() < 4) {
|
||||
// 匹配物模型标识符
|
||||
ThingsModelSimpleItem matchItem = null;
|
||||
if (thingsModelSimpleItems != null) {
|
||||
for (ThingsModelSimpleItem item : thingsModelSimpleItems) {
|
||||
if (item.getId().equals(scriptTemplate.getId())) {
|
||||
matchItem = item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (matchProductId && matchItem != null) {
|
||||
// 记录结果
|
||||
if (sceneThingsModelItems == null) {
|
||||
sceneThingsModelItems = new ArrayList<>();
|
||||
}
|
||||
SceneThingsModelItem sceneItem = new SceneThingsModelItem(scriptTemplate.getId(), matchItem.getValue(), type,
|
||||
scriptTemplate.getScriptId(), scriptTemplate.getSceneId(), scriptTemplate.getProductId(), deviceNum);
|
||||
sceneThingsModelItems.add(sceneItem);
|
||||
// 设备上报值匹配
|
||||
boolean isMatch = matchValue(scriptTemplate.getOperator(), scriptTemplate.getValue(), matchItem.getValue());
|
||||
if (isMatch) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// 上线,下线
|
||||
if (matchProductId && scriptTemplate.getType() == type) {
|
||||
// 记录结果
|
||||
if (sceneThingsModelItems == null) {
|
||||
sceneThingsModelItems = new ArrayList<>();
|
||||
}
|
||||
SceneThingsModelItem sceneItem = new SceneThingsModelItem(type == 5 ? "online" : "offline", type == 5 ? "1" : "0", type,
|
||||
scriptTemplate.getScriptId(), scriptTemplate.getSceneId(), scriptTemplate.getProductId(), deviceNum);
|
||||
sceneThingsModelItems.add(sceneItem);
|
||||
// 记录结果
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 定时触发/执行一次
|
||||
int resultCount = 0;
|
||||
// 查询设备最新上报值去匹配
|
||||
String[] deviceNums = deviceService.getDeviceNumsByProductId(scriptTemplate.getProductId());
|
||||
for (String num : deviceNums) {
|
||||
// 数组类型,key去除前缀,值从逗号分隔的字符串获取
|
||||
String id = "";
|
||||
String value = "";
|
||||
int index = 0;
|
||||
if (scriptTemplate.getId().startsWith("array_")) {
|
||||
id = scriptTemplate.getId().substring(9);
|
||||
index = Integer.parseInt(scriptTemplate.getId().substring(6, 8));
|
||||
} else {
|
||||
id = scriptTemplate.getId();
|
||||
}
|
||||
String key = RedisKeyBuilder.buildTSLVCacheKey(scriptTemplate.getProductId(), num);
|
||||
String cacheValue = redisCache.getCacheMapValue(key, id);
|
||||
if (StringUtils.isEmpty(cacheValue)) {
|
||||
continue;
|
||||
}
|
||||
ValueItem valueItem = JSON.parseObject(cacheValue, ValueItem.class);
|
||||
if (scriptTemplate.getId().startsWith("array_")) {
|
||||
String[] values = valueItem.getValue().split(",");
|
||||
value = values[index];
|
||||
} else {
|
||||
value = valueItem.getValue();
|
||||
}
|
||||
boolean isMatch = matchValue(scriptTemplate.getOperator(), scriptTemplate.getValue(), value);
|
||||
if (isMatch) {
|
||||
// 记录结果
|
||||
if (sceneThingsModelItems == null) {
|
||||
sceneThingsModelItems = new ArrayList<>();
|
||||
}
|
||||
SceneThingsModelItem sceneItem = new SceneThingsModelItem(scriptTemplate.getId(), value, type,
|
||||
scriptTemplate.getScriptId(), scriptTemplate.getSceneId(), scriptTemplate.getProductId(), num);
|
||||
sceneThingsModelItems.add(sceneItem);
|
||||
resultCount++;
|
||||
}
|
||||
}
|
||||
// 任意设备匹配成功返回true
|
||||
return resultCount > 0 ? true : false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 执行动作,下发指令
|
||||
*
|
||||
* @param scriptTemplate
|
||||
*/
|
||||
private void send(ScriptTemplate scriptTemplate) {
|
||||
String[] deviceNumbers = null;
|
||||
if (scriptTemplate.getSource() == 1) {
|
||||
// 下发给指定设备
|
||||
deviceNumbers = scriptTemplate.getDeviceNums().split(",");
|
||||
|
||||
} else if (scriptTemplate.getSource() == 3) {
|
||||
// 下发给产品下所有设备
|
||||
deviceNumbers = deviceService.getDeviceNumsByProductId(scriptTemplate.getProductId());
|
||||
}
|
||||
for (String deviceNum : deviceNumbers) {
|
||||
InvokeReqDto reqDto = new InvokeReqDto();
|
||||
reqDto.setProductId(scriptTemplate.getProductId());
|
||||
reqDto.setSerialNumber(deviceNum);
|
||||
reqDto.setModelName("");
|
||||
reqDto.setType(1);
|
||||
reqDto.setIdentifier(scriptTemplate.getId());
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put(scriptTemplate.getId(), scriptTemplate.getValue());
|
||||
reqDto.setRemoteCommand(params);
|
||||
reqDto.setValue(new JSONObject(reqDto.getRemoteCommand()));
|
||||
functionInvoke.invokeNoReply(reqDto);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行动作,告警处理
|
||||
*
|
||||
* @param sceneId 场景ID
|
||||
* @param delay 延时(单位秒,90秒内)
|
||||
*/
|
||||
/*private void alert(int delay, Long sceneId) {
|
||||
for (SceneThingsModelItem sceneThingsModelItem : sceneThingsModelItems) {
|
||||
// 查询设备信息
|
||||
Device device = deviceService.selectDeviceBySerialNumber(sceneThingsModelItem.getDeviceNumber());
|
||||
Optional.ofNullable(device).orElseThrow(() -> new ServiceException("告警推送,设备不存在" + "[{" + sceneThingsModelItem.getDeviceNumber() + "}]"));
|
||||
// 获取场景相关的告警参数,告警必须要是启动状态
|
||||
List<AlertSceneSendVO> sceneSendVOList = alertService.listByAlertIds(sceneId);
|
||||
if (CollectionUtils.isEmpty(sceneSendVOList)) {
|
||||
return;
|
||||
}
|
||||
// 获取告警推送参数
|
||||
AlertPushParams alertPushParams = new AlertPushParams();
|
||||
alertPushParams.setDeviceName(device.getDeviceName());
|
||||
alertPushParams.setSerialNumber(sceneThingsModelItem.getDeviceNumber());
|
||||
// 获取设备所属及分享用户信息
|
||||
List<DeviceUser> deviceUserList = deviceUserService.selectDeviceUserByDeviceId(device.getDeviceId());
|
||||
if (CollectionUtils.isNotEmpty(deviceUserList)) {
|
||||
alertPushParams.setUserPhoneSet(deviceUserList.stream().map(DeviceUser::getPhonenumber).filter(StringUtils::isNotEmpty).collect(Collectors.toSet()));
|
||||
alertPushParams.setUserIdSet(deviceUserList.stream().map(DeviceUser::getUserId).collect(Collectors.toSet()));
|
||||
}
|
||||
String address;
|
||||
if (StringUtils.isNotEmpty(device.getNetworkAddress())) {
|
||||
address = device.getNetworkAddress();
|
||||
} else if (StringUtils.isNotEmpty(device.getNetworkIp())) {
|
||||
address = device.getNetworkIp();
|
||||
} else if (Objects.nonNull(device.getLongitude()) && Objects.nonNull(device.getLatitude())) {
|
||||
address = device.getLongitude() + "," + device.getLatitude();
|
||||
} else {
|
||||
address = "未知地点";
|
||||
}
|
||||
alertPushParams.setAddress(address);
|
||||
alertPushParams.setAlertTime(DateUtils.parseDateToStr(DateUtils.YY_MM_DD_HH_MM_SS, new Date()));
|
||||
List<AlertLog> alertLogList = new ArrayList<>();
|
||||
// 获取告警关联模版id
|
||||
for (AlertSceneSendVO alertSceneSendVO : sceneSendVOList) {
|
||||
List<AlertNotifyTemplate> alertNotifyTemplateList = alertService.listAlertNotifyTemplate(alertSceneSendVO.getAlertId());
|
||||
alertPushParams.setAlertName(alertSceneSendVO.getAlertName());
|
||||
for (AlertNotifyTemplate alertNotifyTemplate : alertNotifyTemplateList) {
|
||||
alertPushParams.setNotifyTemplateId(alertNotifyTemplate.getNotifyTemplateId());
|
||||
notifySendService.alertSend(alertPushParams);
|
||||
}
|
||||
AlertLog alertLog = getAlertLog(alertSceneSendVO, device, sceneThingsModelItem);
|
||||
alertLogList.add(alertLog);
|
||||
}
|
||||
// 保存告警日志
|
||||
if (CollectionUtils.isNotEmpty(alertLogList)) {
|
||||
alertLogMapper.insertAlertLogBatch(alertLogList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*//**
|
||||
* 组装告警日志
|
||||
*
|
||||
* @param alertSceneSendVO
|
||||
* @return com.fastbee.iot.domain.AlertLog
|
||||
* @param: device
|
||||
*//*
|
||||
private AlertLog getAlertLog(AlertSceneSendVO alertSceneSendVO, Device device, SceneThingsModelItem sceneThingsModelItem) {
|
||||
AlertLog alertLog = new AlertLog();
|
||||
alertLog.setAlertName(alertSceneSendVO.getAlertName());
|
||||
alertLog.setAlertLevel(alertSceneSendVO.getAlertLevel());
|
||||
alertLog.setSerialNumber(sceneThingsModelItem.getDeviceNumber());
|
||||
alertLog.setProductId(sceneThingsModelItem.getProductId());
|
||||
alertLog.setDeviceName(device.getDeviceName());
|
||||
// 统一未处理
|
||||
alertLog.setStatus(2);
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("id", sceneThingsModelItem.getId());
|
||||
jsonObject.put("value", sceneThingsModelItem.getValue());
|
||||
jsonObject.put("remark", "");
|
||||
alertLog.setDetail(jsonObject.toJSONString());
|
||||
alertLog.setCreateTime(new Date());
|
||||
return alertLog;
|
||||
}*/
|
||||
|
||||
/**
|
||||
* 检查静默周期物模型值是否匹配
|
||||
*
|
||||
* @param operator 操作符
|
||||
* @param triggerValue 触发值
|
||||
* @param value 上报的值
|
||||
* @return
|
||||
*/
|
||||
private boolean matchValue(String operator, String triggerValue, String value) {
|
||||
boolean result = false;
|
||||
// 操作符比较
|
||||
switch (operator) {
|
||||
case "=":
|
||||
result = value.equals(triggerValue);
|
||||
break;
|
||||
case "!=":
|
||||
result = !value.equals(triggerValue);
|
||||
break;
|
||||
case ">":
|
||||
if (isNumeric(value) && isNumeric(triggerValue)) {
|
||||
result = Double.parseDouble(value) > Double.parseDouble(triggerValue);
|
||||
}
|
||||
break;
|
||||
case "<":
|
||||
if (isNumeric(value) && isNumeric(triggerValue)) {
|
||||
result = Double.parseDouble(value) < Double.parseDouble(triggerValue);
|
||||
}
|
||||
break;
|
||||
case ">=":
|
||||
if (isNumeric(value) && isNumeric(triggerValue)) {
|
||||
result = Double.parseDouble(value) >= Double.parseDouble(triggerValue);
|
||||
}
|
||||
break;
|
||||
case "<=":
|
||||
if (isNumeric(value) && isNumeric(triggerValue)) {
|
||||
result = Double.parseDouble(value) <= Double.parseDouble(triggerValue);
|
||||
}
|
||||
break;
|
||||
case "between":
|
||||
// 比较值用英文中划线分割 -
|
||||
String[] triggerValues = triggerValue.split("-");
|
||||
if (isNumeric(value) && isNumeric(triggerValues[0]) && isNumeric(triggerValues[1])) {
|
||||
result = Double.parseDouble(value) >= Double.parseDouble(triggerValues[0]) && Double.parseDouble(value) <= Double.parseDouble(triggerValues[1]);
|
||||
}
|
||||
break;
|
||||
case "notBetween":
|
||||
// 比较值用英文中划线分割 -
|
||||
String[] trigValues = triggerValue.split("-");
|
||||
if (isNumeric(value) && isNumeric(trigValues[0]) && isNumeric(trigValues[1])) {
|
||||
result = Double.parseDouble(value) <= Double.parseDouble(trigValues[0]) || Double.parseDouble(value) >= Double.parseDouble(trigValues[1]);
|
||||
}
|
||||
break;
|
||||
case "contain":
|
||||
result = value.contains(triggerValue);
|
||||
break;
|
||||
case "notContain":
|
||||
result = !value.contains(triggerValue);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查静默时间
|
||||
*
|
||||
* @param silent
|
||||
* @param sceneId
|
||||
* @return
|
||||
*/
|
||||
private boolean checkSilent(int silent, Long sceneId) {
|
||||
if (silent == 0 || sceneId == 0) {
|
||||
return true;
|
||||
}
|
||||
// silent:scene_场景编号
|
||||
String key = "silent:" + "scene_" + sceneId;
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
// 查询静默截止时间
|
||||
Long expireTime = redisCache.getCacheObject(key);
|
||||
if (expireTime == null) {
|
||||
// 添加场景静默时间
|
||||
calendar.add(Calendar.MINUTE, silent);
|
||||
redisCache.setCacheObject(key, calendar.getTimeInMillis());
|
||||
return true;
|
||||
} else {
|
||||
Long NowTimestamp = Calendar.getInstance().getTimeInMillis();
|
||||
if (NowTimestamp > expireTime) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新静默时间
|
||||
*
|
||||
* @param sceneId
|
||||
* @param silent
|
||||
*/
|
||||
private void updateSilent(int silent, Long sceneId) {
|
||||
if (silent == 0 || sceneId == 0) {
|
||||
return;
|
||||
}
|
||||
// 更新场景静默时间
|
||||
String key = "silent:" + "scene_" + sceneId;
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.add(Calendar.MINUTE, silent);
|
||||
redisCache.setCacheObject(key, calendar.getTimeInMillis());
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断字符串是否为整数或小数
|
||||
*/
|
||||
private boolean isNumeric(String str) {
|
||||
Pattern pattern = compile("[0-9]*\\.?[0-9]+");
|
||||
Matcher isNum = pattern.matcher(str);
|
||||
if (!isNum.matches()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
package com.fastbee.data.controller;
|
||||
|
||||
import com.fastbee.common.annotation.Log;
|
||||
import com.fastbee.common.core.controller.BaseController;
|
||||
import com.fastbee.common.core.domain.AjaxResult;
|
||||
import com.fastbee.common.core.domain.model.LoginUser;
|
||||
import com.fastbee.common.core.page.TableDataInfo;
|
||||
import com.fastbee.common.enums.BusinessType;
|
||||
import com.fastbee.common.utils.poi.ExcelUtil;
|
||||
import com.fastbee.iot.domain.Scene;
|
||||
import com.fastbee.iot.service.ISceneService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 场景联动Controller
|
||||
*
|
||||
* @author kerwincui
|
||||
* @date 2022-01-13
|
||||
*/
|
||||
@Api(tags = "场景联动")
|
||||
@RestController
|
||||
@RequestMapping("/iot/scene")
|
||||
public class SceneController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private ISceneService sceneService;
|
||||
|
||||
/**
|
||||
* 查询场景联动列表
|
||||
*/
|
||||
@ApiOperation("查询场景联动列表")
|
||||
@PreAuthorize("@ss.hasPermi('iot:scene:list')")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(Scene scene)
|
||||
{
|
||||
startPage();
|
||||
List<Scene> list = sceneService.selectSceneList(scene);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出场景联动列表
|
||||
*/
|
||||
@ApiOperation("导出场景联动列表")
|
||||
@PreAuthorize("@ss.hasPermi('iot:scene:export')")
|
||||
@Log(title = "场景联动", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(HttpServletResponse response, Scene scene)
|
||||
{
|
||||
List<Scene> list = sceneService.selectSceneList(scene);
|
||||
ExcelUtil<Scene> util = new ExcelUtil<Scene>(Scene.class);
|
||||
util.exportExcel(response, list, "场景联动数据");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取场景联动详细信息
|
||||
*/
|
||||
@ApiOperation("获取场景联动详细信息")
|
||||
@PreAuthorize("@ss.hasPermi('iot:scene:query')")
|
||||
@GetMapping(value = "/{sceneId}")
|
||||
public AjaxResult getInfo(@PathVariable("sceneId") Long sceneId)
|
||||
{
|
||||
return AjaxResult.success(sceneService.selectSceneBySceneId(sceneId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增场景联动
|
||||
*/
|
||||
@ApiOperation("新增场景联动")
|
||||
@PreAuthorize("@ss.hasPermi('iot:scene:add')")
|
||||
@Log(title = "场景联动", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public AjaxResult add(@RequestBody Scene scene)
|
||||
{
|
||||
LoginUser loginUser = getLoginUser();
|
||||
if (loginUser == null || loginUser.getUser() == null) {
|
||||
return error("请登录后重试!");
|
||||
}
|
||||
scene.setUserId(loginUser.getUser().getUserId());
|
||||
scene.setUserName(loginUser.getUser().getUserName());
|
||||
return toAjax(sceneService.insertScene(scene));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改场景联动
|
||||
*/
|
||||
@ApiOperation("修改场景联动")
|
||||
@PreAuthorize("@ss.hasPermi('iot:scene:edit')")
|
||||
@Log(title = "场景联动", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public AjaxResult edit(@RequestBody Scene scene)
|
||||
{
|
||||
return toAjax(sceneService.updateScene(scene));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除场景联动
|
||||
*/
|
||||
@ApiOperation("删除场景联动")
|
||||
@PreAuthorize("@ss.hasPermi('iot:scene:remove')")
|
||||
@Log(title = "场景联动", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{sceneIds}")
|
||||
public AjaxResult remove(@PathVariable Long[] sceneIds)
|
||||
{
|
||||
return toAjax(sceneService.deleteSceneBySceneIds(sceneIds));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改场景联动状态
|
||||
*/
|
||||
@ApiOperation("修改场景联动状态")
|
||||
@PreAuthorize("@ss.hasPermi('iot:scene:edit')")
|
||||
@Log(title = "场景联动", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/updateStatus")
|
||||
public AjaxResult updateStatus(@RequestBody Scene scene)
|
||||
{
|
||||
return toAjax(sceneService.updateStatus(scene));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
package com.fastbee.data.controller;
|
||||
|
||||
import com.fastbee.common.annotation.Log;
|
||||
import com.fastbee.common.core.controller.BaseController;
|
||||
import com.fastbee.common.core.domain.AjaxResult;
|
||||
import com.fastbee.common.core.page.TableDataInfo;
|
||||
import com.fastbee.common.enums.BusinessType;
|
||||
import com.fastbee.common.utils.poi.ExcelUtil;
|
||||
import com.fastbee.iot.domain.Script;
|
||||
import com.fastbee.iot.service.IScriptService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 规则引擎脚本Controller
|
||||
*
|
||||
* @author lizhuangpeng
|
||||
* @date 2023-07-01
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/iot/script")
|
||||
public class ScriptController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private IScriptService scriptService;
|
||||
|
||||
/**
|
||||
* 查询规则引擎脚本列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('iot:script:list')")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(Script ruleScript)
|
||||
{
|
||||
startPage();
|
||||
List<Script> list = scriptService.selectRuleScriptList(ruleScript);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出规则引擎脚本列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('iot:script:export')")
|
||||
@Log(title = "规则引擎脚本", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(HttpServletResponse response, Script ruleScript)
|
||||
{
|
||||
List<Script> list = scriptService.selectRuleScriptList(ruleScript);
|
||||
ExcelUtil<Script> util = new ExcelUtil<Script>(Script.class);
|
||||
util.exportExcel(response, list, "规则引擎脚本数据");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取规则引擎脚本详细信息
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('iot:script:query')")
|
||||
@GetMapping(value = "/{scriptId}")
|
||||
public AjaxResult getInfo(@PathVariable("scriptId") String scriptId)
|
||||
{
|
||||
return success(scriptService.selectRuleScriptById(scriptId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增规则引擎脚本
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('iot:script:add')")
|
||||
@Log(title = "规则引擎脚本", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public AjaxResult add(@RequestBody Script ruleScript)
|
||||
{
|
||||
return toAjax(scriptService.insertRuleScript(ruleScript));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改规则引擎脚本
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('iot:script:edit')")
|
||||
@Log(title = "规则引擎脚本", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public AjaxResult edit(@RequestBody Script ruleScript)
|
||||
{
|
||||
return toAjax(scriptService.updateRuleScript(ruleScript));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除规则引擎脚本
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('iot:script:remove')")
|
||||
@Log(title = "规则引擎脚本", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{scriptIds}")
|
||||
public AjaxResult remove(@PathVariable String[] scriptIds)
|
||||
{
|
||||
return toAjax(scriptService.deleteRuleScriptByIds(scriptIds));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除规则引擎脚本
|
||||
*/
|
||||
@PostMapping("/validate")
|
||||
public AjaxResult validateScript(@RequestBody Script ruleScript)
|
||||
{
|
||||
return scriptService.validateScript(ruleScript);
|
||||
}
|
||||
}
|
||||
@@ -331,4 +331,9 @@ public class DeviceJobServiceImpl implements IDeviceJobService
|
||||
{
|
||||
return CronUtils.isValid(cronExpression);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DeviceJob> listShortJobBySceneId(Long[] sceneIds) {
|
||||
return jobMapper.selectShortJobListBySceneIds(sceneIds);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,10 @@ import com.fastbee.common.core.mq.DeviceReportBo;
|
||||
import com.fastbee.common.core.redis.RedisCache;
|
||||
import com.fastbee.common.enums.ServerType;
|
||||
import com.fastbee.common.utils.DateUtils;
|
||||
import com.fastbee.common.utils.StringUtils;
|
||||
import com.fastbee.common.utils.gateway.mq.TopicsUtils;
|
||||
import com.fastbee.iot.ruleEngine.MsgContext;
|
||||
import com.fastbee.iot.ruleEngine.RuleProcess;
|
||||
import com.fastbee.mq.redischannel.producer.MessageProducer;
|
||||
import com.fastbee.mq.service.IDeviceReportMessageService;
|
||||
import com.fastbee.mqtt.annotation.Process;
|
||||
@@ -25,6 +28,8 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 客户端消息推送处理类
|
||||
@@ -44,6 +49,9 @@ public class MqttPublish implements MqttHandler {
|
||||
@Resource
|
||||
private IDeviceReportMessageService deviceReportMessageService;
|
||||
|
||||
@Resource
|
||||
private RuleProcess ruleProcess;
|
||||
|
||||
@Override
|
||||
public void handler(ChannelHandlerContext ctx, MqttMessage message) {
|
||||
MqttPublishMessage publishMessage = (MqttPublishMessage) message;
|
||||
@@ -81,6 +89,7 @@ public class MqttPublish implements MqttHandler {
|
||||
public void sendToMQ(MqttPublishMessage message) {
|
||||
/*获取topic*/
|
||||
String topicName = message.variableHeader().topicName();
|
||||
byte[] source = ByteBufUtil.getBytes(message.content());
|
||||
/*只处理上报数据*/
|
||||
if (!topicName.endsWith(FastBeeConstant.MQTT.UP_TOPIC_SUFFIX)) {
|
||||
return;
|
||||
@@ -102,6 +111,13 @@ public class MqttPublish implements MqttHandler {
|
||||
/*设备上报数据*/
|
||||
reportBo.setReportType(1);
|
||||
}
|
||||
// 规则引擎脚本处理,完成后返回结果
|
||||
MsgContext context = ruleProcess.processRuleScript(reportBo.getSerialNumber(),1, topicName, new String(source));
|
||||
if (!Objects.isNull(context) && StringUtils.isNotEmpty(context.getPayload())
|
||||
&& StringUtils.isNotEmpty(context.getTopic())) {
|
||||
reportBo.setTopicName(context.getTopic());
|
||||
reportBo.setData(context.getPayload().getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
if (topicName.contains("property")) {
|
||||
deviceReportMessageService.parseReportMsg(reportBo);
|
||||
}
|
||||
|
||||
@@ -24,6 +24,8 @@ import com.fastbee.iot.domain.FunctionLog;
|
||||
import com.fastbee.iot.domain.Product;
|
||||
import com.fastbee.iot.model.NtpModel;
|
||||
import com.fastbee.iot.model.ThingsModels.PropertyDto;
|
||||
import com.fastbee.iot.ruleEngine.MsgContext;
|
||||
import com.fastbee.iot.ruleEngine.RuleProcess;
|
||||
import com.fastbee.iot.service.IDeviceService;
|
||||
import com.fastbee.iot.service.IProductService;
|
||||
import com.fastbee.iot.service.IThingsModelService;
|
||||
@@ -37,7 +39,6 @@ import com.fastbee.mq.service.IMqttMessagePublish;
|
||||
import com.fastbee.mqtt.manager.MqttRemoteManager;
|
||||
import com.fastbee.mqtt.model.PushMessageBo;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.java_websocket.protocols.IProtocol;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
@@ -76,6 +77,9 @@ public class MqttMessagePublishImpl implements IMqttMessagePublish {
|
||||
private JsonProtocolService jsonProtocolService;
|
||||
private SnowflakeIdWorker snowflakeIdWorker = new SnowflakeIdWorker(3);
|
||||
|
||||
@Resource
|
||||
private RuleProcess ruleProcess;
|
||||
|
||||
|
||||
@Override
|
||||
public InstructionsMessage buildMessage(DeviceDownMessage downMessage, TopicType type) {
|
||||
@@ -145,19 +149,19 @@ public class MqttMessagePublishImpl implements IMqttMessagePublish {
|
||||
}
|
||||
|
||||
/* 下发服务数据存储对象*/
|
||||
FunctionLog log = new FunctionLog();
|
||||
log.setCreateTime(DateUtils.getNowDate());
|
||||
log.setFunValue(bo.getValue().get(bo.getIdentifier()).toString());
|
||||
log.setMessageId(bo.getMessageId());
|
||||
log.setSerialNumber(bo.getSerialNumber());
|
||||
log.setIdentify(bo.getIdentifier());
|
||||
log.setShowValue(bo.getShowValue());
|
||||
log.setFunType(1);
|
||||
log.setModelName(bo.getModelName());
|
||||
FunctionLog funcLog = new FunctionLog();
|
||||
funcLog.setCreateTime(DateUtils.getNowDate());
|
||||
funcLog.setFunValue(bo.getValue().get(bo.getIdentifier()).toString());
|
||||
funcLog.setMessageId(bo.getMessageId());
|
||||
funcLog.setSerialNumber(bo.getSerialNumber());
|
||||
funcLog.setIdentify(bo.getIdentifier());
|
||||
funcLog.setShowValue(bo.getShowValue());
|
||||
funcLog.setFunType(1);
|
||||
funcLog.setModelName(bo.getModelName());
|
||||
//兼容子设备
|
||||
if (null != bo.getSlaveId()) {
|
||||
PropertyDto thingModels = thingsModelService.getSingleThingModels(bo.getProductId(), bo.getIdentifier() + "#" + bo.getSlaveId());
|
||||
log.setSerialNumber(bo.getSerialNumber() + "_" + bo.getSlaveId());
|
||||
funcLog.setSerialNumber(bo.getSerialNumber() + "_" + bo.getSlaveId());
|
||||
bo.setCode(ModbusCode.Write06);
|
||||
if (!Objects.isNull(thingModels.getCode())){
|
||||
bo.setCode(ModbusCode.getInstance(Integer.parseInt(thingModels.getCode())));
|
||||
@@ -182,8 +186,17 @@ public class MqttMessagePublishImpl implements IMqttMessagePublish {
|
||||
case MQTT:
|
||||
//组建下发服务指令
|
||||
InstructionsMessage instruction = buildMessage(downMessage, TopicType.FUNCTION_GET);
|
||||
mqttClient.publish(instruction.getTopicName(), instruction.getMessage(), log);
|
||||
MqttMessagePublishImpl.log.debug("=>服务下发,topic=[{}],指令=[{}]", instruction.getTopicName(),new String(instruction.getMessage()));
|
||||
|
||||
// 规则引擎脚本处理,完成后返回结果
|
||||
MsgContext context = ruleProcess.processRuleScript(bo.getSerialNumber(), 2,instruction.getTopicName(),new String(instruction.getMessage()));
|
||||
if (!Objects.isNull(context) && StringUtils.isNotEmpty(context.getPayload())
|
||||
&& StringUtils.isNotEmpty(context.getTopic())) {
|
||||
instruction.setTopicName(context.getTopic());
|
||||
instruction.setMessage(context.getPayload().getBytes());
|
||||
}
|
||||
|
||||
mqttClient.publish(instruction.getTopicName(), instruction.getMessage(), funcLog);
|
||||
log.debug("=>服务下发,topic=[{}],指令=[{}]", instruction.getTopicName(),new String(instruction.getMessage()));
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
@@ -15,6 +15,10 @@
|
||||
设备业务模块
|
||||
</description>
|
||||
|
||||
<properties>
|
||||
<liteflow.version>2.11.3</liteflow.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- 通用工具-->
|
||||
@@ -102,6 +106,24 @@
|
||||
<artifactId>hutool-all</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.yomahub</groupId>
|
||||
<artifactId>liteflow-spring-boot-starter</artifactId>
|
||||
<version>${liteflow.version}</version>
|
||||
</dependency>
|
||||
<!--数据库规则配置源插件-->
|
||||
<dependency>
|
||||
<groupId>com.yomahub</groupId>
|
||||
<artifactId>liteflow-rule-sql</artifactId>
|
||||
<version>${liteflow.version}</version>
|
||||
</dependency>
|
||||
<!--groovy脚本插件-->
|
||||
<dependency>
|
||||
<groupId>com.yomahub</groupId>
|
||||
<artifactId>liteflow-script-groovy</artifactId>
|
||||
<version>${liteflow.version}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
||||
@@ -0,0 +1,244 @@
|
||||
package com.fastbee.iot.domain;
|
||||
|
||||
import com.fastbee.common.annotation.Excel;
|
||||
import com.fastbee.common.core.domain.BaseEntity;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 场景联动对象 iot_scene
|
||||
*
|
||||
* @author kerwincui
|
||||
* @date 2023-12-27
|
||||
*/
|
||||
public class Scene extends BaseEntity
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 场景ID */
|
||||
private Long sceneId;
|
||||
|
||||
/** 场景名称 */
|
||||
@Excel(name = "场景名称")
|
||||
private String sceneName;
|
||||
|
||||
/** 规则名称 */
|
||||
private String chainName;
|
||||
|
||||
/** 用户ID */
|
||||
@Excel(name = "用户ID")
|
||||
private Long userId;
|
||||
|
||||
/** 用户名称 */
|
||||
@Excel(name = "用户名称")
|
||||
private String userName;
|
||||
|
||||
/** 执行条件(1=或、任一条件,2=且、所有条件,3=非,不满足) */
|
||||
@Excel(name = "执行条件", readConverterExp = "1==或、任一条件,2=且、所有条件,3=非,不满足")
|
||||
private Integer cond;
|
||||
|
||||
/** 静默周期(分钟) */
|
||||
@Excel(name = "静默周期", readConverterExp = "分=钟")
|
||||
private Integer silentPeriod;
|
||||
|
||||
/** 执行方式(1=串行,顺序执行,2=并行,同时执行) */
|
||||
@Excel(name = "执行方式", readConverterExp = "1==串行,顺序执行,2=并行,同时执行")
|
||||
private Integer executeMode;
|
||||
|
||||
/** 延时执行(秒钟) */
|
||||
@Excel(name = "延时执行", readConverterExp = "秒=钟")
|
||||
private Integer executeDelay;
|
||||
|
||||
/** 是否包含告警推送(1=包含,2=不包含) */
|
||||
@Excel(name = "是否包含告警推送", readConverterExp = "1==包含,2=不包含")
|
||||
private Integer hasAlert;
|
||||
|
||||
/** 场景状态(1-启动,2-停止) */
|
||||
@Excel(name = "场景状态", readConverterExp = "1=-启动,2-停止")
|
||||
private Integer enable;
|
||||
|
||||
/** 规则数据 */
|
||||
@Excel(name = "规则数据")
|
||||
private String elData;
|
||||
|
||||
/** 应用名称 */
|
||||
@Excel(name = "应用名称")
|
||||
private String applicationName;
|
||||
|
||||
/** 接收的触发器列表 */
|
||||
private List<SceneScript> triggers;
|
||||
|
||||
/** 接收的执行动作列表 */
|
||||
private List<SceneScript> actions;
|
||||
|
||||
/**
|
||||
* 执行动作数量
|
||||
*/
|
||||
private Integer actionCount = 0;
|
||||
|
||||
public Integer getActionCount() {
|
||||
return actionCount;
|
||||
}
|
||||
|
||||
public void setActionCount(Integer actionCount) {
|
||||
this.actionCount = actionCount;
|
||||
}
|
||||
|
||||
public String getChainName() {
|
||||
return chainName;
|
||||
}
|
||||
|
||||
public void setChainName(String chainName) {
|
||||
this.chainName = chainName;
|
||||
}
|
||||
|
||||
public List<SceneScript> getTriggers() {
|
||||
return triggers;
|
||||
}
|
||||
|
||||
public void setTriggers(List<SceneScript> triggers) {
|
||||
this.triggers = triggers;
|
||||
}
|
||||
|
||||
public List<SceneScript> getActions() {
|
||||
return actions;
|
||||
}
|
||||
|
||||
public void setActions(List<SceneScript> actions) {
|
||||
this.actions = actions;
|
||||
}
|
||||
|
||||
public void setSceneId(Long sceneId)
|
||||
{
|
||||
this.sceneId = sceneId;
|
||||
}
|
||||
|
||||
public Long getSceneId()
|
||||
{
|
||||
return sceneId;
|
||||
}
|
||||
public void setSceneName(String sceneName)
|
||||
{
|
||||
this.sceneName = sceneName;
|
||||
}
|
||||
|
||||
public String getSceneName()
|
||||
{
|
||||
return sceneName;
|
||||
}
|
||||
public void setUserId(Long userId)
|
||||
{
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public Long getUserId()
|
||||
{
|
||||
return userId;
|
||||
}
|
||||
public void setUserName(String userName)
|
||||
{
|
||||
this.userName = userName;
|
||||
}
|
||||
|
||||
public String getUserName()
|
||||
{
|
||||
return userName;
|
||||
}
|
||||
public void setCond(Integer cond)
|
||||
{
|
||||
this.cond = cond;
|
||||
}
|
||||
|
||||
public Integer getCond()
|
||||
{
|
||||
return cond;
|
||||
}
|
||||
public void setSilentPeriod(Integer silentPeriod)
|
||||
{
|
||||
this.silentPeriod = silentPeriod;
|
||||
}
|
||||
|
||||
public Integer getSilentPeriod()
|
||||
{
|
||||
return silentPeriod;
|
||||
}
|
||||
public void setExecuteMode(Integer executeMode)
|
||||
{
|
||||
this.executeMode = executeMode;
|
||||
}
|
||||
|
||||
public Integer getExecuteMode()
|
||||
{
|
||||
return executeMode;
|
||||
}
|
||||
public void setExecuteDelay(Integer executeDelay)
|
||||
{
|
||||
this.executeDelay = executeDelay;
|
||||
}
|
||||
|
||||
public Integer getExecuteDelay()
|
||||
{
|
||||
return executeDelay;
|
||||
}
|
||||
public void setHasAlert(Integer hasAlert)
|
||||
{
|
||||
this.hasAlert = hasAlert;
|
||||
}
|
||||
|
||||
public Integer getHasAlert()
|
||||
{
|
||||
return hasAlert;
|
||||
}
|
||||
public void setEnable(Integer enable)
|
||||
{
|
||||
this.enable = enable;
|
||||
}
|
||||
|
||||
public Integer getEnable()
|
||||
{
|
||||
return enable;
|
||||
}
|
||||
public void setElData(String elData)
|
||||
{
|
||||
this.elData = elData;
|
||||
}
|
||||
|
||||
public String getElData()
|
||||
{
|
||||
return elData;
|
||||
}
|
||||
public void setApplicationName(String applicationName)
|
||||
{
|
||||
this.applicationName = applicationName;
|
||||
}
|
||||
|
||||
public String getApplicationName()
|
||||
{
|
||||
return applicationName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
||||
.append("sceneId", getSceneId())
|
||||
.append("sceneName", getSceneName())
|
||||
.append("userId", getUserId())
|
||||
.append("userName", getUserName())
|
||||
.append("createBy", getCreateBy())
|
||||
.append("createTime", getCreateTime())
|
||||
.append("updateBy", getUpdateBy())
|
||||
.append("updateTime", getUpdateTime())
|
||||
.append("remark", getRemark())
|
||||
.append("cond", getCond())
|
||||
.append("silentPeriod", getSilentPeriod())
|
||||
.append("executeMode", getExecuteMode())
|
||||
.append("executeDelay", getExecuteDelay())
|
||||
.append("hasAlert", getHasAlert())
|
||||
.append("enable", getEnable())
|
||||
.append("elData", getElData())
|
||||
.append("applicationName", getApplicationName())
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
package com.fastbee.iot.domain;
|
||||
|
||||
import com.fastbee.common.annotation.Excel;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
||||
/**
|
||||
* 场景设备对象 iot_scene_device
|
||||
*
|
||||
* @author kerwincui
|
||||
* @date 2023-12-28
|
||||
*/
|
||||
public class SceneDevice
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 场景设备ID */
|
||||
private Long sceneDeviceId;
|
||||
|
||||
/** 设备编号(产品触发的没有设备编号) */
|
||||
@Excel(name = "设备编号", readConverterExp = "产=品触发的没有设备编号")
|
||||
private String serialNumber;
|
||||
|
||||
/** 产品ID */
|
||||
@Excel(name = "产品ID")
|
||||
private Long productId;
|
||||
|
||||
/** 产品ID */
|
||||
@Excel(name = "产品名称")
|
||||
private String productName;
|
||||
|
||||
/** 场景脚本ID */
|
||||
@Excel(name = "场景脚本ID")
|
||||
private String scriptId;
|
||||
|
||||
/** 场景ID */
|
||||
@Excel(name = "场景ID")
|
||||
private Long sceneId;
|
||||
|
||||
/** 触发源(1=设备触发,3=产品触发) */
|
||||
@Excel(name = "触发源", readConverterExp = "1==设备触发,3=产品触发")
|
||||
private Integer source;
|
||||
|
||||
/** 类型(2=触发器,3=执行动作) */
|
||||
private Integer type;
|
||||
|
||||
public Integer getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(Integer type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getProductName() {
|
||||
return productName;
|
||||
}
|
||||
|
||||
public void setProductName(String productName) {
|
||||
this.productName = productName;
|
||||
}
|
||||
|
||||
public void setSceneDeviceId(Long sceneDeviceId)
|
||||
{
|
||||
this.sceneDeviceId = sceneDeviceId;
|
||||
}
|
||||
|
||||
public Long getSceneDeviceId()
|
||||
{
|
||||
return sceneDeviceId;
|
||||
}
|
||||
public void setSerialNumber(String serialNumber)
|
||||
{
|
||||
this.serialNumber = serialNumber;
|
||||
}
|
||||
|
||||
public String getSerialNumber()
|
||||
{
|
||||
return serialNumber;
|
||||
}
|
||||
public void setProductId(Long productId)
|
||||
{
|
||||
this.productId = productId;
|
||||
}
|
||||
|
||||
public Long getProductId()
|
||||
{
|
||||
return productId;
|
||||
}
|
||||
public void setScriptId(String scriptId)
|
||||
{
|
||||
this.scriptId = scriptId;
|
||||
}
|
||||
|
||||
public String getScriptId()
|
||||
{
|
||||
return scriptId;
|
||||
}
|
||||
public void setSceneId(Long sceneId)
|
||||
{
|
||||
this.sceneId = sceneId;
|
||||
}
|
||||
|
||||
public Long getSceneId()
|
||||
{
|
||||
return sceneId;
|
||||
}
|
||||
public void setSource(Integer source)
|
||||
{
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
public Integer getSource()
|
||||
{
|
||||
return source;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
||||
.append("sceneDeviceId", getSceneDeviceId())
|
||||
.append("serialNumber", getSerialNumber())
|
||||
.append("productId", getProductId())
|
||||
.append("scriptId", getScriptId())
|
||||
.append("sceneId", getSceneId())
|
||||
.append("source", getSource())
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,278 @@
|
||||
package com.fastbee.iot.domain;
|
||||
|
||||
import com.fastbee.common.annotation.Excel;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 场景脚本对象 iot_scene_script
|
||||
*
|
||||
* @author kerwincui
|
||||
* @date 2023-12-27
|
||||
*/
|
||||
@ApiModel(value = "SceneScript", description = "场景脚本")
|
||||
public class SceneScript
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 场景脚本ID */
|
||||
private String scriptId;
|
||||
|
||||
/** 脚本ID */
|
||||
@Excel(name = "场景ID")
|
||||
private Long sceneId;
|
||||
|
||||
/** 触发源(1=设备触发,2=定时触发,3=产品触发,4=执行告警) */
|
||||
@Excel(name = "触发源", readConverterExp = "1=设备触发,2=定时触发,3=产品触发,4=执行告警")
|
||||
private Integer source;
|
||||
|
||||
/** 脚本用途(1=数据流,2=触发器,3=执行动作) */
|
||||
private Integer scriptPurpose;
|
||||
|
||||
/** 物模型标识符 */
|
||||
private String id;
|
||||
|
||||
/** 物模型名称 */
|
||||
@Excel(name = "物模型名称")
|
||||
private String name;
|
||||
|
||||
/** 物模型值 */
|
||||
@Excel(name = "物模型值")
|
||||
private String value;
|
||||
|
||||
/** 操作符 */
|
||||
@Excel(name = "操作符")
|
||||
private String operator;
|
||||
|
||||
/** 物模型类别(1=属性,2=功能,3=事件,4=设备升级,5=设备上线,6=设备下线) */
|
||||
@Excel(name = "物模型类别", readConverterExp = "1==属性,2=功能,3=事件,4=设备升级,5=设备上线,6=设备下线")
|
||||
private Integer type;
|
||||
|
||||
/** 设备数量 */
|
||||
@Excel(name = "设备数量")
|
||||
private Integer deviceCount;
|
||||
|
||||
/** 任务ID */
|
||||
@Excel(name = "任务ID")
|
||||
private Long jobId;
|
||||
|
||||
/** cron执行表达式 */
|
||||
@Excel(name = "cron执行表达式")
|
||||
private String cronExpression;
|
||||
|
||||
/** 是否详细corn表达式(1=是,0=否) */
|
||||
@Excel(name = "是否详细corn表达式", readConverterExp = "1==是,0=否")
|
||||
private Integer isAdvance;
|
||||
|
||||
/** 父物模id */
|
||||
@Excel(name = "父物模id")
|
||||
private String parentId;
|
||||
|
||||
/** 父物模名称 */
|
||||
@Excel(name = "父物模名称")
|
||||
private String parentName;
|
||||
|
||||
/** 数组索引 */
|
||||
@Excel(name = "数组索引")
|
||||
private String arrayIndex;
|
||||
|
||||
/** 数组索引名称(前端展示使用) */
|
||||
@Excel(name = "数组索引名称", readConverterExp = "前=端展示使用")
|
||||
private String arrayIndexName;
|
||||
|
||||
/** 产品ID*/
|
||||
private Long productId;
|
||||
|
||||
/** 产品名称*/
|
||||
private String productName;
|
||||
|
||||
/** 设备编号,仅用于传递*/
|
||||
private String[] deviceNums;
|
||||
|
||||
/** 创建者 */
|
||||
private String createBy;
|
||||
|
||||
/** 创建时间 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date createTime;
|
||||
|
||||
public String getScriptId() {
|
||||
return scriptId;
|
||||
}
|
||||
|
||||
public void setScriptId(String scriptId) {
|
||||
this.scriptId = scriptId;
|
||||
}
|
||||
|
||||
public Long getSceneId() {
|
||||
return sceneId;
|
||||
}
|
||||
|
||||
public void setSceneId(Long sceneId) {
|
||||
this.sceneId = sceneId;
|
||||
}
|
||||
|
||||
public Integer getSource() {
|
||||
return source;
|
||||
}
|
||||
|
||||
public void setSource(Integer source) {
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getOperator() {
|
||||
return operator;
|
||||
}
|
||||
|
||||
public void setOperator(String operator) {
|
||||
this.operator = operator;
|
||||
}
|
||||
|
||||
public Integer getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(Integer type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Integer getDeviceCount() {
|
||||
return deviceCount;
|
||||
}
|
||||
|
||||
public void setDeviceCount(Integer deviceCount) {
|
||||
this.deviceCount = deviceCount;
|
||||
}
|
||||
|
||||
public Long getJobId() {
|
||||
return jobId;
|
||||
}
|
||||
|
||||
public void setJobId(Long jobId) {
|
||||
this.jobId = jobId;
|
||||
}
|
||||
|
||||
public String getCronExpression() {
|
||||
return cronExpression;
|
||||
}
|
||||
|
||||
public void setCronExpression(String cronExpression) {
|
||||
this.cronExpression = cronExpression;
|
||||
}
|
||||
|
||||
public Integer getIsAdvance() {
|
||||
return isAdvance;
|
||||
}
|
||||
|
||||
public void setIsAdvance(Integer isAdvance) {
|
||||
this.isAdvance = isAdvance;
|
||||
}
|
||||
|
||||
public String getParentId() {
|
||||
return parentId;
|
||||
}
|
||||
|
||||
public void setParentId(String parentId) {
|
||||
this.parentId = parentId;
|
||||
}
|
||||
|
||||
public String getParentName() {
|
||||
return parentName;
|
||||
}
|
||||
|
||||
public void setParentName(String parentName) {
|
||||
this.parentName = parentName;
|
||||
}
|
||||
|
||||
public String getArrayIndex() {
|
||||
return arrayIndex;
|
||||
}
|
||||
|
||||
public void setArrayIndex(String arrayIndex) {
|
||||
this.arrayIndex = arrayIndex;
|
||||
}
|
||||
|
||||
public String getArrayIndexName() {
|
||||
return arrayIndexName;
|
||||
}
|
||||
|
||||
public void setArrayIndexName(String arrayIndexName) {
|
||||
this.arrayIndexName = arrayIndexName;
|
||||
}
|
||||
|
||||
public Long getProductId() {
|
||||
return productId;
|
||||
}
|
||||
|
||||
public void setProductId(Long productId) {
|
||||
this.productId = productId;
|
||||
}
|
||||
|
||||
public String getProductName() {
|
||||
return productName;
|
||||
}
|
||||
|
||||
public void setProductName(String productName) {
|
||||
this.productName = productName;
|
||||
}
|
||||
|
||||
public String[] getDeviceNums() {
|
||||
return deviceNums;
|
||||
}
|
||||
|
||||
public void setDeviceNums(String[] deviceNums) {
|
||||
this.deviceNums = deviceNums;
|
||||
}
|
||||
|
||||
public String getCreateBy() {
|
||||
return createBy;
|
||||
}
|
||||
|
||||
public void setCreateBy(String createBy) {
|
||||
this.createBy = createBy;
|
||||
}
|
||||
|
||||
public Date getCreateTime() {
|
||||
return createTime;
|
||||
}
|
||||
|
||||
public void setCreateTime(Date createTime) {
|
||||
this.createTime = createTime;
|
||||
}
|
||||
|
||||
public Integer getScriptPurpose() {
|
||||
return scriptPurpose;
|
||||
}
|
||||
|
||||
public void setScriptPurpose(Integer scriptPurpose) {
|
||||
this.scriptPurpose = scriptPurpose;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
package com.fastbee.iot.domain;
|
||||
|
||||
import com.fastbee.common.annotation.Excel;
|
||||
import com.fastbee.common.core.domain.BaseEntity;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
||||
/**
|
||||
* 规则引擎脚本对象 rule_script
|
||||
*
|
||||
* @author lizhuangpeng
|
||||
* @date 2023-07-01
|
||||
*/
|
||||
public class Script extends BaseEntity
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 脚本ID */
|
||||
@Excel(name = "脚本ID")
|
||||
private String scriptId;
|
||||
|
||||
/** 用户ID */
|
||||
private Long userId;
|
||||
|
||||
/** 用名称 */
|
||||
private String userName;
|
||||
|
||||
/** 应用名 */
|
||||
@Excel(name = "应用名")
|
||||
private String applicationName;
|
||||
|
||||
/** 脚本名 */
|
||||
@Excel(name = "脚本名")
|
||||
private String scriptName;
|
||||
|
||||
/** 脚本数据 */
|
||||
@Excel(name = "脚本数据")
|
||||
private String scriptData;
|
||||
|
||||
/** 脚本类型:script=普通脚本,switch_script=选择脚本,if_script=条件脚本,for_script=数量循环脚本,while_script=条件循环,break_script=退出循环脚本 */
|
||||
@Excel(name = "脚本类型")
|
||||
private String scriptType;
|
||||
|
||||
/** 场景ID */
|
||||
private Long sceneId;
|
||||
|
||||
/** 脚本类型(1=设备上报,2=平台下发,3=设备上线,4=设备离线) */
|
||||
private Integer scriptEvent;
|
||||
|
||||
/** 脚本动作(1=消息重发,2=消息通知,3=Http推送,4=Mqtt桥接,5=数据库存储) */
|
||||
private Integer scriptAction;
|
||||
|
||||
/** 脚本用途(1=数据流,2=触发器,3=执行动作) */
|
||||
private Integer scriptPurpose;
|
||||
|
||||
/** 脚本执行顺序,值越大优先级越高 */
|
||||
private Integer scriptOrder;
|
||||
|
||||
/** 脚本语言(groovy | qlexpress | js | python | lua | aviator) */
|
||||
@Excel(name = "脚本语言", readConverterExp = "groovy,,qlexpress,js,python,lua,aviator")
|
||||
private String scriptLanguage;
|
||||
|
||||
/** 产品ID */
|
||||
private Long productId;
|
||||
|
||||
/** 产品名称 */
|
||||
|
||||
private String productName;
|
||||
|
||||
/**是否生效*/
|
||||
private Integer enable;
|
||||
|
||||
/** 删除标志(0代表存在 2代表删除) */
|
||||
private String delFlag;
|
||||
|
||||
public String getProductName() {
|
||||
return productName;
|
||||
}
|
||||
|
||||
public void setProductName(String productName) {
|
||||
this.productName = productName;
|
||||
}
|
||||
|
||||
public Long getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(Long userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public String getUserName() {
|
||||
return userName;
|
||||
}
|
||||
|
||||
public void setUserName(String userName) {
|
||||
this.userName = userName;
|
||||
}
|
||||
|
||||
public Long getSceneId() {
|
||||
return sceneId;
|
||||
}
|
||||
|
||||
public void setSceneId(Long sceneId) {
|
||||
this.sceneId = sceneId;
|
||||
}
|
||||
|
||||
public Integer getScriptEvent() {
|
||||
return scriptEvent;
|
||||
}
|
||||
|
||||
public void setScriptEvent(Integer scriptEvent) {
|
||||
this.scriptEvent = scriptEvent;
|
||||
}
|
||||
|
||||
public Integer getScriptAction() {
|
||||
return scriptAction;
|
||||
}
|
||||
|
||||
public void setScriptAction(Integer scriptAction) {
|
||||
this.scriptAction = scriptAction;
|
||||
}
|
||||
|
||||
public Integer getScriptPurpose() {
|
||||
return scriptPurpose;
|
||||
}
|
||||
|
||||
public void setScriptPurpose(Integer scriptPurpose) {
|
||||
this.scriptPurpose = scriptPurpose;
|
||||
}
|
||||
|
||||
public Integer getScriptOrder() {
|
||||
return scriptOrder;
|
||||
}
|
||||
|
||||
public void setScriptOrder(Integer scriptOrder) {
|
||||
this.scriptOrder = scriptOrder;
|
||||
}
|
||||
|
||||
public void setApplicationName(String applicationName)
|
||||
{
|
||||
this.applicationName = applicationName;
|
||||
}
|
||||
|
||||
public String getApplicationName()
|
||||
{
|
||||
return applicationName;
|
||||
}
|
||||
public void setScriptId(String scriptId)
|
||||
{
|
||||
this.scriptId = scriptId;
|
||||
}
|
||||
|
||||
public String getScriptId()
|
||||
{
|
||||
return scriptId;
|
||||
}
|
||||
public void setScriptName(String scriptName)
|
||||
{
|
||||
this.scriptName = scriptName;
|
||||
}
|
||||
|
||||
public String getScriptName()
|
||||
{
|
||||
return scriptName;
|
||||
}
|
||||
public void setScriptData(String scriptData)
|
||||
{
|
||||
this.scriptData = scriptData;
|
||||
}
|
||||
|
||||
public String getScriptData()
|
||||
{
|
||||
return scriptData;
|
||||
}
|
||||
public void setScriptType(String scriptType)
|
||||
{
|
||||
this.scriptType = scriptType;
|
||||
}
|
||||
|
||||
public String getScriptType()
|
||||
{
|
||||
return scriptType;
|
||||
}
|
||||
public void setScriptLanguage(String scriptLanguage)
|
||||
{
|
||||
this.scriptLanguage = scriptLanguage;
|
||||
}
|
||||
|
||||
public String getScriptLanguage()
|
||||
{
|
||||
return scriptLanguage;
|
||||
}
|
||||
public void setDelFlag(String delFlag)
|
||||
{
|
||||
this.delFlag = delFlag;
|
||||
}
|
||||
|
||||
public Integer getEnable() {
|
||||
return enable;
|
||||
}
|
||||
|
||||
public void setEnable(Integer enable) {
|
||||
this.enable = enable;
|
||||
}
|
||||
|
||||
public String getDelFlag()
|
||||
{
|
||||
return delFlag;
|
||||
}
|
||||
|
||||
public Long getProductId() {
|
||||
return productId;
|
||||
}
|
||||
|
||||
public void setProductId(Long productId) {
|
||||
this.productId = productId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
||||
.append("applicationName", getApplicationName())
|
||||
.append("scriptId", getScriptId())
|
||||
.append("scriptName", getScriptName())
|
||||
.append("scriptData", getScriptData())
|
||||
.append("scriptType", getScriptType())
|
||||
.append("scriptLanguage", getScriptLanguage())
|
||||
.append("delFlag", getDelFlag())
|
||||
.append("createBy", getCreateBy())
|
||||
.append("createTime", getCreateTime())
|
||||
.append("updateBy", getUpdateBy())
|
||||
.append("updateTime", getUpdateTime())
|
||||
.append("remark", getRemark())
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
@@ -295,4 +295,11 @@ public interface DeviceMapper
|
||||
* @return
|
||||
*/
|
||||
DeviceRelateAlertLogVO selectRelateAlertLogBySerialNumber(String deviceNumber);
|
||||
|
||||
/**
|
||||
* 根据产品ID获取产品下所有编号
|
||||
* @param productId
|
||||
* @return
|
||||
*/
|
||||
public String[] getDeviceNumsByProductId(Long productId);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
package com.fastbee.iot.mapper;
|
||||
|
||||
import com.fastbee.iot.domain.Scene;
|
||||
import com.fastbee.iot.domain.SceneDevice;
|
||||
import com.fastbee.iot.model.SceneDeviceBindVO;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 场景设备Mapper接口
|
||||
*
|
||||
* @author kerwincui
|
||||
* @date 2023-12-28
|
||||
*/
|
||||
@Repository
|
||||
public interface SceneDeviceMapper
|
||||
{
|
||||
/**
|
||||
* 查询场景设备
|
||||
*
|
||||
* @param sceneDeviceId 场景设备主键
|
||||
* @return 场景设备
|
||||
*/
|
||||
public SceneDevice selectSceneDeviceBySceneDeviceId(Long sceneDeviceId);
|
||||
|
||||
/**
|
||||
* 查询场景设备列表
|
||||
*
|
||||
* @param sceneDevice 场景设备
|
||||
* @return 场景设备集合
|
||||
*/
|
||||
public List<SceneDevice> selectSceneDeviceList(SceneDevice sceneDevice);
|
||||
|
||||
/**
|
||||
* 新增场景设备
|
||||
*
|
||||
* @param sceneDevice 场景设备
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertSceneDevice(SceneDevice sceneDevice);
|
||||
|
||||
/**
|
||||
* 修改场景设备
|
||||
*
|
||||
* @param sceneDevice 场景设备
|
||||
* @return 结果
|
||||
*/
|
||||
public int updateSceneDevice(SceneDevice sceneDevice);
|
||||
|
||||
/**
|
||||
* 删除场景设备
|
||||
*
|
||||
* @param sceneDeviceId 场景设备主键
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteSceneDeviceBySceneDeviceId(Long sceneDeviceId);
|
||||
|
||||
/**
|
||||
* 批量删除场景设备
|
||||
*
|
||||
* @param sceneDeviceIds 需要删除的数据主键集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteSceneDeviceBySceneDeviceIds(Long[] sceneDeviceIds);
|
||||
|
||||
/**
|
||||
* 批量删除场景设备
|
||||
*
|
||||
* @param sceneIds 需要删除的数据场景ID集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteSceneDeviceBySceneIds(Long[] sceneIds);
|
||||
|
||||
/**
|
||||
* 批量新增场景脚本
|
||||
*
|
||||
* @param sceneDeviceList 场景联动触发器集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertSceneDeviceList(List<SceneDevice> sceneDeviceList);
|
||||
|
||||
/**
|
||||
* 查询设备关联的场景列表
|
||||
*
|
||||
* @param sceneDevice 场景设备
|
||||
* @return 场景设备集合
|
||||
*/
|
||||
public List<Scene> selectTriggerDeviceRelateScenes(SceneDevice sceneDevice);
|
||||
|
||||
/**
|
||||
* 查询场景联动绑定产品
|
||||
* @param productIds 产品id数组
|
||||
* @return java.util.List<com.fastbee.iot.model.SceneDeviceBindVO>
|
||||
*/
|
||||
List<SceneDeviceBindVO> listSceneProductBind(Long[] productIds);
|
||||
|
||||
/**
|
||||
* 查询场景联动绑定设备
|
||||
* @param serialNumber 设备编号
|
||||
* @return java.util.List<com.fastbee.iot.model.SceneDeviceBindVO>
|
||||
*/
|
||||
List<SceneDeviceBindVO> listSceneDeviceBind(String serialNumber);
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package com.fastbee.iot.mapper;
|
||||
|
||||
import com.fastbee.iot.domain.Scene;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 场景联动Mapper接口
|
||||
*
|
||||
* @author kerwincui
|
||||
* @date 2022-01-13
|
||||
*/
|
||||
@Repository
|
||||
public interface SceneMapper
|
||||
{
|
||||
/**
|
||||
* 查询场景联动
|
||||
*
|
||||
* @param sceneId 场景联动主键
|
||||
* @return 场景联动
|
||||
*/
|
||||
public Scene selectSceneBySceneId(Long sceneId);
|
||||
|
||||
/**
|
||||
* 查询场景联动列表
|
||||
*
|
||||
* @param scene 场景联动
|
||||
* @return 场景联动集合
|
||||
*/
|
||||
public List<Scene> selectSceneList(Scene scene);
|
||||
|
||||
/**
|
||||
* 新增场景联动
|
||||
*
|
||||
* @param scene 场景联动
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertScene(Scene scene);
|
||||
|
||||
|
||||
/**
|
||||
* 修改场景联动
|
||||
*
|
||||
* @param scene 场景联动
|
||||
* @return 结果
|
||||
*/
|
||||
public int updateScene(Scene scene);
|
||||
|
||||
/**
|
||||
* 删除场景联动
|
||||
*
|
||||
* @param sceneId 场景联动主键
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteSceneBySceneId(Long sceneId);
|
||||
|
||||
/**
|
||||
* 批量删除场景联动
|
||||
*
|
||||
* @param sceneIds 需要删除的数据主键集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteSceneBySceneIds(Long[] sceneIds);
|
||||
|
||||
/**
|
||||
* 根据ids批量查询场景联动
|
||||
* @param sceneIds 场景联动id数组
|
||||
* @return 集合
|
||||
*/
|
||||
List<Scene> selectSceneListBySceneIds(Long[] sceneIds);
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package com.fastbee.iot.mapper;
|
||||
|
||||
import com.fastbee.iot.domain.SceneScript;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 场景脚本Mapper接口
|
||||
*
|
||||
* @author kerwincui
|
||||
* @date 2023-12-27
|
||||
*/
|
||||
@Repository
|
||||
public interface SceneScriptMapper
|
||||
{
|
||||
/**
|
||||
* 查询场景脚本
|
||||
*
|
||||
* @param scriptId 场景脚本主键
|
||||
* @return 场景脚本
|
||||
*/
|
||||
public SceneScript selectSceneScriptBySceneScriptId(String scriptId);
|
||||
|
||||
/**
|
||||
* 查询场景脚本列表
|
||||
*
|
||||
* @param sceneScript 场景脚本
|
||||
* @return 场景脚本集合
|
||||
*/
|
||||
public List<SceneScript> selectSceneScriptList(SceneScript sceneScript);
|
||||
|
||||
/**
|
||||
* 新增场景脚本
|
||||
*
|
||||
* @param sceneScript 场景脚本
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertSceneScript(SceneScript sceneScript);
|
||||
|
||||
/**
|
||||
* 修改场景脚本
|
||||
*
|
||||
* @param sceneScript 场景脚本
|
||||
* @return 结果
|
||||
*/
|
||||
public int updateSceneScript(SceneScript sceneScript);
|
||||
|
||||
/**
|
||||
* 删除场景脚本
|
||||
*
|
||||
* @param scriptId 场景脚本主键
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteSceneScriptBySceneScriptId(String scriptId);
|
||||
|
||||
/**
|
||||
* 批量删除场景脚本
|
||||
*
|
||||
* @param scriptIds 需要删除的数据主键集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteSceneScriptBySceneScriptIds(String[] scriptIds);
|
||||
|
||||
/**
|
||||
* 批量删除场景联动脚本
|
||||
*
|
||||
* @param sceneIds 需要删除的数据场景ID集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteSceneScriptBySceneIds(Long[] sceneIds);
|
||||
|
||||
/**
|
||||
* 批量新增场景脚本
|
||||
*
|
||||
* @param sceneScriptList 场景联动触发器集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertSceneScriptList(List<SceneScript> sceneScriptList);
|
||||
|
||||
/**
|
||||
* 通过脚本用途批量查询
|
||||
* @param sceneIdList 场景id
|
||||
* @param: scriptPurpose 脚本用途
|
||||
* @return java.util.List<com.fastbee.iot.domain.SceneScript>
|
||||
*/
|
||||
List<SceneScript> listSceneScriptByPurpose(@Param("sceneIdList") List<Long> sceneIdList, @Param("scriptPurpose") Integer scriptPurpose);
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
package com.fastbee.iot.mapper;
|
||||
|
||||
import com.fastbee.iot.domain.Script;
|
||||
import com.fastbee.iot.model.ScriptCondition;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 规则引擎脚本Mapper接口
|
||||
*
|
||||
* @author lizhuangpeng
|
||||
* @date 2023-07-01
|
||||
*/
|
||||
@Repository
|
||||
public interface ScriptMapper
|
||||
{
|
||||
/**
|
||||
* 查询规则引擎脚本
|
||||
*
|
||||
* @param scriptId 规则引擎脚本主键
|
||||
* @return 规则引擎脚本
|
||||
*/
|
||||
public Script selectRuleScriptById(String scriptId);
|
||||
|
||||
/**
|
||||
* 查询规则引擎脚本列表
|
||||
*
|
||||
* @param ruleScript 规则引擎脚本
|
||||
* @return 规则引擎脚本集合
|
||||
*/
|
||||
public List<Script> selectRuleScriptList(Script ruleScript);
|
||||
|
||||
/**
|
||||
* 查询规则引擎脚本标识数组
|
||||
*
|
||||
* @return 规则引擎脚本数组
|
||||
*/
|
||||
public String[] selectRuleScriptIdArray(ScriptCondition scriptCondition);
|
||||
|
||||
/***
|
||||
* 查询scriptId的数量
|
||||
* @param scriptId
|
||||
* @return
|
||||
*/
|
||||
public int selectRuleScriptIdCount(String scriptId);
|
||||
|
||||
/**
|
||||
* 新增规则引擎脚本
|
||||
*
|
||||
* @param ruleScript 规则引擎脚本
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertRuleScript(Script ruleScript);
|
||||
|
||||
/**
|
||||
* 修改规则引擎脚本
|
||||
*
|
||||
* @param ruleScript 规则引擎脚本
|
||||
* @return 结果
|
||||
*/
|
||||
public int updateRuleScript(Script ruleScript);
|
||||
|
||||
/**
|
||||
* 删除规则引擎脚本
|
||||
*
|
||||
* @param scriptId 规则引擎脚本主键
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteRuleScriptById(String scriptId);
|
||||
|
||||
/**
|
||||
* 批量删除规则引擎脚本
|
||||
*
|
||||
* @param scriptIds 需要删除的数据主键集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteRuleScriptByIds(String[] scriptIds);
|
||||
|
||||
/**
|
||||
* 批量删除规则脚本
|
||||
*
|
||||
* @param sceneIds 需要删除的数据场景ID集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteRuleScriptBySceneIds(Long[] sceneIds);
|
||||
|
||||
/**
|
||||
* 批量新增场景脚本
|
||||
*
|
||||
* @param ruleScriptList 场景联动触发器集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertRuleScriptList(List<Script> ruleScriptList);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.fastbee.iot.model;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author fastb
|
||||
* @version 1.0
|
||||
* @description: 场景关联设备、产品VO类
|
||||
* @date 2024-02-06 15:10
|
||||
*/
|
||||
@Data
|
||||
public class SceneDeviceBindVO {
|
||||
|
||||
/**
|
||||
* 场景联动id
|
||||
*/
|
||||
private Long sceneId;
|
||||
|
||||
/**
|
||||
* 场景联动名称
|
||||
*/
|
||||
private String sceneName;
|
||||
|
||||
/**
|
||||
* 产品id
|
||||
*/
|
||||
private Long productId;
|
||||
|
||||
/**
|
||||
* 设备编号
|
||||
*/
|
||||
private String serialNumber;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.fastbee.iot.model;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
|
||||
/**
|
||||
* 规则引擎脚本查询条件
|
||||
* @author kerwin
|
||||
*/
|
||||
@Data
|
||||
public class ScriptCondition
|
||||
{
|
||||
/** 用户ID */
|
||||
private Long userId;
|
||||
|
||||
/** 租户ID */
|
||||
private Long tencentId;
|
||||
|
||||
/** 应用名 */
|
||||
private String applicationName;
|
||||
|
||||
/** 脚本ID */
|
||||
private String scriptId;
|
||||
|
||||
/** 脚本名 */
|
||||
private String scriptName;
|
||||
|
||||
/** 脚本类型 */
|
||||
private String scriptType;
|
||||
/**
|
||||
* 关联的产品ID
|
||||
*/
|
||||
private Long productId;
|
||||
|
||||
/** 场景ID */
|
||||
private Long sceneId;
|
||||
|
||||
/** 脚本类型(1=设备上报,2=平台下发,3=设备上线,4=设备离线) */
|
||||
private Integer scriptEvent;
|
||||
|
||||
/** 脚本动作(1=消息重发,2=消息通知,3=Http推送,4=Mqtt桥接,5=数据库存储) */
|
||||
private Integer scriptAction;
|
||||
|
||||
/** 脚本用途(1=数据流,2=触发器,3=执行动作) */
|
||||
private Integer scriptPurpose;
|
||||
|
||||
/** 脚本语言(groovy | ql express | js | python | lua | aviator) */
|
||||
private String scriptLanguage;
|
||||
|
||||
/**是否生效*/
|
||||
private Integer enable;
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.fastbee.iot.model;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class ScriptTemplate {
|
||||
/** 场景ID */
|
||||
private Long sceneId;
|
||||
|
||||
/** 脚本ID */
|
||||
private String scriptId;
|
||||
|
||||
/** 类型 1=属性, 2=功能,3=事件,4=设备升级,5=设备上线,6=设备下线 */
|
||||
private int type;
|
||||
|
||||
/** 触发执行源 1=设备触发/执行 2=定时触发 3=产品触发/执行 4=告警执行 */
|
||||
private int source;
|
||||
|
||||
/** 静默时间,单位分钟 */
|
||||
private int silent;
|
||||
|
||||
/** 延迟执行,单位秒钟 */
|
||||
private int delay;
|
||||
|
||||
/** 执行条件(1=或、任意条件,2=且、所有条件,3=非,不满足) */
|
||||
private int cond;
|
||||
|
||||
/** 脚本用途,1=数据流,2=触发器,3=执行动作 */
|
||||
private int purpose;
|
||||
|
||||
/** 物模型标识符 */
|
||||
private String id;
|
||||
|
||||
/** 物模型值 */
|
||||
private String value;
|
||||
|
||||
/** 比较操作符,等于/不等于/大于/小于/包含/不包含/在...之间/不在...之间 */
|
||||
private String operator;
|
||||
|
||||
/** 设备编号,多个设备英文逗号分隔 */
|
||||
private String deviceNums;
|
||||
|
||||
/** 所属产品编号 */
|
||||
private Long productId;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.fastbee.iot.ruleEngine;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class MsgContext {
|
||||
|
||||
/** 消息主题 */
|
||||
private String topic;
|
||||
|
||||
/** 消息内容 */
|
||||
private String payload;
|
||||
/**
|
||||
* 设备编号
|
||||
*/
|
||||
private String serialNumber;
|
||||
/**
|
||||
* 产品id
|
||||
*/
|
||||
private Long productId;
|
||||
/**
|
||||
* 协议编码
|
||||
*/
|
||||
private String protocolCode;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.fastbee.iot.ruleEngine;
|
||||
|
||||
import com.fastbee.common.core.redis.RedisCache;
|
||||
import com.yomahub.liteflow.script.annotation.ScriptBean;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 规则引擎上下文执行方法
|
||||
* @author gsb
|
||||
* @date 2024/2/2 14:19
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
@ScriptBean("msgContextService")
|
||||
public class MsgContextService {
|
||||
|
||||
private final RedisCache redisCache;
|
||||
|
||||
public MsgContextService(RedisCache redisCache){
|
||||
this.redisCache = redisCache;
|
||||
}
|
||||
|
||||
private void process(String serialNumber){
|
||||
//执行的业务逻辑
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package com.fastbee.iot.ruleEngine;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.fastbee.common.core.redis.RedisCache;
|
||||
import com.fastbee.common.core.redis.RedisKeyBuilder;
|
||||
import com.fastbee.iot.model.ProductCode;
|
||||
import com.fastbee.iot.model.ScriptCondition;
|
||||
import com.fastbee.iot.service.IProductService;
|
||||
import com.fastbee.iot.service.IScriptService;
|
||||
import com.yomahub.liteflow.builder.el.LiteFlowChainELBuilder;
|
||||
import com.yomahub.liteflow.core.FlowExecutor;
|
||||
import com.yomahub.liteflow.flow.LiteflowResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 执行规则引擎
|
||||
*
|
||||
* @author gsb
|
||||
* @date 2024/2/3 16:07
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class RuleProcess {
|
||||
|
||||
@Resource
|
||||
private FlowExecutor flowExecutor;
|
||||
@Resource
|
||||
private IScriptService scriptService;
|
||||
@Resource
|
||||
private RedisCache redisCache;
|
||||
@Resource
|
||||
private IProductService productService;
|
||||
|
||||
/**
|
||||
* 规则引擎脚本处理
|
||||
*
|
||||
* @param topic
|
||||
* @param payload
|
||||
* @param event 1=设备上报 2=平台下发 3=设备上线 4=设备下线 (其他可以增加设备完成主题订阅之类)
|
||||
* @return
|
||||
*/
|
||||
public MsgContext processRuleScript(String serialNumber, int event, String topic, String payload) {
|
||||
System.out.println("执行产品规则脚本...");
|
||||
ProductCode productCode = getDeviceDetail(serialNumber);
|
||||
if (Objects.isNull(productCode)){
|
||||
return new MsgContext();
|
||||
}
|
||||
// 查询数据流脚本组件
|
||||
ScriptCondition scriptCondition = new ScriptCondition();
|
||||
scriptCondition.setProductId(productCode.getProductId());
|
||||
scriptCondition.setScriptEvent(event); // 事件 1=设备上报 2=平台下发 3=设备上线 4=设备下线
|
||||
scriptCondition.setScriptPurpose(1); // 脚本用途:数据流=1
|
||||
String[] scriptIds = scriptService.selectRuleScriptIdArray(scriptCondition);
|
||||
MsgContext context = new MsgContext(topic, payload, serialNumber, productCode.getProductId(), productCode.getProtocolCode());
|
||||
//如果查询不到脚本,则认为是不用处理
|
||||
if (Objects.isNull(scriptIds) || scriptIds.length == 0) {
|
||||
return new MsgContext();
|
||||
}
|
||||
// 动态构造Chain和EL表达式
|
||||
String el = String.join(",", scriptIds); // THEN(a,b,c,d)
|
||||
LiteFlowChainELBuilder.createChain().setChainName("dataChain").setEL("THEN(" + el + ")").build();
|
||||
// 执行规则脚本
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("dataChain", null, context);
|
||||
if (!response.isSuccess()) {
|
||||
log.error("规则脚本执行发生错误:" + response.getMessage());
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询产品id,协议编号,缓存到redis,后续查询协议的地方替换数据库查询
|
||||
*
|
||||
* @param serialNumber
|
||||
*/
|
||||
public ProductCode getDeviceDetail(String serialNumber) {
|
||||
ProductCode productCode;
|
||||
String cacheKey = RedisKeyBuilder.buildDeviceMsgCacheKey(serialNumber);
|
||||
if (redisCache.containsKey(cacheKey)) {
|
||||
Object cacheObject = redisCache.getCacheObject(cacheKey);
|
||||
return JSON.parseObject(cacheObject.toString(), ProductCode.class);
|
||||
}
|
||||
productCode = productService.getProtocolBySerialNumber(serialNumber);
|
||||
String jsonString = JSON.toJSONString(productCode);
|
||||
redisCache.setCacheObject(cacheKey, jsonString);
|
||||
return productCode;
|
||||
}
|
||||
}
|
||||
@@ -124,4 +124,11 @@ public interface IDeviceJobService
|
||||
* @return 结果
|
||||
*/
|
||||
public boolean checkCronExpressionIsValid(String cronExpression);
|
||||
|
||||
/**
|
||||
* 通过场景id查询关联定时任务
|
||||
* @param sceneIds 场景id
|
||||
* @return java.util.List<com.fastbee.iot.domain.DeviceJob>
|
||||
*/
|
||||
List<DeviceJob> listShortJobBySceneId(Long[] sceneIds);
|
||||
}
|
||||
|
||||
@@ -260,4 +260,11 @@ public interface IDeviceService
|
||||
* @return
|
||||
*/
|
||||
public DeviceMqttConnectVO getMqttConnectData(Long deviceId);
|
||||
|
||||
/**
|
||||
* 根据产品ID获取产品下所有编号
|
||||
* @param productId
|
||||
* @return
|
||||
*/
|
||||
public String[] getDeviceNumsByProductId(Long productId);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.fastbee.iot.service;
|
||||
|
||||
import com.fastbee.iot.domain.SceneDevice;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 场景设备Service接口
|
||||
*
|
||||
* @author kerwincui
|
||||
* @date 2023-12-28
|
||||
*/
|
||||
public interface ISceneDeviceService
|
||||
{
|
||||
/**
|
||||
* 查询场景设备
|
||||
*
|
||||
* @param sceneDeviceId 场景设备主键
|
||||
* @return 场景设备
|
||||
*/
|
||||
public SceneDevice selectSceneDeviceBySceneDeviceId(Long sceneDeviceId);
|
||||
|
||||
/**
|
||||
* 查询场景设备列表
|
||||
*
|
||||
* @param sceneDevice 场景设备
|
||||
* @return 场景设备集合
|
||||
*/
|
||||
public List<SceneDevice> selectSceneDeviceList(SceneDevice sceneDevice);
|
||||
|
||||
/**
|
||||
* 新增场景设备
|
||||
*
|
||||
* @param sceneDevice 场景设备
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertSceneDevice(SceneDevice sceneDevice);
|
||||
|
||||
/**
|
||||
* 修改场景设备
|
||||
*
|
||||
* @param sceneDevice 场景设备
|
||||
* @return 结果
|
||||
*/
|
||||
public int updateSceneDevice(SceneDevice sceneDevice);
|
||||
|
||||
/**
|
||||
* 批量删除场景设备
|
||||
*
|
||||
* @param sceneDeviceIds 需要删除的场景设备主键集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteSceneDeviceBySceneDeviceIds(Long[] sceneDeviceIds);
|
||||
|
||||
/**
|
||||
* 删除场景设备信息
|
||||
*
|
||||
* @param sceneDeviceId 场景设备主键
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteSceneDeviceBySceneDeviceId(Long sceneDeviceId);
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.fastbee.iot.service;
|
||||
|
||||
import com.fastbee.iot.domain.SceneScript;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 场景脚本Service接口
|
||||
*
|
||||
* @author kerwincui
|
||||
* @date 2023-12-27
|
||||
*/
|
||||
public interface ISceneScriptService
|
||||
{
|
||||
/**
|
||||
* 查询场景脚本
|
||||
*
|
||||
* @param scriptId 场景脚本主键
|
||||
* @return 场景脚本
|
||||
*/
|
||||
public SceneScript selectSceneScriptBySceneScriptId(String scriptId);
|
||||
|
||||
/**
|
||||
* 查询场景脚本列表
|
||||
*
|
||||
* @param sceneScript 场景脚本
|
||||
* @return 场景脚本集合
|
||||
*/
|
||||
public List<SceneScript> selectSceneScriptList(SceneScript sceneScript);
|
||||
|
||||
/**
|
||||
* 新增场景脚本
|
||||
*
|
||||
* @param sceneScript 场景脚本
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertSceneScript(SceneScript sceneScript);
|
||||
|
||||
/**
|
||||
* 修改场景脚本
|
||||
*
|
||||
* @param sceneScript 场景脚本
|
||||
* @return 结果
|
||||
*/
|
||||
public int updateSceneScript(SceneScript sceneScript);
|
||||
|
||||
/**
|
||||
* 批量删除场景脚本
|
||||
*
|
||||
* @param scriptIds 需要删除的场景脚本主键集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteSceneScriptBySceneScriptIds(String[] scriptIds);
|
||||
|
||||
/**
|
||||
* 删除场景脚本信息
|
||||
*
|
||||
* @param scriptId 场景脚本主键
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteSceneScriptBySceneScriptId(String scriptId);
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package com.fastbee.iot.service;
|
||||
|
||||
import com.fastbee.iot.domain.Scene;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 场景联动Service接口
|
||||
*
|
||||
* @author kerwincui
|
||||
* @date 2022-01-13
|
||||
*/
|
||||
public interface ISceneService
|
||||
{
|
||||
/**
|
||||
* 查询场景联动
|
||||
*
|
||||
* @param sceneId 场景联动主键
|
||||
* @return 场景联动
|
||||
*/
|
||||
public Scene selectSceneBySceneId(Long sceneId);
|
||||
|
||||
/**
|
||||
* 查询场景联动列表
|
||||
*
|
||||
* @param scene 场景联动
|
||||
* @return 场景联动集合
|
||||
*/
|
||||
public List<Scene> selectSceneList(Scene scene);
|
||||
|
||||
/**
|
||||
* 新增场景联动
|
||||
*
|
||||
* @param scene 场景联动
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertScene(Scene scene);
|
||||
|
||||
|
||||
/**
|
||||
* 修改场景联动
|
||||
*
|
||||
* @param scene 场景联动
|
||||
* @return 结果
|
||||
*/
|
||||
public int updateScene(Scene scene);
|
||||
|
||||
/**
|
||||
* 批量删除场景联动
|
||||
*
|
||||
* @param sceneIds 需要删除的场景联动主键集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteSceneBySceneIds(Long[] sceneIds);
|
||||
|
||||
/**
|
||||
* 删除场景联动信息
|
||||
*
|
||||
* @param sceneId 场景联动主键
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteSceneBySceneId(Long sceneId);
|
||||
|
||||
/**
|
||||
* 修改场景联动状态
|
||||
* @param scene 场景联动
|
||||
* @return int
|
||||
*/
|
||||
int updateStatus(Scene scene);
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package com.fastbee.iot.service;
|
||||
|
||||
import com.fastbee.common.core.domain.AjaxResult;
|
||||
import com.fastbee.iot.domain.Script;
|
||||
import com.fastbee.iot.model.ScriptCondition;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 规则引擎脚本Service接口
|
||||
*
|
||||
* @author lizhuangpeng
|
||||
* @date 2023-07-01
|
||||
*/
|
||||
public interface IScriptService
|
||||
{
|
||||
/**
|
||||
* 查询规则引擎脚本
|
||||
*
|
||||
* @param scriptId 规则引擎脚本主键
|
||||
* @return 规则引擎脚本
|
||||
*/
|
||||
public Script selectRuleScriptById(String scriptId);
|
||||
|
||||
/**
|
||||
* 查询规则引擎脚本列表
|
||||
*
|
||||
* @param ruleScript 规则引擎脚本
|
||||
* @return 规则引擎脚本集合
|
||||
*/
|
||||
public List<Script> selectRuleScriptList(Script ruleScript);
|
||||
|
||||
/**
|
||||
* 查询规则引擎脚本标识数组(设备用户和租户的脚本)
|
||||
*
|
||||
* @return 规则引擎脚本
|
||||
*/
|
||||
public String[] selectRuleScriptIdArray(ScriptCondition scriptCondition);
|
||||
|
||||
/**
|
||||
* 新增规则引擎脚本
|
||||
*
|
||||
* @param ruleScript 规则引擎脚本
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertRuleScript(Script ruleScript);
|
||||
|
||||
/**
|
||||
* 修改规则引擎脚本
|
||||
*
|
||||
* @param ruleScript 规则引擎脚本
|
||||
* @return 结果
|
||||
*/
|
||||
public int updateRuleScript(Script ruleScript);
|
||||
|
||||
/**
|
||||
* 批量删除规则引擎脚本
|
||||
*
|
||||
* @param ids 需要删除的规则引擎脚本主键集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteRuleScriptByIds(String[] ids);
|
||||
|
||||
/**
|
||||
* 删除规则引擎脚本信息
|
||||
*
|
||||
* @param id 规则引擎脚本主键
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteRuleScriptById(String id);
|
||||
|
||||
|
||||
/**
|
||||
* 验证脚本
|
||||
* @param ruleScript 脚本数据
|
||||
* @return
|
||||
*/
|
||||
public AjaxResult validateScript(Script ruleScript);
|
||||
}
|
||||
@@ -1309,4 +1309,13 @@ public class DeviceServiceImpl implements IDeviceService {
|
||||
return valueList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据产品ID获取产品下所有编号
|
||||
* @param productId
|
||||
* @return
|
||||
*/
|
||||
public String[] getDeviceNumsByProductId(Long productId){
|
||||
return deviceMapper.getDeviceNumsByProductId(productId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
package com.fastbee.iot.service.impl;
|
||||
|
||||
import com.fastbee.iot.domain.SceneDevice;
|
||||
import com.fastbee.iot.mapper.SceneDeviceMapper;
|
||||
import com.fastbee.iot.service.ISceneDeviceService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 场景设备Service业务层处理
|
||||
*
|
||||
* @author kerwincui
|
||||
* @date 2023-12-28
|
||||
*/
|
||||
@Service
|
||||
public class SceneDeviceServiceImpl implements ISceneDeviceService
|
||||
{
|
||||
@Autowired
|
||||
private SceneDeviceMapper sceneDeviceMapper;
|
||||
|
||||
/**
|
||||
* 查询场景设备
|
||||
*
|
||||
* @param sceneDeviceId 场景设备主键
|
||||
* @return 场景设备
|
||||
*/
|
||||
@Override
|
||||
public SceneDevice selectSceneDeviceBySceneDeviceId(Long sceneDeviceId)
|
||||
{
|
||||
return sceneDeviceMapper.selectSceneDeviceBySceneDeviceId(sceneDeviceId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询场景设备列表
|
||||
*
|
||||
* @param sceneDevice 场景设备
|
||||
* @return 场景设备
|
||||
*/
|
||||
@Override
|
||||
public List<SceneDevice> selectSceneDeviceList(SceneDevice sceneDevice)
|
||||
{
|
||||
return sceneDeviceMapper.selectSceneDeviceList(sceneDevice);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增场景设备
|
||||
*
|
||||
* @param sceneDevice 场景设备
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int insertSceneDevice(SceneDevice sceneDevice)
|
||||
{
|
||||
return sceneDeviceMapper.insertSceneDevice(sceneDevice);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改场景设备
|
||||
*
|
||||
* @param sceneDevice 场景设备
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int updateSceneDevice(SceneDevice sceneDevice)
|
||||
{
|
||||
return sceneDeviceMapper.updateSceneDevice(sceneDevice);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除场景设备
|
||||
*
|
||||
* @param sceneDeviceIds 需要删除的场景设备主键
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deleteSceneDeviceBySceneDeviceIds(Long[] sceneDeviceIds)
|
||||
{
|
||||
return sceneDeviceMapper.deleteSceneDeviceBySceneDeviceIds(sceneDeviceIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除场景设备信息
|
||||
*
|
||||
* @param sceneDeviceId 场景设备主键
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deleteSceneDeviceBySceneDeviceId(Long sceneDeviceId)
|
||||
{
|
||||
return sceneDeviceMapper.deleteSceneDeviceBySceneDeviceId(sceneDeviceId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
package com.fastbee.iot.service.impl;
|
||||
|
||||
import com.fastbee.common.utils.DateUtils;
|
||||
import com.fastbee.iot.domain.SceneScript;
|
||||
import com.fastbee.iot.mapper.SceneScriptMapper;
|
||||
import com.fastbee.iot.service.ISceneScriptService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 场景脚本Service业务层处理
|
||||
*
|
||||
* @author kerwincui
|
||||
* @date 2023-12-27
|
||||
*/
|
||||
@Service
|
||||
public class SceneScriptServiceImpl implements ISceneScriptService
|
||||
{
|
||||
@Autowired
|
||||
private SceneScriptMapper sceneScriptMapper;
|
||||
|
||||
/**
|
||||
* 查询场景脚本
|
||||
*
|
||||
* @param scriptId 场景脚本主键
|
||||
* @return 场景脚本
|
||||
*/
|
||||
@Override
|
||||
public SceneScript selectSceneScriptBySceneScriptId(String scriptId)
|
||||
{
|
||||
return sceneScriptMapper.selectSceneScriptBySceneScriptId(scriptId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询场景脚本列表
|
||||
*
|
||||
* @param sceneScript 场景脚本
|
||||
* @return 场景脚本
|
||||
*/
|
||||
@Override
|
||||
public List<SceneScript> selectSceneScriptList(SceneScript sceneScript)
|
||||
{
|
||||
return sceneScriptMapper.selectSceneScriptList(sceneScript);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增场景脚本
|
||||
*
|
||||
* @param sceneScript 场景脚本
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int insertSceneScript(SceneScript sceneScript)
|
||||
{
|
||||
sceneScript.setCreateTime(DateUtils.getNowDate());
|
||||
return sceneScriptMapper.insertSceneScript(sceneScript);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改场景脚本
|
||||
*
|
||||
* @param sceneScript 场景脚本
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int updateSceneScript(SceneScript sceneScript)
|
||||
{
|
||||
return sceneScriptMapper.updateSceneScript(sceneScript);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除场景脚本
|
||||
*
|
||||
* @param scriptIds 需要删除的场景脚本主键
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deleteSceneScriptBySceneScriptIds(String[] scriptIds)
|
||||
{
|
||||
return sceneScriptMapper.deleteSceneScriptBySceneScriptIds(scriptIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除场景脚本信息
|
||||
*
|
||||
* @param scriptId 场景脚本主键
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deleteSceneScriptBySceneScriptId(String scriptId)
|
||||
{
|
||||
return sceneScriptMapper.deleteSceneScriptBySceneScriptId(scriptId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,605 @@
|
||||
package com.fastbee.iot.service.impl;
|
||||
|
||||
import cn.hutool.core.lang.Snowflake;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.fastbee.common.core.domain.entity.SysRole;
|
||||
import com.fastbee.common.core.domain.entity.SysUser;
|
||||
import com.fastbee.common.core.redis.RedisCache;
|
||||
import com.fastbee.common.exception.job.TaskException;
|
||||
import com.fastbee.common.utils.DateUtils;
|
||||
import com.fastbee.common.utils.StringUtils;
|
||||
import com.fastbee.iot.domain.*;
|
||||
import com.fastbee.iot.mapper.SceneDeviceMapper;
|
||||
import com.fastbee.iot.mapper.SceneMapper;
|
||||
import com.fastbee.iot.mapper.SceneScriptMapper;
|
||||
import com.fastbee.iot.mapper.ScriptMapper;
|
||||
import com.fastbee.iot.model.ScriptTemplate;
|
||||
import com.fastbee.iot.service.IDeviceJobService;
|
||||
import com.fastbee.iot.service.ISceneService;
|
||||
import com.fastbee.quartz.util.CronUtils;
|
||||
import com.yomahub.liteflow.builder.LiteFlowNodeBuilder;
|
||||
import com.yomahub.liteflow.builder.el.LiteFlowChainELBuilder;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang.StringEscapeUtils;
|
||||
import org.quartz.Scheduler;
|
||||
import org.quartz.SchedulerException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.fastbee.common.utils.SecurityUtils.getLoginUser;
|
||||
|
||||
/**
|
||||
* 场景联动Service业务层处理
|
||||
*
|
||||
* @author kerwincui
|
||||
* @date 2022-01-13
|
||||
*/
|
||||
@Service
|
||||
public class SceneServiceImpl implements ISceneService {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(SceneServiceImpl.class);
|
||||
|
||||
@Autowired
|
||||
private Scheduler scheduler;
|
||||
|
||||
@Autowired
|
||||
RedisCache redisCache;
|
||||
|
||||
@Autowired
|
||||
private SceneMapper sceneMapper;
|
||||
|
||||
@Autowired
|
||||
private IDeviceJobService jobService;
|
||||
|
||||
@Autowired
|
||||
private ScriptMapper ruleScriptMapper;
|
||||
|
||||
@Autowired
|
||||
private SceneScriptMapper sceneScriptMapper;
|
||||
|
||||
@Autowired
|
||||
private SceneDeviceMapper sceneDeviceMapper;
|
||||
// @Resource
|
||||
// private IAlertService alertService;
|
||||
|
||||
/**
|
||||
* 查询场景联动
|
||||
*
|
||||
* @param sceneId 场景联动主键
|
||||
* @return 场景联动
|
||||
*/
|
||||
@Override
|
||||
public Scene selectSceneBySceneId(Long sceneId) {
|
||||
// 查询场景
|
||||
Scene scene = sceneMapper.selectSceneBySceneId(sceneId);
|
||||
// 查询场景脚本
|
||||
SceneScript scriptParam = new SceneScript();
|
||||
scriptParam.setSceneId(scene.getSceneId());
|
||||
List<SceneScript> sceneScripts = sceneScriptMapper.selectSceneScriptList(scriptParam);
|
||||
// 查询场景设备
|
||||
SceneDevice deviceParam = new SceneDevice();
|
||||
deviceParam.setSceneId(scene.getSceneId());
|
||||
List<SceneDevice> sceneDevices = sceneDeviceMapper.selectSceneDeviceList(deviceParam);
|
||||
// 构建场景设备列表,触发器和执行动作集合
|
||||
List<SceneScript> triggers = new ArrayList<>();
|
||||
List<SceneScript> actions = new ArrayList<>();
|
||||
for (SceneScript sceneScript : sceneScripts) {
|
||||
// 构建设备列表
|
||||
List<String> deviceList = new ArrayList<>();
|
||||
for (SceneDevice sceneDevice : sceneDevices) {
|
||||
if (sceneDevice.getScriptId().equals(sceneScript.getScriptId())) {
|
||||
deviceList.add(sceneDevice.getSerialNumber());
|
||||
}
|
||||
}
|
||||
sceneScript.setDeviceNums(deviceList.toArray(new String[deviceList.size()]));
|
||||
if (sceneScript.getScriptPurpose() == 2) {
|
||||
triggers.add(sceneScript);
|
||||
} else if (sceneScript.getScriptPurpose() == 3) {
|
||||
actions.add(sceneScript);
|
||||
}
|
||||
}
|
||||
scene.setTriggers(triggers);
|
||||
scene.setActions(actions);
|
||||
return scene;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询场景联动列表
|
||||
*
|
||||
* @param scene 场景联动
|
||||
* @return 场景联动
|
||||
*/
|
||||
@Override
|
||||
public List<Scene> selectSceneList(Scene scene) {
|
||||
SysUser user = getLoginUser().getUser();
|
||||
List<SysRole> roles = user.getRoles();
|
||||
for (int i = 0; i < roles.size(); i++) {
|
||||
// 租户和用户,只查看自己分组
|
||||
if (roles.get(i).getRoleKey().equals("tenant") || roles.get(i).getRoleKey().equals("general")) {
|
||||
scene.setUserId(user.getUserId());
|
||||
break;
|
||||
}
|
||||
}
|
||||
List<Scene> sceneList = sceneMapper.selectSceneList(scene);
|
||||
if (CollectionUtils.isNotEmpty(sceneList)) {
|
||||
List<Long> sceneIdList = sceneList.stream().map(Scene::getSceneId).collect(Collectors.toList());
|
||||
List<SceneScript> sceneScriptList = sceneScriptMapper.listSceneScriptByPurpose(sceneIdList, 3);
|
||||
Map<Long, List<SceneScript>> map = sceneScriptList.stream().collect(Collectors.groupingBy(SceneScript::getSceneId));
|
||||
for (Scene updateScene : sceneList) {
|
||||
List<SceneScript> sceneScripts = map.get(updateScene.getSceneId());
|
||||
if (CollectionUtils.isNotEmpty(sceneScripts)) {
|
||||
updateScene.setActionCount(sceneScripts.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
return sceneList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增场景联动
|
||||
*
|
||||
* @param scene 场景联动
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public int insertScene(Scene scene) {
|
||||
if (scene.getTriggers().size() == 0 || scene.getActions().size() == 0) {
|
||||
log.error("场景中至少包含一个触发器或者执行动作,否则规则启动报错!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 保存场景联动
|
||||
SysUser user = getLoginUser().getUser();
|
||||
scene.setCreateBy(user.getUserName());
|
||||
scene.setCreateTime(DateUtils.getNowDate());
|
||||
scene.setUserId(user.getUserId());
|
||||
scene.setUserName(user.getUserName());
|
||||
// 延时不超过90秒
|
||||
if (scene.getExecuteDelay() > 90) {
|
||||
scene.setExecuteDelay(90);
|
||||
}
|
||||
// 设置规则名称,D=数据流,A=执行动作,T=触发器,C=规则链 雪花算法生成唯一数
|
||||
Snowflake snowflake = IdUtil.getSnowflake(1, 1);
|
||||
scene.setChainName("C" + String.valueOf(snowflake.nextId()));
|
||||
sceneMapper.insertScene(scene);
|
||||
|
||||
// 构建EL和场景数据
|
||||
List<Script> ruleScripts = new ArrayList<>();
|
||||
List<SceneScript> sceneScripts = new ArrayList<>();
|
||||
List<SceneDevice> sceneDevices = new ArrayList<>();
|
||||
String elData = buildElData(scene, ruleScripts, sceneScripts, sceneDevices);
|
||||
|
||||
// 更新场景联动规则脚本
|
||||
scene.setElData(elData);
|
||||
sceneMapper.updateScene(scene);
|
||||
// 保存规则脚本
|
||||
ruleScriptMapper.insertRuleScriptList(ruleScripts);
|
||||
// 保存场景脚本
|
||||
sceneScriptMapper.insertSceneScriptList(sceneScripts);
|
||||
// 保存场景设备
|
||||
if (sceneDevices.size() > 0) {
|
||||
sceneDeviceMapper.insertSceneDeviceList(sceneDevices);
|
||||
}
|
||||
|
||||
// 动态构建规则链和脚本组件到内存中
|
||||
dynamicBuildRule(ruleScripts,scene);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改场景联动
|
||||
*
|
||||
* @param scene 场景联动
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public int updateScene(Scene scene) {
|
||||
if (scene.getTriggers().size() == 0 || scene.getActions().size() == 0) {
|
||||
log.error("场景中至少包含一个触发器或者执行动作,否则规则启动报错!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 批量删除规则脚本
|
||||
ruleScriptMapper.deleteRuleScriptBySceneIds(new Long[]{scene.getSceneId()});
|
||||
// 批量删除场景脚本
|
||||
sceneScriptMapper.deleteSceneScriptBySceneIds(new Long[]{scene.getSceneId()});
|
||||
// 批量删除场景设备
|
||||
sceneDeviceMapper.deleteSceneDeviceBySceneIds(new Long[]{scene.getSceneId()});
|
||||
// 批量删除定时任务
|
||||
try {
|
||||
jobService.deleteJobBySceneIds(new Long[]{scene.getSceneId()});
|
||||
} catch (SchedulerException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// 构建EL和场景数据
|
||||
List<Script> ruleScripts = new ArrayList<>();
|
||||
List<SceneScript> sceneScripts = new ArrayList<>();
|
||||
List<SceneDevice> sceneDevices = new ArrayList<>();
|
||||
String elData = buildElData(scene, ruleScripts, sceneScripts, sceneDevices);
|
||||
|
||||
scene.setElData(elData);
|
||||
scene.setUpdateTime(DateUtils.getNowDate());
|
||||
sceneMapper.updateScene(scene);
|
||||
// 保存规则脚本
|
||||
ruleScriptMapper.insertRuleScriptList(ruleScripts);
|
||||
// 保存场景脚本
|
||||
sceneScriptMapper.insertSceneScriptList(sceneScripts);
|
||||
// 保存场景设备
|
||||
if (sceneDevices.size() > 0) {
|
||||
sceneDeviceMapper.insertSceneDeviceList(sceneDevices);
|
||||
}
|
||||
|
||||
// 动态构建规则链和脚本组件到内存中
|
||||
dynamicBuildRule(ruleScripts,scene);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 动态构建规则链和脚本组件
|
||||
* @param ruleScripts
|
||||
*/
|
||||
private void dynamicBuildRule(List<Script> ruleScripts,Scene scene){
|
||||
for(Script ruleScript:ruleScripts){
|
||||
// 规则引擎构建脚本组件
|
||||
if(ruleScript.getScriptPurpose() == 2) {
|
||||
//脚本条件组件
|
||||
LiteFlowNodeBuilder.createScriptIfNode().setId(ruleScript.getScriptId())
|
||||
.setName(ruleScript.getScriptName())
|
||||
.setScript(ruleScript.getScriptData())
|
||||
.build();
|
||||
}else if(ruleScript.getScriptPurpose() == 3){
|
||||
// 普通组件
|
||||
LiteFlowNodeBuilder.createScriptNode().setId(ruleScript.getScriptId())
|
||||
.setName(ruleScript.getScriptName())
|
||||
.setScript(ruleScript.getScriptData())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
// 构建规则链
|
||||
LiteFlowChainELBuilder.createChain().setChainName(scene.getChainName()).setEL(scene.getElData()).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建EL数据
|
||||
*
|
||||
* @param scene 场景
|
||||
* @param ruleScripts 规则脚本集合
|
||||
* @param sceneScripts 场景脚本集合
|
||||
* @param sceneDevices 场景设备集合
|
||||
* @return
|
||||
*/
|
||||
private String buildElData(Scene scene, List<Script> ruleScripts, List<SceneScript> sceneScripts, List<SceneDevice> sceneDevices) {
|
||||
// 排除定时后的触发器,等于0不生成规则数据,等于1移除AND和OR
|
||||
Long triggerNodeCount = scene.getTriggers().stream().filter(x -> x.getSource() != 2).count();
|
||||
Long triggerTimingCount = scene.getTriggers().stream().filter(x -> x.getSource() == 2).count();
|
||||
|
||||
// 拼接规则数据,格式如:IF(AND(T1,T2,T3),THEN(A1,A2,A3))
|
||||
StringBuilder triggerBuilder = new StringBuilder();
|
||||
StringBuilder actionBuilder = new StringBuilder();
|
||||
if (0 == triggerNodeCount && triggerTimingCount != 0) {
|
||||
switch (scene.getExecuteMode()) {
|
||||
case 1:
|
||||
actionBuilder.append("THEN(");
|
||||
break;
|
||||
case 2:
|
||||
actionBuilder.append("WHEN(");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (scene.getCond()) {
|
||||
case 1:
|
||||
triggerBuilder.append("IF(OR(");
|
||||
break;
|
||||
case 2:
|
||||
triggerBuilder.append("IF(AND(");
|
||||
break;
|
||||
case 3:
|
||||
triggerBuilder.append("IF(NOT(");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch (scene.getExecuteMode()) {
|
||||
case 1:
|
||||
actionBuilder.append(",THEN(");
|
||||
break;
|
||||
case 2:
|
||||
actionBuilder.append(",WHEN(");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < scene.getTriggers().size(); i++) {
|
||||
// 保存触发器和执行动作
|
||||
String scriptId = buildTriggerAction(scene.getTriggers().get(i), 2, scene, ruleScripts, sceneScripts, sceneDevices);
|
||||
// 构建触发器EL,排除定时触发器
|
||||
if (scene.getTriggers().get(i).getSource() != 2) {
|
||||
triggerBuilder.append(scriptId + ",");
|
||||
}
|
||||
}
|
||||
if (triggerNodeCount > 0) {
|
||||
triggerBuilder.deleteCharAt(triggerBuilder.lastIndexOf(","));
|
||||
triggerBuilder.append(")");
|
||||
}
|
||||
|
||||
for (int i = 0; i < scene.getActions().size(); i++) {
|
||||
// 保存触发器和执行动作
|
||||
String scriptId = buildTriggerAction(scene.getActions().get(i), 3, scene, ruleScripts, sceneScripts, sceneDevices);
|
||||
// 构建执行动作EL
|
||||
actionBuilder.append(scriptId + ",");
|
||||
}
|
||||
if (scene.getActions().size() > 0) {
|
||||
actionBuilder.deleteCharAt(actionBuilder.lastIndexOf(","));
|
||||
}
|
||||
String elData;
|
||||
if (StringUtils.isEmpty(triggerBuilder)) {
|
||||
actionBuilder.append(")");
|
||||
elData = actionBuilder.toString();
|
||||
} else {
|
||||
actionBuilder.append("))");
|
||||
elData = triggerBuilder.append(actionBuilder).toString();
|
||||
}
|
||||
if (triggerNodeCount == 1) {
|
||||
// 移除AND和OR,它们必须包含两个以上组件
|
||||
if(elData.indexOf("AND(")!=-1){
|
||||
elData=elData.replace("AND(", "").replace("),", ",");
|
||||
}else if(elData.indexOf("OR(")!=-1){
|
||||
elData=elData.replace("OR(", "").replace("),", ",");
|
||||
}
|
||||
}
|
||||
return elData;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建场景中的触发器和执行动作
|
||||
*
|
||||
* @param sceneScript 场景脚本
|
||||
* @param scriptPurpose 脚本用途:1=数据流,2=触发器,3=执行动作
|
||||
* @param scene 场景
|
||||
* @return 返回规则脚本ID
|
||||
*/
|
||||
private String buildTriggerAction(SceneScript sceneScript, int scriptPurpose, Scene scene, List<Script> ruleScripts, List<SceneScript> sceneScripts, List<SceneDevice> sceneDevices) {
|
||||
// 构建规则脚本
|
||||
Script ruleScript = new Script();
|
||||
// 设置脚本标识,D=数据流,A=执行动作,T=触发器,雪花算法生成唯一数
|
||||
Snowflake snowflake = IdUtil.getSnowflake(1, 1);
|
||||
String scriptId = String.valueOf(snowflake.nextId());
|
||||
if (scriptPurpose == 2) {
|
||||
scriptId = "T" + scriptId;
|
||||
ruleScript.setScriptType("if_script");
|
||||
} else if (scriptPurpose == 3) {
|
||||
scriptId = "A" + scriptId;
|
||||
ruleScript.setScriptType("script");
|
||||
}
|
||||
ruleScript.setScriptId(scriptId);
|
||||
ruleScript.setScriptName(scriptId);
|
||||
ruleScript.setApplicationName("fastbee");
|
||||
ruleScript.setScriptLanguage("groovy");
|
||||
SysUser user = getLoginUser().getUser();
|
||||
ruleScript.setUserId(user.getUserId());
|
||||
ruleScript.setUserName(user.getUserName());
|
||||
ruleScript.setScriptPurpose(scriptPurpose);
|
||||
ruleScript.setEnable(1);
|
||||
ruleScript.setScriptOrder(0);
|
||||
ruleScript.setScriptEvent(0);
|
||||
ruleScript.setScriptAction(0);
|
||||
ruleScript.setSceneId(scene.getSceneId());
|
||||
ruleScript.setCreateBy(user.getUserName());
|
||||
ruleScript.setCreateTime(DateUtils.getNowDate());
|
||||
// 构建脚本内容
|
||||
ScriptTemplate template=new ScriptTemplate(
|
||||
scene.getSceneId(),scriptId,sceneScript.getType(),sceneScript.getSource(),scene.getSilentPeriod(),
|
||||
scene.getExecuteDelay(), scene.getCond(),sceneScript.getScriptPurpose(),sceneScript.getId(),sceneScript.getValue(),
|
||||
StringUtils.isEmpty(sceneScript.getOperator())?"=":sceneScript.getOperator(),String.join(",", sceneScript.getDeviceNums()),sceneScript.getProductId()
|
||||
);
|
||||
String data = String.format("String json =\"%s\";\n" +
|
||||
"sceneContext.process(json);", StringEscapeUtils.escapeJava(JSONObject.toJSONString(template)));
|
||||
ruleScript.setScriptData(data);
|
||||
// 构建脚本集合,规则脚本不需要存储定时触发器
|
||||
if (sceneScript.getSource() != 2) {
|
||||
ruleScripts.add(ruleScript);
|
||||
}
|
||||
|
||||
if (scriptPurpose == 2) {
|
||||
// 触发器
|
||||
if (sceneScript.getSource() == 1) {
|
||||
// 构建场景设备集合
|
||||
for (int j = 0; j < sceneScript.getDeviceNums().length; j++) {
|
||||
SceneDevice sceneDevice = new SceneDevice();
|
||||
sceneDevice.setSceneId(scene.getSceneId());
|
||||
sceneDevice.setScriptId(scriptId);
|
||||
sceneDevice.setSource(sceneScript.getSource());
|
||||
sceneDevice.setSerialNumber(sceneScript.getDeviceNums()[j]);
|
||||
sceneDevice.setProductId(0L);
|
||||
sceneDevice.setProductName("");
|
||||
sceneDevice.setType(scriptPurpose);
|
||||
sceneDevices.add(sceneDevice);
|
||||
}
|
||||
}else if (sceneScript.getSource() == 2) {
|
||||
// 创建告警定时任务
|
||||
createSceneTask(scene, sceneScript);
|
||||
}else if (sceneScript.getSource() == 3) {
|
||||
// 构建场景设备集合
|
||||
SceneDevice sceneDevice = new SceneDevice();
|
||||
sceneDevice.setSceneId(scene.getSceneId());
|
||||
sceneDevice.setScriptId(scriptId);
|
||||
sceneDevice.setSource(sceneScript.getSource());
|
||||
sceneDevice.setSerialNumber("");
|
||||
sceneDevice.setProductId(sceneScript.getProductId());
|
||||
sceneDevice.setProductName(sceneScript.getProductName());
|
||||
sceneDevice.setType(scriptPurpose);
|
||||
sceneDevices.add(sceneDevice);
|
||||
}
|
||||
} else if (scriptPurpose == 3) {
|
||||
if (sceneScript.getSource() == 1) {
|
||||
// 构建场景设备集合
|
||||
for (int j = 0; j < sceneScript.getDeviceNums().length; j++) {
|
||||
SceneDevice sceneDevice = new SceneDevice();
|
||||
sceneDevice.setSceneId(scene.getSceneId());
|
||||
sceneDevice.setScriptId(scriptId);
|
||||
sceneDevice.setSource(sceneScript.getSource());
|
||||
sceneDevice.setSerialNumber(sceneScript.getDeviceNums()[j]);
|
||||
sceneDevice.setProductId(0L);
|
||||
sceneDevice.setProductName("");
|
||||
sceneDevice.setType(scriptPurpose);
|
||||
sceneDevices.add(sceneDevice);
|
||||
}
|
||||
} else if (sceneScript.getSource() == 3) {
|
||||
// 构建场景设备集合
|
||||
SceneDevice sceneDevice = new SceneDevice();
|
||||
sceneDevice.setSceneId(scene.getSceneId());
|
||||
sceneDevice.setScriptId(scriptId);
|
||||
sceneDevice.setSource(sceneScript.getSource());
|
||||
sceneDevice.setSerialNumber("");
|
||||
sceneDevice.setProductId(sceneScript.getProductId());
|
||||
sceneDevice.setProductName(sceneScript.getProductName());
|
||||
sceneDevice.setType(scriptPurpose);
|
||||
sceneDevices.add(sceneDevice);
|
||||
}
|
||||
}
|
||||
|
||||
// 构建场景脚本集合
|
||||
sceneScript.setSceneId(scene.getSceneId());
|
||||
sceneScript.setScriptId(scriptId);
|
||||
sceneScript.setCreateTime(DateUtils.getNowDate());
|
||||
sceneScript.setCreateBy(user.getUserName());
|
||||
sceneScript.setOperator(StringUtils.isEmpty(sceneScript.getOperator())?"=":sceneScript.getOperator());
|
||||
sceneScripts.add(sceneScript);
|
||||
// 返回脚本ID
|
||||
return scriptId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建场景定时任务
|
||||
*
|
||||
* @param scene
|
||||
* @param sceneScript
|
||||
*/
|
||||
private void createSceneTask(Scene scene, SceneScript sceneScript) {
|
||||
// 创建定时任务
|
||||
try {
|
||||
if (!CronUtils.isValid(sceneScript.getCronExpression())) {
|
||||
log.error("新增场景联动定时任务失败,Cron表达式不正确");
|
||||
throw new Exception("新增场景联动定时任务失败,Cron表达式不正确");
|
||||
}
|
||||
DeviceJob deviceJob = new DeviceJob();
|
||||
deviceJob.setJobName("场景联动定时触发");
|
||||
deviceJob.setJobType(3);
|
||||
deviceJob.setJobGroup("DEFAULT");
|
||||
deviceJob.setConcurrent("1");
|
||||
deviceJob.setMisfirePolicy("2");
|
||||
deviceJob.setStatus(scene.getEnable() == 1 ? "0" : "1");
|
||||
deviceJob.setCronExpression(sceneScript.getCronExpression());
|
||||
deviceJob.setIsAdvance(sceneScript.getIsAdvance());
|
||||
deviceJob.setSceneId(scene.getSceneId());
|
||||
deviceJob.setDeviceName("场景联动定时触发");
|
||||
jobService.insertJob(deviceJob);
|
||||
} catch (SchedulerException e) {
|
||||
e.printStackTrace();
|
||||
} catch (TaskException e) {
|
||||
e.printStackTrace();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除场景联动
|
||||
*
|
||||
* @param sceneIds 需要删除的场景联动主键
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public int deleteSceneBySceneIds(Long[] sceneIds) {
|
||||
// 批量删除规则脚本
|
||||
ruleScriptMapper.deleteRuleScriptBySceneIds(sceneIds);
|
||||
// 批量删除场景脚本
|
||||
sceneScriptMapper.deleteSceneScriptBySceneIds(sceneIds);
|
||||
// 批量删除场景设备
|
||||
sceneDeviceMapper.deleteSceneDeviceBySceneIds(sceneIds);
|
||||
// 批量删除定时任务
|
||||
try {
|
||||
jobService.deleteJobBySceneIds(sceneIds);
|
||||
} catch (SchedulerException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// 删除告警关联的场景
|
||||
// alertService.deleteAlertByAlertIds(sceneIds);
|
||||
// 删除缓存静默时间
|
||||
for(Long sceneId:sceneIds){
|
||||
String key = "silent:" + "scene_" + sceneId;
|
||||
redisCache.deleteObject(key);
|
||||
}
|
||||
return sceneMapper.deleteSceneBySceneIds(sceneIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除场景联动信息
|
||||
*
|
||||
* @param sceneId 场景联动主键
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public int deleteSceneBySceneId(Long sceneId) {
|
||||
// 批量删除规则脚本
|
||||
ruleScriptMapper.deleteRuleScriptBySceneIds(new Long[]{sceneId});
|
||||
// 批量删除场景脚本
|
||||
sceneScriptMapper.deleteSceneScriptBySceneIds(new Long[]{sceneId});
|
||||
// 批量删除场景设备
|
||||
sceneDeviceMapper.deleteSceneDeviceBySceneIds(new Long[]{sceneId});
|
||||
// 批量删除定时任务
|
||||
try {
|
||||
jobService.deleteJobBySceneIds(new Long[]{sceneId});
|
||||
} catch (SchedulerException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// 删除告警关联的场景
|
||||
// alertService.deleteAlertByAlertIds(new Long[]{sceneId});
|
||||
// 删除缓存静默时间
|
||||
String key = "silent:" + "scene_" + sceneId;
|
||||
redisCache.deleteObject(key);
|
||||
return sceneMapper.deleteSceneBySceneId(sceneId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int updateStatus(Scene scene) {
|
||||
Integer enable = scene.getEnable();
|
||||
// 更新定时任务状态
|
||||
List<DeviceJob> deviceJobList = jobService.listShortJobBySceneId(new Long[]{scene.getSceneId()});
|
||||
try {
|
||||
for (DeviceJob job : deviceJobList) {
|
||||
DeviceJob deviceJob = new DeviceJob();
|
||||
deviceJob.setJobId(job.getJobId());
|
||||
deviceJob.setJobGroup(job.getJobGroup());
|
||||
deviceJob.setActions(enable == 1 ? "0" : "1");
|
||||
jobService.changeStatus(deviceJob);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Scene updateScene = new Scene();
|
||||
updateScene.setSceneId(scene.getSceneId());
|
||||
updateScene.setEnable(enable);
|
||||
return sceneMapper.updateScene(updateScene);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
package com.fastbee.iot.service.impl;
|
||||
|
||||
import cn.hutool.core.lang.Snowflake;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import com.fastbee.common.core.domain.AjaxResult;
|
||||
import com.fastbee.common.core.domain.entity.SysRole;
|
||||
import com.fastbee.common.core.domain.entity.SysUser;
|
||||
import com.fastbee.common.utils.DateUtils;
|
||||
import com.fastbee.iot.domain.Script;
|
||||
import com.fastbee.iot.mapper.ScriptMapper;
|
||||
import com.fastbee.iot.model.ScriptCondition;
|
||||
import com.fastbee.iot.service.IScriptService;
|
||||
import com.yomahub.liteflow.core.FlowExecutor;
|
||||
import com.yomahub.liteflow.script.ScriptExecutorFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static com.fastbee.common.core.domain.AjaxResult.success;
|
||||
import static com.fastbee.common.utils.SecurityUtils.getLoginUser;
|
||||
|
||||
/**
|
||||
* 规则引擎脚本Service业务层处理
|
||||
*
|
||||
* @author lizhuangpeng
|
||||
* @date 2023-07-01
|
||||
*/
|
||||
@Service
|
||||
public class ScriptServiceImpl implements IScriptService
|
||||
{
|
||||
@Autowired
|
||||
private ScriptMapper ruleScriptMapper;
|
||||
|
||||
@Resource
|
||||
private FlowExecutor flowExecutor;
|
||||
|
||||
/**
|
||||
* 查询规则引擎脚本
|
||||
*
|
||||
* @param scriptId 规则引擎脚本主键
|
||||
* @return 规则引擎脚本
|
||||
*/
|
||||
@Override
|
||||
public Script selectRuleScriptById(String scriptId)
|
||||
{
|
||||
return ruleScriptMapper.selectRuleScriptById(scriptId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询规则引擎脚本列表
|
||||
*
|
||||
* @param ruleScript 规则引擎脚本
|
||||
* @return 规则引擎脚本
|
||||
*/
|
||||
@Override
|
||||
public List<Script> selectRuleScriptList(Script ruleScript)
|
||||
{
|
||||
SysUser sysUser = getLoginUser().getUser();
|
||||
List<SysRole> roles = sysUser.getRoles();
|
||||
for (SysRole role : roles) {
|
||||
if (role.getRoleKey().equals("general") || role.getRoleKey().equals("tenant")) {
|
||||
// 用户和租户只能查看自己的规则脚本
|
||||
ruleScript.setUserId(sysUser.getUserId());
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ruleScriptMapper.selectRuleScriptList(ruleScript);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询规则引擎脚本标识数组(设备用户和租户的脚本)
|
||||
*
|
||||
* @return 规则引擎脚本
|
||||
*/
|
||||
@Override
|
||||
public String[] selectRuleScriptIdArray(ScriptCondition scriptCondition)
|
||||
{
|
||||
return ruleScriptMapper.selectRuleScriptIdArray(scriptCondition);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增规则引擎脚本
|
||||
*
|
||||
* @param ruleScript 规则引擎脚本
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int insertRuleScript(Script ruleScript)
|
||||
{
|
||||
// 脚本中引用包替换为许可的包
|
||||
ruleScript.setScriptData(replaceAllowPackage(ruleScript.getScriptData()));
|
||||
// 设置脚本标识,D=数据流,A=执行动作,T=触发器,雪花算法生成唯一数
|
||||
Snowflake snowflake = IdUtil.createSnowflake(1,1);
|
||||
ruleScript.setScriptId("D"+snowflake.nextId());
|
||||
SysUser sysUser = getLoginUser().getUser();
|
||||
ruleScript.setUserId(sysUser.getUserId());
|
||||
ruleScript.setUserName(sysUser.getUserName());
|
||||
ruleScript.setCreateTime(DateUtils.getNowDate());
|
||||
int result = ruleScriptMapper.insertRuleScript(ruleScript);
|
||||
// 动态刷新脚本
|
||||
if(result==1){
|
||||
ScriptExecutorFactory.loadInstance().getScriptExecutor(ruleScript.getScriptLanguage()).load(ruleScript.getScriptId(), ruleScript.getScriptData());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 脚本中引用包替换为许可的包
|
||||
* @return
|
||||
*/
|
||||
private String replaceAllowPackage(String scriptData){
|
||||
String header="import cn.hutool.json.JSONArray;\n" +
|
||||
"import cn.hutool.json.JSONObject;\n" +
|
||||
"import cn.hutool.json.JSONUtil;\n" +
|
||||
"import cn.hutool.core.util.NumberUtil;\n";
|
||||
// 正则替换import为许可的引用包
|
||||
String pattern = "import.*[;\\n\\s]";
|
||||
String data = scriptData.replaceAll(pattern, "");
|
||||
return header + data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改规则引擎脚本
|
||||
*
|
||||
* @param ruleScript 规则引擎脚本
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int updateRuleScript(Script ruleScript)
|
||||
{
|
||||
// 脚本中引用包替换为许可的包
|
||||
ruleScript.setScriptData(replaceAllowPackage(ruleScript.getScriptData()));
|
||||
ruleScript.setUpdateTime(DateUtils.getNowDate());
|
||||
int result = ruleScriptMapper.updateRuleScript(ruleScript);
|
||||
// 动态刷新脚本
|
||||
if(result==1){
|
||||
ScriptExecutorFactory.loadInstance().getScriptExecutor(ruleScript.getScriptLanguage()).load(ruleScript.getScriptId(), ruleScript.getScriptData());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除规则引擎脚本
|
||||
*
|
||||
* @param ids 需要删除的规则引擎脚本主键
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deleteRuleScriptByIds(String[] ids)
|
||||
{
|
||||
return ruleScriptMapper.deleteRuleScriptByIds(ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除规则引擎脚本信息
|
||||
*
|
||||
* @param id 规则引擎脚本主键
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deleteRuleScriptById(String id)
|
||||
{
|
||||
return ruleScriptMapper.deleteRuleScriptById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证脚本
|
||||
* ruleScript.scriptData 脚本数据
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public AjaxResult validateScript(Script ruleScript){
|
||||
// 检查安全性检查
|
||||
String pattern = ".*while|for\\s*\\(|InputStream|OutputStream|Reader|Writer|File|Socket.*";
|
||||
Pattern r = Pattern.compile(pattern);
|
||||
Matcher m = r.matcher(ruleScript.getScriptData());
|
||||
if(m.find()){
|
||||
return success("验证失败,错误信息:" + "不能包含关键词for、while、Reader、Write、File、Socket等",false);
|
||||
}
|
||||
// 热刷新脚本
|
||||
try {
|
||||
ScriptExecutorFactory.loadInstance().getScriptExecutor("groovy").load("validateScript", ruleScript.getScriptData());
|
||||
}catch(Exception e){
|
||||
return success("验证失败,错误信息:" + e.getMessage(),false);
|
||||
}
|
||||
return success("验证成功,脚本的实际执行情况可以查看后端日志文件",true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.fastbee.iot.mapper.SceneDeviceMapper">
|
||||
|
||||
<resultMap type="SceneDevice" id="SceneDeviceResult">
|
||||
<result property="sceneDeviceId" column="scene_device_id" />
|
||||
<result property="serialNumber" column="serial_number" />
|
||||
<result property="productId" column="product_id" />
|
||||
<result property="productName" column="product_name" />
|
||||
<result property="scriptId" column="script_id" />
|
||||
<result property="sceneId" column="scene_id" />
|
||||
<result property="source" column="source" />
|
||||
<result property="type" column="type" />
|
||||
</resultMap>
|
||||
|
||||
<resultMap type="com.fastbee.iot.domain.Scene" id="SceneResult">
|
||||
<result property="sceneId" column="scene_id" />
|
||||
<result property="chainName" column="chain_name" />
|
||||
<result property="elData" column="el_data" />
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectSceneDeviceVo">
|
||||
select scene_device_id, serial_number, product_id, product_name, script_id, scene_id, source,type from iot_scene_device
|
||||
</sql>
|
||||
|
||||
<select id="selectSceneDeviceList" parameterType="SceneDevice" resultMap="SceneDeviceResult">
|
||||
<include refid="selectSceneDeviceVo"/>
|
||||
<where>
|
||||
<if test="serialNumber != null and serialNumber != ''"> and serial_number = #{serialNumber}</if>
|
||||
<if test="productId != null "> and product_id = #{productId}</if>
|
||||
<if test="productName != null "> and product_name = #{productName}</if>
|
||||
<if test="scriptId != null "> and script_id = #{scriptId}</if>
|
||||
<if test="sceneId != null "> and scene_id = #{sceneId}</if>
|
||||
<if test="source != null "> and source = #{source}</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<select id="selectTriggerDeviceRelateScenes" parameterType="SceneDevice" resultMap="SceneResult">
|
||||
select s.scene_id,s.chain_name
|
||||
from (select distinct scene_id from iot_scene_device where type = 2 and (serial_number = #{serialNumber} OR product_id = #{productId})) d
|
||||
left join iot_scene s on s.scene_id=d.scene_id
|
||||
where s.`enable`= 1
|
||||
</select>
|
||||
|
||||
<select id="selectSceneDeviceBySceneDeviceId" parameterType="Long" resultMap="SceneDeviceResult">
|
||||
<include refid="selectSceneDeviceVo"/>
|
||||
where scene_device_id = #{sceneDeviceId}
|
||||
</select>
|
||||
|
||||
<select id="listSceneProductBind" resultType="com.fastbee.iot.model.SceneDeviceBindVO">
|
||||
select d.scene_id, s.scene_name, d.product_id
|
||||
from iot_scene_device d
|
||||
left join iot_scene s on d.scene_id = s.scene_id
|
||||
where d.product_id in
|
||||
<foreach item="productId" collection="array" open="(" separator="," close=")">
|
||||
#{productId}
|
||||
</foreach>
|
||||
</select>
|
||||
|
||||
<select id="listSceneDeviceBind" resultType="com.fastbee.iot.model.SceneDeviceBindVO">
|
||||
select d.scene_id, s.scene_name, d.serial_number
|
||||
from iot_scene_device d
|
||||
left join iot_scene s on d.scene_id = s.scene_id
|
||||
where d.serial_number = #{serialNumber}
|
||||
</select>
|
||||
|
||||
<insert id="insertSceneDevice" parameterType="SceneDevice" useGeneratedKeys="true" keyProperty="sceneDeviceId" >
|
||||
insert into iot_scene_device
|
||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||
<if test="serialNumber != null">serial_number,</if>
|
||||
<if test="productId != null">product_id,</if>
|
||||
<if test="productName != null">product_name,</if>
|
||||
<if test="scriptId != null">script_id,</if>
|
||||
<if test="sceneId != null">scene_id,</if>
|
||||
<if test="source != null">source,</if>
|
||||
<if test="type != null">type,</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="serialNumber != null">#{serialNumber},</if>
|
||||
<if test="productId != null">#{productId},</if>
|
||||
<if test="productName != null">#{productName},</if>
|
||||
<if test="scriptId != null">#{scriptId},</if>
|
||||
<if test="sceneId != null">#{sceneId},</if>
|
||||
<if test="source != null">#{source},</if>
|
||||
<if test="type != null">#{type},</if>
|
||||
</trim>
|
||||
</insert>
|
||||
|
||||
<update id="updateSceneDevice" parameterType="SceneDevice">
|
||||
update iot_scene_device
|
||||
<trim prefix="SET" suffixOverrides=",">
|
||||
<if test="serialNumber != null">serial_number = #{serialNumber},</if>
|
||||
<if test="productId != null">product_id = #{productId},</if>
|
||||
<if test="productName != null">product_name = #{productName},</if>
|
||||
<if test="scriptId != null">script_id = #{scriptId},</if>
|
||||
<if test="sceneId != null">scene_id = #{sceneId},</if>
|
||||
<if test="source != null">source = #{source},</if>
|
||||
<if test="type != null">type = #{type},</if>
|
||||
</trim>
|
||||
where scene_device_id = #{sceneDeviceId}
|
||||
</update>
|
||||
|
||||
<delete id="deleteSceneDeviceBySceneDeviceId" parameterType="Long">
|
||||
delete from iot_scene_device where scene_device_id = #{sceneDeviceId}
|
||||
</delete>
|
||||
|
||||
<delete id="deleteSceneDeviceBySceneDeviceIds" parameterType="String">
|
||||
delete from iot_scene_device where scene_device_id in
|
||||
<foreach item="sceneDeviceId" collection="array" open="(" separator="," close=")">
|
||||
#{sceneDeviceId}
|
||||
</foreach>
|
||||
</delete>
|
||||
|
||||
<insert id="insertSceneDeviceList" parameterType="java.util.List" useGeneratedKeys="true" keyProperty="sceneDeviceId">
|
||||
insert into iot_scene_device (serial_number,product_id,product_name, script_id,scene_id,source,type)
|
||||
VALUES
|
||||
<foreach collection ="list" item="sceneDevice" separator =",">
|
||||
(#{sceneDevice.serialNumber},
|
||||
#{sceneDevice.productId},
|
||||
#{sceneDevice.productName},
|
||||
#{sceneDevice.scriptId},
|
||||
#{sceneDevice.sceneId},
|
||||
#{sceneDevice.source},
|
||||
#{sceneDevice.type})
|
||||
</foreach >
|
||||
</insert>
|
||||
|
||||
<delete id="deleteSceneDeviceBySceneIds" parameterType="String">
|
||||
delete from iot_scene_device where scene_id in
|
||||
<foreach item="sceneId" collection="array" open="(" separator="," close=")">
|
||||
#{sceneId}
|
||||
</foreach>
|
||||
</delete>
|
||||
</mapper>
|
||||
@@ -0,0 +1,141 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.fastbee.iot.mapper.SceneMapper">
|
||||
|
||||
<resultMap type="com.fastbee.iot.domain.Scene" id="SceneResult">
|
||||
<result property="sceneId" column="scene_id" />
|
||||
<result property="sceneName" column="scene_name" />
|
||||
<result property="chainName" column="chain_name" />
|
||||
<result property="userId" column="user_id" />
|
||||
<result property="userName" column="user_name" />
|
||||
<result property="createBy" column="create_by" />
|
||||
<result property="createTime" column="create_time" />
|
||||
<result property="updateBy" column="update_by" />
|
||||
<result property="updateTime" column="update_time" />
|
||||
<result property="remark" column="remark" />
|
||||
<result property="cond" column="cond" />
|
||||
<result property="silentPeriod" column="silent_period" />
|
||||
<result property="executeMode" column="execute_mode" />
|
||||
<result property="executeDelay" column="execute_delay" />
|
||||
<result property="hasAlert" column="has_alert" />
|
||||
<result property="enable" column="enable" />
|
||||
<result property="elData" column="el_data" />
|
||||
<result property="applicationName" column="application_name" />
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectSceneVo">
|
||||
select scene_id, scene_name,chain_name, user_id, user_name, create_by, create_time, update_by, update_time, remark, cond, silent_period, execute_mode, execute_delay, has_alert, enable, el_data, application_name from iot_scene
|
||||
</sql>
|
||||
|
||||
<sql id="selectSceneListVo">
|
||||
select scene_id, scene_name,chain_name, user_id, user_name, create_by, create_time, update_by, update_time, remark, cond, silent_period, execute_mode, execute_delay, has_alert, enable, application_name from iot_scene
|
||||
</sql>
|
||||
|
||||
<select id="selectSceneList" parameterType="Scene" resultMap="SceneResult">
|
||||
<include refid="selectSceneListVo"/>
|
||||
<where>
|
||||
<if test="sceneName != null and sceneName != ''"> and scene_name like concat('%', #{sceneName}, '%')</if>
|
||||
<if test="userId != null "> and user_id = #{userId}</if>
|
||||
<if test="userName != null and userName != ''"> and user_name like concat('%', #{userName}, '%')</if>
|
||||
<if test="cond != null "> and cond = #{cond}</if>
|
||||
<if test="silentPeriod != null "> and silent_period = #{silentPeriod}</if>
|
||||
<if test="executeMode != null "> and execute_mode = #{executeMode}</if>
|
||||
<if test="executeDelay != null "> and execute_delay = #{executeDelay}</if>
|
||||
<if test="hasAlert != null "> and has_alert = #{hasAlert}</if>
|
||||
<if test="enable != null "> and enable = #{enable}</if>
|
||||
</where>
|
||||
order by create_time desc
|
||||
</select>
|
||||
|
||||
<select id="selectSceneBySceneId" parameterType="Long" resultMap="SceneResult">
|
||||
<include refid="selectSceneVo"/>
|
||||
where scene_id = #{sceneId}
|
||||
</select>
|
||||
|
||||
<select id="selectSceneListBySceneIds" parameterType="String" resultMap="SceneResult">
|
||||
<include refid="selectSceneVo"/>
|
||||
where scene_id in
|
||||
<foreach item="sceneId" collection="array" open="(" separator="," close=")">
|
||||
#{sceneId}
|
||||
</foreach>
|
||||
</select>
|
||||
|
||||
<insert id="insertScene" parameterType="com.fastbee.iot.domain.Scene" useGeneratedKeys="true" keyProperty="sceneId">
|
||||
insert into iot_scene
|
||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||
<if test="sceneName != null and sceneName != ''">scene_name,</if>
|
||||
<if test="chainName != null and chainName != ''">chain_name,</if>
|
||||
<if test="userId != null">user_id,</if>
|
||||
<if test="userName != null and userName != ''">user_name,</if>
|
||||
<if test="createBy != null">create_by,</if>
|
||||
<if test="createTime != null">create_time,</if>
|
||||
<if test="updateBy != null">update_by,</if>
|
||||
<if test="updateTime != null">update_time,</if>
|
||||
<if test="remark != null">remark,</if>
|
||||
<if test="cond != null">cond,</if>
|
||||
<if test="silentPeriod != null">silent_period,</if>
|
||||
<if test="executeMode != null">execute_mode,</if>
|
||||
<if test="executeDelay != null">execute_delay,</if>
|
||||
<if test="hasAlert != null">has_alert,</if>
|
||||
<if test="enable != null">enable,</if>
|
||||
<if test="elData != null">el_data,</if>
|
||||
<if test="applicationName != null and applicationName != ''">application_name,</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="sceneName != null and sceneName != ''">#{sceneName},</if>
|
||||
<if test="chainName != null and chainName != ''">#{chainName},</if>
|
||||
<if test="userId != null">#{userId},</if>
|
||||
<if test="userName != null and userName != ''">#{userName},</if>
|
||||
<if test="createBy != null">#{createBy},</if>
|
||||
<if test="createTime != null">#{createTime},</if>
|
||||
<if test="updateBy != null">#{updateBy},</if>
|
||||
<if test="updateTime != null">#{updateTime},</if>
|
||||
<if test="remark != null">#{remark},</if>
|
||||
<if test="cond != null">#{cond},</if>
|
||||
<if test="silentPeriod != null">#{silentPeriod},</if>
|
||||
<if test="executeMode != null">#{executeMode},</if>
|
||||
<if test="executeDelay != null">#{executeDelay},</if>
|
||||
<if test="hasAlert != null">#{hasAlert},</if>
|
||||
<if test="enable != null">#{enable},</if>
|
||||
<if test="elData != null">#{elData},</if>
|
||||
<if test="applicationName != null and applicationName != ''">#{applicationName},</if>
|
||||
</trim>
|
||||
</insert>
|
||||
|
||||
<update id="updateScene" parameterType="com.fastbee.iot.domain.Scene">
|
||||
update iot_scene
|
||||
<trim prefix="SET" suffixOverrides=",">
|
||||
<if test="sceneName != null and sceneName != ''">scene_name = #{sceneName},</if>
|
||||
<if test="chainName != null and chainName != ''">chain_name = #{chainName},</if>
|
||||
<if test="userId != null">user_id = #{userId},</if>
|
||||
<if test="userName != null and userName != ''">user_name = #{userName},</if>
|
||||
<if test="createBy != null">create_by = #{createBy},</if>
|
||||
<if test="createTime != null">create_time = #{createTime},</if>
|
||||
<if test="updateBy != null">update_by = #{updateBy},</if>
|
||||
<if test="updateTime != null">update_time = #{updateTime},</if>
|
||||
<if test="remark != null">remark = #{remark},</if>
|
||||
<if test="cond != null">cond = #{cond},</if>
|
||||
<if test="silentPeriod != null">silent_period = #{silentPeriod},</if>
|
||||
<if test="executeMode != null">execute_mode = #{executeMode},</if>
|
||||
<if test="executeDelay != null">execute_delay = #{executeDelay},</if>
|
||||
<if test="hasAlert != null">has_alert = #{hasAlert},</if>
|
||||
<if test="enable != null">enable = #{enable},</if>
|
||||
<if test="elData != null">el_data = #{elData},</if>
|
||||
<if test="applicationName != null and applicationName != ''">application_name = #{applicationName},</if>
|
||||
</trim>
|
||||
where scene_id = #{sceneId}
|
||||
</update>
|
||||
|
||||
<delete id="deleteSceneBySceneId" parameterType="Long">
|
||||
delete from iot_scene where scene_id = #{sceneId}
|
||||
</delete>
|
||||
|
||||
<delete id="deleteSceneBySceneIds" parameterType="String">
|
||||
delete from iot_scene where scene_id in
|
||||
<foreach item="sceneId" collection="array" open="(" separator="," close=")">
|
||||
#{sceneId}
|
||||
</foreach>
|
||||
</delete>
|
||||
</mapper>
|
||||
@@ -0,0 +1,222 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.fastbee.iot.mapper.SceneScriptMapper">
|
||||
|
||||
<resultMap type="SceneScript" id="SceneScriptResult">
|
||||
<result property="scriptId" column="script_id"/>
|
||||
<result property="sceneId" column="scene_id"/>
|
||||
<result property="productId" column="product_id"/>
|
||||
<result property="productName" column="product_name"/>
|
||||
<result property="source" column="source"/>
|
||||
<result property="scriptPurpose" column="script_purpose"/>
|
||||
<result property="id" column="id"/>
|
||||
<result property="name" column="name"/>
|
||||
<result property="value" column="value"/>
|
||||
<result property="operator" column="operator"/>
|
||||
<result property="type" column="type"/>
|
||||
<result property="deviceCount" column="device_count"/>
|
||||
<result property="jobId" column="job_id"/>
|
||||
<result property="cronExpression" column="cron_expression"/>
|
||||
<result property="isAdvance" column="is_advance"/>
|
||||
<result property="parentId" column="parent_id"/>
|
||||
<result property="parentName" column="parent_name"/>
|
||||
<result property="arrayIndex" column="array_index"/>
|
||||
<result property="arrayIndexName" column="array_index_name"/>
|
||||
<result property="createBy" column="create_by"/>
|
||||
<result property="createTime" column="create_time"/>
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectSceneScriptVo">
|
||||
select script_id,
|
||||
scene_id,
|
||||
product_id,
|
||||
product_name,
|
||||
source,
|
||||
script_purpose,
|
||||
id,
|
||||
name,
|
||||
value,
|
||||
operator,
|
||||
type,
|
||||
device_count,
|
||||
job_id,
|
||||
cron_expression,
|
||||
is_advance,
|
||||
parent_id,
|
||||
parent_name,
|
||||
array_index,
|
||||
array_index_name,
|
||||
create_by,
|
||||
create_time
|
||||
from iot_scene_script
|
||||
</sql>
|
||||
|
||||
<select id="selectSceneScriptList" parameterType="SceneScript" resultMap="SceneScriptResult">
|
||||
<include refid="selectSceneScriptVo"/>
|
||||
<where>
|
||||
<if test="scriptId != null ">and script_id = #{scriptId}</if>
|
||||
<if test="sceneId != null ">and scene_id = #{sceneId}</if>
|
||||
<if test="productId != null ">and product_id = #{productId}</if>
|
||||
<if test="productName != null ">and product_name = #{productName}</if>
|
||||
<if test="source != null ">and source = #{source}</if>
|
||||
<if test="scriptPurpose != null ">and script_purpose = #{scriptPurpose}</if>
|
||||
<if test="name != null and name != ''">and name like concat('%', #{name}, '%')</if>
|
||||
<if test="value != null and value != ''">and value = #{value}</if>
|
||||
<if test="operator != null and operator != ''">and operator = #{operator}</if>
|
||||
<if test="type != null ">and type = #{type}</if>
|
||||
<if test="jobId != null ">and job_id = #{jobId}</if>
|
||||
<if test="cronExpression != null and cronExpression != ''">and cron_expression = #{cronExpression}</if>
|
||||
<if test="isAdvance != null ">and is_advance = #{isAdvance}</if>
|
||||
<if test="parentId != null and parentId != ''">and parent_id = #{parentId}</if>
|
||||
<if test="parentName != null and parentName != ''">and parent_name like concat('%', #{parentName}, '%')
|
||||
</if>
|
||||
<if test="arrayIndex != null and arrayIndex != ''">and array_index = #{arrayIndex}</if>
|
||||
<if test="arrayIndexName != null and arrayIndexName != ''">and array_index_name like concat('%',
|
||||
#{arrayIndexName}, '%')
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<select id="selectSceneScriptBySceneScriptId" parameterType="String" resultMap="SceneScriptResult">
|
||||
<include refid="selectSceneScriptVo"/>
|
||||
where script_id = #{scriptId}
|
||||
</select>
|
||||
|
||||
<select id="listSceneScriptByPurpose" resultMap="SceneScriptResult">
|
||||
<include refid="selectSceneScriptVo"/>
|
||||
where scene_id in
|
||||
<foreach collection="sceneIdList" item="sceneId" open="(" separator="," close=")">
|
||||
#{sceneId}
|
||||
</foreach>
|
||||
and script_purpose = #{scriptPurpose}
|
||||
</select>
|
||||
|
||||
<insert id="insertSceneScript" parameterType="SceneScript" useGeneratedKeys="false">
|
||||
insert into iot_scene_script
|
||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||
<if test="scriptId != null">script_id,</if>
|
||||
<if test="sceneId != null">scene_id,</if>
|
||||
<if test="productId != null">product_id,</if>
|
||||
<if test="productName != null">product_name,</if>
|
||||
<if test="source != null">source,</if>
|
||||
<if test="scriptPurpose != null">script_purpose,</if>
|
||||
<if test="id != null">id,</if>
|
||||
<if test="name != null">name,</if>
|
||||
<if test="value != null">value,</if>
|
||||
<if test="operator != null">operator,</if>
|
||||
<if test="type != null">type,</if>
|
||||
<if test="deviceCount != null">device_count,</if>
|
||||
<if test="jobId != null">job_id,</if>
|
||||
<if test="cronExpression != null">cron_expression,</if>
|
||||
<if test="isAdvance != null">is_advance,</if>
|
||||
<if test="parentId != null">parent_id,</if>
|
||||
<if test="parentName != null">parent_name,</if>
|
||||
<if test="arrayIndex != null">array_index,</if>
|
||||
<if test="arrayIndexName != null">array_index_name,</if>
|
||||
<if test="createBy != null">create_by,</if>
|
||||
<if test="createTime != null">create_time,</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="scriptId != null">#{scriptId},</if>
|
||||
<if test="sceneId != null">#{sceneId},</if>
|
||||
<if test="productId != null">#{productId},</if>
|
||||
<if test="productName != null">#{productName},</if>
|
||||
<if test="source != null">#{source},</if>
|
||||
<if test="scriptPurpose != null">#{scriptPurpose},</if>
|
||||
<if test="id != null">#{id},</if>
|
||||
<if test="name != null">#{name},</if>
|
||||
<if test="value != null">#{value},</if>
|
||||
<if test="operator != null">#{operator},</if>
|
||||
<if test="type != null">#{type},</if>
|
||||
<if test="deviceCount != null">#{deviceCount},</if>
|
||||
<if test="jobId != null">#{jobId},</if>
|
||||
<if test="cronExpression != null">#{cronExpression},</if>
|
||||
<if test="isAdvance != null">#{isAdvance},</if>
|
||||
<if test="parentId != null">#{parentId},</if>
|
||||
<if test="parentName != null">#{parentName},</if>
|
||||
<if test="arrayIndex != null">#{arrayIndex},</if>
|
||||
<if test="arrayIndexName != null">#{arrayIndexName},</if>
|
||||
<if test="createBy != null">#{createBy},</if>
|
||||
<if test="createTime != null">#{createTime},</if>
|
||||
</trim>
|
||||
</insert>
|
||||
|
||||
<update id="updateSceneScript" parameterType="SceneScript">
|
||||
update iot_scene_script
|
||||
<trim prefix="SET" suffixOverrides=",">
|
||||
<if test="scriptId != null">script_id = #{scriptId},</if>
|
||||
<if test="sceneId != null">scene_id = #{sceneId},</if>
|
||||
<if test="productId != null">product_id = #{productId},</if>
|
||||
<if test="productName != null">product_name = #{productName},</if>
|
||||
<if test="source != null">source = #{source},</if>
|
||||
<if test="scriptPurpose != null">script_purpose = #{scriptPurpose},</if>
|
||||
<if test="id != null">id = #{id},</if>
|
||||
<if test="name != null">name = #{name},</if>
|
||||
<if test="value != null">value = #{value},</if>
|
||||
<if test="operator != null">operator = #{operator},</if>
|
||||
<if test="type != null">type = #{type},</if>
|
||||
<if test="deviceCount != null">device_count = #{deviceCount},</if>
|
||||
<if test="jobId != null">job_id = #{jobId},</if>
|
||||
<if test="cronExpression != null">cron_expression = #{cronExpression},</if>
|
||||
<if test="isAdvance != null">is_advance = #{isAdvance},</if>
|
||||
<if test="parentId != null">parent_id = #{parentId},</if>
|
||||
<if test="parentName != null">parent_name = #{parentName},</if>
|
||||
<if test="arrayIndex != null">array_index = #{arrayIndex},</if>
|
||||
<if test="arrayIndexName != null">array_index_name = #{arrayIndexName},</if>
|
||||
<if test="createBy != null">create_by = #{createBy},</if>
|
||||
<if test="createTime != null">create_time = #{createTime},</if>
|
||||
</trim>
|
||||
where script_id = #{scriptId}
|
||||
</update>
|
||||
|
||||
<delete id="deleteSceneScriptBySceneScriptId" parameterType="String">
|
||||
delete
|
||||
from iot_scene_script
|
||||
where script_id = #{scriptId}
|
||||
</delete>
|
||||
|
||||
<delete id="deleteSceneScriptBySceneScriptIds" parameterType="String">
|
||||
delete from iot_scene_script where script_id in
|
||||
<foreach item="sceneScriptId" collection="array" open="(" separator="," close=")">
|
||||
#{scriptId}
|
||||
</foreach>
|
||||
</delete>
|
||||
|
||||
<insert id="insertSceneScriptList" parameterType="java.util.List">
|
||||
insert into iot_scene_script (script_id,scene_id,product_id,product_name,source,script_purpose,id, name,value,operator,type,device_count,job_id,
|
||||
cron_expression,is_advance,parent_id,parent_name,array_index,array_index_name,create_by,create_time)
|
||||
VALUES
|
||||
<foreach collection="list" item="sceneScript" separator=",">
|
||||
(#{sceneScript.scriptId},
|
||||
#{sceneScript.sceneId},
|
||||
#{sceneScript.productId},
|
||||
#{sceneScript.productName},
|
||||
#{sceneScript.source},
|
||||
#{sceneScript.scriptPurpose},
|
||||
#{sceneScript.id},
|
||||
#{sceneScript.name},
|
||||
#{sceneScript.value},
|
||||
#{sceneScript.operator},
|
||||
#{sceneScript.type},
|
||||
#{sceneScript.deviceCount},
|
||||
#{sceneScript.jobId},
|
||||
#{sceneScript.cronExpression},
|
||||
#{sceneScript.isAdvance},
|
||||
#{sceneScript.parentId},
|
||||
#{sceneScript.parentName},
|
||||
#{sceneScript.arrayIndex},
|
||||
#{sceneScript.arrayIndexName},
|
||||
#{sceneScript.createBy},
|
||||
#{sceneScript.createTime})
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
<delete id="deleteSceneScriptBySceneIds" parameterType="String">
|
||||
delete from iot_scene_script where scene_id in
|
||||
<foreach item="sceneId" collection="array" open="(" separator="," close=")">
|
||||
#{sceneId}
|
||||
</foreach>
|
||||
</delete>
|
||||
</mapper>
|
||||
@@ -0,0 +1,209 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.fastbee.iot.mapper.ScriptMapper">
|
||||
|
||||
<resultMap type="com.fastbee.iot.domain.Script" id="RuleScriptResult">
|
||||
<result property="userId" column="user_id" />
|
||||
<result property="userName" column="user_name" />
|
||||
<result property="sceneId" column="scene_id" />
|
||||
<result property="productId" column="product_id" />
|
||||
<result property="productName" column="product_name" />
|
||||
<result property="scriptEvent" column="script_event" />
|
||||
<result property="scriptAction" column="script_action" />
|
||||
<result property="scriptPurpose" column="script_purpose" />
|
||||
<result property="scriptOrder" column="script_order" />
|
||||
<result property="applicationName" column="application_name" />
|
||||
<result property="scriptId" column="script_id" />
|
||||
<result property="scriptName" column="script_name" />
|
||||
<result property="scriptData" column="script_data" />
|
||||
<result property="scriptType" column="script_type" />
|
||||
<result property="scriptLanguage" column="script_language" />
|
||||
<result property="enable" column="enable" />
|
||||
<result property="delFlag" column="del_flag" />
|
||||
<result property="createBy" column="create_by" />
|
||||
<result property="createTime" column="create_time" />
|
||||
<result property="updateBy" column="update_by" />
|
||||
<result property="updateTime" column="update_time" />
|
||||
<result property="remark" column="remark" />
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectRuleScriptVo">
|
||||
select user_id, user_name, scene_id,product_id,product_name,script_event,script_action,script_purpose,script_order,application_name, script_id, script_name, script_data, script_type, script_language,enable, del_flag, create_by, create_time, update_by, update_time, remark,product_id from iot_script
|
||||
</sql>
|
||||
|
||||
<sql id="selectRuleScriptList">
|
||||
select user_id, user_name, scene_id,product_id,product_name, script_event,script_action,script_purpose,script_order,application_name, script_id, script_name, script_type, script_language,enable, create_by, create_time, update_by, update_time,product_id from iot_script
|
||||
</sql>
|
||||
|
||||
<select id="selectRuleScriptList" parameterType="com.fastbee.iot.model.ScriptCondition" resultMap="RuleScriptResult">
|
||||
<include refid="selectRuleScriptList"/>
|
||||
<where>
|
||||
<if test="applicationName != null and applicationName != ''"> and application_name like concat('%', #{applicationName}, '%')</if>
|
||||
<if test="scriptId != null and scriptId != ''"> and script_id = #{scriptId}</if>
|
||||
<if test="userId != null and userId != ''"> and user_id = #{userId}</if>
|
||||
<if test="sceneId != null and sceneId != ''"> and scene_id = #{sceneId}</if>
|
||||
<if test="productId != null and productId != ''"> and product_id = #{productId}</if>
|
||||
<if test="scriptEvent != null and scriptEvent != ''"> and script_event = #{scriptEvent}</if>
|
||||
<if test="scriptAction != null and scriptAction != ''"> and script_action = #{scriptAction}</if>
|
||||
<if test="scriptPurpose != null and scriptPurpose != ''"> and script_purpose = #{scriptPurpose}</if>
|
||||
<if test="scriptName != null and scriptName != ''"> and script_name like concat('%', #{scriptName}, '%')</if>
|
||||
<if test="scriptType != null and scriptType != ''"> and script_type = #{scriptType}</if>
|
||||
<if test="enable != null"> and enable = #{enable}</if>
|
||||
<if test="scriptLanguage != null and scriptLanguage != ''"> and script_language = #{scriptLanguage}</if>
|
||||
</where>
|
||||
order by script_order
|
||||
</select>
|
||||
|
||||
<select id="selectRuleScriptIdArray" parameterType="com.fastbee.iot.model.ScriptCondition" resultType="String">
|
||||
select script_id from iot_script
|
||||
<where>
|
||||
<if test="applicationName != null and applicationName != ''"> and application_name like concat('%', #{applicationName}, '%')</if>
|
||||
<if test="sceneId != null and sceneId != ''"> and scene_id = #{sceneId}</if>
|
||||
<if test="productId != null and productId != ''"> and product_id = #{productId}</if>
|
||||
<if test="scriptId != null and scriptId != ''"> and script_id = #{scriptId}</if>
|
||||
<if test="scriptEvent != null and scriptEvent != ''"> and script_event = #{scriptEvent}</if>
|
||||
<if test="scriptAction != null and scriptAction != ''"> and script_action = #{scriptAction}</if>
|
||||
<if test="scriptPurpose != null and scriptPurpose != ''"> and script_purpose = #{scriptPurpose}</if>
|
||||
<if test="enable != null"> and enable = #{enable}</if>
|
||||
<if test="scriptLanguage != null and scriptLanguage != ''"> and script_language = #{scriptLanguage}</if>
|
||||
<if test="userId != null and userId != ''"> and (user_id = #{userId} or user_id = #{tencentId})</if>
|
||||
</where>
|
||||
order by script_order
|
||||
</select>
|
||||
|
||||
<select id="selectRuleScriptIdCount" parameterType="String" resultType="int">
|
||||
select count(script_id) from iot_script where script_id = #{scriptId}
|
||||
</select>
|
||||
|
||||
<select id="selectRuleScriptById" parameterType="String" resultMap="RuleScriptResult">
|
||||
<include refid="selectRuleScriptVo"/>
|
||||
where script_id = #{scriptId}
|
||||
</select>
|
||||
|
||||
<insert id="insertRuleScript" parameterType="Script" useGeneratedKeys="false">
|
||||
insert into iot_script
|
||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||
<if test="userId != null and userId != ''">user_id,</if>
|
||||
<if test="userName != null and userName != ''">user_name,</if>
|
||||
<if test="sceneId != null">scene_id,</if>
|
||||
<if test="scriptEvent != null ">script_event,</if>
|
||||
<if test="scriptAction != null ">script_action,</if>
|
||||
<if test="scriptPurpose != null ">script_purpose,</if>
|
||||
<if test="scriptOrder != null ">script_order,</if>
|
||||
<if test="applicationName != null and applicationName != ''">application_name,</if>
|
||||
<if test="scriptId != null and scriptId != ''">script_id,</if>
|
||||
<if test="scriptName != null and scriptName != ''">script_name,</if>
|
||||
<if test="scriptData != null">script_data,</if>
|
||||
<if test="scriptType != null ">script_type,</if>
|
||||
<if test="scriptLanguage != null and scriptLanguage != ''">script_language,</if>
|
||||
<if test="enable != null">enable,</if>
|
||||
<if test="delFlag != null and delFlag != ''">del_flag,</if>
|
||||
<if test="createBy != null and createBy != ''">create_by,</if>
|
||||
<if test="createTime != null">create_time,</if>
|
||||
<if test="updateBy != null">update_by,</if>
|
||||
<if test="updateTime != null">update_time,</if>
|
||||
<if test="remark != null">remark,</if>
|
||||
<if test="productId != null">product_id,</if>
|
||||
<if test="productName != null">product_name,</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="userId != null and userId != ''">#{userId},</if>
|
||||
<if test="userName != null and userName != ''">#{userName},</if>
|
||||
<if test="sceneId != null">#{sceneId},</if>
|
||||
<if test="scriptEvent != null ">#{scriptEvent},</if>
|
||||
<if test="scriptAction != null ">#{scriptAction},</if>
|
||||
<if test="scriptPurpose != null ">#{scriptPurpose},</if>
|
||||
<if test="scriptOrder != null ">#{scriptOrder},</if>
|
||||
<if test="applicationName != null and applicationName != ''">#{applicationName},</if>
|
||||
<if test="scriptId != null and scriptId != ''">#{scriptId},</if>
|
||||
<if test="scriptName != null and scriptName != ''">#{scriptName},</if>
|
||||
<if test="scriptData != null">#{scriptData},</if>
|
||||
<if test="scriptType != null ">#{scriptType},</if>
|
||||
<if test="scriptLanguage != null and scriptLanguage != ''">#{scriptLanguage},</if>
|
||||
<if test="enable != null">#{enable},</if>
|
||||
<if test="delFlag != null and delFlag != ''">#{delFlag},</if>
|
||||
<if test="createBy != null and createBy != ''">#{createBy},</if>
|
||||
<if test="createTime != null">#{createTime},</if>
|
||||
<if test="updateBy != null">#{updateBy},</if>
|
||||
<if test="updateTime != null">#{updateTime},</if>
|
||||
<if test="remark != null">#{remark},</if>
|
||||
<if test="productId != null">#{productId},</if>
|
||||
<if test="productName != null">#{productName},</if>
|
||||
</trim>
|
||||
</insert>
|
||||
|
||||
<update id="updateRuleScript" parameterType="Script">
|
||||
update iot_script
|
||||
<trim prefix="SET" suffixOverrides=",">
|
||||
<if test="userId != null and userId != ''">user_id = #{userId},</if>
|
||||
<if test="userName != null and userName != ''">user_name = #{userName},</if>
|
||||
<if test="sceneId != null and sceneId != ''">scene_id = #{sceneId},</if>
|
||||
<if test="scriptEvent != null ">script_event = #{scriptEvent},</if>
|
||||
<if test="scriptAction != null ">script_action = #{scriptAction},</if>
|
||||
<if test="scriptPurpose != null ">script_purpose = #{scriptPurpose},</if>
|
||||
<if test="scriptOrder != null ">script_order = #{scriptOrder},</if>
|
||||
<if test="applicationName != null and applicationName != ''">application_name = #{applicationName},</if>
|
||||
<if test="scriptId != null and scriptId != ''">script_id = #{scriptId},</if>
|
||||
<if test="scriptName != null and scriptName != ''">script_name = #{scriptName},</if>
|
||||
<if test="scriptData != null">script_data = #{scriptData},</if>
|
||||
<if test="scriptType != null ">script_type = #{scriptType},</if>
|
||||
<if test="scriptLanguage != null and scriptLanguage != ''">script_language = #{scriptLanguage},</if>
|
||||
<if test="enable != null">enable = #{enable},</if>
|
||||
<if test="delFlag != null and delFlag != ''">del_flag = #{delFlag},</if>
|
||||
<if test="createBy != null and createBy != ''">create_by = #{createBy},</if>
|
||||
<if test="createTime != null">create_time = #{createTime},</if>
|
||||
<if test="updateBy != null">update_by = #{updateBy},</if>
|
||||
<if test="updateTime != null">update_time = #{updateTime},</if>
|
||||
<if test="remark != null">remark = #{remark},</if>
|
||||
<if test="productId != null">product_id = #{productId},</if>
|
||||
<if test="productName != null">product_name = #{productName},</if>
|
||||
</trim>
|
||||
where script_id = #{scriptId}
|
||||
</update>
|
||||
|
||||
<delete id="deleteRuleScriptById" parameterType="String">
|
||||
delete from iot_script where script_id = #{scriptId}
|
||||
</delete>
|
||||
|
||||
<delete id="deleteRuleScriptByIds" parameterType="String">
|
||||
delete from iot_script where script_id in
|
||||
<foreach item="scriptId" collection="array" open="(" separator="," close=")">
|
||||
#{scriptId}
|
||||
</foreach>
|
||||
</delete>
|
||||
|
||||
<insert id="insertRuleScriptList" parameterType="java.util.List">
|
||||
insert into iot_script (user_id,user_name,scene_id,script_event, script_action, script_purpose,script_order,
|
||||
application_name,script_id,script_name,script_data,script_type,script_language,enable,create_by,create_time,product_id,product_name)
|
||||
VALUES
|
||||
<foreach collection ="list" item="ruleScript" separator =",">
|
||||
(#{ruleScript.userId},
|
||||
#{ruleScript.userName},
|
||||
#{ruleScript.sceneId},
|
||||
#{ruleScript.scriptEvent},
|
||||
#{ruleScript.scriptAction},
|
||||
#{ruleScript.scriptPurpose},
|
||||
#{ruleScript.scriptOrder},
|
||||
#{ruleScript.applicationName},
|
||||
#{ruleScript.scriptId},
|
||||
#{ruleScript.scriptName},
|
||||
#{ruleScript.scriptData},
|
||||
#{ruleScript.scriptType},
|
||||
#{ruleScript.scriptLanguage},
|
||||
#{ruleScript.enable},
|
||||
#{ruleScript.createBy},
|
||||
#{ruleScript.createTime},
|
||||
#{ruleScript.productId},
|
||||
#{ruleScript.productName})
|
||||
</foreach >
|
||||
</insert>
|
||||
|
||||
<delete id="deleteRuleScriptBySceneIds" parameterType="String">
|
||||
delete from iot_script where scene_id in
|
||||
<foreach item="sceneId" collection="array" open="(" separator="," close=")">
|
||||
#{sceneId}
|
||||
</foreach>
|
||||
</delete>
|
||||
</mapper>
|
||||
@@ -73,6 +73,7 @@
|
||||
"vue-qr": "^4.0.9",
|
||||
"vue-router": "3.4.9",
|
||||
"vue-seamless-scroll": "^1.1.23",
|
||||
"vue2-ace-editor": "^0.0.15",
|
||||
"vuedraggable": "2.24.3",
|
||||
"vuex": "3.6.0"
|
||||
},
|
||||
|
||||
53
vue/src/api/iot/scene.js
Normal file
53
vue/src/api/iot/scene.js
Normal file
@@ -0,0 +1,53 @@
|
||||
import request from '@/utils/request';
|
||||
|
||||
// 查询场景联动列表
|
||||
export function listScene(query) {
|
||||
return request({
|
||||
url: '/iot/scene/list',
|
||||
method: 'get',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
|
||||
// 查询场景联动详细
|
||||
export function getScene(sceneId) {
|
||||
return request({
|
||||
url: '/iot/scene/' + sceneId,
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
|
||||
// 新增场景联动
|
||||
export function addScene(data) {
|
||||
return request({
|
||||
url: '/iot/scene',
|
||||
method: 'post',
|
||||
data: data,
|
||||
});
|
||||
}
|
||||
|
||||
// 修改场景联动
|
||||
export function updateScene(data) {
|
||||
return request({
|
||||
url: '/iot/scene',
|
||||
method: 'put',
|
||||
data: data,
|
||||
});
|
||||
}
|
||||
|
||||
// 删除场景联动
|
||||
export function delScene(sceneId) {
|
||||
return request({
|
||||
url: '/iot/scene/' + sceneId,
|
||||
method: 'delete',
|
||||
});
|
||||
}
|
||||
|
||||
// 执行场景
|
||||
export function runScene(query) {
|
||||
return request({
|
||||
url: '/iot/runtime/runScene',
|
||||
method: 'post',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
53
vue/src/api/iot/script.js
Normal file
53
vue/src/api/iot/script.js
Normal file
@@ -0,0 +1,53 @@
|
||||
import request from '@/utils/request';
|
||||
|
||||
// 查询规则引擎脚本列表
|
||||
export function listScript(query) {
|
||||
return request({
|
||||
url: '/iot/script/list',
|
||||
method: 'get',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
|
||||
// 查询规则引擎脚本详细
|
||||
export function getScript(scriptId) {
|
||||
return request({
|
||||
url: '/iot/script/' + scriptId,
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
|
||||
// 新增规则引擎脚本
|
||||
export function addScript(data) {
|
||||
return request({
|
||||
url: '/iot/script',
|
||||
method: 'post',
|
||||
data: data,
|
||||
});
|
||||
}
|
||||
|
||||
// 修改规则引擎脚本
|
||||
export function updateScript(data) {
|
||||
return request({
|
||||
url: '/iot/script',
|
||||
method: 'put',
|
||||
data: data,
|
||||
});
|
||||
}
|
||||
|
||||
// 删除规则引擎脚本
|
||||
export function delScript(scriptId) {
|
||||
return request({
|
||||
url: '/iot/script/' + scriptId,
|
||||
method: 'delete',
|
||||
});
|
||||
}
|
||||
|
||||
// 验证规则脚本
|
||||
export function validateScript(scriptData) {
|
||||
return request({
|
||||
url: '/iot/script/validate',
|
||||
method: 'post',
|
||||
data: scriptData,
|
||||
});
|
||||
}
|
||||
103
vue/src/views/components/editor/editor.vue
Normal file
103
vue/src/views/components/editor/editor.vue
Normal file
@@ -0,0 +1,103 @@
|
||||
<template>
|
||||
<div style="border: 0px solid #ebebeb; overflow: hidden; border-radius: 6px; background-color: #ebebeb; padding: 8px 5px 8px 0">
|
||||
<editor ref="codeEditor" v-model="currentContent" @init="editorInit" :options="options" :lang="lang" :theme="codeStyle" :width="width" :height="height" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// import { mapState } from 'vuex';
|
||||
|
||||
export default {
|
||||
name: 'AceEditor',
|
||||
components: {
|
||||
editor: require('vue2-ace-editor'),
|
||||
},
|
||||
props: {
|
||||
width: {
|
||||
type: String,
|
||||
default: '100%',
|
||||
},
|
||||
height: {
|
||||
type: String,
|
||||
default: '500px',
|
||||
},
|
||||
content: {
|
||||
type: String,
|
||||
required: true,
|
||||
default: () => null,
|
||||
},
|
||||
lang: {
|
||||
type: String,
|
||||
default: 'groovy',
|
||||
},
|
||||
readOnly: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
codeStyle: {
|
||||
type: String,
|
||||
default: 'chrome',
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
options: {
|
||||
autoScrollEditorIntoView: true,
|
||||
// enableBasicAutocompletion: true,
|
||||
enableLiveAutocompletion: true,
|
||||
enableSnippets: true,
|
||||
// 只读
|
||||
readOnly: this.readOnly,
|
||||
// 显示打印边距线
|
||||
showPrintMargin: false,
|
||||
// 字体大小
|
||||
fontSize: 13,
|
||||
},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
// ...mapState({
|
||||
// codeStyle: (state) => state.settings.codeStyle,
|
||||
// codeSize: (state) => state.settings.codeSize,
|
||||
// }),
|
||||
currentContent: {
|
||||
get() {
|
||||
return this.content;
|
||||
},
|
||||
set(val) {
|
||||
this.$emit('update:content', val);
|
||||
},
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
codeSize: {
|
||||
handler: function (value) {
|
||||
this.$refs.codeEditor.editor.setOptions({
|
||||
fontSize: value,
|
||||
});
|
||||
},
|
||||
deep: true,
|
||||
},
|
||||
},
|
||||
created() {},
|
||||
mounted() {},
|
||||
methods: {
|
||||
editorInit(editor) {
|
||||
require('brace/ext/language_tools');
|
||||
require('brace/mode/groovy');
|
||||
require('brace/mode/mysql');
|
||||
require('brace/mode/json');
|
||||
require('brace/theme/chrome');
|
||||
require('brace/snippets/groovy');
|
||||
require('brace/snippets/json');
|
||||
require('brace/ext/beautify');
|
||||
},
|
||||
format() {
|
||||
const ace = require('brace');
|
||||
const editor = this.$refs.codeEditor.editor;
|
||||
const beautify = ace.acequire('ace/ext/beautify');
|
||||
beautify.beautify(editor.session);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
180
vue/src/views/iot/scene/device-list.vue
Normal file
180
vue/src/views/iot/scene/device-list.vue
Normal file
@@ -0,0 +1,180 @@
|
||||
<template>
|
||||
<el-dialog title="选择设备" :visible.sync="openDeviceList" width="900px" append-to-body>
|
||||
<el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px">
|
||||
<el-form-item label="设备名称" prop="deviceName">
|
||||
<el-input v-model="queryParams.deviceName" placeholder="请输入设备名称" clearable size="small" @keyup.enter.native="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="设备编号" prop="serialNumber">
|
||||
<el-input v-model="queryParams.serialNumber" placeholder="请输入设备编号" clearable size="small" @keyup.enter.native="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-table ref="multipleTable" v-loading="loading" :data="deviceList" @select="handleSelectionChange" row-key="serialNumber" size="mini">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="设备名称" align="center" prop="deviceName" />
|
||||
<el-table-column label="设备编号" align="center" prop="serialNumber" />
|
||||
<el-table-column label="产品名称" align="center" prop="productName" />
|
||||
<el-table-column label="设备类型" align="center" width="75">
|
||||
<template slot-scope="scope">
|
||||
<el-tag type="success" v-if="scope.row.isOwner == 0">分享</el-tag>
|
||||
<el-tag type="primary" v-else>拥有</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="定位方式" align="center" prop="locationWay" width="100">
|
||||
<template slot-scope="scope">
|
||||
<dict-tag :options="dict.type.iot_location_way" :value="scope.row.locationWay" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="设备状态" align="center" prop="status" width="80">
|
||||
<template slot-scope="scope">
|
||||
<dict-tag :options="dict.type.iot_device_status" :value="scope.row.status" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList(null)" />
|
||||
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="confirmSelectDevice">确 定</el-button>
|
||||
<el-button @click="closeSelectDeviceList">取 消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listDeviceShort } from '@/api/iot/device';
|
||||
export default {
|
||||
name: 'device-list',
|
||||
dicts: ['iot_device_status', 'iot_location_way'],
|
||||
data() {
|
||||
return {
|
||||
// 遮罩层
|
||||
loading: true,
|
||||
// 选中设备
|
||||
selectDeviceNums: [],
|
||||
productId: 0,
|
||||
productName: '',
|
||||
// 是否显示设备列表
|
||||
openDeviceList: false,
|
||||
// 总条数
|
||||
total: 0,
|
||||
// 设备表格数据
|
||||
deviceList: [],
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
deviceName: null,
|
||||
productId: null,
|
||||
productName: null,
|
||||
serialNumber: null,
|
||||
status: null,
|
||||
},
|
||||
};
|
||||
},
|
||||
created() {},
|
||||
methods: {
|
||||
// 获取设备列表
|
||||
getList() {
|
||||
this.deviceList = [];
|
||||
this.loading = true;
|
||||
this.queryParams.productId = this.queryParams.productId == 0 ? null : this.queryParams.productId;
|
||||
listDeviceShort(this.queryParams).then((response) => {
|
||||
this.deviceList = response.rows;
|
||||
this.total = response.total;
|
||||
this.loading = false;
|
||||
// 设置选中
|
||||
if (this.selectDeviceNums) {
|
||||
this.deviceList.forEach((row) => {
|
||||
this.$nextTick(() => {
|
||||
if (this.selectDeviceNums.some((x) => x === row.serialNumber)) {
|
||||
this.$refs.multipleTable.toggleRowSelection(row, true);
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
// 初始化
|
||||
this.selectDeviceNums = [];
|
||||
}
|
||||
});
|
||||
},
|
||||
/** 搜索按钮操作 */
|
||||
handleQuery() {
|
||||
this.queryParams.pageNum = 1;
|
||||
this.getList(null);
|
||||
},
|
||||
/** 重置按钮操作 */
|
||||
resetQuery() {
|
||||
this.resetForm('queryForm');
|
||||
this.handleQuery();
|
||||
},
|
||||
/** 多选框选中数据 */
|
||||
handleSelectionChange(selection, row) {
|
||||
// 设备ID是否存在于原始设备ID数组中
|
||||
let index = this.selectDeviceNums.indexOf(row.serialNumber);
|
||||
// 是否选中
|
||||
let value = selection.indexOf(row);
|
||||
if (index == -1 && value != -1) {
|
||||
// 不存在且选中
|
||||
this.selectDeviceNums.push(row.serialNumber);
|
||||
this.productId = row.productId;
|
||||
this.productName = row.productName;
|
||||
} else if (index != -1 && value == -1) {
|
||||
// 存在且取消选中
|
||||
this.selectDeviceNums.splice(index, 1);
|
||||
}
|
||||
|
||||
// 筛选产品下的设备比
|
||||
if (this.selectDeviceNums.length == 0) {
|
||||
this.queryParams.productId = null;
|
||||
this.getList();
|
||||
} else if (this.selectDeviceNums.length == 1) {
|
||||
this.queryParams.productId = row.productId;
|
||||
this.getList();
|
||||
}
|
||||
},
|
||||
// 全选事件处理
|
||||
handleSelectionAll(selection) {
|
||||
for (let i = 0; i < this.deviceList.length; i++) {
|
||||
// 设备ID是否存在于原始设备ID数组中
|
||||
let index = this.selectDeviceNums.indexOf(this.deviceList[i].serialNumber);
|
||||
// 是否选中
|
||||
let value = selection.indexOf(this.deviceList[i]);
|
||||
if (index == -1 && value != -1) {
|
||||
// 不存在且选中
|
||||
this.selectDeviceNums.push(this.deviceList[i].serialNumber);
|
||||
} else if (index != -1 && value == -1) {
|
||||
// 存在且取消选中
|
||||
this.selectDeviceNums.splice(index, 1);
|
||||
}
|
||||
}
|
||||
},
|
||||
// 关闭选择设备列表
|
||||
closeSelectDeviceList() {
|
||||
this.openDeviceList = false;
|
||||
},
|
||||
/**确定选择设备,设备传递给父组件 */
|
||||
confirmSelectDevice() {
|
||||
if (this.selectDeviceNums.length > 0) {
|
||||
var data = {
|
||||
productId: this.productId,
|
||||
productName: this.productName,
|
||||
deviceNums: this.selectDeviceNums,
|
||||
};
|
||||
this.$emit('deviceEvent', data);
|
||||
}
|
||||
this.openDeviceList = false;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/***隐藏全选,避免选中不同产品的设备**/
|
||||
::v-deep .el-table__header-wrapper .el-checkbox {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
1602
vue/src/views/iot/scene/index.vue
Normal file
1602
vue/src/views/iot/scene/index.vue
Normal file
File diff suppressed because it is too large
Load Diff
253
vue/src/views/iot/scene/log.vue
Normal file
253
vue/src/views/iot/scene/log.vue
Normal file
@@ -0,0 +1,253 @@
|
||||
<template>
|
||||
<div style="padding: 6px">
|
||||
<el-card v-show="showSearch" style="margin-bottom: 6px">
|
||||
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px" style="margin-bottom: -20px">
|
||||
<el-form-item label="告警名称" prop="alertName">
|
||||
<el-input v-model="queryParams.alertName" placeholder="请输入告警名称" clearable size="small" @keyup.enter.native="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="告警级别" prop="alertLevel">
|
||||
<el-select v-model="queryParams.alertLevel" placeholder="请选择告警级别" clearable size="small">
|
||||
<el-option v-for="dict in dict.type.iot_alert_level" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="处理状态" prop="status">
|
||||
<el-select v-model="queryParams.status" placeholder="请选择处理状态" clearable size="small">
|
||||
<el-option v-for="dict in dict.type.iot_process_status" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card style="padding-bottom: 100px">
|
||||
<el-table v-loading="loading" :data="alertLogList" @selection-change="handleSelectionChange" border>
|
||||
<el-table-column label="告警名称" align="center" prop="alertName" />
|
||||
<el-table-column label="设备编号" align="center" prop="serialNumber" />
|
||||
<el-table-column label="设备名称" align="center" prop="deviceName" />
|
||||
<el-table-column label="告警级别" align="center" prop="alertLevel" width="120">
|
||||
<template slot-scope="scope">
|
||||
<dict-tag :options="dict.type.iot_alert_level" :value="scope.row.alertLevel" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="告警时间" align="center" prop="createTime" width="170">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="数据" align="left" header-align="center" prop="detail">
|
||||
<template slot-scope="scope">
|
||||
<div v-html="formatDetail(scope.row.detail)"></div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="处理状态" align="center" prop="status">
|
||||
<template slot-scope="scope">
|
||||
<dict-tag :options="dict.type.iot_process_status" :value="scope.row.status" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" v-hasPermi="['iot:alertLog:edit']">处理</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
|
||||
|
||||
<!-- 添加或修改设备告警对话框 -->
|
||||
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
|
||||
<el-form-item label="处理结果" prop="remark">
|
||||
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" rows="8" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// import { listAlertLog, getAlertLog, delAlertLog, addAlertLog, updateAlertLog } from '@/api/iot/alertLog';
|
||||
|
||||
export default {
|
||||
name: 'SceneLog',
|
||||
dicts: ['iot_alert_level', 'iot_process_status'],
|
||||
data() {
|
||||
return {
|
||||
// 遮罩层
|
||||
loading: true,
|
||||
// 选中数组
|
||||
ids: [],
|
||||
// 非单个禁用
|
||||
single: true,
|
||||
// 非多个禁用
|
||||
multiple: true,
|
||||
// 显示搜索条件
|
||||
showSearch: true,
|
||||
// 总条数
|
||||
total: 0,
|
||||
// 设备告警表格数据
|
||||
alertLogList: [],
|
||||
// 弹出层标题
|
||||
title: '',
|
||||
// 是否显示弹出层
|
||||
open: false,
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
alertName: null,
|
||||
alertLevel: null,
|
||||
status: null,
|
||||
productId: null,
|
||||
productName: null,
|
||||
deviceId: null,
|
||||
deviceName: null,
|
||||
},
|
||||
// 表单参数
|
||||
form: {},
|
||||
// 表单校验
|
||||
rules: {
|
||||
remark: [
|
||||
{
|
||||
required: true,
|
||||
message: '处理内容不能为空',
|
||||
trigger: 'blur',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
/** 查询设备告警列表 */
|
||||
getList() {
|
||||
this.loading = true;
|
||||
listAlertLog(this.queryParams).then((response) => {
|
||||
this.alertLogList = response.rows;
|
||||
this.total = response.total;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
// 取消按钮
|
||||
cancel() {
|
||||
this.open = false;
|
||||
this.reset();
|
||||
},
|
||||
// 表单重置
|
||||
reset() {
|
||||
this.form = {
|
||||
alertLogId: null,
|
||||
alertName: null,
|
||||
alertLevel: null,
|
||||
status: null,
|
||||
productId: null,
|
||||
productName: null,
|
||||
deviceId: null,
|
||||
deviceName: null,
|
||||
createBy: null,
|
||||
createTime: null,
|
||||
updateBy: null,
|
||||
updateTime: null,
|
||||
remark: null,
|
||||
};
|
||||
this.resetForm('form');
|
||||
},
|
||||
/** 搜索按钮操作 */
|
||||
handleQuery() {
|
||||
this.queryParams.pageNum = 1;
|
||||
this.getList();
|
||||
},
|
||||
/** 重置按钮操作 */
|
||||
resetQuery() {
|
||||
this.resetForm('queryForm');
|
||||
this.handleQuery();
|
||||
},
|
||||
// 多选框选中数据
|
||||
handleSelectionChange(selection) {
|
||||
this.ids = selection.map((item) => item.alertLogId);
|
||||
this.single = selection.length !== 1;
|
||||
this.multiple = !selection.length;
|
||||
},
|
||||
/** 新增按钮操作 */
|
||||
handleAdd() {
|
||||
this.reset();
|
||||
this.open = true;
|
||||
this.title = '添加设备告警';
|
||||
},
|
||||
/** 修改按钮操作 */
|
||||
handleUpdate(row) {
|
||||
this.reset();
|
||||
const alertLogId = row.alertLogId || this.ids;
|
||||
getAlertLog(alertLogId).then((response) => {
|
||||
this.form = response.data;
|
||||
this.open = true;
|
||||
this.title = '修改设备告警';
|
||||
});
|
||||
},
|
||||
/** 提交按钮 */
|
||||
submitForm() {
|
||||
this.$refs['form'].validate((valid) => {
|
||||
if (valid) {
|
||||
if (this.form.alertLogId != null) {
|
||||
updateAlertLog(this.form).then((response) => {
|
||||
this.$modal.msgSuccess('修改成功');
|
||||
this.open = false;
|
||||
this.getList();
|
||||
});
|
||||
} else {
|
||||
addAlertLog(this.form).then((response) => {
|
||||
this.$modal.msgSuccess('新增成功');
|
||||
this.open = false;
|
||||
this.getList();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
/** 删除按钮操作 */
|
||||
handleDelete(row) {
|
||||
const alertLogIds = row.alertLogId || this.ids;
|
||||
this.$modal
|
||||
.confirm('是否确认删除设备告警编号为"' + alertLogIds + '"的数据项?')
|
||||
.then(function () {
|
||||
return delAlertLog(alertLogIds);
|
||||
})
|
||||
.then(() => {
|
||||
this.getList();
|
||||
this.$modal.msgSuccess('删除成功');
|
||||
})
|
||||
.catch(() => {});
|
||||
},
|
||||
/** 导出按钮操作 */
|
||||
handleExport() {
|
||||
this.download(
|
||||
'iot/alertLog/export',
|
||||
{
|
||||
...this.queryParams,
|
||||
},
|
||||
`alertLog_${new Date().getTime()}.xlsx`
|
||||
);
|
||||
},
|
||||
/**格式化显示物模型**/
|
||||
formatDetail(json) {
|
||||
if (json == null || json == '') {
|
||||
return;
|
||||
}
|
||||
let item = JSON.parse(json);
|
||||
let result = 'id:<span style="color:#F56C6C">' + item.id + '</span><br />';
|
||||
result = result + 'value:<span style="color:#F56C6C">' + item.value + '</span><br />';
|
||||
result = result + 'remark:<span style="color:#F56C6C">' + item.remark + '</span>';
|
||||
return result;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
147
vue/src/views/iot/scene/product-list.vue
Normal file
147
vue/src/views/iot/scene/product-list.vue
Normal file
@@ -0,0 +1,147 @@
|
||||
<template>
|
||||
<el-dialog title="选择产品" :visible.sync="open" width="800px">
|
||||
<div style="margin-top: -55px">
|
||||
<el-divider style="margin-top: -30px"></el-divider>
|
||||
<el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px">
|
||||
<el-form-item label="产品名称" prop="productName">
|
||||
<el-input v-model="queryParams.productName" placeholder="请输入产品名称" clearable size="small" @keyup.enter.native="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-table v-loading="loading" ref="singleTable" :data="productList" @row-click="rowClick" highlight-current-row size="mini">
|
||||
<el-table-column label="选择" width="50" align="center">
|
||||
<template slot-scope="scope">
|
||||
<input type="radio" :checked="scope.row.isSelect" name="product" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="产品名称" align="center" prop="productName" />
|
||||
<el-table-column label="分类名称" align="center" prop="categoryName" />
|
||||
<el-table-column label="租户名称" align="center" prop="tenantName" />
|
||||
<el-table-column label="授权码" align="center" prop="status" width="70">
|
||||
<template slot-scope="scope">
|
||||
<el-tag type="success" v-if="scope.row.isAuthorize == 1">启用</el-tag>
|
||||
<el-tag type="info" v-if="scope.row.isAuthorize == 0">未启用</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="认证方式" align="center" prop="status">
|
||||
<template slot-scope="scope">
|
||||
<dict-tag :options="dict.type.iot_vertificate_method" :value="scope.row.vertificateMethod" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="联网方式" align="center" prop="networkMethod">
|
||||
<template slot-scope="scope">
|
||||
<dict-tag :options="dict.type.iot_network_method" :value="scope.row.networkMethod" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="100">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
|
||||
</div>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="confirmSelectProduct" type="primary">确定</el-button>
|
||||
<el-button @click="closeDialog" type="info">关 闭</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listProduct } from '@/api/iot/product';
|
||||
|
||||
export default {
|
||||
name: 'ProductList',
|
||||
dicts: ['iot_vertificate_method', 'iot_network_method'],
|
||||
data() {
|
||||
return {
|
||||
// 遮罩层
|
||||
loading: true,
|
||||
// 总条数
|
||||
total: 0,
|
||||
// 打开选择产品对话框
|
||||
open: false,
|
||||
// 产品列表
|
||||
productList: [],
|
||||
// 选中的产品编号
|
||||
selectProductId: 0,
|
||||
// 选中的产品
|
||||
product: {},
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
productName: null,
|
||||
categoryId: null,
|
||||
categoryName: null,
|
||||
tenantId: null,
|
||||
tenantName: null,
|
||||
isSys: null,
|
||||
status: 2, //已发布
|
||||
deviceType: null,
|
||||
networkMethod: null,
|
||||
},
|
||||
};
|
||||
},
|
||||
created() {},
|
||||
methods: {
|
||||
/** 查询产品列表 */
|
||||
getList() {
|
||||
this.loading = true;
|
||||
listProduct(this.queryParams).then((response) => {
|
||||
//产品列表初始化isSelect值,用于单选
|
||||
for (let i = 0; i < response.rows.length; i++) {
|
||||
response.rows[i].isSelect = false;
|
||||
}
|
||||
this.productList = response.rows;
|
||||
this.total = response.total;
|
||||
this.loading = false;
|
||||
// 设置产品选中
|
||||
this.setRadioSelected(this.selectProductId);
|
||||
});
|
||||
},
|
||||
/** 搜索按钮操作 */
|
||||
handleQuery() {
|
||||
this.queryParams.pageNum = 1;
|
||||
this.getList();
|
||||
},
|
||||
/** 重置按钮操作 */
|
||||
resetQuery() {
|
||||
this.resetForm('queryForm');
|
||||
this.handleQuery();
|
||||
},
|
||||
/** 单选数据 */
|
||||
rowClick(product) {
|
||||
if (product != null) {
|
||||
this.setRadioSelected(product.productId);
|
||||
this.product = product;
|
||||
}
|
||||
},
|
||||
/** 设置单选按钮选中 */
|
||||
setRadioSelected(productId) {
|
||||
for (let i = 0; i < this.productList.length; i++) {
|
||||
if (this.productList[i].productId == productId) {
|
||||
this.productList[i].isSelect = true;
|
||||
} else {
|
||||
this.productList[i].isSelect = false;
|
||||
}
|
||||
}
|
||||
},
|
||||
/**确定选择产品,产品传递给父组件 */
|
||||
confirmSelectProduct() {
|
||||
this.$emit('productEvent', this.product);
|
||||
this.open = false;
|
||||
},
|
||||
/**关闭对话框 */
|
||||
closeDialog() {
|
||||
this.open = false;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
384
vue/src/views/iot/scene/script.vue
Normal file
384
vue/src/views/iot/scene/script.vue
Normal file
@@ -0,0 +1,384 @@
|
||||
<template>
|
||||
<div style="padding: 6px">
|
||||
<el-card v-show="showSearch" style="margin-bottom: 6px">
|
||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch"
|
||||
label-width="68px" style="margin-bottom: -20px">
|
||||
<el-form-item label="脚本标识" prop="scriptId">
|
||||
<el-input v-model="queryParams.scriptId" placeholder="请输入脚本名" clearable
|
||||
@keyup.enter.native="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="脚本名" prop="scriptName">
|
||||
<el-input v-model="queryParams.scriptName" placeholder="请输入脚本名" clearable
|
||||
@keyup.enter.native="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item style="float: right">
|
||||
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
|
||||
v-hasPermi="['iot:script:add']">新增</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card style="padding-bottom: 100px">
|
||||
<el-table v-loading="loading" :data="scriptList" @selection-change="handleSelectionChange">
|
||||
<el-table-column label="脚本名称" align="center" prop="scriptName" />
|
||||
<el-table-column label="所属产品" align="center" prop="productName" />
|
||||
<el-table-column label="脚本标识" align="center" prop="scriptId" width="180" />
|
||||
<el-table-column label="脚本事件" align="center" prop="status">
|
||||
<template slot-scope="scope">
|
||||
<dict-tag :options="dict.type.rule_script_event" :value="scope.row.scriptEvent" size="small" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="脚本动作" align="center" prop="status">
|
||||
<template slot-scope="scope">
|
||||
<dict-tag :options="dict.type.rule_script_action" :value="scope.row.scriptAction"
|
||||
size="small" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="脚本语言" align="center" prop="scriptLanguage" />
|
||||
<el-table-column label="状态" align="center" prop="enable" width="120">
|
||||
<template slot-scope="scope">
|
||||
<el-tag v-if="scope.row.enable == 1" type="success" size="small">启动</el-tag>
|
||||
<el-tag v-if="scope.row.enable == 0" type="danger" size="small">暂停</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="执行顺序" align="center" prop="scriptOrder" />
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="200">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="mini" type="text" icon="el-icon-view" @click="handleUpdate(scope.row)"
|
||||
v-hasPermi="['iot:script:query']">查看</el-button>
|
||||
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
|
||||
v-hasPermi="['iot:script:remove']">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum"
|
||||
:limit.sync="queryParams.pageSize" @pagination="getList" />
|
||||
|
||||
<!-- 添加或修改规则引擎脚本对话框 -->
|
||||
<el-dialog :title="title" :visible.sync="open" width="800px" append-to-body :close-on-click-modal="false"
|
||||
:close-on-press-escape="false">
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="90px">
|
||||
<el-row :gutter="50">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="脚本名称" prop="scriptName">
|
||||
<el-input v-model="form.scriptName" placeholder="请输入脚本名" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="执行顺序" prop="scriptOrder">
|
||||
<el-input-number v-model="form.scriptOrder" placeholder="请输入脚本名" type="number"
|
||||
controls-position="right" style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="脚本事件" prop="scriptEvent">
|
||||
<el-select v-model="form.scriptEvent" placeholder="请选择脚本事件" style="width: 100%">
|
||||
<el-option v-for="dict in dict.type.rule_script_event" :key="dict.label"
|
||||
:label="dict.label" :value="Number(dict.value)"
|
||||
:disabled="dict.value !== '1' && dict.value !== '2'"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="12">
|
||||
<el-form-item label="脚本动作" prop="scriptAction">
|
||||
<el-select v-model="form.scriptAction" placeholder="请选择脚本动作" style="width: 100%">
|
||||
<el-option v-for="dict in dict.type.rule_script_action" :key="dict.label"
|
||||
:label="dict.label" :value="Number(dict.value)"
|
||||
:disabled="dict.value !== '1'"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="脚本状态" prop="enable">
|
||||
<el-switch v-model="form.enable" :active-value="1" :inactive-value="0" disabled />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="所属产品" prop="productName">
|
||||
<el-input readonly v-model="form.productName" size="small" placeholder="请选择产品"
|
||||
style="margin-top: 3px">
|
||||
<el-button slot="append" @click="handleSelectProduct()"
|
||||
size="small">选择产品</el-button>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" style="float: right"></el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<div style="padding: 0px 10px" @click="editClick">
|
||||
<AceEditor ref="codeEditor" :content.sync="form.scriptData" lang="groovy" codeStyle="chrome"
|
||||
:read-only="false" width="100%" height="450px"></AceEditor>
|
||||
</div>
|
||||
<div style="padding: 0 10px; margin: 10px 0">
|
||||
<el-alert :title="validateMsg" type="success" show-icon v-if="isValidate && validateMsg"
|
||||
:closable="false"></el-alert>
|
||||
<el-alert :title="validateMsg" type="error" show-icon v-if="!isValidate && validateMsg"
|
||||
:closable="false"></el-alert>
|
||||
</div>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<span style="float: left">
|
||||
<el-link style="line-height: 40px; padding-left: 20px" icon="el-icon-question"
|
||||
:underline="false" type="primary" href="https://fastbee.cn/doc/pages/rule_engine/"
|
||||
target="_blank">
|
||||
脚本使用Groovy引擎,查看教程>>>
|
||||
</el-link>
|
||||
</span>
|
||||
<el-button type="success" @click="handleValidate">验 证</el-button>
|
||||
<el-button type="primary" @click="submitForm" v-hasPermi="['iot:script:edit']"
|
||||
v-show="form.scriptId" :disabled="!isValidate">修
|
||||
改</el-button>
|
||||
<el-button type="primary" @click="submitForm" v-hasPermi="['iot:script:add']"
|
||||
v-show="!form.scriptId" :disabled="!isValidate">新
|
||||
增</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</el-card>
|
||||
<!-- 产品列表 -->
|
||||
<productList ref="productList" @productEvent="getSelectProduct($event)"></productList>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listScript, getScript, delScript, addScript, updateScript, validateScript } from '@/api/iot/script';
|
||||
import AceEditor from '@/views/components/editor/editor.vue';
|
||||
import productList from './product-list';
|
||||
export default {
|
||||
name: 'Script',
|
||||
dicts: ['rule_script_type', 'rule_script_language', 'rule_script_event', 'rule_script_action'],
|
||||
components: {
|
||||
AceEditor,
|
||||
productList,
|
||||
},
|
||||
data() {
|
||||
// 自定义验证规则
|
||||
var checkScriptId = (rule, value, callback) => {
|
||||
const regex = /^[a-zA-Z]+[0-9]*[a-zA-Z]*$/; // 定义只包含字母和数字,且字母开头的正则表达式
|
||||
if (!regex.test(value)) {
|
||||
return callback(new Error('脚本标识只能输入字母和数字,且字母开头'));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
return {
|
||||
// 脚本数据验证
|
||||
isValidate: false,
|
||||
// 脚本数据验证结果
|
||||
validateMsg: '',
|
||||
// 遮罩层
|
||||
loading: true,
|
||||
// 选中数组
|
||||
scriptIds: [],
|
||||
// 非单个禁用
|
||||
single: true,
|
||||
// 非多个禁用
|
||||
multiple: true,
|
||||
// 显示搜索条件
|
||||
showSearch: true,
|
||||
// 总条数
|
||||
total: 0,
|
||||
// 规则引擎脚本表格数据
|
||||
scriptList: [],
|
||||
// 弹出层标题
|
||||
title: '',
|
||||
// 是否显示弹出层
|
||||
open: false,
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
scriptPurpose: 1, // 只展示数据流(1=数据流,2=触发器,3=执行动作)
|
||||
scriptId: null,
|
||||
scriptName: null,
|
||||
scriptData: null,
|
||||
scriptType: null,
|
||||
scriptLanguage: null,
|
||||
enable: null,
|
||||
},
|
||||
// 表单参数
|
||||
form: {},
|
||||
// 表单校验
|
||||
rules: {
|
||||
scriptId: [{ required: true, message: '脚本标识不能为空', trigger: 'blur' }],
|
||||
productName: [{ required: true, message: '所属产品不能为空', trigger: 'blur' }],
|
||||
scriptName: [{ required: true, message: '脚本名不能为空', trigger: 'blur' }],
|
||||
scriptType: [{ required: true, message: '脚本类型不能为空', trigger: 'change' }],
|
||||
scriptLanguage: [{ required: true, message: '脚本语言不能为空', trigger: 'change' }],
|
||||
scriptEvent: [{ required: true, message: '', trigger: 'change' }],
|
||||
scriptAction: [{ required: true, message: '', trigger: 'change' }],
|
||||
scriptOrder: [{ required: true, message: '', trigger: 'change' }],
|
||||
enable: [{ required: true, message: '状态不能为空', trigger: 'blur' }],
|
||||
},
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
/** 查询规则引擎脚本列表 */
|
||||
getList() {
|
||||
this.loading = true;
|
||||
listScript(this.queryParams).then((response) => {
|
||||
this.scriptList = response.rows;
|
||||
this.total = response.total;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
// 取消按钮
|
||||
cancel() {
|
||||
this.open = false;
|
||||
this.reset();
|
||||
},
|
||||
// 表单重置
|
||||
reset() {
|
||||
this.validateMsg = '';
|
||||
this.isValidate = false;
|
||||
this.form = {
|
||||
id: null,
|
||||
applicationName: 'fastbee', // 后端配置和规则/脚本需要一致
|
||||
scriptId: null,
|
||||
productId: null,
|
||||
productName: '',
|
||||
scriptName: null,
|
||||
scriptType: 'script',
|
||||
remark: null,
|
||||
scriptLanguage: 'groovy',
|
||||
enable: 1,
|
||||
scriptPurpose: 1, // 脚本用途(1=数据流,2=触发器,3=执行动作)
|
||||
scriptOrder: 1, // 脚本执行顺序,数字越大越先执行
|
||||
scriptAction: 1, // 脚本动作(1=消息重发,2=消息通知,3=Http推送,4=Mqtt桥接,5=数据库存储)
|
||||
scriptEvent: 1, // 脚本事件(1=设备上报,2=平台下发,3=设备上线,4=设备离线)
|
||||
sceneId: 0,
|
||||
scriptData: `import cn.hutool.json.JSONArray;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import cn.hutool.core.util.NumberUtil;
|
||||
|
||||
// 1. 获取主题和内容(必要)
|
||||
String topic = msgContext.getTopic();
|
||||
String payload = msgContext.getPayload();
|
||||
|
||||
|
||||
// 2. 数据转换(自己处理)
|
||||
println ("根据情况转换数据")
|
||||
String NewTopic = topic;
|
||||
String NewPayload = payload;
|
||||
|
||||
|
||||
// 3. 返回新的数据(必要)
|
||||
msgContext.setTopic(NewTopic);
|
||||
msgContext.setPayload(NewPayload);`,
|
||||
};
|
||||
this.resetForm('form');
|
||||
},
|
||||
/** 搜索按钮操作 */
|
||||
handleQuery() {
|
||||
this.queryParams.pageNum = 1;
|
||||
this.getList();
|
||||
},
|
||||
/** 重置按钮操作 */
|
||||
resetQuery() {
|
||||
this.resetForm('queryForm');
|
||||
this.handleQuery();
|
||||
},
|
||||
// 多选框选中数据
|
||||
handleSelectionChange(selection) {
|
||||
this.scriptIds = selection.map((item) => item.scriptId);
|
||||
this.single = selection.length !== 1;
|
||||
this.multiple = !selection.length;
|
||||
},
|
||||
/** 新增按钮操作 */
|
||||
handleAdd() {
|
||||
this.reset();
|
||||
this.open = true;
|
||||
this.title = '编辑规则脚本';
|
||||
},
|
||||
/** 修改按钮操作 */
|
||||
handleUpdate(row) {
|
||||
this.reset();
|
||||
const scriptId = row.scriptId || this.scriptIds;
|
||||
getScript(scriptId).then((response) => {
|
||||
this.form = response.data;
|
||||
this.open = true;
|
||||
this.title = '修改规则引擎脚本';
|
||||
});
|
||||
},
|
||||
/**选择产品 */
|
||||
handleSelectProduct(data) {
|
||||
// 刷新子组建
|
||||
this.$refs.productList.queryParams.pageNum = 1;
|
||||
this.$refs.productList.open = true;
|
||||
this.$refs.productList.selectProductId = this.form.productId;
|
||||
this.$refs.productList.getList();
|
||||
},
|
||||
getSelectProduct(data) {
|
||||
this.form.productId = data.productId;
|
||||
this.form.productName = data.productName;
|
||||
},
|
||||
/** 提交按钮 */
|
||||
submitForm() {
|
||||
this.$refs['form'].validate((valid) => {
|
||||
if (valid) {
|
||||
if (this.form.scriptId != null) {
|
||||
updateScript(this.form).then((response) => {
|
||||
this.$modal.msgSuccess('修改成功');
|
||||
this.open = false;
|
||||
this.getList();
|
||||
});
|
||||
} else {
|
||||
addScript(this.form).then((response) => {
|
||||
this.$modal.msgSuccess('新增成功');
|
||||
this.open = false;
|
||||
this.getList();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
/** 删除按钮操作 */
|
||||
handleDelete(row) {
|
||||
const scriptIds = row.scriptId || this.scriptIds;
|
||||
this.$modal
|
||||
.confirm('是否确认删除规则引擎脚本编号为"' + scriptIds + '"的数据项?')
|
||||
.then(function () {
|
||||
return delScript(scriptIds);
|
||||
})
|
||||
.then(() => {
|
||||
this.getList();
|
||||
this.$modal.msgSuccess('删除成功');
|
||||
})
|
||||
.catch(() => { });
|
||||
},
|
||||
/** 验证按钮操作 */
|
||||
handleValidate() {
|
||||
this.validateMsg = '';
|
||||
this.isValidate = false;
|
||||
validateScript(this.form).then((response) => {
|
||||
this.isValidate = response.data;
|
||||
this.validateMsg = response.msg;
|
||||
});
|
||||
},
|
||||
/** 编辑器单机事件 */
|
||||
editClick() {
|
||||
this.validateMsg = '';
|
||||
this.isValidate = false;
|
||||
},
|
||||
/** 导出按钮操作 */
|
||||
handleExport() {
|
||||
this.download(
|
||||
'iot/script/export',
|
||||
{
|
||||
...this.queryParams,
|
||||
},
|
||||
`script_${new Date().getTime()}.xlsx`
|
||||
);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
Reference in New Issue
Block a user