Merge remote-tracking branch 'origin/main'
This commit is contained in:
commit
79eac71645
@ -0,0 +1,19 @@
|
|||||||
|
package com.das.common.constant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 事件等级
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface EventLevelConstant {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 告警
|
||||||
|
*/
|
||||||
|
Integer ALARM = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 故障
|
||||||
|
*/
|
||||||
|
Integer FAULT = 1;
|
||||||
|
|
||||||
|
}
|
@ -4,9 +4,9 @@ import cn.hutool.core.collection.CollUtil;
|
|||||||
import cn.hutool.core.convert.Convert;
|
import cn.hutool.core.convert.Convert;
|
||||||
import cn.hutool.core.lang.Validator;
|
import cn.hutool.core.lang.Validator;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import org.springframework.boot.configurationprocessor.json.JSONTokener;
|
|
||||||
import org.springframework.util.AntPathMatcher;
|
import org.springframework.util.AntPathMatcher;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@ -355,7 +355,7 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils {
|
|||||||
*/
|
*/
|
||||||
public static boolean isJsonString(String jsonString) {
|
public static boolean isJsonString(String jsonString) {
|
||||||
try {
|
try {
|
||||||
new JSONTokener(jsonString).nextValue();
|
JSONObject.parseObject(jsonString);
|
||||||
return true;
|
return true;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -1,13 +1,19 @@
|
|||||||
package com.das.modules.data.domain;
|
package com.das.modules.data.domain;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
|
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class DeviceEventInfo {
|
public class DeviceEventInfo {
|
||||||
private Long updateTime;
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
private Long eventTime;
|
||||||
|
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
private Long eventId;
|
private Long eventId;
|
||||||
|
|
||||||
|
private Integer eventType;
|
||||||
|
|
||||||
private Integer eventLevel;
|
private Integer eventLevel;
|
||||||
|
|
||||||
private String eventText;
|
private String eventText;
|
||||||
@ -16,6 +22,7 @@ public class DeviceEventInfo {
|
|||||||
|
|
||||||
private String confirmAccount;
|
private String confirmAccount;
|
||||||
|
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
private Long confirmTime;
|
private Long confirmTime;
|
||||||
|
|
||||||
private String deviceId;
|
private String deviceId;
|
||||||
|
@ -18,6 +18,7 @@ import org.springframework.beans.factory.annotation.Value;
|
|||||||
import org.springframework.scheduling.annotation.Async;
|
import org.springframework.scheduling.annotation.Async;
|
||||||
import org.springframework.scheduling.annotation.EnableAsync;
|
import org.springframework.scheduling.annotation.EnableAsync;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
@ -95,7 +96,7 @@ public class TDEngineService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void createCalStable(String iotmodel, String iotModelField,String dataType) {
|
public void createCalStable(String iotmodel, String iotModelField, String dataType) {
|
||||||
try (Connection conn = hikariDataSource.getConnection();
|
try (Connection conn = hikariDataSource.getConnection();
|
||||||
Statement pstmt = conn.createStatement()) {
|
Statement pstmt = conn.createStatement()) {
|
||||||
StringBuilder sb = new StringBuilder(1024 * 1024);
|
StringBuilder sb = new StringBuilder(1024 * 1024);
|
||||||
@ -251,9 +252,9 @@ public class TDEngineService {
|
|||||||
for (IotModelFieldVo info : list) {
|
for (IotModelFieldVo info : list) {
|
||||||
String iotModelCode = info.getIotModelCode();
|
String iotModelCode = info.getIotModelCode();
|
||||||
Map<String, String> calFieldMap = calculateIotFieldMap.get(iotModelCode);
|
Map<String, String> calFieldMap = calculateIotFieldMap.get(iotModelCode);
|
||||||
if (calFieldMap.keySet().size() != 0){
|
if (calFieldMap.keySet().size() != 0) {
|
||||||
for (String key : calFieldMap.keySet()){
|
for (String key : calFieldMap.keySet()) {
|
||||||
createCalStable(iotModelCode,key,calFieldMap.get(key));
|
createCalStable(iotModelCode, key, calFieldMap.get(key));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -385,15 +386,19 @@ public class TDEngineService {
|
|||||||
for (DeviceEventInfo dv : list) {
|
for (DeviceEventInfo dv : list) {
|
||||||
sb.append("E_");
|
sb.append("E_");
|
||||||
sb.append(dv.getDeviceId());
|
sb.append(dv.getDeviceId());
|
||||||
sb.append(" using event_info tags ('");
|
sb.append(" using event_info tags (");
|
||||||
|
sb.append(dv.getDeviceId());
|
||||||
|
sb.append(",'");
|
||||||
sb.append(dv.getDeviceCode());
|
sb.append(dv.getDeviceCode());
|
||||||
sb.append("','");
|
sb.append("','");
|
||||||
sb.append(dv.getDeviceName());
|
sb.append(dv.getDeviceName());
|
||||||
sb.append("') values (");
|
sb.append("') values (");
|
||||||
sb.append(dv.getUpdateTime());
|
sb.append(dv.getEventTime());
|
||||||
sb.append(",");
|
sb.append(",");
|
||||||
sb.append(dv.getEventId());
|
sb.append(dv.getEventId());
|
||||||
sb.append(",");
|
sb.append(",");
|
||||||
|
sb.append(dv.getEventType());
|
||||||
|
sb.append(",");
|
||||||
sb.append(dv.getEventLevel());
|
sb.append(dv.getEventLevel());
|
||||||
sb.append(",'");
|
sb.append(",'");
|
||||||
sb.append(dv.getEventText());
|
sb.append(dv.getEventText());
|
||||||
@ -460,11 +465,11 @@ public class TDEngineService {
|
|||||||
Map<String, Map<String, Map<String, Object>>> result = new HashMap<>();
|
Map<String, Map<String, Map<String, Object>>> result = new HashMap<>();
|
||||||
Map<String, Map<String, Object>> valueMap = new HashMap<>();
|
Map<String, Map<String, Object>> valueMap = new HashMap<>();
|
||||||
for (String item : fieldList) {
|
for (String item : fieldList) {
|
||||||
Map<String,Object> timeValueMap = new HashMap<>();
|
Map<String, Object> timeValueMap = new HashMap<>();
|
||||||
List<Long> times = new ArrayList<>();
|
List<Long> times = new ArrayList<>();
|
||||||
List<Object> objects = new ArrayList<>();
|
List<Object> objects = new ArrayList<>();
|
||||||
timeValueMap.put("times",times);
|
timeValueMap.put("times", times);
|
||||||
timeValueMap.put("values",objects);
|
timeValueMap.put("values", objects);
|
||||||
valueMap.put(item, timeValueMap);
|
valueMap.put(item, timeValueMap);
|
||||||
}
|
}
|
||||||
StringBuffer sb = new StringBuffer(2048);
|
StringBuffer sb = new StringBuffer(2048);
|
||||||
@ -529,7 +534,6 @@ public class TDEngineService {
|
|||||||
|
|
||||||
public Map<String, Map<String, Map<String, Object>>> fetchLowHistoryCurve(Long irn, Date startTime, Date endTime, String interval, List<String> fieldList) {
|
public Map<String, Map<String, Map<String, Object>>> fetchLowHistoryCurve(Long irn, Date startTime, Date endTime, String interval, List<String> fieldList) {
|
||||||
SimpleDateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
SimpleDateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
|
||||||
String tbName = String.format("l%d", irn);
|
String tbName = String.format("l%d", irn);
|
||||||
Date now = new Date();
|
Date now = new Date();
|
||||||
if (endTime.after(now)) {
|
if (endTime.after(now)) {
|
||||||
@ -538,11 +542,11 @@ public class TDEngineService {
|
|||||||
Map<String, Map<String, Map<String, Object>>> result = new HashMap<>();
|
Map<String, Map<String, Map<String, Object>>> result = new HashMap<>();
|
||||||
Map<String, Map<String, Object>> valueMap = new HashMap<>();
|
Map<String, Map<String, Object>> valueMap = new HashMap<>();
|
||||||
for (String item : fieldList) {
|
for (String item : fieldList) {
|
||||||
Map<String,Object> timeValueMap = new HashMap<>();
|
Map<String, Object> timeValueMap = new HashMap<>();
|
||||||
List<Long> times = new ArrayList<>();
|
List<Long> times = new ArrayList<>();
|
||||||
List<Object> objects = new ArrayList<>();
|
List<Object> objects = new ArrayList<>();
|
||||||
timeValueMap.put("times",times);
|
timeValueMap.put("times", times);
|
||||||
timeValueMap.put("values",objects);
|
timeValueMap.put("values", objects);
|
||||||
valueMap.put(item, timeValueMap);
|
valueMap.put(item, timeValueMap);
|
||||||
}
|
}
|
||||||
StringBuffer sb = new StringBuffer(2048);
|
StringBuffer sb = new StringBuffer(2048);
|
||||||
@ -605,6 +609,73 @@ public class TDEngineService {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<DeviceEventInfo> queryEvent(Integer eventLevel, Long startTime, Long endTime, List<String> deviceCodeList) {
|
||||||
|
List<DeviceEventInfo> result = new ArrayList<>();
|
||||||
|
StringBuffer sb = new StringBuffer(2048);
|
||||||
|
sb.append("select t.* from event_info t where ");
|
||||||
|
sb.append(String.format(" t.event_time >= %d and t.event_time < %d", startTime, endTime));
|
||||||
|
if (eventLevel != null) {
|
||||||
|
sb.append(String.format(" and t.event_level = %d", eventLevel));
|
||||||
|
}
|
||||||
|
if (!CollectionUtils.isEmpty(deviceCodeList)) {
|
||||||
|
sb.append(" and t.device_code in (");
|
||||||
|
for (int i = 0; i < deviceCodeList.size(); i++) {
|
||||||
|
if (i == deviceCodeList.size() - 1) {
|
||||||
|
sb.append("'").append(deviceCodeList.get(i)).append("')");
|
||||||
|
} else {
|
||||||
|
sb.append("'").append(deviceCodeList.get(i)).append("',");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sb.append(" order by t.event_time");
|
||||||
|
log.debug(sb.toString());
|
||||||
|
try (Connection conn = hikariDataSource.getConnection();
|
||||||
|
Statement smt = conn.createStatement();
|
||||||
|
ResultSet rs = smt.executeQuery(sb.toString())) {
|
||||||
|
while (rs.next()) {
|
||||||
|
DeviceEventInfo deviceEventInfo = new DeviceEventInfo();
|
||||||
|
deviceEventInfo.setEventTime(rs.getLong("event_time"));
|
||||||
|
deviceEventInfo.setEventId(rs.getLong("event_id"));
|
||||||
|
deviceEventInfo.setEventLevel(rs.getInt("event_level"));
|
||||||
|
deviceEventInfo.setEventType(rs.getInt("event_type"));
|
||||||
|
deviceEventInfo.setEventText(rs.getString("event_text"));
|
||||||
|
deviceEventInfo.setConfirmed(rs.getInt("confirmed"));
|
||||||
|
deviceEventInfo.setConfirmAccount(rs.getString("confirm_account"));
|
||||||
|
deviceEventInfo.setConfirmTime(rs.getLong("confirm_time"));
|
||||||
|
deviceEventInfo.setDeviceCode(rs.getString("device_code"));
|
||||||
|
deviceEventInfo.setDeviceId(rs.getString("device_id"));
|
||||||
|
result.add(deviceEventInfo);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("获取数据异常", e);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void confirmEvent(DeviceEventInfo deviceEventInfo) {
|
||||||
|
StringBuffer sb = new StringBuffer(2048);
|
||||||
|
sb.append("insert into e_");
|
||||||
|
sb.append(deviceEventInfo.getDeviceId());
|
||||||
|
sb.append(" USING event_info (device_id)TAGS (null) (event_time,event_id,confirmed,confirm_account,confirm_time) VALUES (");
|
||||||
|
sb.append(deviceEventInfo.getEventTime());
|
||||||
|
sb.append(",");
|
||||||
|
sb.append(deviceEventInfo.getEventId());
|
||||||
|
sb.append(",");
|
||||||
|
sb.append(deviceEventInfo.getConfirmed());
|
||||||
|
sb.append(",'");
|
||||||
|
sb.append(deviceEventInfo.getConfirmAccount());
|
||||||
|
sb.append("',");
|
||||||
|
sb.append(deviceEventInfo.getConfirmTime());
|
||||||
|
sb.append(")");
|
||||||
|
try (Connection conn = hikariDataSource.getConnection();
|
||||||
|
Statement pstmt = conn.createStatement()) {
|
||||||
|
pstmt.executeUpdate(sb.toString());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("新增超级表列失败:{},失败原因{}", sb.toString(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private String convertInterval(String interval) {
|
private String convertInterval(String interval) {
|
||||||
if (!StringUtils.hasText(interval)) {
|
if (!StringUtils.hasText(interval)) {
|
||||||
interval = "1m";
|
interval = "1m";
|
||||||
|
@ -51,7 +51,7 @@ public class DataServiceImpl implements DataService {
|
|||||||
//key:modelId value:modelCode
|
//key:modelId value:modelCode
|
||||||
public ConcurrentHashMap<String, String> iotModelMap = new ConcurrentHashMap<>(10000);
|
public ConcurrentHashMap<String, String> iotModelMap = new ConcurrentHashMap<>(10000);
|
||||||
|
|
||||||
//key:modelId value:fieldCode fieldName
|
//key:modelCode value:fieldCode fieldName
|
||||||
public ConcurrentHashMap<String, Map<String, String>> fieldCodeNameMap = new ConcurrentHashMap<>(10000);
|
public ConcurrentHashMap<String, Map<String, String>> fieldCodeNameMap = new ConcurrentHashMap<>(10000);
|
||||||
|
|
||||||
//key:modelCode value:FiledCode,dataType
|
//key:modelCode value:FiledCode,dataType
|
||||||
|
@ -0,0 +1,53 @@
|
|||||||
|
package com.das.modules.event.controller;
|
||||||
|
|
||||||
|
import com.das.common.result.R;
|
||||||
|
import com.das.common.utils.JsonUtils;
|
||||||
|
import com.das.modules.data.domain.DeviceEventInfo;
|
||||||
|
import com.das.modules.event.domain.EventQueryParam;
|
||||||
|
import com.das.modules.event.service.EventService;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 告警event相关controller
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@RequestMapping("/api/event")
|
||||||
|
@RestController
|
||||||
|
public class EventController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private EventService eventService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询设备告警信息列表
|
||||||
|
* @param param 查询条件
|
||||||
|
* @return TD数据库数据
|
||||||
|
*/
|
||||||
|
@PostMapping("/query")
|
||||||
|
public R<List<DeviceEventInfo>> queryEvent(@RequestBody @Valid EventQueryParam param) {
|
||||||
|
if (log.isDebugEnabled()){
|
||||||
|
log.debug("/api/event/query is calling");
|
||||||
|
log.debug(JsonUtils.toJsonString(param));
|
||||||
|
}
|
||||||
|
return R.success(eventService.queryEvent(param));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 确认告警信息
|
||||||
|
* @param deviceEventInfo 确认信息
|
||||||
|
*/
|
||||||
|
@PostMapping("/confirm")
|
||||||
|
public R<Void> confirmEvent(@RequestBody DeviceEventInfo deviceEventInfo){
|
||||||
|
eventService.confirmEvent(deviceEventInfo);
|
||||||
|
return R.success();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
package com.das.modules.event.domain;
|
||||||
|
|
||||||
|
import com.das.modules.data.domain.SnapshotValueQueryParam;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 时序数据查询实体
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class EventQueryParam
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 开始时间
|
||||||
|
*/
|
||||||
|
private String startTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 结束时间
|
||||||
|
*/
|
||||||
|
private String endTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 事件等级
|
||||||
|
*/
|
||||||
|
private Integer eventLevel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设备编码列表
|
||||||
|
*/
|
||||||
|
private List<String> deviceCode;
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.das.modules.event.service;
|
||||||
|
|
||||||
|
import com.das.modules.data.domain.DeviceEventInfo;
|
||||||
|
import com.das.modules.event.domain.EventQueryParam;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface EventService {
|
||||||
|
List<DeviceEventInfo> queryEvent(EventQueryParam param);
|
||||||
|
|
||||||
|
void confirmEvent(DeviceEventInfo deviceEventInfo);
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
package com.das.modules.event.service.impl;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
|
import com.das.common.config.SessionUtil;
|
||||||
|
import com.das.common.exceptions.ServiceException;
|
||||||
|
import com.das.modules.auth.domain.vo.SysUserVo;
|
||||||
|
import com.das.modules.data.domain.DeviceEventInfo;
|
||||||
|
import com.das.modules.data.service.TDEngineService;
|
||||||
|
import com.das.modules.event.domain.EventQueryParam;
|
||||||
|
import com.das.modules.event.service.EventService;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@Slf4j
|
||||||
|
public class EventServiceImpl implements EventService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TDEngineService tdEngineService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<DeviceEventInfo> queryEvent(EventQueryParam param) {
|
||||||
|
if (param.getStartTime() == null || param.getEndTime() ==null){
|
||||||
|
throw new ServiceException("查询时间不能为空");
|
||||||
|
}
|
||||||
|
List<DeviceEventInfo> deviceEventInfos = tdEngineService.queryEvent(param.getEventLevel(), Long.valueOf(param.getStartTime()), Long.valueOf(param.getEndTime()), param.getDeviceCode());
|
||||||
|
return deviceEventInfos;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void confirmEvent(DeviceEventInfo deviceEventInfo) {
|
||||||
|
Long confirmTime = System.currentTimeMillis();
|
||||||
|
deviceEventInfo.setConfirmTime(confirmTime);
|
||||||
|
SysUserVo sysUserVo = (SysUserVo) StpUtil.getTokenSession().get(SessionUtil.SESSION_USER_KEY);
|
||||||
|
deviceEventInfo.setConfirmAccount(sysUserVo.getAccount());
|
||||||
|
tdEngineService.confirmEvent(deviceEventInfo);
|
||||||
|
}
|
||||||
|
}
|
@ -301,7 +301,7 @@ public class NodeMessageServiceImpl implements NodeMessageService {
|
|||||||
for (DeviceEventVo item : list){
|
for (DeviceEventVo item : list){
|
||||||
DeviceInfoCache deviceInfoCache = cacheService.getEquipmentCache().getDeviceInfoCacheById(Long.valueOf(item.getDeviceId()));
|
DeviceInfoCache deviceInfoCache = cacheService.getEquipmentCache().getDeviceInfoCacheById(Long.valueOf(item.getDeviceId()));
|
||||||
DeviceEventInfo deviceEventInfo = new DeviceEventInfo();
|
DeviceEventInfo deviceEventInfo = new DeviceEventInfo();
|
||||||
deviceEventInfo.setUpdateTime(item.getEventTime());
|
deviceEventInfo.setEventTime(item.getEventTime());
|
||||||
deviceEventInfo.setEventId(IdWorker.getId());
|
deviceEventInfo.setEventId(IdWorker.getId());
|
||||||
deviceEventInfo.setDeviceId(item.getDeviceId());
|
deviceEventInfo.setDeviceId(item.getDeviceId());
|
||||||
deviceEventInfo.setDeviceName(deviceInfoCache.getDeviceName());
|
deviceEventInfo.setDeviceName(deviceInfoCache.getDeviceName());
|
||||||
@ -315,6 +315,7 @@ public class NodeMessageServiceImpl implements NodeMessageService {
|
|||||||
if (StringUtils.isEmpty(fieldName)){
|
if (StringUtils.isEmpty(fieldName)){
|
||||||
log.debug("未查询到物模型属性code,设备id:{}",item.getDeviceId());
|
log.debug("未查询到物模型属性code,设备id:{}",item.getDeviceId());
|
||||||
}
|
}
|
||||||
|
deviceEventInfo.setEventType(item.getEventType());
|
||||||
deviceEventInfo.setEventLevel(0);
|
deviceEventInfo.setEventLevel(0);
|
||||||
deviceEventInfo.setConfirmed(0);
|
deviceEventInfo.setConfirmed(0);
|
||||||
if (!StringUtils.isEmpty(eventType) && eventType.equals("遥信变位")){
|
if (!StringUtils.isEmpty(eventType) && eventType.equals("遥信变位")){
|
||||||
@ -334,20 +335,16 @@ public class NodeMessageServiceImpl implements NodeMessageService {
|
|||||||
}catch (Exception e){
|
}catch (Exception e){
|
||||||
log.error("事件信息存入Td失败,失败原因{}",e);
|
log.error("事件信息存入Td失败,失败原因{}",e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getEventType(int eventType) {
|
private String getEventType(int eventType) {
|
||||||
switch (eventType) {
|
return switch (eventType) {
|
||||||
case 0:
|
case 0 -> "遥信变位";
|
||||||
return "遥信变位";
|
case 1 -> "越上限";
|
||||||
case 1:
|
case 2 -> "越下限";
|
||||||
return "越上限";
|
case 3 -> "越上上限";
|
||||||
case 2:
|
case 4 -> "越下下限";
|
||||||
return "越下限";
|
default -> null;
|
||||||
default:
|
};
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -315,7 +315,7 @@ PS: 同一节点只允许建立一条连接。
|
|||||||
"attrCode": "stop",
|
"attrCode": "stop",
|
||||||
//属性值
|
//属性值
|
||||||
"attrValue": 0,
|
"attrValue": 0,
|
||||||
//事件类型 ( 0-遥信变位 1-越上限 2-越下限)
|
//事件类型 ( 0-遥信变位 1-越上限 2-越下限 3-越上上限 4-越下下限 5-越限复归)
|
||||||
"eventType": 0,
|
"eventType": 0,
|
||||||
//事件发生时刻
|
//事件发生时刻
|
||||||
"eventTime": 12321351235123,
|
"eventTime": 12321351235123,
|
||||||
|
@ -35,3 +35,50 @@ export const runAirBlowerReq = (
|
|||||||
data: data,
|
data: data,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const getReportTemplateListReq = (data: { category: '单机报表' | '多机报表', pageNum: number, pageSize: number }) => {
|
||||||
|
return createAxios<never, Promise<{
|
||||||
|
code: number,
|
||||||
|
msg: string,
|
||||||
|
data: {
|
||||||
|
total: number,
|
||||||
|
rows: { id: string, category: '单机报表' | '多机报表', template: string }[]
|
||||||
|
code: number,
|
||||||
|
msg: string
|
||||||
|
},
|
||||||
|
success: boolean
|
||||||
|
}>>({
|
||||||
|
url: '/api/report/template/getList',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const addReportTemplateListReq = (data: { category: '单机报表' | '多机报表', template: string }) => {
|
||||||
|
return createAxios<never, Promise<{
|
||||||
|
code: number,
|
||||||
|
msg: string,
|
||||||
|
data: {
|
||||||
|
id: string,
|
||||||
|
category: '单机报表' | '多机报表',
|
||||||
|
template: string
|
||||||
|
}[],
|
||||||
|
success: boolean
|
||||||
|
}>>({
|
||||||
|
url: '/api/report/template/add',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const delReportTemplateListReq = (data: { id: string }) => {
|
||||||
|
return createAxios<never, Promise<{
|
||||||
|
code: number,
|
||||||
|
msg: string,
|
||||||
|
success: boolean
|
||||||
|
}>>({
|
||||||
|
url: '/api/report/template/del',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
@ -409,9 +409,7 @@ const initpowerChart = () => {
|
|||||||
axisLabel: {
|
axisLabel: {
|
||||||
//x轴文字的配置
|
//x轴文字的配置
|
||||||
show: true,
|
show: true,
|
||||||
textStyle: {
|
color: '#4E5969',
|
||||||
color: '#4E5969',
|
|
||||||
},
|
|
||||||
interval: 'auto',
|
interval: 'auto',
|
||||||
//rotate: 45
|
//rotate: 45
|
||||||
},
|
},
|
||||||
@ -442,9 +440,7 @@ const initpowerChart = () => {
|
|||||||
axisLabel: {
|
axisLabel: {
|
||||||
//x轴文字的配置
|
//x轴文字的配置
|
||||||
show: true,
|
show: true,
|
||||||
textStyle: {
|
color: '#4E5969',
|
||||||
color: '#4E5969',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
axisTick: { show: false },
|
axisTick: { show: false },
|
||||||
splitLine: {
|
splitLine: {
|
||||||
@ -472,9 +468,7 @@ const initpowerChart = () => {
|
|||||||
axisLabel: {
|
axisLabel: {
|
||||||
//x轴文字的配置
|
//x轴文字的配置
|
||||||
show: true,
|
show: true,
|
||||||
textStyle: {
|
color: '#4E5969',
|
||||||
color: '#4E5969',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
axisTick: { show: false },
|
axisTick: { show: false },
|
||||||
splitLine: {
|
splitLine: {
|
||||||
@ -623,9 +617,7 @@ const initTrendChart = (type: 'day' | 'month') => {
|
|||||||
axisLabel: {
|
axisLabel: {
|
||||||
//x轴文字的配置
|
//x轴文字的配置
|
||||||
show: true,
|
show: true,
|
||||||
textStyle: {
|
color: '#4E5969',
|
||||||
color: '#4E5969',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
splitLine: {
|
splitLine: {
|
||||||
//分割线配置
|
//分割线配置
|
||||||
@ -654,9 +646,7 @@ const initTrendChart = (type: 'day' | 'month') => {
|
|||||||
axisLabel: {
|
axisLabel: {
|
||||||
//x轴文字的配置
|
//x轴文字的配置
|
||||||
show: true,
|
show: true,
|
||||||
textStyle: {
|
color: '#4E5969',
|
||||||
color: '#4E5969',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
axisTick: { show: false },
|
axisTick: { show: false },
|
||||||
splitLine: {
|
splitLine: {
|
||||||
@ -1403,7 +1393,7 @@ const sendManualCommand = (type: 1 | 0) => {
|
|||||||
deviceId: route.query.irn as string,
|
deviceId: route.query.irn as string,
|
||||||
serviceCode: 'Locked',
|
serviceCode: 'Locked',
|
||||||
serviceName,
|
serviceName,
|
||||||
optDesc: serviceName +',设定值为:'+ type,
|
optDesc: serviceName + ',设定值为:' + type,
|
||||||
opValue: type,
|
opValue: type,
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
if (res.code == 200) {
|
if (res.code == 200) {
|
||||||
|
@ -523,7 +523,7 @@ const initpowerChart = () => {
|
|||||||
top: 50,
|
top: 50,
|
||||||
right: 23,
|
right: 23,
|
||||||
bottom: 10,
|
bottom: 10,
|
||||||
left: 18,
|
left: 25,
|
||||||
containLabel: true,
|
containLabel: true,
|
||||||
},
|
},
|
||||||
tooltip: {
|
tooltip: {
|
||||||
|
@ -11,8 +11,10 @@
|
|||||||
:sortable="item.sortable"
|
:sortable="item.sortable"
|
||||||
>
|
>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<div v-if="item.prop === 'realTimeValue'" class="realTimeValue" @click="openLineChart(scope.row)">
|
<div v-if="item.prop === 'realTimeValue'" class="realTimeValue">
|
||||||
<el-button text type="primary">{{ scope.row.realTimeValue }}</el-button>
|
<div class="realTimeValueText">{{ scope.row.realTimeValue }}</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="item.prop === 'operate'" @click="openLineChart(scope.row)" class="operate">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon" width="20px" height="20px" viewBox="0 0 1024 1024" version="1.1">
|
<svg xmlns="http://www.w3.org/2000/svg" class="icon" width="20px" height="20px" viewBox="0 0 1024 1024" version="1.1">
|
||||||
<path
|
<path
|
||||||
d="M896 896H96a32 32 0 0 1-32-32V224a32 32 0 0 1 64 0v608h768a32 32 0 1 1 0 64zM247.008 640a32 32 0 0 1-20.992-56.192l200.992-174.24a32 32 0 0 1 42.272 0.288l172.128 153.44 229.088-246.304a32 32 0 0 1 46.88 43.616l-250.432 269.216a31.936 31.936 0 0 1-44.704 2.08l-174.56-155.52-179.744 155.84a31.872 31.872 0 0 1-20.928 7.776z"
|
d="M896 896H96a32 32 0 0 1-32-32V224a32 32 0 0 1 64 0v608h768a32 32 0 1 1 0 64zM247.008 640a32 32 0 0 1-20.992-56.192l200.992-174.24a32 32 0 0 1 42.272 0.288l172.128 153.44 229.088-246.304a32 32 0 0 1 46.88 43.616l-250.432 269.216a31.936 31.936 0 0 1-44.704 2.08l-174.56-155.52-179.744 155.84a31.872 31.872 0 0 1-20.928 7.776z"
|
||||||
@ -54,17 +56,13 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<el-form-item prop="interval" label="时间间隔:" style="margin-right: 2px">
|
<el-form-item prop="interval" label="时间间隔:">
|
||||||
<el-input v-model="seachOptions.interval" style="width: 100px" placeholder="请输入时间间隔"></el-input>
|
<el-select v-model="seachOptions.interval" placeholder="请选择时间间隔" style="width: 100px">
|
||||||
</el-form-item>
|
<el-option label="原始" value="40s"></el-option>
|
||||||
<el-form-item prop="unit">
|
<el-option label="5分钟" value="5m"></el-option>
|
||||||
<el-select v-model="seachOptions.unit" placeholder="请选择时间单位" style="width: 75px">
|
<el-option label="15分钟" value="15m"></el-option>
|
||||||
<el-option label="秒" value="s"></el-option>
|
<el-option label="1小时" value="1h"></el-option>
|
||||||
<el-option label="分钟" value="m"></el-option>
|
<el-option label="1天" value="1d"></el-option>
|
||||||
<el-option label="小时" value="h"></el-option>
|
|
||||||
<el-option label="天" value="d"></el-option>
|
|
||||||
<el-option label="周" value="w"></el-option>
|
|
||||||
<el-option label="年" value="y"></el-option>
|
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
@ -86,28 +84,6 @@ import { getModelAttributeListReq, getRealValueListReq } from '/@/api/backend/de
|
|||||||
import * as echarts from 'echarts'
|
import * as echarts from 'echarts'
|
||||||
import { getRealValueRangeReq } from '/@/api/backend/deviceModel/request'
|
import { getRealValueRangeReq } from '/@/api/backend/deviceModel/request'
|
||||||
|
|
||||||
// const props = defineProps({
|
|
||||||
// iotModelId: {
|
|
||||||
// type: String,
|
|
||||||
// default: '',
|
|
||||||
// },
|
|
||||||
// deviceId: {
|
|
||||||
// type: String,
|
|
||||||
// default: '',
|
|
||||||
// },
|
|
||||||
// show: {
|
|
||||||
// type: Boolean,
|
|
||||||
// default: false,
|
|
||||||
// },
|
|
||||||
// autoUpdate: {
|
|
||||||
// type: Boolean,
|
|
||||||
// default: false,
|
|
||||||
// },
|
|
||||||
// attributeType: {
|
|
||||||
// type: Number,
|
|
||||||
// default: '138',
|
|
||||||
// },
|
|
||||||
// })
|
|
||||||
const props = withDefaults(
|
const props = withDefaults(
|
||||||
defineProps<{ iotModelId: string; deviceId: string; show: boolean; autoUpdate: boolean; attributeType: ModelAttributeType }>(),
|
defineProps<{ iotModelId: string; deviceId: string; show: boolean; autoUpdate: boolean; attributeType: ModelAttributeType }>(),
|
||||||
{
|
{
|
||||||
@ -154,6 +130,13 @@ const tableColumn = [
|
|||||||
align: 'center',
|
align: 'center',
|
||||||
sortable: false,
|
sortable: false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: '历史曲线',
|
||||||
|
prop: 'operate',
|
||||||
|
align: 'center',
|
||||||
|
width: 80,
|
||||||
|
sortable: false,
|
||||||
|
},
|
||||||
]
|
]
|
||||||
const tableData = ref<any[]>([])
|
const tableData = ref<any[]>([])
|
||||||
|
|
||||||
@ -348,7 +331,7 @@ const getChartData = () => {
|
|||||||
attributes: [searchInfo.attr],
|
attributes: [searchInfo.attr],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
interval: seachOptions.interval + seachOptions.unit,
|
interval: seachOptions.interval,
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
initChart(res.data?.[props.deviceId]?.[searchInfo.attr])
|
initChart(res.data?.[props.deviceId]?.[searchInfo.attr])
|
||||||
})
|
})
|
||||||
@ -360,8 +343,7 @@ const chartRef = ref()
|
|||||||
let chartInstance: any = null
|
let chartInstance: any = null
|
||||||
const seachOptions = reactive({
|
const seachOptions = reactive({
|
||||||
datePickerValue: [0, 0],
|
datePickerValue: [0, 0],
|
||||||
interval: 5,
|
interval: '5m',
|
||||||
unit: 'm',
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const searchRules = {
|
const searchRules = {
|
||||||
@ -384,18 +366,11 @@ const searchRules = {
|
|||||||
trigger: 'input',
|
trigger: 'input',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
unit: [
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: '请选择时间单位',
|
|
||||||
trigger: 'change',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const initChart = (data: { values: number[]; times: number[] }) => {
|
const initChart = (data: { values: number[]; times: number[] }) => {
|
||||||
chartInstance && chartInstance.clear()
|
chartInstance && chartInstance.clear()
|
||||||
|
|
||||||
chartInstance = chartInstance ? chartInstance : echarts.init(chartRef.value)
|
chartInstance = chartInstance ? chartInstance : echarts.init(chartRef.value)
|
||||||
const times = data?.times.map((item) => dayjs(item).format('YYYY-MM-DD HH:mm:ss'))
|
const times = data?.times.map((item) => dayjs(item).format('YYYY-MM-DD HH:mm:ss'))
|
||||||
|
|
||||||
@ -426,9 +401,7 @@ const initChart = (data: { values: number[]; times: number[] }) => {
|
|||||||
axisLabel: {
|
axisLabel: {
|
||||||
//x轴文字的配置
|
//x轴文字的配置
|
||||||
show: true,
|
show: true,
|
||||||
textStyle: {
|
color: '#4E5969',
|
||||||
color: '#4E5969',
|
|
||||||
},
|
|
||||||
interval: 'auto',
|
interval: 'auto',
|
||||||
//rotate: 45
|
//rotate: 45
|
||||||
},
|
},
|
||||||
@ -459,9 +432,7 @@ const initChart = (data: { values: number[]; times: number[] }) => {
|
|||||||
axisLabel: {
|
axisLabel: {
|
||||||
//x轴文字的配置
|
//x轴文字的配置
|
||||||
show: true,
|
show: true,
|
||||||
textStyle: {
|
color: '#4E5969',
|
||||||
color: '#4E5969',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
axisTick: { show: false },
|
axisTick: { show: false },
|
||||||
splitLine: {
|
splitLine: {
|
||||||
@ -511,13 +482,16 @@ watch(
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.realTimeValue {
|
.realTimeValueText {
|
||||||
display: flex;
|
color: #0064aa;
|
||||||
align-items: center;
|
}
|
||||||
|
|
||||||
|
.operate {
|
||||||
&:hover {
|
&:hover {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.searchPart {
|
.searchPart {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -37,8 +37,17 @@
|
|||||||
<div>
|
<div>
|
||||||
<el-space style="margin-top: 10px">
|
<el-space style="margin-top: 10px">
|
||||||
<div style="min-width: 30px">模板</div>
|
<div style="min-width: 30px">模板</div>
|
||||||
<el-select v-model="template" placeholder="请选择模板" class="commonSelect">
|
<el-select v-model="template" placeholder="请选择模板" class="commonSelect" @change="changeTemplate">
|
||||||
<el-option v-for="v in templateList" :key="v.value" :label="v.label" :value="v.value"></el-option>
|
<el-option v-for="v in reportTemplateList" :key="v.value" :label="v.label" :value="v.value">
|
||||||
|
<template #default>
|
||||||
|
<div class="tamplateOption">
|
||||||
|
<span>{{ v.label }}</span>
|
||||||
|
<el-icon style="color: red" @click="delReportTemplate(v.value)">
|
||||||
|
<Delete />
|
||||||
|
</el-icon>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-space>
|
</el-space>
|
||||||
</div>
|
</div>
|
||||||
@ -46,7 +55,7 @@
|
|||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
<el-button class="button" :icon="Search" @click="queryHistoryData" type="primary">查询</el-button>
|
<el-button class="button" :icon="Search" @click="queryHistoryData" type="primary">查询</el-button>
|
||||||
<el-button class="button" :icon="Upload" type="primary" plain>导出</el-button>
|
<el-button class="button" :icon="Upload" type="primary" plain>导出</el-button>
|
||||||
<el-button class="button" :icon="Notebook" type="primary" plain>保存为模板</el-button>
|
<el-button class="button" :icon="Notebook" type="primary" @click="addReportTemplate" plain>保存为模板</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<el-table
|
<el-table
|
||||||
@ -56,6 +65,7 @@
|
|||||||
:row-key="(row: any) => row.id"
|
:row-key="(row: any) => row.id"
|
||||||
:row-style="tableRowClassName"
|
:row-style="tableRowClassName"
|
||||||
v-loading="reportLoading"
|
v-loading="reportLoading"
|
||||||
|
max-height="100%"
|
||||||
>
|
>
|
||||||
<el-table-column prop="deviceId" label="风机" fixed width="80px" align="center">
|
<el-table-column prop="deviceId" label="风机" fixed width="80px" align="center">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
@ -118,10 +128,16 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { reactive, ref, nextTick, onMounted } from 'vue'
|
import { reactive, ref, nextTick, onMounted } from 'vue'
|
||||||
import { ElMessage, TableInstance, TreeInstance } from 'element-plus'
|
import { ElMessage, TableInstance, TreeInstance, ElMessageBox } from 'element-plus'
|
||||||
import { Search, Upload, Notebook, Plus } from '@element-plus/icons-vue'
|
import { Search, Upload, Notebook, Plus, Delete } from '@element-plus/icons-vue'
|
||||||
import { WindBlowerList, RequestData, Devices } from './type'
|
import { WindBlowerList, RequestData, Devices } from './type'
|
||||||
import { queryWindTurbinesPages, historyReq } from '/@/api/backend/statAnalysis/request'
|
import {
|
||||||
|
queryWindTurbinesPages,
|
||||||
|
historyReq,
|
||||||
|
getReportTemplateListReq,
|
||||||
|
addReportTemplateListReq,
|
||||||
|
delReportTemplateListReq,
|
||||||
|
} from '/@/api/backend/statAnalysis/request'
|
||||||
import Measurement from './measureList.vue'
|
import Measurement from './measureList.vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import { shortUuid } from '/@/utils/random'
|
import { shortUuid } from '/@/utils/random'
|
||||||
@ -197,10 +213,80 @@ const intervals = [
|
|||||||
]
|
]
|
||||||
// 模板
|
// 模板
|
||||||
const template = ref('')
|
const template = ref('')
|
||||||
const templateList = [
|
const reportTemplateList = ref<{ label: string; value: string; columns: any[]; interval: string }[]>([])
|
||||||
{ label: '模板一', value: '1' },
|
const getReportTemplateList = () => {
|
||||||
{ label: '模板二', value: '2' },
|
getReportTemplateListReq({
|
||||||
]
|
pageNum: 1,
|
||||||
|
pageSize: 1000,
|
||||||
|
category: '多机报表',
|
||||||
|
}).then((res) => {
|
||||||
|
if (res.success) {
|
||||||
|
reportTemplateList.value = res.data.rows.map((item) => {
|
||||||
|
const tem = item.template ? JSON.parse(item.template) : {}
|
||||||
|
return {
|
||||||
|
label: tem.name,
|
||||||
|
value: item.id,
|
||||||
|
columns: tem.columns,
|
||||||
|
interval: tem.interval,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const addReportTemplate = () => {
|
||||||
|
ElMessageBox.prompt('请输入模板名称', '添加模板', {
|
||||||
|
confirmButtonText: '提交',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
inputPattern: /\S/,
|
||||||
|
inputErrorMessage: '模板名称不能为空',
|
||||||
|
}).then(({ value }) => {
|
||||||
|
const tem = {
|
||||||
|
name: value,
|
||||||
|
interval: interval.value,
|
||||||
|
columns: reportTableColumn.value,
|
||||||
|
}
|
||||||
|
const data = {
|
||||||
|
category: '多机报表' as const,
|
||||||
|
template: JSON.stringify(tem),
|
||||||
|
}
|
||||||
|
console.log(data)
|
||||||
|
|
||||||
|
addReportTemplateListReq(data).then((res) => {
|
||||||
|
if (res.success) {
|
||||||
|
ElMessage.success('添加成功!')
|
||||||
|
getReportTemplateList()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const delReportTemplate = (id: string) => {
|
||||||
|
ElMessageBox.confirm('确定删除该模板吗?', '删除模板', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning',
|
||||||
|
}).then(() => {
|
||||||
|
delReportTemplateListReq({ id }).then((res) => {
|
||||||
|
if (res.success) {
|
||||||
|
ElMessage.success('删除成功!')
|
||||||
|
getReportTemplateList()
|
||||||
|
template.value = ''
|
||||||
|
if (template.value == id) {
|
||||||
|
reportTableColumn.value = JSON.parse(JSON.stringify(originReportColumn))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const changeTemplate = (val: string) => {
|
||||||
|
const target = reportTemplateList.value.find((item) => item.value === val)
|
||||||
|
if (target) {
|
||||||
|
interval.value = target.interval ? target.interval : interval.value
|
||||||
|
reportTableColumn.value = target.columns
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 测点名称
|
// 测点名称
|
||||||
const showMeasure = ref(false)
|
const showMeasure = ref(false)
|
||||||
const currentChooseRows = ref([])
|
const currentChooseRows = ref([])
|
||||||
@ -250,7 +336,7 @@ const addColumn = () => {
|
|||||||
const addRow = () => {}
|
const addRow = () => {}
|
||||||
const removeColumn = (val: any) => {
|
const removeColumn = (val: any) => {
|
||||||
const columnName = val.column.property
|
const columnName = val.column.property
|
||||||
reportTableColumn.value = reportTableColumn.value.filter((val) => val.prop !== columnName)
|
reportTableColumn.value = reportTableColumn.value.filter((val:any) => val.prop !== columnName)
|
||||||
}
|
}
|
||||||
const handleSelections = (value: any) => {
|
const handleSelections = (value: any) => {
|
||||||
currentChooseRows.value = JSON.parse(JSON.stringify(value))
|
currentChooseRows.value = JSON.parse(JSON.stringify(value))
|
||||||
@ -284,7 +370,7 @@ const selectMeasurePoint = () => {
|
|||||||
showMeasure.value = false
|
showMeasure.value = false
|
||||||
}
|
}
|
||||||
const reportLoading = ref(false)
|
const reportLoading = ref(false)
|
||||||
const reportTableColumn = ref([
|
const originReportColumn = [
|
||||||
{
|
{
|
||||||
label: `风速`,
|
label: `风速`,
|
||||||
prop: 'iWindSpeed',
|
prop: 'iWindSpeed',
|
||||||
@ -330,14 +416,15 @@ const reportTableColumn = ref([
|
|||||||
prop: 'iHydrPress',
|
prop: 'iHydrPress',
|
||||||
unit: 'kpa',
|
unit: 'kpa',
|
||||||
},
|
},
|
||||||
])
|
]
|
||||||
|
const reportTableColumn = ref(JSON.parse(JSON.stringify(originReportColumn)))
|
||||||
const reportTableData = ref([] as any)
|
const reportTableData = ref([] as any)
|
||||||
// const idCounter = ref(0)
|
// const idCounter = ref(0)
|
||||||
const queryHistoryData = () => {
|
const queryHistoryData = () => {
|
||||||
if (!windBlowerValue.value.length) return ElMessage.warning('请选择风机!')
|
if (!windBlowerValue.value.length) return ElMessage.warning('请选择风机!')
|
||||||
if (!timeRange.value.length) return ElMessage.warning('请选择时间!')
|
if (!timeRange.value.length) return ElMessage.warning('请选择时间!')
|
||||||
if (!interval.value) return ElMessage.warning('请选择间隔!')
|
if (!interval.value) return ElMessage.warning('请选择间隔!')
|
||||||
const attributeCodes = reportTableColumn.value.map((val) => val.prop).filter((item) => item != null && item !== '')
|
const attributeCodes = reportTableColumn.value.map((val:any) => val.prop).filter((item:any) => item != null && item !== '')
|
||||||
if (!attributeCodes.length) return ElMessage.warning('请添加测点!')
|
if (!attributeCodes.length) return ElMessage.warning('请添加测点!')
|
||||||
reportLoading.value = true
|
reportLoading.value = true
|
||||||
// idCounter.value = 0
|
// idCounter.value = 0
|
||||||
@ -363,7 +450,7 @@ const queryHistoryData = () => {
|
|||||||
|
|
||||||
if (realResult) {
|
if (realResult) {
|
||||||
let tableData = [] as any
|
let tableData = [] as any
|
||||||
attributeCodes.forEach((item) => {
|
attributeCodes.forEach((item:any) => {
|
||||||
if (Object.keys(realResult).includes(item)) {
|
if (Object.keys(realResult).includes(item)) {
|
||||||
tableData.push({
|
tableData.push({
|
||||||
name: item,
|
name: item,
|
||||||
@ -540,4 +627,9 @@ onMounted(() => {
|
|||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.tamplateOption {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -33,8 +33,17 @@
|
|||||||
<div>
|
<div>
|
||||||
<el-space style="margin-top: 10px">
|
<el-space style="margin-top: 10px">
|
||||||
<div style="min-width: 30px">模板</div>
|
<div style="min-width: 30px">模板</div>
|
||||||
<el-select v-model="template" placeholder="请选择模板" class="commonSelect">
|
<el-select v-model="template" placeholder="请选择模板" class="commonSelect" @change="changeTemplate">
|
||||||
<el-option v-for="v in templateList" :key="v.value" :label="v.label" :value="v.value"></el-option>
|
<el-option v-for="v in reportTemplateList" :key="v.value" :label="v.label" :value="v.value">
|
||||||
|
<template #default>
|
||||||
|
<div class="tamplateOption">
|
||||||
|
<span>{{ v.label }}</span>
|
||||||
|
<el-icon style="color: red" @click="delReportTemplate(v.value)">
|
||||||
|
<Delete />
|
||||||
|
</el-icon>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
<div style="width: 20px"></div>
|
<div style="width: 20px"></div>
|
||||||
<!-- <div>{{ t('statAnalysis.attributes') }}</div>
|
<!-- <div>{{ t('statAnalysis.attributes') }}</div>
|
||||||
@ -50,7 +59,7 @@
|
|||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
<el-button class="button" :icon="Search" @click="queryHistoryData" type="primary">查询</el-button>
|
<el-button class="button" :icon="Search" @click="queryHistoryData" type="primary">查询</el-button>
|
||||||
<el-button class="button" :icon="Upload" type="primary" plain>导出</el-button>
|
<el-button class="button" :icon="Upload" type="primary" plain>导出</el-button>
|
||||||
<el-button class="button" :icon="Notebook" type="primary" plain>保存为模板</el-button>
|
<el-button class="button" :icon="Notebook" type="primary" @click="addReportTemplate" plain>保存为模板</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<el-table
|
<el-table
|
||||||
@ -116,10 +125,16 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { reactive, ref, nextTick, onMounted } from 'vue'
|
import { reactive, ref, nextTick, onMounted } from 'vue'
|
||||||
import { ElMessage, TableInstance, TreeInstance } from 'element-plus'
|
import { ElMessage, TableInstance, TreeInstance, ElMessageBox } from 'element-plus'
|
||||||
import { Search, Upload, Notebook, Plus } from '@element-plus/icons-vue'
|
import { Search, Upload, Notebook, Plus, Delete } from '@element-plus/icons-vue'
|
||||||
import { WindBlowerList, RequestData, Devices } from './type'
|
import { WindBlowerList, RequestData, Devices } from './type'
|
||||||
import { queryWindTurbinesPages, historyReq } from '/@/api/backend/statAnalysis/request'
|
import {
|
||||||
|
queryWindTurbinesPages,
|
||||||
|
historyReq,
|
||||||
|
getReportTemplateListReq,
|
||||||
|
addReportTemplateListReq,
|
||||||
|
delReportTemplateListReq,
|
||||||
|
} from '/@/api/backend/statAnalysis/request'
|
||||||
import Measurement from './measureList.vue'
|
import Measurement from './measureList.vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
@ -194,10 +209,79 @@ const intervals = [
|
|||||||
]
|
]
|
||||||
// 模板
|
// 模板
|
||||||
const template = ref('')
|
const template = ref('')
|
||||||
const templateList = [
|
const reportTemplateList = ref<{ label: string; value: string; columns: any[]; interval: string }[]>([])
|
||||||
{ label: '模板一', value: '1' },
|
const getReportTemplateList = () => {
|
||||||
{ label: '模板二', value: '2' },
|
getReportTemplateListReq({
|
||||||
]
|
pageNum: 1,
|
||||||
|
pageSize: 1000,
|
||||||
|
category: '单机报表',
|
||||||
|
}).then((res) => {
|
||||||
|
if (res.success) {
|
||||||
|
reportTemplateList.value = res.data.rows.map((item) => {
|
||||||
|
const tem = item.template ? JSON.parse(item.template) : {}
|
||||||
|
return {
|
||||||
|
label: tem.name,
|
||||||
|
value: item.id,
|
||||||
|
columns: tem.columns,
|
||||||
|
interval: tem.interval,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const addReportTemplate = () => {
|
||||||
|
ElMessageBox.prompt('请输入模板名称', '添加模板', {
|
||||||
|
confirmButtonText: '提交',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
inputPattern: /\S/,
|
||||||
|
inputErrorMessage: '模板名称不能为空',
|
||||||
|
}).then(({ value }) => {
|
||||||
|
const tem = {
|
||||||
|
name: value,
|
||||||
|
interval: interval.value,
|
||||||
|
columns: reportTableColumn.value,
|
||||||
|
}
|
||||||
|
const data = {
|
||||||
|
category: '单机报表' as const,
|
||||||
|
template: JSON.stringify(tem),
|
||||||
|
}
|
||||||
|
console.log(data)
|
||||||
|
|
||||||
|
addReportTemplateListReq(data).then((res) => {
|
||||||
|
if (res.success) {
|
||||||
|
ElMessage.success('添加成功!')
|
||||||
|
getReportTemplateList()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const delReportTemplate = (id: string) => {
|
||||||
|
ElMessageBox.confirm('确定删除该模板吗?', '删除模板', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning',
|
||||||
|
}).then(() => {
|
||||||
|
delReportTemplateListReq({ id }).then((res) => {
|
||||||
|
if (res.success) {
|
||||||
|
ElMessage.success('删除成功!')
|
||||||
|
getReportTemplateList()
|
||||||
|
template.value = ''
|
||||||
|
if (template.value == id) {
|
||||||
|
reportTableColumn.value = JSON.parse(JSON.stringify(originReportColumn))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const changeTemplate = (val: string) => {
|
||||||
|
const target = reportTemplateList.value.find((item) => item.value === val)
|
||||||
|
if (target) {
|
||||||
|
interval.value = target.interval ? target.interval : interval.value
|
||||||
|
reportTableColumn.value = target.columns
|
||||||
|
}
|
||||||
|
}
|
||||||
// 测点名称
|
// 测点名称
|
||||||
const showMeasure = ref(false)
|
const showMeasure = ref(false)
|
||||||
const currentChoose = ref('')
|
const currentChoose = ref('')
|
||||||
@ -230,7 +314,7 @@ const chooseMeasurePoint = () => {
|
|||||||
}
|
}
|
||||||
const removeColumn = (val: any) => {
|
const removeColumn = (val: any) => {
|
||||||
const columnName = val.column.property
|
const columnName = val.column.property
|
||||||
reportTableColumn.value = reportTableColumn.value.filter((val) => val.prop !== columnName)
|
reportTableColumn.value = reportTableColumn.value.filter((val:any) => val.prop !== columnName)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleSelections = (value: any) => {
|
const handleSelections = (value: any) => {
|
||||||
@ -264,7 +348,7 @@ const selectMeasurePoint = () => {
|
|||||||
showMeasure.value = false
|
showMeasure.value = false
|
||||||
}
|
}
|
||||||
const reportLoading = ref(false)
|
const reportLoading = ref(false)
|
||||||
const reportTableColumn = ref([
|
const originReportColumn = [
|
||||||
{
|
{
|
||||||
label: `风速`,
|
label: `风速`,
|
||||||
prop: 'iWindSpeed',
|
prop: 'iWindSpeed',
|
||||||
@ -310,7 +394,8 @@ const reportTableColumn = ref([
|
|||||||
prop: 'iHydrPress',
|
prop: 'iHydrPress',
|
||||||
unit: 'kpa',
|
unit: 'kpa',
|
||||||
},
|
},
|
||||||
])
|
]
|
||||||
|
const reportTableColumn = ref(JSON.parse(JSON.stringify(originReportColumn)))
|
||||||
|
|
||||||
const reportTableData = ref([]) as any
|
const reportTableData = ref([]) as any
|
||||||
const idCounter = ref(0)
|
const idCounter = ref(0)
|
||||||
@ -318,7 +403,7 @@ const queryHistoryData = () => {
|
|||||||
if (!windBlowerValue.value) return ElMessage.warning('请选择风机!')
|
if (!windBlowerValue.value) return ElMessage.warning('请选择风机!')
|
||||||
if (!timeRange.value.length) return ElMessage.warning('请选择时间!')
|
if (!timeRange.value.length) return ElMessage.warning('请选择时间!')
|
||||||
if (!interval.value) return ElMessage.warning('请选择间隔!')
|
if (!interval.value) return ElMessage.warning('请选择间隔!')
|
||||||
const attributeCodes = reportTableColumn.value.map((val) => val.prop).filter((item) => item != null && item !== '')
|
const attributeCodes = reportTableColumn.value.map((val:any) => val.prop).filter((item:any) => item != null && item !== '')
|
||||||
if (!attributeCodes.length) return ElMessage.warning('请添加测点!')
|
if (!attributeCodes.length) return ElMessage.warning('请添加测点!')
|
||||||
reportLoading.value = true
|
reportLoading.value = true
|
||||||
const requestData = {
|
const requestData = {
|
||||||
@ -338,7 +423,7 @@ const queryHistoryData = () => {
|
|||||||
if (Object.keys(result)?.length) {
|
if (Object.keys(result)?.length) {
|
||||||
const realResult = result[windBlowerValue.value]
|
const realResult = result[windBlowerValue.value]
|
||||||
let tableData = [] as any
|
let tableData = [] as any
|
||||||
attributeCodes.forEach((item) => {
|
attributeCodes.forEach((item:any) => {
|
||||||
if (Object.keys(realResult).includes(item)) {
|
if (Object.keys(realResult).includes(item)) {
|
||||||
tableData.push({
|
tableData.push({
|
||||||
name: item,
|
name: item,
|
||||||
@ -418,6 +503,8 @@ const timestampToTime = (timestamp: any) => {
|
|||||||
let s = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
|
let s = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
|
||||||
return Y + M + D + h + m + s
|
return Y + M + D + h + m + s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getReportTemplateList()
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
queryWindBlower()
|
queryWindBlower()
|
||||||
})
|
})
|
||||||
@ -464,4 +551,9 @@ onMounted(() => {
|
|||||||
transition: 0.2;
|
transition: 0.2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.tamplateOption {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
Loading…
Reference in New Issue
Block a user