Merge remote-tracking branch 'origin/main'
@ -41,6 +41,9 @@ public class SysMenusController {
|
||||
if(!hasPermission){
|
||||
return R.fail("没有系统管理权限");
|
||||
}
|
||||
if (!sysMenuDto.getMenuName().matches("^[a-zA-Z]*$")){
|
||||
return R.fail("菜单名称,必须为英文");
|
||||
}
|
||||
return R.success(sysMenuService.createMenu(sysMenuDto));
|
||||
}
|
||||
|
||||
@ -55,7 +58,7 @@ public class SysMenusController {
|
||||
if(!hasPermission){
|
||||
return R.fail("没有系统管理权限");
|
||||
}
|
||||
if (StringUtils.isAllEnglishLetters(sysMenuDto.getMenuName())){
|
||||
if (!sysMenuDto.getMenuName().matches("^[a-zA-Z]*$")){
|
||||
return R.fail("菜单名称,必须为英文");
|
||||
}
|
||||
sysMenuService.updateMenu(sysMenuDto);
|
||||
|
@ -49,12 +49,12 @@ public class DataService {
|
||||
//为空查全部
|
||||
List<String> sysIotModelFields = sysIotModelFieldMapper.queryAllFiledNames(Long.valueOf(snapshotValueQueryParam.getDeviceId()));
|
||||
for (String item : sysIotModelFields) {
|
||||
String key = String.format("RT:[%s]:[%s]", snapshotValueQueryParam.getDeviceId(), item);
|
||||
String key = String.format("RT:%s:%s", snapshotValueQueryParam.getDeviceId(), item);
|
||||
keyList.add(key);
|
||||
}
|
||||
} else {
|
||||
for (String item : attributes) {
|
||||
String key = String.format("RT:[%s]:[%s]", snapshotValueQueryParam.getDeviceId(), item);
|
||||
String key = String.format("RT:%s:%s", snapshotValueQueryParam.getDeviceId(), item);
|
||||
keyList.add(key);
|
||||
}
|
||||
}
|
||||
@ -62,12 +62,10 @@ public class DataService {
|
||||
List<Object> dataList = adminRedisTemplate.mGet(keyList);
|
||||
for (int i = 0; i < keyList.size(); i++) {
|
||||
String key = keyList.get(i);
|
||||
int firstColonIndex = key.indexOf('[');
|
||||
int firstIndex = key.indexOf(']');
|
||||
int secondIndex = key.indexOf(']', firstIndex + 1);
|
||||
int secondColonIndex = key.indexOf('[', firstColonIndex + 1);
|
||||
String deviceId = key.substring(firstColonIndex + 1, firstIndex);
|
||||
String fieldName = key.substring(secondColonIndex + 1, secondIndex);
|
||||
int firstColonIndex = key.indexOf(':');
|
||||
int secondColonIndex = key.indexOf(':', firstColonIndex + 1);
|
||||
String deviceId = key.substring(firstColonIndex + 1, secondColonIndex);
|
||||
String fieldName = key.substring(secondColonIndex + 1);
|
||||
if (finalResult.get(deviceId) == null) {
|
||||
Map<String, Object> valueMap = new HashMap<>();
|
||||
valueMap.put(fieldName, dataList.get(i));
|
||||
|
@ -62,6 +62,23 @@ public class SysEnumController {
|
||||
}
|
||||
|
||||
|
||||
/** 更新枚举值 */
|
||||
@PostMapping("/updateEnumValues")
|
||||
public R<SysEnumValuesVo> updateEnumValues(@RequestBody SysEnumValuesDto sysEnumValuesDto) {
|
||||
//判断是否有权限
|
||||
boolean hasPermission = StpUtil.hasPermission(SysAuthorityIds.SYS_AUTHORITY_ID_DEVICE_MGR.toString());
|
||||
if(!hasPermission){
|
||||
return R.fail("没有设备管理权限");
|
||||
}
|
||||
if (sysEnumValuesDto.getEnumTypeId() ==null && StringUtils.isBlank(sysEnumValuesDto.getValue())
|
||||
|| sysEnumValuesDto.getOrderNumber() == null || sysEnumValuesDto.getIsActive() ==null ||
|
||||
sysEnumValuesDto.getId() ==null) {
|
||||
throw new ServiceException("参数缺失");
|
||||
}
|
||||
SysEnumValuesVo sysEnumValuesVo = sysEnumService.updateEnumValues(sysEnumValuesDto);
|
||||
return R.success(sysEnumValuesVo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询枚举类型列表
|
||||
*
|
||||
@ -72,7 +89,7 @@ public class SysEnumController {
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询枚举类型列表
|
||||
* 查询枚举值列表
|
||||
*
|
||||
* */
|
||||
@PostMapping("/queryEnumValuesList")
|
||||
|
@ -19,6 +19,10 @@ public class SysEnumValuesVo {
|
||||
* 关联到枚举类型表的ID
|
||||
*/
|
||||
private Long enumTypeId;
|
||||
/**
|
||||
* 关联到枚举类型表的ID字符串类型
|
||||
*/
|
||||
private String enumTypeIdStr;
|
||||
|
||||
/**
|
||||
* 枚举值的具体内容
|
||||
|
@ -1,9 +1,13 @@
|
||||
package com.das.modules.equipment.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.das.modules.equipment.domain.dto.SysEnumTypesDto;
|
||||
import com.das.modules.equipment.entity.SysEnumTypes;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
@Mapper
|
||||
public interface SysEnumTypesMapper extends BaseMapper<SysEnumTypes> {
|
||||
|
||||
Long queryEnumTypesByName(@Param("sysDto") SysEnumTypesDto sysDto);
|
||||
}
|
||||
|
@ -14,6 +14,8 @@ public interface SysEnumService {
|
||||
|
||||
SysEnumValuesVo addEnumValues(SysEnumValuesDto sysEnumValuesDto);
|
||||
|
||||
SysEnumValuesVo updateEnumValues(SysEnumValuesDto sysEnumValuesDto);
|
||||
|
||||
List<SysEnumTypesVo> queryEnumTypesList();
|
||||
|
||||
PageDataInfo<SysEnumValuesVo> queryEnumValuesList(SysEnumValuesDto sysEnumValuesDto);
|
||||
|
@ -1,8 +1,10 @@
|
||||
package com.das.modules.equipment.service.impl;
|
||||
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.das.common.config.SessionUtil;
|
||||
import com.das.common.exceptions.ServiceException;
|
||||
import com.das.common.utils.BeanCopyUtils;
|
||||
import com.das.common.utils.PageDataInfo;
|
||||
import com.das.common.utils.PageQuery;
|
||||
@ -35,13 +37,18 @@ public class SysEnumServiceImpl implements SysEnumService {
|
||||
/** 新增枚举类型 */
|
||||
@Override
|
||||
public SysEnumTypesVo addEnumTypes(SysEnumTypesDto sysEnumTypesDto) {
|
||||
//判断枚举类型,是否重复
|
||||
Long count = sysEnumTypesMapper.queryEnumTypesByName(sysEnumTypesDto);
|
||||
if (count >0){
|
||||
throw new ServiceException("枚举类型,不可重复!");
|
||||
}
|
||||
SysEnumTypes sysEnumTypes = new SysEnumTypes();
|
||||
BeanCopyUtils.copy(sysEnumTypesDto, sysEnumTypes);
|
||||
SysUserVo sysUserVo = (SysUserVo) StpUtil.getTokenSession().get(SessionUtil.SESSION_USER_KEY);
|
||||
sysEnumTypes.setCreatedTime(new Date());
|
||||
sysEnumTypes.setUpdatedTime(new Date());
|
||||
sysEnumTypes.setCreatedBy(sysUserVo.getAccount());
|
||||
sysEnumTypes.setUpdatedBy(sysUserVo.getAccount());
|
||||
sysEnumTypes.setCreatedTime(new Date());
|
||||
sysEnumTypes.setUpdatedTime(new Date());
|
||||
sysEnumTypes.setRevision(1);
|
||||
sysEnumTypesMapper.insert(sysEnumTypes);
|
||||
SysEnumTypesVo sysEnumTypesVo = new SysEnumTypesVo();
|
||||
@ -54,11 +61,18 @@ public class SysEnumServiceImpl implements SysEnumService {
|
||||
public SysEnumValuesVo addEnumValues(SysEnumValuesDto sysEnumValuesDto) {
|
||||
SysEnumValues sysEnumValues = new SysEnumValues();
|
||||
BeanCopyUtils.copy(sysEnumValuesDto,sysEnumValues);
|
||||
QueryWrapper<SysEnumValues> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("enum_type_id",sysEnumValuesDto.getEnumTypeId());
|
||||
queryWrapper.eq("description",sysEnumValuesDto.getDescription());
|
||||
Long count = sysEnumValuesMapper.selectCount(queryWrapper);
|
||||
if (count >0){
|
||||
throw new ServiceException("枚举值描述,不可重复!");
|
||||
}
|
||||
SysUserVo sysUserVo = (SysUserVo) StpUtil.getTokenSession().get(SessionUtil.SESSION_USER_KEY);
|
||||
sysEnumValues.setCreatedTime(new Date());
|
||||
sysEnumValues.setUpdatedTime(new Date());
|
||||
sysEnumValues.setCreatedBy(sysUserVo.getAccount());
|
||||
sysEnumValues.setUpdatedBy(sysUserVo.getAccount());
|
||||
sysEnumValues.setCreatedTime(new Date());
|
||||
sysEnumValues.setUpdatedTime(new Date());
|
||||
sysEnumValues.setRevision(1);
|
||||
sysEnumValuesMapper.insert(sysEnumValues);
|
||||
SysEnumValuesVo sysEnumValuesVo = new SysEnumValuesVo();
|
||||
@ -66,6 +80,26 @@ public class SysEnumServiceImpl implements SysEnumService {
|
||||
return sysEnumValuesVo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SysEnumValuesVo updateEnumValues(SysEnumValuesDto sysEnumValuesDto) {
|
||||
SysEnumValues sysEnumValues = new SysEnumValues();
|
||||
BeanCopyUtils.copy(sysEnumValuesDto,sysEnumValues);
|
||||
QueryWrapper<SysEnumValues> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("enum_type_id",sysEnumValuesDto.getEnumTypeId());
|
||||
queryWrapper.eq("description",sysEnumValuesDto.getDescription());
|
||||
Long count = sysEnumValuesMapper.selectCount(queryWrapper);
|
||||
if (count >0){
|
||||
throw new ServiceException("枚举值描述,不可重复!");
|
||||
}
|
||||
SysUserVo sysUserVo = (SysUserVo) StpUtil.getTokenSession().get(SessionUtil.SESSION_USER_KEY);
|
||||
sysEnumValues.setUpdatedBy(sysUserVo.getAccount());
|
||||
sysEnumValues.setUpdatedTime(new Date());
|
||||
sysEnumValuesMapper.updateById(sysEnumValues);
|
||||
SysEnumValuesVo sysEnumValuesVo = new SysEnumValuesVo();
|
||||
BeanCopyUtils.copy(sysEnumValues, sysEnumValuesVo);
|
||||
return sysEnumValuesVo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询枚举类型列表
|
||||
* @return
|
||||
|
@ -60,6 +60,8 @@ public class SysEquipmentServiceImpl implements SysEquipmentService {
|
||||
|
||||
@Override
|
||||
public SysEquipmentVo creatSysEquipment(SysEquipmentDto sysEquipmentDto) {
|
||||
//去除空格
|
||||
sysEquipmentDto.setCode(sysEquipmentDto.getCode().replaceAll(" ", ""));
|
||||
SysEquipment sysEquipment = new SysEquipment();
|
||||
BeanCopyUtils.copy(sysEquipmentDto, sysEquipment);
|
||||
|
||||
@ -81,6 +83,8 @@ public class SysEquipmentServiceImpl implements SysEquipmentService {
|
||||
|
||||
@Override
|
||||
public SysEquipmentVo updateSysEquipment(SysEquipmentDto sysEquipmentDto) {
|
||||
//去除空格
|
||||
sysEquipmentDto.setCode(sysEquipmentDto.getCode().replaceAll(" ", ""));
|
||||
SysEquipment sysEquipment = new SysEquipment();
|
||||
BeanCopyUtils.copy(sysEquipmentDto, sysEquipment);
|
||||
SysUserVo sysUserVo = (SysUserVo) StpUtil.getTokenSession().get(SessionUtil.SESSION_USER_KEY);
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.das.modules.equipment.service.impl;
|
||||
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
import cn.hutool.poi.excel.ExcelReader;
|
||||
import cn.hutool.poi.excel.ExcelUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
@ -25,6 +26,7 @@ import com.das.modules.equipment.mapper.SysIotModelFieldMapper;
|
||||
import com.das.modules.equipment.mapper.SysIotModelMapper;
|
||||
import com.das.modules.equipment.mapper.SysIotModelServiceMapper;
|
||||
import com.das.modules.equipment.service.SysIotModelService;
|
||||
import com.das.modules.node.service.TDEngineService;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@ -35,15 +37,13 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Service
|
||||
@Slf4j
|
||||
public class SysIotModelServiceImpl implements SysIotModelService {
|
||||
public static final int COMMIT_COUNT = 1000;
|
||||
|
||||
@Autowired
|
||||
private SysIotModelMapper sysIotModelMapper;
|
||||
@ -54,6 +54,8 @@ public class SysIotModelServiceImpl implements SysIotModelService {
|
||||
@Autowired
|
||||
private SysIotModelServiceMapper sysIotModelServiceMapper;
|
||||
|
||||
@Autowired
|
||||
private TDEngineService tdEngineService;
|
||||
|
||||
public SysIotModelVo creatSysIotModel(SysIotModelDto sysIotModelDto) {
|
||||
SysIotModel sysIotModel = new SysIotModel();
|
||||
@ -162,6 +164,8 @@ public class SysIotModelServiceImpl implements SysIotModelService {
|
||||
sysIotModelField.setDataType("tinyint");
|
||||
}
|
||||
|
||||
//动态执行创建td超级表,字段
|
||||
createTdStableOrColumn(sysIotModelField);
|
||||
sysIotModelFieldMapper.insert(sysIotModelField);
|
||||
SysIotModelFieldVo sysIotModelFieldVo = new SysIotModelFieldVo();
|
||||
BeanCopyUtils.copy(sysIotModelField, sysIotModelFieldVo);
|
||||
@ -188,6 +192,15 @@ public class SysIotModelServiceImpl implements SysIotModelService {
|
||||
|
||||
}
|
||||
sysIotModelFieldMapper.updateById(sysIotModelField);
|
||||
|
||||
SysIotModelField oldSysIotField = sysIotModelFieldMapper.selectById(sysIotModelFieldDto.getId());
|
||||
if (oldSysIotField == null){
|
||||
throw new ServiceException("未查找到该条记录");
|
||||
}
|
||||
if (!oldSysIotField.getAttributeCode().equals(sysIotModelField.getAttributeCode()) && oldSysIotField.getDataType().equals(sysIotModelField.getDataType()) && Objects.equals(oldSysIotField.getHighSpeed(), sysIotModelField.getHighSpeed())){
|
||||
//更新td表结构
|
||||
updateTDStableOrColumn(sysIotModelField,oldSysIotField);
|
||||
}
|
||||
SysIotModelFieldVo sysIotModelFieldVo = new SysIotModelFieldVo();
|
||||
BeanCopyUtils.copy(sysIotModelField, sysIotModelFieldVo);
|
||||
return sysIotModelFieldVo;
|
||||
@ -195,6 +208,8 @@ public class SysIotModelServiceImpl implements SysIotModelService {
|
||||
|
||||
@Override
|
||||
public void deleteSysIotModelField(SysIotModelFieldDto sysIotModelFieldDto) {
|
||||
SysIotModelField sysIotModelField = sysIotModelFieldMapper.selectById(sysIotModelFieldDto.getId());
|
||||
deleteTDStableOrColumn(sysIotModelField);
|
||||
sysIotModelFieldMapper.deleteById(sysIotModelFieldDto.getId());
|
||||
}
|
||||
|
||||
@ -401,11 +416,35 @@ public class SysIotModelServiceImpl implements SysIotModelService {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(sysIotModelFieldList)) {
|
||||
sysIotModelFieldMapper.insertBatch(sysIotModelFieldList);
|
||||
ListUtil.page(sysIotModelFieldList, COMMIT_COUNT, create -> {
|
||||
for (SysIotModelField item : create){
|
||||
createTdStableOrColumn(item);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(updateSysIotModelFieldList)) {
|
||||
ListUtil.page(updateSysIotModelFieldList, COMMIT_COUNT, update -> {
|
||||
for (SysIotModelField item : update){
|
||||
SysIotModelField oldSysIotField = sysIotModelFieldMapper.selectById(item.getId());
|
||||
if (oldSysIotField != null){
|
||||
if (!oldSysIotField.getAttributeCode().equals(item.getAttributeCode()) && oldSysIotField.getDataType().equals(item.getDataType()) && Objects.equals(oldSysIotField.getHighSpeed(), item.getHighSpeed())){
|
||||
//更新td表结构
|
||||
updateTDStableOrColumn(item,oldSysIotField);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
sysIotModelFieldMapper.updateBatchById(updateSysIotModelFieldList);
|
||||
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(delSysIotModelFieldList)) {
|
||||
ListUtil.page(updateSysIotModelFieldList, COMMIT_COUNT, delete -> {
|
||||
for (SysIotModelField item : delete){
|
||||
deleteTDStableOrColumn(item);
|
||||
}
|
||||
});
|
||||
sysIotModelFieldMapper.deleteBatchIds(delSysIotModelFieldList);
|
||||
}
|
||||
}
|
||||
@ -428,4 +467,70 @@ public class SysIotModelServiceImpl implements SysIotModelService {
|
||||
return list;
|
||||
}
|
||||
|
||||
public void createTdStableOrColumn(SysIotModelField sysIotModelField){
|
||||
//如果新增的是第一条记录 创建tdengine超级表 分为高频和低频
|
||||
QueryWrapper<SysIotModelField> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("iot_model_id",sysIotModelField.getIotModelId());
|
||||
queryWrapper.eq("highspeed",sysIotModelField.getHighSpeed());
|
||||
List<SysIotModelField> sysIotModelFields = sysIotModelFieldMapper.selectList(queryWrapper);
|
||||
if (CollectionUtils.isEmpty(sysIotModelFields)){
|
||||
if (sysIotModelField.getHighSpeed() == 0){
|
||||
SysIotModel sysIotModel = sysIotModelMapper.selectById(sysIotModelField.getIotModelId());
|
||||
Map<String,String> map = new HashMap<>();
|
||||
map.put(sysIotModelField.getAttributeCode(), sysIotModelField.getDataType());
|
||||
//创建低频超级表
|
||||
tdEngineService.createStable(sysIotModel.getIotModelCode(),"l_",map);
|
||||
}
|
||||
if (sysIotModelField.getHighSpeed() == 1){
|
||||
SysIotModel sysIotModel = sysIotModelMapper.selectById(sysIotModelField.getIotModelId());
|
||||
Map<String,String> map = new HashMap<>();
|
||||
map.put(sysIotModelField.getAttributeCode(), sysIotModelField.getDataType());
|
||||
//创建高频超级表
|
||||
tdEngineService.createStable(sysIotModel.getIotModelCode(),"h_",map);
|
||||
}
|
||||
}else {
|
||||
//stable已经存在,新增stable列
|
||||
if (sysIotModelField.getHighSpeed() == 0){
|
||||
SysIotModel sysIotModel = sysIotModelMapper.selectById(sysIotModelField.getIotModelId());
|
||||
Map<String,String> map = new HashMap<>();
|
||||
map.put(sysIotModelField.getAttributeCode(), sysIotModelField.getDataType());
|
||||
//创建低频超级表
|
||||
tdEngineService.addStableColumn(sysIotModel.getIotModelCode(),"l_",map);
|
||||
}
|
||||
if (sysIotModelField.getHighSpeed() == 1){
|
||||
SysIotModel sysIotModel = sysIotModelMapper.selectById(sysIotModelField.getIotModelId());
|
||||
Map<String,String> map = new HashMap<>();
|
||||
map.put(sysIotModelField.getAttributeCode(), sysIotModelField.getDataType());
|
||||
//创建高频超级表
|
||||
tdEngineService.addStableColumn(sysIotModel.getIotModelCode(),"h_",map);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void updateTDStableOrColumn(SysIotModelField sysIotModelField,SysIotModelField oldIotModelField){
|
||||
deleteTDStableOrColumn(oldIotModelField);
|
||||
createTdStableOrColumn(sysIotModelField);
|
||||
}
|
||||
|
||||
public void deleteTDStableOrColumn(SysIotModelField sysIotModelField){
|
||||
String stableName = null;
|
||||
SysIotModel sysIotModel = sysIotModelMapper.selectById(sysIotModelField.getIotModelId());
|
||||
if(sysIotModelField.getHighSpeed() == 0) {
|
||||
stableName = "l_" + sysIotModel.getIotModelCode();
|
||||
}
|
||||
if(sysIotModelField.getHighSpeed() == 1) {
|
||||
stableName = "h_" + sysIotModel.getIotModelCode();
|
||||
}
|
||||
QueryWrapper<SysIotModelField> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("iot_model_id",sysIotModelField.getIotModelId());
|
||||
queryWrapper.eq("highspeed",sysIotModelField.getHighSpeed());
|
||||
List<SysIotModelField> sysIotModelFields = sysIotModelFieldMapper.selectList(queryWrapper);
|
||||
if (CollectionUtils.isNotEmpty(sysIotModelFields) && sysIotModelFields.size() > 1){
|
||||
tdEngineService.deleteColumn(stableName,sysIotModelField.getAttributeCode());
|
||||
}
|
||||
//物模型属性只剩下最后一个删除表
|
||||
if (CollectionUtils.isNotEmpty(sysIotModelFields) && sysIotModelFields.size() == 1){
|
||||
tdEngineService.deleteStable(stableName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ public class ConfigUpdateVo {
|
||||
|
||||
private List<LinkVo> links;
|
||||
|
||||
private List equipments;
|
||||
private List<EquipmentVo> equipments;
|
||||
|
||||
public ConfigUpdateVo() {
|
||||
|
||||
|
@ -28,7 +28,9 @@ public interface SysImptabmappingMapper extends BaseMapperPlus<SysImptabmapping,
|
||||
|
||||
List<Long> getEquipmentId(Long linkId);
|
||||
|
||||
List<IotModelVo> getIotModelFieldByEquipmentId(Long equipmentId);
|
||||
List<IotModelVo> getIotModelFieldByDeviceId(@Param("deviceId") Long deviceId);
|
||||
|
||||
List<IotModelVo> getIotModelServiceByDeviceId(@Param("deviceId") Long deviceId);
|
||||
|
||||
List<IotModelVo> getIotModelServiceByEquipmentId(Long equipmentId);
|
||||
|
||||
|
@ -61,6 +61,7 @@ public class TDEngineService {
|
||||
/**
|
||||
* 创建超级表
|
||||
*/
|
||||
@Async
|
||||
public void createStable(String iotModelCode, String stableType, Map<String, String> fieldNameTypeMap) {
|
||||
try (Connection conn = hikariDataSource.getConnection();
|
||||
Statement pstmt = conn.createStatement()) {
|
||||
@ -94,6 +95,7 @@ public class TDEngineService {
|
||||
/**
|
||||
* 新增超级表列
|
||||
*/
|
||||
@Async
|
||||
public void addStableColumn(String iotModelCode, String stableType, Map<String, String> fieldNameTypeMap) {
|
||||
try (Connection conn = hikariDataSource.getConnection();
|
||||
Statement pstmt = conn.createStatement()) {
|
||||
@ -124,6 +126,7 @@ public class TDEngineService {
|
||||
/**
|
||||
* 删除超级表列
|
||||
*/
|
||||
@Async
|
||||
public void deleteColumn(String stableName, String fieldCode) {
|
||||
try (Connection conn = hikariDataSource.getConnection();
|
||||
Statement pstmt = conn.createStatement()) {
|
||||
@ -131,7 +134,7 @@ public class TDEngineService {
|
||||
sb.setLength(0);
|
||||
sb.append("ALTER STABLE ");
|
||||
sb.append(stableName);
|
||||
sb.append(" DROP COLUMN");
|
||||
sb.append(" DROP COLUMN ");
|
||||
;
|
||||
sb.append(fieldCode);
|
||||
sb.append(";");
|
||||
@ -149,6 +152,7 @@ public class TDEngineService {
|
||||
/**
|
||||
* 删除超级表
|
||||
*/
|
||||
@Async
|
||||
public void deleteStable(String stableName) {
|
||||
try (Connection conn = hikariDataSource.getConnection();
|
||||
Statement pstmt = conn.createStatement()) {
|
||||
|
@ -141,13 +141,12 @@ public class DataServiceImpl implements DataService {
|
||||
ObjectNode equipJsonNode = equipObjectMapper.convertValue(map, ObjectNode.class);
|
||||
List<NewIotModelVo> newIotModelFieldList = new ArrayList<>();
|
||||
List<NewIotModelVo> newIotModelServiceList = new ArrayList<>();
|
||||
// 获取设备IOT地址
|
||||
String iotAddr = sysImptabmappingMapper.getIotAddrByEquipmentId(equipmentId);
|
||||
// 根据设备Id获取对应的物模型属性和动作
|
||||
List<IotModelVo> iotModelFieldList = sysImptabmappingMapper.getIotModelFieldByEquipmentId(equipmentId);
|
||||
List<IotModelVo> iotModelFieldList = sysImptabmappingMapper.getIotModelFieldByDeviceId(equipmentId);
|
||||
List<IotModelVo> iotModelServiceList = sysImptabmappingMapper.getIotModelServiceByDeviceId(equipmentId);
|
||||
if (!CollectionUtils.isEmpty(iotModelFieldList)) {
|
||||
for (IotModelVo info : iotModelFieldList) {
|
||||
if (info.getServiceType() == null) {
|
||||
|
||||
NewIotModelVo newIotModelVo = new NewIotModelVo();
|
||||
newIotModelVo.setName(info.getEquipmentAttribute());
|
||||
newIotModelVo.setHighSpeed(info.getHighSpeed());
|
||||
@ -164,7 +163,10 @@ public class DataServiceImpl implements DataService {
|
||||
newIotModelVo.setType("yx");
|
||||
}
|
||||
newIotModelFieldList.add(newIotModelVo);
|
||||
} else if (info.getAttributeType() == null) {
|
||||
}
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(iotModelServiceList)){
|
||||
for (IotModelVo info : iotModelServiceList) {
|
||||
NewIotModelVo newIotModelVo = new NewIotModelVo();
|
||||
newIotModelVo.setName(info.getEquipmentService());
|
||||
if (info.getParams() == null) {
|
||||
@ -180,7 +182,6 @@ public class DataServiceImpl implements DataService {
|
||||
newIotModelServiceList.add(newIotModelVo);
|
||||
}
|
||||
}
|
||||
}
|
||||
EquipmentVo equipment = new EquipmentVo();
|
||||
equipment.setAddr(iotModelFieldList.get(0).getIotAddr());
|
||||
equipment.setId(equipmentId);
|
||||
@ -247,9 +248,8 @@ public class DataServiceImpl implements DataService {
|
||||
Iterator<String> keysHigh = values.fieldNames();
|
||||
while (keysHigh.hasNext()) {
|
||||
String fieldName = keysHigh.next();
|
||||
String key = String.format("RT:[%s]:[%s]", deviceId, fieldName);
|
||||
keyValueMap.put(key, values.get(fieldName).asDouble());
|
||||
|
||||
String key = String.format("RT:%s:%s", deviceId, fieldName);
|
||||
keyValueMap.put(key,values.get(fieldName));
|
||||
}
|
||||
adminRedisTemplate.mSet(keyValueMap);
|
||||
// Long dataTime = data.getTime();
|
||||
|
19
das/src/main/resources/mapper/SysEnumTypesMapper.xml
Normal file
@ -0,0 +1,19 @@
|
||||
<?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.das.modules.equipment.mapper.SysEnumTypesMapper">
|
||||
|
||||
|
||||
|
||||
<select id="queryEnumTypesByName" resultType="long">
|
||||
select
|
||||
count(*)
|
||||
from
|
||||
public.sys_enum_types
|
||||
where
|
||||
"name" = #{sysDto.name}
|
||||
or description = #{sysDto.description}
|
||||
</select>
|
||||
|
||||
|
||||
|
||||
</mapper>
|
@ -4,6 +4,7 @@
|
||||
|
||||
<resultMap type="com.das.modules.equipment.domain.vo.SysEnumValuesVo" id="EnumValuesMap">
|
||||
<result property="enumTypeId" column="enum_type_id" jdbcType="BIGINT"/>
|
||||
<result property="enumTypeIdStr" column="enum_type_id" jdbcType="VARCHAR"/>
|
||||
<result property="value" column="value" jdbcType="VARCHAR"/>
|
||||
<result property="description" column="description" jdbcType="VARCHAR"/>
|
||||
<result property="orderNumber" column="order_number" jdbcType="INTEGER"/>
|
||||
@ -22,6 +23,7 @@
|
||||
<if test="sysEnumValuesDto.isActive != null and sysEnumValuesDto.isActive != ''">
|
||||
and e.is_active =#{sysEnumValuesDto.isActive}
|
||||
</if>
|
||||
order by e.order_number asc
|
||||
</where>
|
||||
</select>
|
||||
|
||||
|
@ -58,14 +58,6 @@
|
||||
where sc.id = #{linkId}
|
||||
</select>
|
||||
|
||||
<select id="getIotModelFieldByEquipmentId" resultType="com.das.modules.node.domain.vo.IotModelVo">
|
||||
select simf.attribute_type as attributeType,sims.service_type as serviceType, se.iot_addr as iotAddr,si.equipment_attribute as equipmentAttribute,si.equipment_service as equipmentService, si.params, simf.highspeed as highSpeed from sys_imptabmapping si
|
||||
left join sys_equipment se on si.equipment_id = se.id
|
||||
left join sys_iot_model_field simf on si.equipment_attribute = simf.attribute_code and se.iot_model_id = simf.iot_model_id
|
||||
left join sys_iot_model_service sims on si.equipment_service = sims.service_code and se.iot_model_id = sims.iot_model_id
|
||||
where si.equipment_id = #{equipmentId}
|
||||
</select>
|
||||
|
||||
|
||||
<select id="getIotModelServiceByEquipmentId" resultType="com.das.modules.node.domain.vo.IotModelVo">
|
||||
select sims.service_code as name ,sims.service_type as type ,si.params from sys_imptabmapping si
|
||||
@ -95,5 +87,33 @@
|
||||
left join sys_equipment se on si.equipment_id = se.id
|
||||
where si.link_id = #{linkId}
|
||||
</select>
|
||||
<select id="getIotModelFieldByDeviceId" resultType="com.das.modules.node.domain.vo.IotModelVo">
|
||||
select
|
||||
field.attribute_type as attributeType,
|
||||
null as serviceType,
|
||||
(select iot_addr from sys_equipment e where e.id=1846101273013739522) as iot_addr,
|
||||
field.attribute_code as equipmentAttribute,
|
||||
null as equipmentService,
|
||||
si.params,
|
||||
field.highspeed
|
||||
from sys_iot_model_field field
|
||||
left join sys_imptabmapping si on (field.attribute_code=si.equipment_attribute)
|
||||
where field.iot_model_id = (select equip.iot_model_id from sys_equipment equip where equip.id = #{deviceId}) and si.equipment_id = #{deviceId}
|
||||
order by field.attribute_type ,field.porder
|
||||
</select>
|
||||
<select id="getIotModelServiceByDeviceId" resultType="com.das.modules.node.domain.vo.IotModelVo">
|
||||
select
|
||||
null as attributeType,
|
||||
service.service_type as serviceType,
|
||||
(select iot_addr from sys_equipment e where e.id=1846101273013739522) as iot_addr,
|
||||
null as equipmentAttribute,
|
||||
service.service_code as equipmentService,
|
||||
si.params,
|
||||
null as highspeed
|
||||
from sys_iot_model_service service
|
||||
left join sys_imptabmapping si on (service.service_code=si.equipment_service)
|
||||
where service.iot_model_id = (select equip.iot_model_id from sys_equipment equip where equip.id = #{deviceId}) and si.equipment_id = #{deviceId}
|
||||
order by service.service_type ,service.porder
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
|
@ -5,3 +5,6 @@
|
||||
- [节点管理接口](api/node.md)
|
||||
- [数据访问接口](api/data.md)
|
||||
- [数据采集](datacollect/)
|
||||
- [系统部署](deploy/)
|
||||
- [Linux系统部署](deploy/linux.md)
|
||||
- [TDEngine3部署](deploy/tdengine3.md)
|
36
docs/deploy/README.md
Normal file
@ -0,0 +1,36 @@
|
||||
# 润阳系统部署
|
||||
|
||||
|
||||
## 硬件环境
|
||||
|
||||
> CPU: 24核
|
||||
|
||||
> 内存: 32GB
|
||||
|
||||
> 硬盘: 16T
|
||||
|
||||
|
||||
## 软件环境
|
||||
|
||||
> 操作系统: OpenEuler 24.03 (LTS)
|
||||
|
||||
> JDK: OpenJDK 17
|
||||
|
||||
> 关系数据库: PostgreSQL 15.8
|
||||
|
||||
> 缓存数据库: Redis 6
|
||||
|
||||
> 时序数据库: TDEngine 3.3.2.0
|
||||
|
||||
|
||||
## 目录结构
|
||||
|
||||
`/das` - 系统根目录
|
||||
|
||||
`/das/data` - 系统数据目录
|
||||
|
||||
`/das/data/tddata` - TDEngine3数据目录
|
||||
|
||||
`/das/data/pgdata` - PostgreSQL数据目录
|
||||
|
||||
`/das/data/redis` - Redis数据目录
|
1
docs/deploy/_sidebar.md
Normal file
@ -0,0 +1 @@
|
||||
- [首页](/)
|
3
docs/deploy/linux.md
Normal file
@ -0,0 +1,3 @@
|
||||
# OpenEuler 24.03 (LTS) 安装部署
|
||||
|
||||
!> 等待更新
|
4
docs/deploy/tdengine3.md
Normal file
@ -0,0 +1,4 @@
|
||||
# TDEngine3 安装部署
|
||||
|
||||
> 当前版本: 3.3.2.0
|
||||
|
@ -6,7 +6,7 @@ VITE_BASE_PATH = './'
|
||||
|
||||
# 代理配置(开发使用),必须在一行中
|
||||
# 本地
|
||||
# VITE_APP_PROXY=[["/api","http://192.168.130.12:8080/api"]]
|
||||
# VITE_APP_PROXY=[["/api","http://192.168.130.22:8080/api"]]
|
||||
# 线上
|
||||
VITE_APP_PROXY=[["/api","https://test.jsspisoft.com/api"]]
|
||||
|
||||
|
@ -34,7 +34,7 @@ export function enumValueAdd(params: object = {}) {
|
||||
})
|
||||
}
|
||||
|
||||
// 枚举值新增
|
||||
// 枚举值删除
|
||||
export function enumValueDelete(params: object = {}) {
|
||||
return createAxios({
|
||||
url: '/api/enum/deleteEnumValues',
|
||||
@ -42,4 +42,12 @@ export function enumValueDelete(params: object = {}) {
|
||||
data: params,
|
||||
})
|
||||
}
|
||||
// 枚举值编辑
|
||||
export function enumValuepageEdit(params: object = {}) {
|
||||
return createAxios({
|
||||
url: '/api/enum/updateEnumValues',
|
||||
method: 'POST',
|
||||
data: params,
|
||||
})
|
||||
}
|
||||
|
||||
|
9
ui/dasadmin/src/api/backend/control/request.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import createAxios from '/@/utils/axios'
|
||||
|
||||
export const sendValueReq = (data: any) => {
|
||||
return createAxios({
|
||||
url: '/api/node/link/deviceControl',
|
||||
method: 'post',
|
||||
data: data,
|
||||
})
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
import createAxios from '/@/utils/axios'
|
||||
import {addDataType, getDataReturnType, getDataType, getTreeDataReturnType} from "/@/views/backend/auth/org/type";
|
||||
|
||||
export const url = '/admin/Dashboard/'
|
||||
|
||||
@ -8,3 +9,11 @@ export function index() {
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
|
||||
export const getInstitutionalListReq = (data: getDataType) => {
|
||||
return createAxios<addDataType, getDataReturnType<getTreeDataReturnType>>({
|
||||
url: '/api/org/query',
|
||||
method: 'post',
|
||||
data: data,
|
||||
})
|
||||
}
|
||||
|
@ -142,8 +142,16 @@ export const downloadModelReq = (data: { id: string }) => {
|
||||
}
|
||||
|
||||
export const getDeviceTypeEnumReq = () => {
|
||||
return createAxios<never,RequestReturnType<DeviceType[]>>({
|
||||
return createAxios<never, RequestReturnType<DeviceType[]>>({
|
||||
url: '/api/equipment/type',
|
||||
method: 'post',
|
||||
})
|
||||
}
|
||||
|
||||
export const getRealValueListReq = (data: { deviceId: string, attributes: string[] }[]) => {
|
||||
return createAxios<never, RequestReturnType<any>>({
|
||||
url: '/api/data/snapshot',
|
||||
method: 'post',
|
||||
data: data,
|
||||
})
|
||||
}
|
||||
|
24
ui/dasadmin/src/api/backend/linkMonitor/request.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import createAxios from '/@/utils/axios'
|
||||
import {
|
||||
RequestReturnType,
|
||||
RequestReturnRowType,
|
||||
LinkMonitorTreeType,
|
||||
GetLinkMonitorTableParam,
|
||||
LinkMonitorTableType,
|
||||
} from '/@/views/backend/linkMonitor/type'
|
||||
|
||||
// 左侧树节点树结构
|
||||
export const getNodeListReq = () => {
|
||||
return createAxios<never, RequestReturnType<LinkMonitorTreeType[]>>({
|
||||
url: '/api/node/list',
|
||||
method: 'post',
|
||||
})
|
||||
}
|
||||
// 链路列表
|
||||
export const getLinkListReq = (data: GetLinkMonitorTableParam) => {
|
||||
return createAxios<never, RequestReturnRowType<LinkMonitorTableType[]>>({
|
||||
url: '/api/node/link/list',
|
||||
method: 'post',
|
||||
data: data,
|
||||
})
|
||||
}
|
BIN
ui/dasadmin/src/assets/dashboard/Standby.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
ui/dasadmin/src/assets/dashboard/bg1.png
Normal file
After Width: | Height: | Size: 877 KiB |
BIN
ui/dasadmin/src/assets/dashboard/biaogan.png
Normal file
After Width: | Height: | Size: 574 B |
BIN
ui/dasadmin/src/assets/dashboard/fanlist1.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
ui/dasadmin/src/assets/dashboard/fanlist2.png
Normal file
After Width: | Height: | Size: 844 B |
BIN
ui/dasadmin/src/assets/dashboard/fault.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
ui/dasadmin/src/assets/dashboard/fdl1.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
ui/dasadmin/src/assets/dashboard/fdl2.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
ui/dasadmin/src/assets/dashboard/fdl3.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
ui/dasadmin/src/assets/dashboard/fdl4.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
ui/dasadmin/src/assets/dashboard/offline.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
ui/dasadmin/src/assets/dashboard/run.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
ui/dasadmin/src/assets/dashboard/status1.png
Normal file
After Width: | Height: | Size: 4.7 KiB |
BIN
ui/dasadmin/src/assets/dashboard/status2.png
Normal file
After Width: | Height: | Size: 4.9 KiB |
BIN
ui/dasadmin/src/assets/dashboard/viewP.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
ui/dasadmin/src/assets/dashboard/viewR.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
ui/dasadmin/src/assets/dashboard/viewW.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
ui/dasadmin/src/assets/dashboard/viewY.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<div class="nav-menus" :class="configStore.layout.layoutMode">
|
||||
<router-link class="h100" target="_blank" :title="t('Home')" to="/">
|
||||
<!-- <router-link class="h100" target="_blank" :title="t('Home')" to="/">
|
||||
<div class="nav-menu-item">
|
||||
<Icon :color="configStore.getColorVal('headerBarTabColor')" class="nav-menu-icon" name="el-icon-Monitor" size="18" />
|
||||
</div>
|
||||
</router-link>
|
||||
</router-link> -->
|
||||
<!-- <el-dropdown
|
||||
@visible-change="onCurrentNavMenu($event, 'lang')"
|
||||
class="h100"
|
||||
|
@ -106,11 +106,12 @@ export const useConfig = defineStore(
|
||||
|
||||
const getColorVal = function (name: keyof Layout): string {
|
||||
const colors = layout[name] as string[]
|
||||
if (layout.isDark) {
|
||||
return colors[1]
|
||||
} else {
|
||||
// TODO 切换暗黑模式
|
||||
// if (layout.isDark) {
|
||||
// return colors[1]
|
||||
// } else {
|
||||
return colors[0]
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
return { layout, lang, menuWidth, setLang, setLayoutMode, setLayout, getColorVal, onSetLayoutColor }
|
||||
|
@ -3,26 +3,6 @@
|
||||
<el-container class="containerPart">
|
||||
<el-aside class="defaultAside">
|
||||
<el-main class="treeMain">
|
||||
<!-- <div class="demo-collapse">-->
|
||||
<!-- <el-collapse v-model="activeName" accordion>-->
|
||||
<!-- <el-collapse-item name="1">-->
|
||||
<!-- <template #title>-->
|
||||
<!-- <span class="collapse-title">枚举类型配置</span>-->
|
||||
<!-- </template>-->
|
||||
<!-- <div>-->
|
||||
<!-- <el-tree-->
|
||||
<!-- style="max-width: 600px;margin-top: 2.2%"-->
|
||||
<!-- ref="TypeTree"-->
|
||||
<!-- :data="TypeData"-->
|
||||
<!-- :props="defaultProps"-->
|
||||
<!-- node-key="id"-->
|
||||
<!-- @node-click="handleNodeClick"-->
|
||||
<!-- />-->
|
||||
<!-- </div>-->
|
||||
<!-- </el-collapse-item>-->
|
||||
<!-- </el-collapse>-->
|
||||
<!-- </div>-->
|
||||
<!-- <label class="treeTitle">枚举类型配置</label>-->
|
||||
<el-tree
|
||||
style="max-width: 600px;margin-top: 2.2%"
|
||||
ref="TypeTree"
|
||||
@ -93,7 +73,7 @@
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="visibleTypeAdd = false"> 取消 </el-button>
|
||||
<el-button @click="visibleTypeAdd = false">取消</el-button>
|
||||
<el-button type="primary" @click="onSubmitType">提交</el-button>
|
||||
</div>
|
||||
</template>
|
||||
@ -118,13 +98,16 @@
|
||||
<el-input-number :min="0" v-model="formInlineValue.orderNumber" placeholder="" />
|
||||
</el-form-item>
|
||||
<el-form-item label=" 是否有效:">
|
||||
<el-switch v-model="formInlineValue.isActive" />
|
||||
<el-switch @change="addhandleSwitchChange"
|
||||
:active-value="1"
|
||||
:inactive-value="0"
|
||||
v-model="formInlineValue.isActive" />
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="visibleValueAdd = false"> 取消 </el-button>
|
||||
<el-button @click="visibleValueAdd = false">取消</el-button>
|
||||
<el-button type="primary" @click="onSubmitvalue">提交</el-button>
|
||||
</div>
|
||||
</template>
|
||||
@ -139,7 +122,7 @@
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<!--查看枚举值-->
|
||||
<!--编辑枚举值-->
|
||||
<el-dialog v-model="visibleValueEdit" title="查看枚举值" width="500" :before-close="edithandleClosevalue">
|
||||
<el-form
|
||||
ref="formRef"
|
||||
@ -158,14 +141,17 @@
|
||||
<el-input-number :min="0" v-model="fromUpDate.orderNumber" placeholder="" />
|
||||
</el-form-item>
|
||||
<el-form-item label=" 是否有效:">
|
||||
<el-switch v-model="fromUpDate.isActive" />
|
||||
<el-switch @change="edithandleSwitchChange"
|
||||
:active-value="1"
|
||||
:inactive-value="0"
|
||||
v-model="fromUpDate.isActive" />
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="visibleValueEdit = false"> 取消 </el-button>
|
||||
<!-- <el-button type="primary" @click="onSubmitvalue">提交</el-button>-->
|
||||
<el-button type="primary" @click="EditonSubmitvalue">提交</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
@ -182,13 +168,10 @@ import {
|
||||
enumTreeQuery,
|
||||
enumTypeAdd,
|
||||
enumValueAdd,
|
||||
enumValueDelete
|
||||
enumValueDelete, enumValuepageEdit
|
||||
} from "/@/api/backend/Enumeration/request";
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const activeName = ref('1')
|
||||
interface Tree {
|
||||
enumId: number,
|
||||
@ -260,7 +243,6 @@ const handleNodeClick = (data: any) => {
|
||||
queryListData.description=queryName.value,
|
||||
queryListData.pageNum=currentPage.value,
|
||||
queryListData.pageSize=currentPageSize.value
|
||||
console.log(queryListData)
|
||||
queryenumValueMethod(queryListData)
|
||||
}
|
||||
|
||||
@ -385,13 +367,6 @@ const queryenumValueMethod = (data: any) => {
|
||||
const onSubmitvalue = () => {
|
||||
formRef.value.validate((valid: any) => {
|
||||
if (valid) {
|
||||
if(formInlineValue.isActive==true){
|
||||
formInlineValue.isActive=1
|
||||
}else{
|
||||
formInlineValue.isActive=0
|
||||
}
|
||||
|
||||
console.log(formInlineValue)
|
||||
enumValueAdd(formInlineValue).then((res: any) => {
|
||||
if (res.code == 200) {
|
||||
queryListData.description =queryName.value
|
||||
@ -459,40 +434,66 @@ const dialogVisibleDelete1 = (done: () => void) => {
|
||||
}
|
||||
})
|
||||
}
|
||||
// 菜单修改
|
||||
// 编辑枚举值
|
||||
const fromUpDate = reactive({
|
||||
id: '',
|
||||
enumTypeId: '',
|
||||
value:'',
|
||||
description : '',
|
||||
orderNumber: 0,
|
||||
isActive: false
|
||||
isActive: 0
|
||||
})
|
||||
const addhandleSwitchChange = (value: any) => {
|
||||
formInlineValue.isActive = value ? 1 : 0
|
||||
}
|
||||
const edithandleSwitchChange = (value: any) => {
|
||||
fromUpDate.isActive = value ? 1 : 0
|
||||
}
|
||||
const visibleValueEdit = ref(false)
|
||||
const enumValueEdit = (data: any) => {
|
||||
visibleValueEdit.value = true
|
||||
fromUpDate.id = data.row.id
|
||||
fromUpDate.enumTypeId = data.row.enumTypeId
|
||||
fromUpDate.enumTypeId = data.row.enumTypeIdStr
|
||||
fromUpDate.value = data.row.value
|
||||
fromUpDate.description = data.row.description
|
||||
fromUpDate.orderNumber = data.row.orderNumber
|
||||
if(data.row.isActive==1){
|
||||
fromUpDate.isActive = true
|
||||
}else{
|
||||
fromUpDate.isActive = false
|
||||
}
|
||||
fromUpDate.isActive = data.row.isActive
|
||||
|
||||
|
||||
}
|
||||
|
||||
const edithandleClosevalue = (done: () => void) => {
|
||||
visibleValueEdit.value = false
|
||||
}
|
||||
const EditonSubmitvalue = () => {
|
||||
formRef.value.validate((valid: any) => {
|
||||
if (valid) {
|
||||
enumValuepageEdit(fromUpDate).then((res: any) => {
|
||||
if (res.code == 200) {
|
||||
queryListData.description =queryName.value
|
||||
queryListData.enumTypeId = enumTypeId.value
|
||||
queryListData.pageNum=currentPage.value,
|
||||
queryListData.pageSize=currentPageSize.value
|
||||
queryenumValueMethod(queryListData)
|
||||
ElMessage({
|
||||
message: res.msg,
|
||||
type: 'success',
|
||||
})
|
||||
} else {
|
||||
ElMessage.error({
|
||||
message: res.msg,
|
||||
type: 'error',
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
visibleValueEdit.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
enumTreeTypeList()
|
||||
const firstNode = TypeTree.value.store.root.childNodes[0];
|
||||
/*if (firstNode) {
|
||||
handleNodeClick(firstNode.data, null, TypeTree.value);
|
||||
}*/
|
||||
})
|
||||
</script>
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
</el-form-item>
|
||||
<el-form-item prop="iotModelCode" :label="ModelFieldsEnums['iotModelCode']">
|
||||
<el-input
|
||||
:disabled="modelDialogState === ModelDialogTitleStateType['detail']"
|
||||
:disabled="!(modelDialogState === ModelDialogTitleStateType['add'])"
|
||||
v-model="modelForm.iotModelCode"
|
||||
:placeholder="'请输入' + ModelFieldsEnums['iotModelCode']"
|
||||
></el-input>
|
||||
@ -960,7 +960,7 @@ const downLoadModel = () => {
|
||||
}
|
||||
|
||||
const currentPage = ref(1)
|
||||
const currentPageSize = ref(10)
|
||||
const currentPageSize = ref(20)
|
||||
const pageTotal = ref(0)
|
||||
const pagePagination = ref([10, 20, 30])
|
||||
const getcurrentPage = () => {
|
||||
|
@ -379,9 +379,9 @@ const getInstitutionList = (data: getDataType = { name: null }) => {
|
||||
})
|
||||
}
|
||||
|
||||
const pagePagination = [5, 10, 20, 30]
|
||||
const pagePagination = [ 10, 20, 30]
|
||||
const currentPage = ref(1)
|
||||
const currentPageSize = ref(pagePagination[0])
|
||||
const currentPageSize = ref(pagePagination[1])
|
||||
const pageTotal = ref(0)
|
||||
const originData = ref<getTreeDataReturnType[]>()
|
||||
const tableData = computed(() => {
|
||||
|
@ -203,9 +203,9 @@ const tableData = computed(() => {
|
||||
return originData.value?.slice(start, end)
|
||||
})
|
||||
|
||||
const pagePagination = [5, 10, 20, 30]
|
||||
const pagePagination = [10, 20, 30]
|
||||
const currentPage = ref(1)
|
||||
const currentPageSize = ref(pagePagination[0])
|
||||
const currentPageSize = ref(pagePagination[1])
|
||||
const pageTotal = ref(0)
|
||||
const originData = ref<tableDataType<authorityDataListType>[]>()
|
||||
const addClick = () => {
|
||||
|
@ -546,9 +546,9 @@ const selectUpdataName = (data: string) => {
|
||||
formUserUpData.profilePicture = data
|
||||
}
|
||||
// 分页
|
||||
const pagePagination = [5, 10, 20, 30]
|
||||
const pagePagination = [ 10, 20, 30]
|
||||
const currentPage = ref(1)
|
||||
const currentPageSize = ref(pagePagination[0])
|
||||
const currentPageSize = ref(pagePagination[1])
|
||||
const handleSizeChange = (val: number) => {
|
||||
formQuery.pageSize = val
|
||||
RyUserQuery(formQuery)
|
||||
|
@ -0,0 +1,274 @@
|
||||
<template>
|
||||
<div class="controlPage" v-loading="loading" element-loading-text="提交中...">
|
||||
<h1 class="pageName">遥调遥控调试</h1>
|
||||
<div class="control">
|
||||
<el-form :model="serviceType147Form" :rules="validData(147)" ref="serviceType147Ref">
|
||||
<el-row>
|
||||
<el-col :span="2">
|
||||
<div class="title">遥控</div>
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<div class="center">
|
||||
<el-form-item label="服务名" prop="serviceName">
|
||||
<el-select v-model="serviceType147Form.serviceName" placeholder="请选择服务名">
|
||||
<el-option
|
||||
v-for="item in deviceServiceType147List"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="7" :offset="1">
|
||||
<el-form-item label="设定值" prop="opValue">
|
||||
<el-select v-model="serviceType147Form.opValue" placeholder="请选择设定值">
|
||||
<el-option :value="0"></el-option>
|
||||
<el-option :value="1"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="2" :offset="1">
|
||||
<el-button type="primary" @click="submit(147)">提交</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<br />
|
||||
<el-form :model="serviceType146Form" :rules="validData(146)" ref="serviceType146Ref">
|
||||
<el-row>
|
||||
<el-col :span="2">
|
||||
<div class="title">遥调</div>
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<div class="center">
|
||||
<el-form-item label="服务名" prop="serviceName">
|
||||
<el-select v-model="serviceType146Form.serviceName" placeholder="请选择服务名">
|
||||
<el-option
|
||||
v-for="item in deviceServiceType146List"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="7" :offset="1">
|
||||
<el-form-item label="设定值" prop="opValue">
|
||||
<el-input v-model="serviceType146Form.opValue" placeholder="请输入设定值"> </el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="2" :offset="1">
|
||||
<el-button type="primary" @click="submit(146)">提交</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</div>
|
||||
<div style="height: 20px"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue'
|
||||
import { sendValueReq } from '/@/api/backend/control/request'
|
||||
import { ElMessage, FormInstance } from 'element-plus'
|
||||
import { getModelServiceListReq } from '/@/api/backend/deviceModel/request'
|
||||
|
||||
const props = defineProps({
|
||||
iotModelId: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
deviceId: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
})
|
||||
|
||||
const loading = ref(false)
|
||||
|
||||
const serviceType147Ref = ref<FormInstance>()
|
||||
const serviceType146Ref = ref<FormInstance>()
|
||||
const serviceType147Form = ref({
|
||||
//节点ID
|
||||
nodeId: '1',
|
||||
//服务名
|
||||
serviceName: '',
|
||||
//操作值
|
||||
opValue: null,
|
||||
})
|
||||
|
||||
const serviceType146Form = ref({
|
||||
//节点ID
|
||||
nodeId: '1',
|
||||
//服务名
|
||||
serviceName: '',
|
||||
//操作值
|
||||
opValue: null,
|
||||
})
|
||||
|
||||
const deviceServiceType147List = ref<any[]>([])
|
||||
const deviceServiceType146List = ref<any[]>([])
|
||||
|
||||
const init = () => {
|
||||
getModelServiceListReq({ iotModelId: props.iotModelId, pageNum: 1, pageSize: 100000 }).then((res) => {
|
||||
const type147: { label: string; value: string }[] = []
|
||||
const type146: { label: string; value: string }[] = []
|
||||
res.rows.forEach((item) => {
|
||||
if (item.serviceType === 147) {
|
||||
type147.push({ label: item.serviceName, value: item.serviceCode })
|
||||
} else if (item.serviceType === 146) {
|
||||
type146.push({ label: item.serviceName, value: item.serviceCode })
|
||||
}
|
||||
})
|
||||
deviceServiceType147List.value = type147
|
||||
deviceServiceType146List.value = type146
|
||||
})
|
||||
}
|
||||
|
||||
const validData = (type: number) => {
|
||||
if (type === 147) {
|
||||
return {
|
||||
serviceName: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入服务名',
|
||||
trigger: 'change',
|
||||
},
|
||||
],
|
||||
opValue: [
|
||||
{
|
||||
required: true,
|
||||
message: '请选择操作值',
|
||||
trigger: 'change',
|
||||
},
|
||||
],
|
||||
}
|
||||
} else if (type === 146) {
|
||||
return {
|
||||
serviceName: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入服务名',
|
||||
trigger: 'change',
|
||||
},
|
||||
],
|
||||
opValue: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入操作值',
|
||||
trigger: 'blur',
|
||||
},
|
||||
{
|
||||
pattern: /^[0-9]+$/,
|
||||
message: '请输入数字',
|
||||
trigger: 'blur',
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
}
|
||||
const submit = (type: number) => {
|
||||
if (type === 147) {
|
||||
serviceType147Ref.value?.validate((valid) => {
|
||||
if (valid) {
|
||||
loading.value = true
|
||||
sendValue(serviceType147Form.value)
|
||||
}
|
||||
})
|
||||
} else if (type === 146) {
|
||||
serviceType146Ref.value?.validate((valid) => {
|
||||
if (valid) {
|
||||
loading.value = true
|
||||
sendValue(serviceType146Form.value)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const sendValue = (data: any) => {
|
||||
const val = JSON.parse(JSON.stringify(data))
|
||||
val.deviceId = props.deviceId
|
||||
sendValueReq(val)
|
||||
.then((res) => {
|
||||
console.log(res)
|
||||
ElMessage.success('发送成功!')
|
||||
})
|
||||
.catch((err) => {
|
||||
ElMessage.error('发送失败!')
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.deviceId,
|
||||
() => {
|
||||
if (props.iotModelId) {
|
||||
init()
|
||||
} else {
|
||||
deviceServiceType147List.value = []
|
||||
deviceServiceType146List.value = []
|
||||
}
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
}
|
||||
)
|
||||
watch(
|
||||
() => props.show,
|
||||
(newVal) => {
|
||||
if (newVal) {
|
||||
serviceType147Form.value = {
|
||||
nodeId: '1',
|
||||
serviceName: '',
|
||||
opValue: null,
|
||||
}
|
||||
serviceType146Form.value = {
|
||||
nodeId: '1',
|
||||
serviceName: '',
|
||||
opValue: null,
|
||||
}
|
||||
serviceType147Ref.value?.resetFields()
|
||||
serviceType146Ref.value?.resetFields()
|
||||
}
|
||||
}
|
||||
)
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.controlPage {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
// justify-content: center;
|
||||
font-size: 18px;
|
||||
.pageName {
|
||||
margin: 20px auto;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
.control {
|
||||
width: 100%;
|
||||
height: 100px;
|
||||
.title {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.el-form-item {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -49,9 +49,13 @@
|
||||
<el-table-column property="model" label="规格型号" />
|
||||
<el-table-column property="address" label="操作">
|
||||
<template #default="scope">
|
||||
<span style="color: #0064aa; cursor: pointer" @click="viewDeviceDetails(scope)">查看 </span>
|
||||
<span style="color: #0064aa; cursor: pointer" @click="openMeasure(scope)">量测</span>
|
||||
<span style="color: #0064aa"> | </span>
|
||||
<span style="color: #0064aa; cursor: pointer" @click="deviceDeletion(scope)"> 删除 </span>
|
||||
<span style="color: #0064aa; cursor: pointer" @click="openControl(scope)">调控</span>
|
||||
<span style="color: #0064aa"> | </span>
|
||||
<span style="color: #0064aa; cursor: pointer" @click="viewDeviceDetails(scope)">查看</span>
|
||||
<span style="color: #0064aa"> | </span>
|
||||
<span style="color: #0064aa; cursor: pointer" @click="deviceDeletion(scope)">删除</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@ -418,11 +422,39 @@
|
||||
</template>
|
||||
</el-dialog>
|
||||
</el-container>
|
||||
<el-dialog v-model="showControlPage" :width="800">
|
||||
<div class="controlSlot">
|
||||
<ControlPage :deviceId="contorlData.deviceId" :iotModelId="contorlData.iotModelId" :show="showControlPage"></ControlPage>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<el-dialog v-model="showMeasure" title="量测" :width="800">
|
||||
<template #header>
|
||||
<div class="measureSlotHeader">
|
||||
<span style="font-size: 20px">量测</span>
|
||||
<div class="measureSlotHeaderRight">
|
||||
<span>自动更新:</span>
|
||||
<el-switch
|
||||
v-model="measureData.autoUpdate"
|
||||
class="ml-2"
|
||||
style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949"
|
||||
></el-switch>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<div class="measureSlot">
|
||||
<MeasurementPage
|
||||
:show="showMeasure"
|
||||
:deviceId="measureData.deviceId"
|
||||
:iotModelId="measureData.iotModelId"
|
||||
:autoUpdate="measureData.autoUpdate"
|
||||
></MeasurementPage>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted, nextTick } from 'vue'
|
||||
import { ref, reactive, onMounted, nextTick, watch } from 'vue'
|
||||
import { Search, CirclePlusFilled, Upload, Download } from '@element-plus/icons-vue'
|
||||
import {
|
||||
equipTree,
|
||||
@ -437,9 +469,10 @@ import {
|
||||
equipDetailsOrg,
|
||||
} from '/@/api/backend'
|
||||
import { ElTable, ElMessage, ElMessageBox } from 'element-plus'
|
||||
import type Node from 'element-plus/es/components/tree/src/model/node'
|
||||
import { useAdminInfo } from '/@/stores/adminInfo'
|
||||
import { encrypt_aes, generateRandomNumber } from '/@/utils/crypto'
|
||||
import ControlPage from './control.vue'
|
||||
import MeasurementPage from './measurement.vue'
|
||||
|
||||
const adminInfo = useAdminInfo()
|
||||
interface Tree {
|
||||
@ -615,9 +648,9 @@ const deviceTypeQuery = () => {
|
||||
}
|
||||
|
||||
// 分页
|
||||
const pagePagination = [5, 10, 20, 30]
|
||||
const pagePagination = [10, 20, 30]
|
||||
const currentPage = ref(1)
|
||||
const currentPageSize = ref(pagePagination[0])
|
||||
const currentPageSize = ref(pagePagination[1])
|
||||
const handleSizeChange = (val: number) => {
|
||||
formQuery.pageSize = val
|
||||
deviceQuery(formQuery)
|
||||
@ -939,6 +972,43 @@ const Export = () => {
|
||||
document.body.removeChild(a)
|
||||
})
|
||||
}
|
||||
|
||||
const showControlPage = ref(false)
|
||||
const contorlData = reactive({
|
||||
deviceId: '',
|
||||
iotModelId: '',
|
||||
})
|
||||
const openControl = (data: any) => {
|
||||
contorlData.deviceId = data.row.id
|
||||
contorlData.iotModelId = data.row.iotModelId
|
||||
if (contorlData.iotModelId) {
|
||||
showControlPage.value = true
|
||||
} else {
|
||||
ElMessage.warning('该设备没有绑定物模型!')
|
||||
}
|
||||
}
|
||||
|
||||
const measureData = reactive({
|
||||
deviceId: '',
|
||||
iotModelId: '',
|
||||
autoUpdate: false,
|
||||
})
|
||||
const showMeasure = ref(false)
|
||||
const openMeasure = (data: any) => {
|
||||
measureData.deviceId = data.row.id
|
||||
measureData.iotModelId = data.row.iotModelId
|
||||
if (measureData.iotModelId) {
|
||||
showMeasure.value = true
|
||||
} else {
|
||||
ElMessage.warning('该设备没有绑定物模型!')
|
||||
}
|
||||
}
|
||||
watch(
|
||||
showMeasure,
|
||||
(newVal: boolean) => {
|
||||
!newVal && (measureData.autoUpdate = false)
|
||||
}
|
||||
)
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@ -1030,4 +1100,10 @@ $paginationHeight: 32px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.measureSlotHeader {
|
||||
display: flex;
|
||||
.measureSlotHeaderRight {
|
||||
margin-left: 20px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -0,0 +1,233 @@
|
||||
<template>
|
||||
<div class="measurement">
|
||||
<el-table :columns="tableColumn" :data="tableData" @sort-change="sortChange" max-height="495">
|
||||
<el-table-column
|
||||
v-for="item in tableColumn"
|
||||
:key="item.prop"
|
||||
:label="item.label"
|
||||
:prop="item.prop"
|
||||
:width="item.width ?? ''"
|
||||
:align="item.align"
|
||||
:sortable="item.sortable"
|
||||
>
|
||||
<template #default="scope">
|
||||
<div v-if="item.prop === 'realTimeValue'">
|
||||
<el-button @click="openChart(scope.row)" text type="primary">{{ scope.row.realTimeValue }}</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div>
|
||||
<el-pagination
|
||||
v-model:current-page="pageSetting.current"
|
||||
v-model:page-size="pageSetting.pageSize"
|
||||
:total="pageSetting.total"
|
||||
:page-sizes="pageSetting.pageSizes"
|
||||
background
|
||||
:pager-count="7"
|
||||
layout="prev, pager, next, jumper,sizes,total"
|
||||
@change="getcurrentPage"
|
||||
></el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref, watch } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import type { ModelAttributeFieldsEnums, GetModelAttributeType } from '/@/views/backend/auth/model/type'
|
||||
import { getModelAttributeListReq, getRealValueListReq } 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,
|
||||
},
|
||||
})
|
||||
|
||||
const tableColumn = [
|
||||
{
|
||||
label: '序号',
|
||||
prop: 'porder',
|
||||
width: 76,
|
||||
align: 'center',
|
||||
sortable:'custom'
|
||||
},
|
||||
{
|
||||
label: '属性名称',
|
||||
prop: 'attributeName',
|
||||
align: 'left',
|
||||
sortable:'custom'
|
||||
},
|
||||
{
|
||||
label: '属性编码',
|
||||
prop: 'attributeCode',
|
||||
align: 'left',
|
||||
width: 200,
|
||||
sortable:'custom'
|
||||
},
|
||||
{
|
||||
label: '子系统',
|
||||
prop: 'subSystem',
|
||||
align: 'left',
|
||||
width: 110,
|
||||
sortable:false
|
||||
},
|
||||
{
|
||||
label: '实时值',
|
||||
prop: 'realTimeValue',
|
||||
width: 140,
|
||||
align: 'center',
|
||||
sortable:false
|
||||
},
|
||||
]
|
||||
const tableData = ref<any[]>([])
|
||||
|
||||
const getAttributeList = () => {
|
||||
const requestData: GetModelAttributeType = {
|
||||
iotModelId: props.iotModelId,
|
||||
pageNum: pageSetting.current,
|
||||
pageSize: pageSetting.pageSize,
|
||||
orderColumn: sortData.orderColumn,
|
||||
orderType: sortData.orderType,
|
||||
}
|
||||
|
||||
return new Promise((resolve) => {
|
||||
getModelAttributeListReq(requestData)
|
||||
.then((res) => {
|
||||
if (res.rows && res.rows.length > 0) {
|
||||
const codeList: any = []
|
||||
const data = res.rows!.map((item) => {
|
||||
codeList.push(item.attributeCode)
|
||||
return {
|
||||
...item,
|
||||
attributeTypeName:
|
||||
item.attributeType === 138
|
||||
? '模拟量'
|
||||
: item.attributeType === 139
|
||||
? '累积量'
|
||||
: item.attributeType === 140
|
||||
? '离散量'
|
||||
: item.attributeType!,
|
||||
}
|
||||
})
|
||||
pageSetting.total = res.total
|
||||
resolve({ data, codeList })
|
||||
} else {
|
||||
if (res.rows && res.rows.length === 0) {
|
||||
tableData.value = []
|
||||
} else {
|
||||
ElMessage.error(res.msg)
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
ElMessage.error(err?.response?.data?.msg ?? '查询失败')
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const getRealValueList = (data: { deviceId: string; attributes: string[] }, list?: any) => {
|
||||
return new Promise((resolve) => {
|
||||
getRealValueListReq([data]).then((res) => {
|
||||
if (res.success && res.data) {
|
||||
resolve({ realVal: res.data, list })
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const getCompleteData = () => {
|
||||
getAttributeList()
|
||||
.then(({ data, codeList }: any) => {
|
||||
return getRealValueList({ deviceId: props.deviceId, attributes: codeList }, data)
|
||||
})
|
||||
.then((realData: any) => {
|
||||
const data = realData.list.map((item: any) => {
|
||||
const realValItem = realData.realVal[props.deviceId]?.[item.attributeCode] ?? '-'
|
||||
return {
|
||||
...item,
|
||||
realTimeValue: realValItem % 1 === 0 ? realValItem : realValItem.toFixed(3),
|
||||
}
|
||||
})
|
||||
|
||||
tableData.value = data
|
||||
})
|
||||
}
|
||||
|
||||
const sortData = reactive<{ orderColumn?: keyof typeof ModelAttributeFieldsEnums; orderType?: 'asc' | 'desc' }>({
|
||||
orderColumn: 'porder',
|
||||
orderType: 'asc',
|
||||
})
|
||||
|
||||
const sortChange = ({ prop, order }: { prop: keyof typeof ModelAttributeFieldsEnums; order: 'ascending' | 'descending' | null }) => {
|
||||
const propEnums = {
|
||||
attributeCode: 'attribute_code',
|
||||
attributeName: 'attribute_name',
|
||||
attributeTypeName: 'attribute_type',
|
||||
porder: 'porder',
|
||||
serviceCode: 'service_code',
|
||||
serviceName: 'service_name',
|
||||
serviceTypeName: 'service_type',
|
||||
}
|
||||
const orderType = order === 'ascending' ? 'asc' : order === 'descending' ? 'desc' : undefined
|
||||
const filed = propEnums[prop as keyof typeof propEnums] as keyof typeof ModelAttributeFieldsEnums
|
||||
sortData.orderColumn = orderType ? filed : undefined
|
||||
sortData.orderType = orderType
|
||||
getCompleteData()
|
||||
}
|
||||
|
||||
const pageSetting = reactive({
|
||||
current: 1,
|
||||
pageSize: 20,
|
||||
total: 0,
|
||||
pageSizes: [10, 20, 30],
|
||||
})
|
||||
|
||||
const getcurrentPage = () => {
|
||||
getCompleteData()
|
||||
}
|
||||
|
||||
const openChart = (data: any) => {}
|
||||
|
||||
watch(
|
||||
() => props.show,
|
||||
(newVal) => {
|
||||
newVal && getCompleteData()
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
}
|
||||
)
|
||||
let autoUpdateTimer: any = null
|
||||
watch(
|
||||
() => props.autoUpdate,
|
||||
(newVal) => {
|
||||
if (newVal) {
|
||||
if (!autoUpdateTimer) {
|
||||
autoUpdateTimer = setInterval(() => {
|
||||
console.log('刷新')
|
||||
getCompleteData()
|
||||
}, 2000)
|
||||
}
|
||||
} else {
|
||||
clearInterval(autoUpdateTimer)
|
||||
autoUpdateTimer = null
|
||||
}
|
||||
}
|
||||
)
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
237
ui/dasadmin/src/views/backend/home/windMatrix.vue
Normal file
@ -0,0 +1,237 @@
|
||||
<template>
|
||||
<div class="FanList-content">
|
||||
<el-row :gutter="10">
|
||||
<el-col :span="8" v-for="(item, index) in FanList" style="margin-bottom: 10px;">
|
||||
<div class="grid-content ep-bg-purple">
|
||||
<div class="FanList-panel" :class="item.standard==true ? 'wind-mark' : 'wind-default'">
|
||||
<div class="fanlist-top">
|
||||
<span :class="item.standard==true ? 'wind-mark-icon' : 'fanlist-icon'">
|
||||
<img :class="item.standard==true ? '' : 'wind-picture'" src="~assets/dashboard/biaogan.png" alt="">
|
||||
</span>
|
||||
<span class="fanlist-name"> {{ item.windTurbine }}</span>
|
||||
<el-tag class="tag-panel" :class="getItemClass(item)" type="primary">{{ item.windStatus }}</el-tag>
|
||||
</div>
|
||||
<div class="fanlist-main">
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<div class="fanlist-pic">
|
||||
<!-- <div class="mask">
|
||||
<div class="leafs">
|
||||
<div class="leaf_1"></div>
|
||||
<div class="leaf_2"></div>
|
||||
<div class="leaf_3"></div>
|
||||
</div>
|
||||
</div>-->
|
||||
<img src="~assets/dashboard/fanlist1.png" alt="">
|
||||
<!-- <img class="fc" src="~assets/dashboard/fanlist1.png" alt=""></img>-->
|
||||
<!-- <img :style="{ transform: `rotate(${rotationDegrees}deg)` }" src="~assets/dashboard/fanlist1.png" alt="">-->
|
||||
</div>
|
||||
<div class="fanlist-pic">
|
||||
<img src="~assets/dashboard/fanlist2.png" alt="">
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row class="fanlist-data">
|
||||
<el-col :span="8">
|
||||
<div class="fanlist-text"><span class="content-number">{{ item.windSpeed }}</span><span>风速m/s</span></div>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<div class="fanlist-text"><span class="content-number">{{ item.power }}</span><span>功率MW</span></div>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<div class="fanlist-text"><span class="content-number">{{ item.dayGeneration }}</span><span>日发电量kWh</span></div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref ,onMounted,onUnmounted } from 'vue'
|
||||
|
||||
const FanList = ref([
|
||||
{windSpeed:'10.34','power':'10.34','dayGeneration':'10.34',windStatus:'并网',windTurbine:'A-001',standard:true},
|
||||
{windSpeed:'34','power':'10.34','dayGeneration':'10.34',windStatus:'待机',windTurbine:'A-002',standard:false},
|
||||
{windSpeed:'11','power':'10.34','dayGeneration':'10.34',windStatus:'启动',windTurbine:'A-003',standard:false},
|
||||
{windSpeed:'45','power':'10.34','dayGeneration':'10.34',windStatus:'解缆',windTurbine:'A-004',standard:false},
|
||||
{windSpeed:'12','power':'10.34','dayGeneration':'10.34',windStatus:'电网故障停机',windTurbine:'A-005',standard:false},
|
||||
{windSpeed:'10','power':'10.34','dayGeneration':'10.34',windStatus:'维护',windTurbine:'A-006',standard:false}
|
||||
])
|
||||
|
||||
const getItemClass = (FanList) => {
|
||||
switch (FanList.windStatus) {
|
||||
case '并网':
|
||||
return 'is-primary';
|
||||
case '并网- AGC限功率':
|
||||
return 'is-primary';
|
||||
case '解缆':
|
||||
return 'is-info';
|
||||
case '待机':
|
||||
return 'is-warning';
|
||||
case '故障':
|
||||
return 'is-warning';
|
||||
case '启动':
|
||||
return 'is-success';
|
||||
case '电网故障停机':
|
||||
return 'is-danger';
|
||||
case '风速超限停机':
|
||||
return 'is-danger';
|
||||
case '故障停机':
|
||||
return 'is-danger';
|
||||
case '塔基手动停机':
|
||||
return 'is-danger';
|
||||
case '远程监控停机':
|
||||
return 'is-danger';
|
||||
case 'AGC停机':
|
||||
return 'is-danger';
|
||||
case '集控停机':
|
||||
return 'is-danger';
|
||||
case '小风停机':
|
||||
return 'is-danger';
|
||||
case '维护':
|
||||
return 'is-maintenance';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
return { FanList, getItemClass };
|
||||
};
|
||||
|
||||
const rotationDegrees = ref(0)
|
||||
const speed = 5; // 设定一个基本旋转速度
|
||||
function startRotation(speed) {
|
||||
return setInterval(() => {
|
||||
rotationDegrees.value += 100;
|
||||
}, 100); // 每100毫秒旋转一次
|
||||
}
|
||||
let intervalId;
|
||||
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
// 当组件挂载时开始旋转
|
||||
intervalId = startRotation(speed);
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
// 当组件卸载时清除定时器
|
||||
clearInterval(intervalId);
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.wind-mark{
|
||||
background-image: linear-gradient(140deg, #FFE3E3 0%, #FFFFFF 93%);
|
||||
border: 1px solid #FFE3E3;
|
||||
}
|
||||
.wind-default{
|
||||
background-image: linear-gradient(180deg, #F0F6FF 0%, #FFFFFF 50%);
|
||||
border: 1px solid #E1EDF6;
|
||||
}
|
||||
.wind-picture{
|
||||
display: none;
|
||||
}
|
||||
.wind-mark-icon{
|
||||
background: #FFFFFF;
|
||||
border: 1px solid #FFE3E3;
|
||||
border-radius: 8px 0 100px 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.FanList-panel{
|
||||
border-radius: 8px;
|
||||
.fanlist-top{
|
||||
display: flex;
|
||||
width: 100%;
|
||||
}
|
||||
.fanlist-icon{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.fanlist-name{
|
||||
width: 100%;
|
||||
margin-top: 5px;
|
||||
}
|
||||
.tag-panel{
|
||||
border-radius: 0 8px 0 0;
|
||||
line-height: 20px;
|
||||
}
|
||||
.is-primary{
|
||||
background: rgba(2,119,179,0.20);
|
||||
border: 1px solid #0277B3;
|
||||
color: #0277B3;
|
||||
}
|
||||
.is-success{
|
||||
background: rgba(6,180,41,0.20);
|
||||
border: 1px solid #06B429;
|
||||
color: #06B429;
|
||||
}
|
||||
.is-info{
|
||||
background: rgba(48,89,236,0.20);
|
||||
border: 1px solid #3059EC;
|
||||
color: #3059EC;
|
||||
}
|
||||
.is-warning{
|
||||
background: rgba(255,126,0,0.20);
|
||||
border: 1px solid #FF7E00;
|
||||
color: #FF7E00;
|
||||
}
|
||||
.is-danger{
|
||||
background: rgba(254,55,49,0.20);
|
||||
border: 1px solid #FE3731;
|
||||
color: #FE3731;
|
||||
}
|
||||
.is-offline{
|
||||
background: rgba(153,153,153,0.20);
|
||||
border: 1px solid #999999;
|
||||
color: #999999;
|
||||
}
|
||||
.is-maintenance{
|
||||
background: rgba(0,160,150,0.20);
|
||||
border: 1px solid #00A096;
|
||||
color: #00A096;
|
||||
}
|
||||
.fanlist-main{
|
||||
width: 100%;
|
||||
display: flex;
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
.fanlist-pic{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-top: -10px;
|
||||
.mask{
|
||||
width: 43px;
|
||||
height: 38px;
|
||||
}
|
||||
}
|
||||
.fanlist-text{
|
||||
margin-top:30px;
|
||||
.content-number{
|
||||
color: #333333;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
}
|
||||
.fanlist-text span{
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</style>
|
459
ui/dasadmin/src/views/backend/linkMonitor/index.vue
Normal file
@ -0,0 +1,459 @@
|
||||
<template>
|
||||
<div class="linkMonitor">
|
||||
<el-container class="containerPart">
|
||||
<el-aside class="asidePart">
|
||||
<el-header class="asideHeader">
|
||||
<el-input
|
||||
v-model="searchLinkTreeInputValue"
|
||||
:suffix-icon="Search"
|
||||
clearable
|
||||
@input="debounceSearchLinkTree"
|
||||
placeholder="搜索"
|
||||
class="searchLinkTreeInput"
|
||||
></el-input>
|
||||
</el-header>
|
||||
<el-main class="treeMain">
|
||||
<el-tree
|
||||
ref="linkTreeRef"
|
||||
node-key="id"
|
||||
:data="treeData"
|
||||
@node-click="linkTreeNodeClick"
|
||||
@node-expand="linkTreeNodeExpand"
|
||||
@node-collapse="linkTreeNodeCollapse"
|
||||
:props="LinkTreePropReplace"
|
||||
class="treePart"
|
||||
highlight-current
|
||||
:render-content="renderContent"
|
||||
:default-expanded-keys="linkTreeNodeExpandKeys"
|
||||
>
|
||||
<!-- <template #default="{ node, data }">
|
||||
<span>{{ node.label }}</span>
|
||||
</template> -->
|
||||
</el-tree>
|
||||
</el-main>
|
||||
</el-aside>
|
||||
<el-container class="mainContainer">
|
||||
<el-header class="mainHeader">
|
||||
<div class="mainHeaderCenter">
|
||||
<el-input clearable placeholder="请输入链路名称" class="linkMonitorInput" v-model="linkMonitorInputValue"></el-input>
|
||||
<el-button :icon="Search" type="primary" @click="searchLinkMonitor">查询</el-button>
|
||||
</div>
|
||||
</el-header>
|
||||
<el-main class="mainMain">
|
||||
<div class="tabsPart">
|
||||
<el-table :data="linkMonitorTableData" class="tablePart" highlight-current-row>
|
||||
<el-table-column prop="linkName" :label="LinkMonitorFieldsEnums['linkName']" align="left"> </el-table-column>
|
||||
<el-table-column prop="status" :label="LinkMonitorFieldsEnums['status']" align="center" width="80">
|
||||
<template #default="scope">
|
||||
<div class="status-container">
|
||||
<span
|
||||
:class="{
|
||||
'status-dot-online': !scope.row.status,
|
||||
'status-dot-offline': scope.row.status,
|
||||
}"
|
||||
></span>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="protocolName" :label="LinkMonitorFieldsEnums['protocolName']" align="center">
|
||||
<template #default="scope"> </template>
|
||||
</el-table-column>
|
||||
<!-- <el-table-column prop="remoteRegulation" :label="LinkMonitorFieldsEnums['remoteRegulation']" align="center">
|
||||
<template #default="scope">
|
||||
<span style="cursor: pointer; color: #0064aa; font-weight: 600">查看参数</span>
|
||||
</template>
|
||||
</el-table-column> -->
|
||||
<el-table-column label="操作" width="200" align="center">
|
||||
<template #default="scope">
|
||||
<div class="tableOperate">
|
||||
<a @click="opneLog(scope.row)">日志</a>
|
||||
<a>|</a>
|
||||
<a @click="startLink(scope.row)">启动</a>
|
||||
<a>|</a>
|
||||
<el-popconfirm title="确定停止么?" @confirm="stopLink(scope.row)">
|
||||
<template #reference>
|
||||
<a style="color: red">停止</a>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="mainFooter">
|
||||
<el-pagination
|
||||
v-model:current-page="paginationOptions.current"
|
||||
v-model:page-size="paginationOptions.pageSize"
|
||||
:total="paginationOptions.total"
|
||||
:page-sizes="paginationOptions.pageSizes"
|
||||
background
|
||||
:pager-count="7"
|
||||
layout="prev, pager, next, jumper,sizes,total"
|
||||
@change="getcurrentPage"
|
||||
></el-pagination>
|
||||
</div>
|
||||
</el-main>
|
||||
</el-container>
|
||||
</el-container>
|
||||
<el-dialog v-model="linkLogVisible" title="日志" @close="closeLinklog" :width="900">
|
||||
<template #footer> </template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref, nextTick } from 'vue'
|
||||
import { ElContainer, ElAside, ElHeader, ElMain, ElTree, ElInput, ElMessage, ElButton, ElTable, TreeInstance } from 'element-plus'
|
||||
import { Search } from '@element-plus/icons-vue'
|
||||
import { LinkMonitorFieldsEnums, LinkMonitorTreeType, LinkMonitorTableType } from './type'
|
||||
import { getNodeListReq, getLinkListReq } from '/@/api/backend/linkMonitor/request'
|
||||
import { debounce, cloneDeep } from 'lodash'
|
||||
|
||||
const LinkTreePropReplace = {
|
||||
label: 'nodeName',
|
||||
children: 'children',
|
||||
}
|
||||
const linkTreeRef = ref<TreeInstance>()
|
||||
const treeData = ref<LinkMonitorTreeType[]>([])
|
||||
const originTreeData = ref<LinkMonitorTreeType[]>([])
|
||||
const curContextMenuTreeData = ref<LinkMonitorTreeType>()
|
||||
const searchLinkTreeInputValue = ref('')
|
||||
const getlinkTreeList = () => {
|
||||
return new Promise((resolve) => {
|
||||
getNodeListReq()
|
||||
.then((res) => {
|
||||
if (res.success) {
|
||||
originTreeData.value = res.data!
|
||||
treeData.value = res.data!
|
||||
// originTreeData.value = res.data!
|
||||
// const other = [
|
||||
// {
|
||||
// id: '5555',
|
||||
// nodeName: '鱼丸吃人111112222222222222222222222222222222',
|
||||
// nodeIp: '',
|
||||
// orgName: '',
|
||||
// orgId: '',
|
||||
// revision: 0,
|
||||
// children: [
|
||||
// {
|
||||
// id: '1111',
|
||||
// nodeName: '鱼丸吃人22222',
|
||||
// nodeIp: '',
|
||||
// orgName: '',
|
||||
// orgId: '',
|
||||
// revision: 0,
|
||||
// children: [],
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// ]
|
||||
// originTreeData.value[0].children = [...other]
|
||||
// originTreeData.value[1] = {
|
||||
// id: '55654',
|
||||
// nodeName: '鱼丸吃人33',
|
||||
// nodeIp: '',
|
||||
// orgName: '',
|
||||
// orgId: '',
|
||||
// revision: 0,
|
||||
// children: [
|
||||
// {
|
||||
// id: '324232',
|
||||
// nodeName: '鱼丸吃人11',
|
||||
// nodeIp: '',
|
||||
// orgName: '',
|
||||
// orgId: '',
|
||||
// revision: 0,
|
||||
// children: [],
|
||||
// },
|
||||
// ],
|
||||
// }
|
||||
// const tree: LinkMonitorTreeType[] = [...originTreeData.value]
|
||||
// treeData.value = tree
|
||||
|
||||
resolve(res.data![0])
|
||||
} else {
|
||||
ElMessage.error(res.msg)
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
ElMessage.error(err?.response?.data?.msg ?? '查询失败')
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
getlinkTreeList().then((res) => {
|
||||
curContextMenuTreeData.value = cloneDeep(res as LinkMonitorTreeType)
|
||||
linkTreeRef.value?.setCurrentKey(curContextMenuTreeData.value!.id!)
|
||||
getlinkMonitorList(curContextMenuTreeData.value!.id!, linkMonitorInputValue.value)
|
||||
})
|
||||
|
||||
const searchLinkTree = () => {
|
||||
if (searchLinkTreeInputValue.value === '') {
|
||||
treeData.value = originTreeData.value
|
||||
nextTick(() => {
|
||||
linkTreeRef.value?.setCurrentKey(curContextMenuTreeData.value!.id!)
|
||||
})
|
||||
return
|
||||
}
|
||||
treeData.value = filterAndHighlightTreeArray(cloneDeep(originTreeData.value), searchLinkTreeInputValue.value) as LinkMonitorTreeType[]
|
||||
linkTreeNodeExpandKeys.value = Array.from(new Set([...linkTreeNodeExpandKeys.value, ...getAllIds(treeData.value)]))
|
||||
nextTick(() => {
|
||||
linkTreeRef.value?.setCurrentKey(curContextMenuTreeData.value!.id!)
|
||||
})
|
||||
}
|
||||
const getAllIds = (nodes: LinkMonitorTreeType[]) => {
|
||||
let ids: any = []
|
||||
nodes.forEach((node) => {
|
||||
ids.push(node.id)
|
||||
if (node.children && node.children.length > 0) {
|
||||
ids = ids.concat(getAllIds(node.children))
|
||||
}
|
||||
})
|
||||
return ids
|
||||
}
|
||||
const filterAndHighlightTreeArray = (treeArray: LinkMonitorTreeType[], searchQuery: string) => {
|
||||
return treeArray.map((tree: LinkMonitorTreeType) => filterAndHighlightTree(tree, searchQuery)).filter(Boolean)
|
||||
}
|
||||
const filterAndHighlightTree = (tree: LinkMonitorTreeType, searchQuery: string): (LinkMonitorTreeType & { isMatch?: boolean }) | null => {
|
||||
const isMatch = tree.nodeName.toLowerCase().includes(searchQuery.toLowerCase())
|
||||
if (isMatch) {
|
||||
return {
|
||||
...tree,
|
||||
children: tree?.children?.map((child) => filterAndHighlightTree(child, searchQuery)).filter(Boolean) as LinkMonitorTreeType[],
|
||||
isMatch: true,
|
||||
}
|
||||
}
|
||||
if (tree.children && tree.children.length > 0) {
|
||||
const filteredChildren = tree.children.map((child) => filterAndHighlightTree(child, searchQuery)).filter(Boolean) as LinkMonitorTreeType[]
|
||||
|
||||
if (filteredChildren.length > 0) {
|
||||
return { ...tree, children: filteredChildren }
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
const debounceSearchLinkTree = debounce(searchLinkTree, 200)
|
||||
|
||||
const linkTreeNodeExpandKeys = ref([] as any)
|
||||
const linkTreeNodeExpand = (node: any) => {
|
||||
if (!linkTreeNodeExpandKeys.value.includes(node.id)) {
|
||||
linkTreeNodeExpandKeys.value.push(node.id)
|
||||
}
|
||||
}
|
||||
const linkTreeNodeCollapse = (node: any) => {
|
||||
const index = linkTreeNodeExpandKeys.value.indexOf(node.id)
|
||||
if (index > -1) {
|
||||
linkTreeNodeExpandKeys.value.splice(index, 1)
|
||||
}
|
||||
}
|
||||
const linkTreeNodeClick = (target: LinkMonitorTreeType) => {
|
||||
curContextMenuTreeData.value = cloneDeep(target)
|
||||
getlinkMonitorList(curContextMenuTreeData.value!.id!, linkMonitorInputValue.value)
|
||||
}
|
||||
const renderContent = (h: any, { node, data }: any) => {
|
||||
const label = node.label || ''
|
||||
const searchTerm = searchLinkTreeInputValue.value.toLowerCase()
|
||||
const startIndex = label.toLowerCase().indexOf(searchTerm)
|
||||
if (startIndex === -1) {
|
||||
return h('span', {}, label)
|
||||
}
|
||||
const beforeMatch = label.substring(0, startIndex)
|
||||
const matchText = label.substring(startIndex, startIndex + searchLinkTreeInputValue.value.length)
|
||||
const afterMatch = label.substring(startIndex + searchLinkTreeInputValue.value.length)
|
||||
return h('span', {}, [beforeMatch, h('span', { style: { color: '#f14c4c', fontWeight: 'bold' } }, matchText), afterMatch])
|
||||
}
|
||||
const linkMonitorInputValue = ref('')
|
||||
const searchLinkMonitor = () => {
|
||||
if (linkMonitorInputValue.value === '') {
|
||||
getlinkMonitorList(curContextMenuTreeData.value!.id!)
|
||||
return
|
||||
}
|
||||
getlinkMonitorList(curContextMenuTreeData.value!.id!, linkMonitorInputValue.value)
|
||||
}
|
||||
|
||||
const linkMonitorTableData = ref<LinkMonitorTableType[]>([])
|
||||
|
||||
// 链路监视列表
|
||||
const paginationOptions = reactive({
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
pageSizes: [10, 20, 30],
|
||||
})
|
||||
const getcurrentPage = () => {
|
||||
getlinkMonitorList(curContextMenuTreeData.value!.id!, linkMonitorInputValue.value)
|
||||
}
|
||||
const protocolList = [
|
||||
{ label: 'IEC104主 *', value: 8 },
|
||||
{ label: 'IEC104从 *', value: 9 },
|
||||
{ label: 'MODBUSRTU主 *', value: 12 },
|
||||
{ label: 'MODBUSTCP主 *', value: 16 },
|
||||
]
|
||||
const getlinkMonitorList = (nodeId: string, linkName?: string) => {
|
||||
getLinkListReq({ nodeId, linkName, pageNum: paginationOptions.current, pageSize: paginationOptions.pageSize })
|
||||
.then((res) => {
|
||||
if (res.rows) {
|
||||
linkMonitorTableData.value = res.rows.map((item) => {
|
||||
return {
|
||||
...item,
|
||||
protocolName: protocolList.find((i) => i.value === item.protocol)?.label,
|
||||
}
|
||||
})
|
||||
paginationOptions.total = res.total
|
||||
} else {
|
||||
ElMessage.error(res.msg ?? '查询失败')
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
ElMessage.error(err?.response?.data?.msg ?? '查询失败')
|
||||
})
|
||||
}
|
||||
|
||||
const linkLogVisible = ref(false)
|
||||
const closeLinklog = () => {
|
||||
linkLogVisible.value = false
|
||||
}
|
||||
const opneLog = (val: LinkMonitorTableType) => {
|
||||
// linkLogVisible.value = true
|
||||
}
|
||||
const startLink = (val: LinkMonitorTableType) => {
|
||||
console.log('startLink')
|
||||
}
|
||||
const stopLink = (val: LinkMonitorTableType) => {
|
||||
console.log('stopLink')
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
$headerHeight: 60px;
|
||||
$defaultBackgroundColor: #fff;
|
||||
$defaultAsideWidth: 260px;
|
||||
$paginationHeight: 32px;
|
||||
.linkMonitor {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
.containerPart {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
.asidePart {
|
||||
width: $defaultAsideWidth;
|
||||
height: 100%;
|
||||
border-right: 1px solid #eaebed;
|
||||
.asideHeader {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
.searchLinkTreeInput {
|
||||
height: 40px;
|
||||
}
|
||||
}
|
||||
.treeMain {
|
||||
height: calc(100% - $headerHeight);
|
||||
overflow-y: auto;
|
||||
|
||||
.treePart {
|
||||
min-width: 100%;
|
||||
overflow: auto;
|
||||
display: inline-block;
|
||||
background-color: $defaultBackgroundColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
.mainContainer {
|
||||
width: calc(100% - $defaultAsideWidth);
|
||||
height: 100%;
|
||||
.mainHeader {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: $headerHeight;
|
||||
padding: 0 20px;
|
||||
border-bottom: 1px solid #eaebed;
|
||||
.linkMonitorInput {
|
||||
height: 40px;
|
||||
width: 220px;
|
||||
}
|
||||
.mainHeaderCenter {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 320px;
|
||||
}
|
||||
}
|
||||
.mainMain {
|
||||
height: calc(100% - $headerHeight);
|
||||
.tabsPart {
|
||||
height: calc(100% - $paginationHeight);
|
||||
padding-bottom: 5px;
|
||||
:deep(.el-tabs__content) {
|
||||
height: calc(100% - 55px);
|
||||
.el-tab-pane {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
.tablePart {
|
||||
height: 100%;
|
||||
}
|
||||
.tableOperate {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
a {
|
||||
margin: 5px;
|
||||
color: #0064aa;
|
||||
font-weight: 600;
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.mainFooter {
|
||||
display: flex;
|
||||
justify-content: right;
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.modelOperate {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 80px;
|
||||
height: 150px;
|
||||
.el-button {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 状态
|
||||
.status-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.status-dot-online,
|
||||
.status-dot-offline {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.status-dot-online {
|
||||
background-color: #06b429;
|
||||
}
|
||||
|
||||
.status-dot-offline {
|
||||
background-color: red;
|
||||
}
|
||||
.highlight {
|
||||
background-color: yellow; /* 高亮背景颜色 */
|
||||
color: red; /* 字体颜色 */
|
||||
font-weight: bold; /* 加粗字体 */
|
||||
}
|
||||
</style>
|
45
ui/dasadmin/src/views/backend/linkMonitor/type.ts
Normal file
@ -0,0 +1,45 @@
|
||||
export type RequestReturnType<T = never> = Promise<{
|
||||
code: number
|
||||
msg: string
|
||||
success: boolean
|
||||
data?: T
|
||||
}>
|
||||
|
||||
export type RequestReturnRowType<T = never> = Promise<{
|
||||
code: number
|
||||
msg: string
|
||||
rows: T
|
||||
total: number
|
||||
}>
|
||||
export type LinkMonitorTreeType = {
|
||||
id?: string
|
||||
nodeName: string
|
||||
nodeIp: string
|
||||
orgName?: string
|
||||
orgId: string
|
||||
revision?: number
|
||||
children?: LinkMonitorTreeType[]
|
||||
}
|
||||
export type LinkMonitorTableType = {
|
||||
id?: string
|
||||
linkName: string
|
||||
protocol?: number
|
||||
protocolName?: string
|
||||
params: string
|
||||
nodeName: string
|
||||
nodeId: string
|
||||
revision: number
|
||||
}
|
||||
export type GetLinkMonitorTableParam = {
|
||||
nodeId: string
|
||||
linkName?: string
|
||||
pageNum: number
|
||||
pageSize: number
|
||||
}
|
||||
|
||||
export enum LinkMonitorFieldsEnums {
|
||||
'id' = 'id',
|
||||
'linkName' = '链路名称',
|
||||
'status' = '状态',
|
||||
'protocolName' = '协议类型',
|
||||
}
|
@ -103,7 +103,8 @@ let timer: number
|
||||
|
||||
const config = useConfig()
|
||||
const adminInfo = useAdminInfo()
|
||||
toggleDark(config.layout.isDark)
|
||||
|
||||
// TODO 切换暗黑 toggleDark(config.layout.isDark)
|
||||
|
||||
const formRef = ref<FormInstance>()
|
||||
const usernameRef = ref<InputInstance>()
|
||||
|
@ -484,7 +484,7 @@ const submitLinkForm = () => {
|
||||
|
||||
const paginationOptions = reactive({
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
pageSize: 20,
|
||||
total: 0,
|
||||
pageSizes: [10, 20, 30],
|
||||
})
|
||||
|