This commit is contained in:
高云鹏 2024-10-30 14:05:14 +08:00
commit 35531ea3d3
13 changed files with 1610 additions and 862 deletions

View File

@ -5,10 +5,8 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
import com.das.modules.auth.mapper.BaseMapperPlus;
import com.das.modules.equipment.domain.dto.SysEquipmentDto;
import com.das.modules.equipment.domain.excel.SysEquipmentExcel;
import com.das.modules.equipment.domain.vo.BaseImptabmappingVo;
import com.das.modules.equipment.domain.vo.SysEquipmentVo;
import com.das.modules.equipment.entity.SysEquipment;
import com.das.modules.page.domian.WindTurbinesPageVo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@ -16,8 +14,13 @@ import java.util.List;
@Mapper
public interface SysEquipmentMapper extends BaseMapperPlus<SysEquipment, SysEquipment> {
IPage<SysEquipmentVo> querySysEquipmentList(IPage<SysEquipmentVo> page, @Param("info") SysEquipmentDto sysEquipmentDto);
/**
* 分页查询设备列表
* @param page 分页信息
* @param sysEquipmentDto 查询条件
* @return 返回值
*/
IPage<SysEquipmentVo> queryEquipmentListInPage(IPage<SysEquipmentVo> page, @Param("info") SysEquipmentDto sysEquipmentDto);
/**
* 查询根设备列表
@ -25,7 +28,12 @@ public interface SysEquipmentMapper extends BaseMapperPlus<SysEquipment, SysEqui
*/
List<SysEquipmentVo> queryRootEquipments();
List<SysEquipmentExcel> queryInfoById (@Param("info") SysEquipmentDto sysEquipmentDto);
/**
* 导出设备信息
* @param sysEquipmentDto 查询条件
* @return SysEquipmentExcel 列表
*/
List<SysEquipmentExcel> queryExportExcelInfo(@Param("info") SysEquipmentDto sysEquipmentDto);
Long queryChildEquipmentCount(@Param("id")Long id);
@ -35,11 +43,16 @@ public interface SysEquipmentMapper extends BaseMapperPlus<SysEquipment, SysEqui
SysEquipmentVo queryEquipmentInfoByCode(@Param("code")String code);
List<String> queryBelongLines(@Param("objectType") Long objectType);
List<String> queryBelongLines(@Param("objectType") Integer objectType);
List<SysEquipmentVo> querySysEquipmentList(@Param("info") SysEquipmentDto sysEquipmentDto);
List<SysEquipmentVo> queryEquipmentListInPage(@Param("info") SysEquipmentDto sysEquipmentDto);
SysEquipmentVo queryWindFarm(@Param("info") SysEquipmentDto sysEquipmentDto);
/**
* 查询设备列表
* @param sysEquipmentDto 查询条件
* @return
*/
List<SysEquipmentVo> queryEquipmentList(@Param("info") SysEquipmentDto sysEquipmentDto);
}

View File

@ -117,7 +117,7 @@ public class SysEquipmentServiceImpl implements SysEquipmentService {
PageQuery pageQuery = new PageQuery();
pageQuery.setPageNum(sysEquipmentDto.getPageNum());
pageQuery.setPageSize(sysEquipmentDto.getPageSize());
IPage<SysEquipmentVo> iPage = sysEquipmentMapper.querySysEquipmentList(pageQuery.build(), sysEquipmentDto);
IPage<SysEquipmentVo> iPage = sysEquipmentMapper.queryEquipmentListInPage(pageQuery.build(), sysEquipmentDto);
return PageDataInfo.build(iPage.getRecords(), iPage.getTotal());
}
@ -145,9 +145,15 @@ public class SysEquipmentServiceImpl implements SysEquipmentService {
return equipList;
}
/**
* 设备台账导出Excel
* @param sysEquipmentDto 查询参数
* @param request HttpServletRequest
* @param response HttpServletResponse
*/
@Override
public void exportSysEquipment(SysEquipmentDto sysEquipmentDto, HttpServletRequest request, HttpServletResponse response) {
List<SysEquipmentExcel> sysEquipmentList = sysEquipmentMapper.queryInfoById(sysEquipmentDto);
List<SysEquipmentExcel> sysEquipmentList = sysEquipmentMapper.queryExportExcelInfo(sysEquipmentDto);
//自定义别名 别名的key和实体类中的名称要对应上
LinkedHashMap<String, String> map = new LinkedHashMap<>();
map.put("tag", "*标识I新增U修改D删除");

View File

@ -80,7 +80,7 @@ public class TDEngineService {
}
sb.append(") TAGS (`deviceid` BIGINT);");
try {
System.out.println(sb.toString());
log.info(sb.toString());
pstmt.executeUpdate(sb.toString());
} catch (Exception e) {
log.error("创建超级表失败,失败原因{}", e);
@ -353,6 +353,9 @@ public class TDEngineService {
}
Map<String, Map<String, Map<String, Object>>> result = new HashMap<>();
Map<String, Map<String, Object>> valueMap = new HashMap<>();
for (String item : fieldList){
valueMap.put(item,null);
}
StringBuffer sb = new StringBuffer(2048);
if (StrUtil.isNotBlank(interval)) {
String startTimeStr = SIMPLE_DATE_FORMAT.format(startTime);
@ -392,7 +395,7 @@ public class TDEngineService {
List<Long> timeList = new ArrayList<>();
timeList.add(rs.getTimestamp(1).getTime());
List<Object> valueList = new ArrayList<>();
valueList.add(rs.getObject(fieldList.get(i)));
valueList.add(rs.getObject(fieldList.get(i).toLowerCase()));
map.put("times",timeList);
map.put("values",valueList);
valueMap.put(fieldList.get(i),map);
@ -401,7 +404,7 @@ public class TDEngineService {
List<Long> times = (List<Long>) map.get("times");
List<Object> values = (List<Object>) map.get("values");
times.add(rs.getTimestamp(1).getTime());
values.add(rs.getObject(fieldList.get(i)));
values.add(rs.getObject(fieldList.get(i).toLowerCase()));
}
}
}
@ -423,6 +426,9 @@ public class TDEngineService {
}
Map<String, Map<String, Map<String, Object>>> result = new HashMap<>();
Map<String, Map<String, Object>> valueMap = new HashMap<>();
for (String item : fieldList){
valueMap.put(item,null);
}
StringBuffer sb = new StringBuffer(2048);
if (StrUtil.isNotBlank(interval)) {
String startTimeStr = SIMPLE_DATE_FORMAT.format(startTime);

View File

@ -196,6 +196,7 @@ public class DataServiceImpl implements DataService {
configUpdateVo.setVersion(1);
configUpdateVo.setLinks(links);
configUpdateVo.setEquipments(equipments);
log.info("下发配置为{}",configUpdateVo);
JsonNode jsonNode = JSON_MAPPER.valueToTree(configUpdateVo);
long time = System.currentTimeMillis();

View File

@ -237,6 +237,7 @@ public class SysNodeServiceImpl implements SysNodeService {
List<SysTabMapping> addList = new ArrayList<>();
List<SysTabMapping> updateList = new ArrayList<>();
//过滤已经存在的记录
Set<Long> PassedMappingIds = new HashSet<>();
@ -264,6 +265,13 @@ public class SysNodeServiceImpl implements SysNodeService {
if(mappingVoMap.containsKey(key)){
SysTabMappingVo item = mappingVoMap.get(key);
PassedMappingIds.add(item.getId());
SysTabMapping mapping = sysImptabmappingMapper.selectById(item.getId());
mapping.setMeasPointName(iotModelVo.getAttributeName());
mapping.setHighSpeed(iotModelVo.getHighSpeed());
mapping.setPorder(iotModelVo.getPorder());
updateList.add(mapping);
}else{
SysTabMapping mapping = new SysTabMapping();
mapping.setId(SequenceUtils.generateId());
@ -297,6 +305,11 @@ public class SysNodeServiceImpl implements SysNodeService {
if(mappingVoMap.containsKey(key)){
SysTabMappingVo item = mappingVoMap.get(key);
PassedMappingIds.add(item.getId());
SysTabMapping mapping = sysImptabmappingMapper.selectById(item.getId());
mapping.setMeasPointName(iotServiceVo.getServiceName());
mapping.setPorder(iotServiceVo.getPorder());
updateList.add(mapping);
}else{
SysTabMapping mapping = new SysTabMapping();
mapping.setId(SequenceUtils.generateId());
@ -317,6 +330,9 @@ public class SysNodeServiceImpl implements SysNodeService {
if (!CollectionUtils.isEmpty(addList)) {
sysImptabmappingMapper.insertOrUpdateBatch(addList);
}
if (!CollectionUtils.isEmpty(updateList)) {
sysImptabmappingMapper.insertOrUpdateBatch(updateList);
}
//删除为匹配的历史配置
for(SysTabMappingVo item : mappingVoMap.values()){

View File

@ -1,5 +1,6 @@
package com.das.modules.page.service;
import com.das.common.constant.EquipmentTypeIds;
import com.das.common.exceptions.ServiceException;
import com.das.modules.data.domain.SnapshotValueQueryParam;
import com.das.modules.data.service.DataService;
@ -24,7 +25,6 @@ import java.util.concurrent.TimeUnit;
@Service
@Slf4j
public class WindTurbinesPageService {
private static final Integer OBJECT_TYPE = 10002;
@Autowired
SysEquipmentMapper sysEquipmentMapper;
@ -41,7 +41,7 @@ public class WindTurbinesPageService {
* @return 返回字符串数组
*/
public List<String> queryBelongLines() {
return sysEquipmentMapper.queryBelongLines(Long.valueOf(OBJECT_TYPE));
return sysEquipmentMapper.queryBelongLines(EquipmentTypeIds.EQUIPMENT_TYPE_STATION_WTG);
}
@ -54,8 +54,8 @@ public class WindTurbinesPageService {
StopWatch stopWatch = new StopWatch();
stopWatch.start("获取风机页面数据");
SysEquipmentDto sysEquipmentDto = new SysEquipmentDto();
sysEquipmentDto.setObjectType(OBJECT_TYPE);
List<SysEquipmentVo> sysEquipmentVos = sysEquipmentMapper.querySysEquipmentList(sysEquipmentDto);
sysEquipmentDto.setObjectType(EquipmentTypeIds.EQUIPMENT_TYPE_STATION_WTG);
List<SysEquipmentVo> sysEquipmentVos = sysEquipmentMapper.queryEquipmentListInPage(sysEquipmentDto);
//风机返回数据列表
List<WindTurbinesPageVo> windTurbinesPageVos = new ArrayList<>();
List<SnapshotValueQueryParam> paramList = new ArrayList<>();

View File

@ -27,6 +27,9 @@ public class HomeServiceImpl implements HomeService {
@Autowired
private DataService dataService;
//缺省风电场对象
private long defaultWindFarmId = 0;
/**
* 接口1 首页风机矩阵数据
@ -38,7 +41,7 @@ public class HomeServiceImpl implements HomeService {
SysEquipmentDto sysEquipmentDto = new SysEquipmentDto();
sysEquipmentDto.setObjectType(EquipmentTypeIds.EQUIPMENT_TYPE_STATION_WTG);
//获取所有风机设备
List<SysEquipmentVo> sysEquipmentVos = sysEquipmentMapper.querySysEquipmentList(sysEquipmentDto);
List<SysEquipmentVo> sysEquipmentVos = sysEquipmentMapper.queryEquipmentListInPage(sysEquipmentDto);
//风机返回数据列表
List<HomeWindTurbineMatrixDataVoVo> homeWindRealTimeVoList = new ArrayList<>();
List<SnapshotValueQueryParam> paramList = new ArrayList<>();
@ -98,10 +101,20 @@ public class HomeServiceImpl implements HomeService {
Long windFarmId = windFarmRealDataDto.getWindFarmId();
//查询数据库中风电场设备取第一个风电场
if (windFarmId == null) {
SysEquipmentDto sysEquipmentDto = new SysEquipmentDto();
sysEquipmentDto.setObjectType(EquipmentTypeIds.EQUIPMENT_TYPE_WIND_FARM);
SysEquipmentVo sysEquipmentVo1 = sysEquipmentMapper.queryWindFarm(sysEquipmentDto);
windFarmId = sysEquipmentVo1.getId();
if(defaultWindFarmId ==0){
SysEquipmentDto sysEquipmentDto = new SysEquipmentDto();
sysEquipmentDto.setObjectType(EquipmentTypeIds.EQUIPMENT_TYPE_WIND_FARM);
List<SysEquipmentVo> list = sysEquipmentMapper.queryEquipmentList(sysEquipmentDto);
if(!list.isEmpty()){
defaultWindFarmId = list.get(0).getId();
}
}
if(defaultWindFarmId==0){
throw new RuntimeException("系统中没有风电场台账信息");
}
windFarmId = defaultWindFarmId;
}
List<SnapshotValueQueryParam> paramList = new ArrayList<>();
//构建需要查询的物模型属

View File

@ -64,7 +64,7 @@
</resultMap>
<select id="querySysEquipmentList" resultMap="SysEquipmentMap">
<select id="queryEquipmentListInPage" resultMap="SysEquipmentMap">
select t.* from sys_equipment t
<where>
<if test="info.iotModelId != null and info.iotModelId != ''">
@ -99,7 +99,7 @@
</select>
<select id="queryInfoById" resultMap="SysEquipmentExcelMap">
<select id="queryExportExcelInfo" resultMap="SysEquipmentExcelMap">
select t.*,se."name" as parentEquipmentName,sim.iot_model_name as iotModelName,
sim.iot_model_code, so."name" as orgName,
so.mrid,se.code as parentEquipmentCode from sys_equipment t
@ -135,13 +135,13 @@
select * from sys_equipment where code = #{code}
</select>
<select id="queryBelongLines" resultType="java.lang.String">
select distinct belong_line as name from sys_equipment t where t.object_type = 10002 and belong_line !='';
select distinct belong_line as name from sys_equipment t where t.object_type = 10002 and belong_line !='' order by belong_line;
</select>
<select id="queryAllWindList" resultType="com.das.modules.page.domian.WindTurbinesPageVo">
select se.id as irn,se.name,se.model,se.belong_line as belongLine, se.iot_model_id as modelId from sys_equipment se where se.object_type = #{objectType} order by se.name
</select>
<select id="queryWindFarm" resultMap="SysEquipmentMap">
<select id="queryEquipmentList" resultMap="SysEquipmentMap">
select t.* from sys_equipment t
<where>
<if test="info.iotModelId != null and info.iotModelId != ''">
@ -167,7 +167,6 @@
</if>
</where>
order by t.name
limit 1
</select>
</mapper>

File diff suppressed because it is too large Load Diff

View File

@ -18,7 +18,8 @@
:data="modalTbleData"
@selectionChange="selectTable"
:row-key="getRowKey">
<el-table-column type="selection" width="55" :reserve-selection="true"/>
<!-- <el-table-column type="selection" width="55" :reserve-selection="true"/>-->
<el-table-column type="selection" width="55"/>
<el-table-column prop="porder" label="序号" width="60" />
<el-table-column prop="attributeCode" sortable label="名称" />
<el-table-column prop="attributeName" sortable label="描述" />
@ -54,6 +55,7 @@
<div>
<el-icon :size="20" @click="moveUp(index)"><Top /></el-icon>
<el-icon :size="20" @click="moveDown(index)"><Bottom /></el-icon>
<el-icon :size="20" @click="removeremove(index, item)"><Close /></el-icon>
</div>
</div>
</el-scrollbar>
@ -110,7 +112,7 @@
</template>
<script setup lang="ts">
import {Crop,Download,Top,Bottom} from '@element-plus/icons-vue'
import {Crop,Download,Top,Bottom,Close} from '@element-plus/icons-vue'
import {onMounted, onUnmounted, reactive, ref, watch,computed,nextTick} from 'vue'
import {ElMessage} from 'element-plus'
import {equipList,getModelAttributeList,getsnapshotData} from "/@/api/backend/realData/request.ts";
@ -123,7 +125,8 @@ const tableItem0: any = [
prop: 'code',
align: 'center',
custom: 'default',
name:''
name:'',
title: '风机列表'
}]
const tableItem1: any = [
{
@ -195,7 +198,7 @@ const tableItem1: any = [
prop: 'itempnacelle_1sec',
align: 'center',
custom: 'header',
name:'iItemPnAcelle_1Sec',
name:'iTempNacelle_1sec',
title: '机舱温度'
},
{
@ -281,6 +284,7 @@ const defaultdeviceQuery = () => {
return acc;
}, [...tableData.value]);
tableData.value = updatedTableData;
debugger;
} else {
ElMessage.error({
message: res.msg,
@ -299,7 +303,8 @@ const modelAttributeList=(data: any) =>{
getModelAttributeList(data).then((res) => {
if (res.code == 200) {
modalTbleData.value = res.rows
pageTotal.value = res.total
pageTotal.value = res.total;
} else {
ElMessage.error({
message: res.msg,
@ -331,35 +336,47 @@ const selectList=ref([])
const getSel = () => {
debugger
selectList.value=[]
tableColumn.value.forEach(item => {
if (item.prop) {
if(item.prop!='code'){
selectList.value.push({
attributeName: item.title,
attributeCode: item.name,
});
try {
if (tableColumn.value && Array.isArray(tableColumn.value)) {
for (const item of tableColumn.value) {
if (item && item.prop && item.prop !== 'code') {
if(item.title!==undefined){
selectList.value.push({
attributeName: item.title || '',
attributeCode: item.name || '',
unit: item.unit || '',
});
}
}
}
}
});
//tableRef.value.clearSelection()
} catch (error) {
console.error('Error in tableColumn processing:', error);
}
multipleSelection.value=selectList.value
/*tableRef.value.clearSelection()
if (selectList.value.length > 0) {
//setTimeout(()=>{
selectList.value.forEach((item1, index1) => {
tableRef.value.toggleRowSelection(item1, true);
tableRef.value.toggleRowSelection(item1, undefined, true);
});
//},0)
}
}*/
};
const tableRef=ref()
let isCheckRow = false;
const tableRef=ref<any>()
const multipleSelection = ref<TableType[]>([])
const Statistic = computed(() => multipleSelection.value.length)
const selectTable = (selected: TableType[] | null) => {
// if (isCheckRow) {
// isCheckRow = false;
// return;
// }
if (!selected) {
console.error('Selected is null or undefined')
return
}
if (Array.isArray(selected) && Array.isArray(multipleSelection.value)) {
/* if (Array.isArray(selected) && Array.isArray(multipleSelection.value)) {
const selectedAttributeCodes = new Set(selected.map(item => item?.attributeCode));
multipleSelection.value = multipleSelection.value.filter(item => selectedAttributeCodes.has(item?.attributeCode));
selected.forEach((item, index) => {
@ -367,8 +384,35 @@ const selectTable = (selected: TableType[] | null) => {
multipleSelection.value.push(item);
}
});
}
//multipleSelection.value = selected
}*/
//const selectedAttributeCodes = new Set(selected.map(item => item?.attributeCode));
//multipleSelection.value = multipleSelection.value.filter(item => selectedAttributeCodes.has(item?.attributeCode));
selected.forEach((item, index) => {
if (!multipleSelection.value.some(item1 => item1.attributeCode === item.attributeCode)) {
multipleSelection.value.push(item);
//ElMessage.success(``)
}
/*else{
ElMessage.warning(`当前页面中已存在${item.attributeName}`)
}*/
});
//const selectedCopy = multipleSelection.value;
/*if(multipleSelection.value.length>0){
multipleSelection.value = JSON.parse(JSON.stringify(selected));
}*/
//multipleSelection.value = JSON.parse(JSON.stringify(selected));
// selected.forEach((item, index) => {
// multipleSelection.value.push({...item});
// });
// if (Array.isArray(selected) && Array.isArray(multipleSelection.value)) {
// const selectedAttributeCodes = new Set(selected.map(item => item?.attributeCode));
// multipleSelection.value = multipleSelection.value.filter(item => selectedAttributeCodes.has(item?.attributeCode));
// selected.forEach((item, index) => {
// if (!multipleSelection.value.some(item1 => item1.attributeCode === item.attributeCode)) {
// multipleSelection.value.push(item);
// }
// });
// }
}
//const getRowKey = (row) => row.id;
const getRowKey = (row) => row.attributeCode;
@ -401,6 +445,25 @@ const moveDown = (index:number) => {
selectedIndex.value = index + 1;
}
};
const removeremove=(index:number, row:any)=>{
multipleSelection.value.splice(index, 1);
// const row = multipleSelection.value.splice(index, 1);
nextTick(() => {
isCheckRow = true;
const finIindexNum = modalTbleData.value.findIndex((item: any) => item.attributeCode === row.attributeCode);
if (finIindexNum !== -1) {
tableRef.value.toggleRowSelection(modalTbleData.value[finIindexNum], false, false);
ElMessage.success('删除成功')
} else {
ElMessage.warning(`当前页面中不存在${row.attributeName},请切换到别的分页操作`)
}
//selectTable(row)
})
//selectTable(multipleSelection.value)
//tableRef.value.clearSelection()
}
const clearList=() => {
Statistic.value=0
multipleSelection.value = [];
@ -472,10 +535,9 @@ const objparms = reactive({
const getTableData = () => {
debugger
const deviceId=deviceList.value.map((item) => item.id);
const tableColumnEnds = ref([]);
const tableColumnup = ref([]);
/*const tableColumnup = ref([]);
const tableColumnMap = new Map();
tableColumn.value.forEach(item1 => {
if (item1.prop) {
@ -488,7 +550,7 @@ const getTableData = () => {
custom: 'header',
});
}
});
});*/
if(multipleSelection.value.length === 0){
tableColumn.value = [...tableItem0, ...tableColumnEnds.value];
}else{
@ -503,6 +565,8 @@ const getTableData = () => {
prop: 'ipitchangle',
align: 'center',
custom: 'header',
name: 'ipitchangle',
title: '变桨角度',
});
}else{
tableColumnEnds.value.push({
@ -533,7 +597,9 @@ const getTableData = () => {
getsnapshotData(snapshotParms).then((res) => {
if (res.code == 200) {
const tsnapshotVoObject: any = res.data;
console.log(multipleSelection.value, tsnapshotVoObject, tableData.value, 'multipleSelection.valuemultipleSelection.value');
multipleSelection.value.map((item1: any) => {
// const newItem: any = { };
tableData.value.forEach((item: any, i: number, arr: any) => {
for (const itemKey in tsnapshotVoObject) {
if (item.id === itemKey) {
@ -546,13 +612,22 @@ const getTableData = () => {
}else{
ipitchanglevalue=ipitchangle1 !== undefined ? (ipitchangle1 % 1 === 0 ? ipitchangle1 : ipitchangle1.toFixed(3)) : '-';
}
// for (const rowKey in item) {
// if (attributeCodeLower == rowKey) {
// newItem[rowKey] = item[rowKey];
// }
// }
// console.log(newItem, item1, 'newItemnewItemnewItem')
const value = tsnapshotVoObject[itemKey]?.[attributeCodeLower];
const formattedValue =value ? (value % 1 === 0 ? value : value.toFixed(3)) : '-';
//console.log(tsnapshotVoObject[itemKey], value, 'valuevaluevaluevalue');
const formattedValue = value !== undefined ? (value % 1 === 0 ? value : value.toFixed(3)) : '-';
//arr[i] = { code: item.code, [attributeCodeLower]: formattedValue,[ipitchangle]: ipitchanglevalue};
arr[i] = { ...item, [attributeCodeLower]: formattedValue,[ipitchangle]: ipitchanglevalue};
}
}
});
})
//console.log(tableData.value, multipleSelection.value, 'tableData.valuetableData.valuetableData.valuetableData.value');
} else {
ElMessage.error({
message: res.msg,
@ -572,12 +647,77 @@ const downFun=(tableColumn,tableData)=>{
const { id, belongLine, iotModelId, location,madeinFactory,model,name,nominalCapacity,objectType,parentEquipmentId,remarks,standard,...rest } = item;
return rest;
});
debugger;
/*let itemsWithoutAge;
tableColumn.forEach(item1 => {
if (item1.prop) {
tableData.forEach((item: any, i: number) => {
for (const itemKey in item) {
if(item1.prop!=='code'){
if(item1.prop==itemKey){
/!*itemsWithoutAge=tableData.map(item => {
const {
id,
belongLine,
iotModelId,
location,
madeinFactory,
model,
name,
nominalCapacity,
objectType,
parentEquipmentId,
remarks,
standard,
igenpower,
igenspeed,
ihydrpress,
ikwhoverall,
ikwhthisday,
ipitchangle,
irotorspeed,
iwindspeed,
itempnacelle_1sec,
ipitchangle1,
...rest
} = item;
return rest;
});*!/
}else{
itemsWithoutAge=tableData.map(item => {
const {
id,
belongLine,
iotModelId,
location,
madeinFactory,
model,
name,
nominalCapacity,
objectType,
parentEquipmentId,
remarks,
standard,
...rest
} = item;
return rest;
});
}
}
}
});
}
})*/
let addobj = {}
tableColumn.map((v, i) => {
addobj['rowData' + i] = v.label
})
let tableDatadown = JSON.parse(JSON.stringify(itemsWithoutAge))
tableDatadown.unshift(addobj)
console.log(tableDatadown, 'tableDatadowntableDatadowntableDatadown')
debugger;
let str = ``;
for(let i = 0; i < tableDatadown.length; i++) {
for(let item in tableDatadown[i]) {
@ -601,14 +741,11 @@ const downFun=(tableColumn,tableData)=>{
onUnmounted(() => {
autoUpdateInterval.value && clearInterval(autoUpdateInterval.value)
autoUpdateInterval.value = null
//selectList.value=[]
})
onMounted(() => {
deviceQuery(devicelistData)
//queryListData.pageSize=200
modelAttributeList(queryListData)
//tableRef.value.toggleRowSelection(modalTbleData.value[0], true);
})
</script>

View File

@ -11,11 +11,7 @@
:sortable="item.sortable"
>
<template #default="scope">
<el-radio
v-if="item.prop === 'index'"
:label="scope.$index"
v-model="selectedIndex"
@change="handleRadioChange(scope.$index, scope.row)"
<el-radio v-if="item.prop === 'index'" :label="scope.row.id" v-model="selectedIndex" @change="handleRadioChange(scope.row)"
>&nbsp;</el-radio
>
</template>
@ -94,12 +90,11 @@ const tableColumn = [
]
const tableData = ref<any[]>([])
const emit = defineEmits(['handleRadioChange'])
const handleRadioChange = (index, row) => {
const handleRadioChange = (row) => {
selectedIndex.value = row.id
emit('handleRadioChange', row)
console.log(row)
}
const getAttributeList = () => {
console.log(props)
const requestData: GetModelAttributeType = {
iotModelId: props.iotModelId,
pageNum: pageSetting.current,
@ -108,8 +103,6 @@ const getAttributeList = () => {
orderColumn: sortData.orderColumn,
orderType: sortData.orderType,
}
console.log('🚀 ~ getAttributeList ~ requestData:', requestData)
console.log(requestData)
return new Promise((resolve) => {
getModelAttributeListReq(requestData)
.then((res) => {
@ -161,8 +154,6 @@ const getCompleteData = () => {
return getRealValueList({ deviceId: props.deviceId, attributes: codeList }, data)
})
.then((realData: any) => {
console.log(realData)
const data = realData.list.map((item: any) => {
const realValItem = realData.realVal[props.deviceId]?.[item.attributeCode?.toLowerCase()]
return {

View File

@ -3,414 +3,24 @@
<el-menu :default-active="activeIndex" class="headerList" mode="horizontal" @select="handleSelect">
<el-menu-item v-for="(item, index) in headerList" :index="index" :key="index"> {{ item }} </el-menu-item>
</el-menu>
<div class="contain">
<el-header class="headerPart">
<div class="topLeft">
<div class="selectPart">
<span>{{ t('statAnalysis.deviceId') }}</span>
<el-select
v-model="statAnalysisSelect.deviceId"
@change="selectstatAnalysis('deviceId')"
:placeholder="'请选择' + t('statAnalysis.deviceId')"
class="statAnalysisSelect"
>
<el-option v-for="v in statAnalysisSelectOptions.deviceId" :key="v.value" :label="v.label" :value="v.value"></el-option>
</el-select>
</div>
<div class="selectPart">
<span>{{ t('statAnalysis.attributes') }}</span>
<el-input
class="statAnalysisSelect"
v-model="statAnalysisSelect.attributes"
@click="showMeasure = true"
:placeholder="'请选择' + t('statAnalysis.attributes')"
></el-input>
</div>
<div class="selectPart">
<span>{{ t('statAnalysis.interval') }}</span>
<el-select
v-model="statAnalysisSelect.interval"
@change="selectstatAnalysis('interval')"
:placeholder="'请选择' + t('statAnalysis.interval')"
class="statAnalysisSelect"
>
<el-option v-for="v in statAnalysisSelectOptions.interval" :key="v.value" :label="v.label" :value="v.value"></el-option>
</el-select>
</div>
</div>
<div class="topRight">
<el-button type="primary" @click="statAnalysisOperate()">{{ t('statAnalysis.search') }}</el-button>
<el-button style="color: #0064aa" @click="statAnalysiImport()">{{ t('statAnalysis.import') }}</el-button>
<el-button style="color: #0064aa" @click="statAnalysisExport()">{{ t('statAnalysis.export') }}</el-button>
</div>
</el-header>
<div class="timeColumns" :class="{ expand: isExpand }">
<div class="headerPart" v-for="(time, index) in times" :key="index">
<div class="topLeft">
<div class="selectPart">
<span>{{ customName }}</span>
<span>{{ t('statAnalysis.time') }}</span>
<el-date-picker
class="datetime-picker"
v-model="times[index]"
:type="statAnalysisSelect.interval == '1d' ? 'daterange' : 'datetimerange'"
:value-format="statAnalysisSelect.interval == '1d' ? 'YYYY-MM-DD' : 'YYYY-MM-DD HH:mm:ss'"
:teleported="false"
:shortcuts="shortcuts"
@change="timechange(index)"
/>
</div>
<div class="topLeft">
<div class="selectPart" v-if="index === times.length - 1">
<el-button type="primary" size="small" :icon="Plus" circle @click="addTime(index)"> </el-button>
</div>
<div class="selectPart" v-if="index !== 0">
<el-button type="danger" size="small" :icon="Delete" @click="switchTime(index)" circle />
</div>
<div class="selectPart">
<span>{{ t('statAnalysis.max') }}</span>
<span class="max">11</span>
</div>
<div class="selectPart">
<span>{{ t('statAnalysis.min') }}</span>
<span class="min">22</span>
</div>
<div class="selectPart">
<span>{{ t('statAnalysis.average') }}</span>
<span class="average">33</span>
</div>
</div>
</div>
</div>
</div>
<div v-if="times.length > 2" class="ralIcon" @click="handleClick">
<el-icon :size="20" color="#0064AA"><DArrowRight /></el-icon>
</div>
<div ref="chartContainer" style="width: 100%; height: 400px"></div>
<el-dialog v-model="showMeasure" title="测点名称" :width="800">
<template #header>
<div class="measureSlotHeader">
<span style="font-size: 20px">测点名称</span>
</div>
</template>
<div class="measureSlot">
<MeasurementPage :show="showMeasure" :iotModelId="iotModelId" @handleRadioChange="handleRadioChange"></MeasurementPage>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="showMeasure = false">取消</el-button>
<el-button type="primary" @click="selectstatAnalysisAttributes"> 确认 </el-button>
</span>
</template>
</el-dialog>
</div>
<TrendAnalysis v-if="activeIndex == 1"></TrendAnalysis>
<TrendComparison v-if="activeIndex == 2"></TrendComparison>
</div>
</template>
<script setup lang="ts">
import { SelectTypeObjType, SelectTypeKeyUnionType, TableDataObjType, TableColumnType } from './type'
import { onUnmounted, reactive, ref, watch, nextTick, onMounted, computed } from 'vue'
import { ref } from 'vue'
import { useI18n } from 'vue-i18n'
import { queryWindTurbinesPages, historyReq } from '/@/api/backend/statAnalysis/request'
import { ElMessage, TableInstance, ElMenu } from 'element-plus'
import { useRouter, useRoute } from 'vue-router'
import { useConfig } from '/@/stores/config'
import { DArrowRight, Plus, Delete } from '@element-plus/icons-vue'
import MeasurementPage from './analysisAttributes.vue'
import * as echarts from 'echarts'
import TrendAnalysis from './trendAnalysis.vue'
import TrendComparison from './trendComparison.vue'
const config = useConfig()
const router = useRouter()
const route = useRoute()
const activeIndex = ref(0)
const activeIndex = ref(1)
const { t } = useI18n()
const headerList = [t('statAnalysis.PowerCurveAnalysis'), t('statAnalysis.trendAnalysis'), t('statAnalysis.trendComparison')]
const statAnalysisSelect = reactive({
deviceId: '',
attributes: '',
attributeCode: '',
interval: '',
time: '',
})
const times = reactive([{ time: '' }])
const addTime = (index) => {
console.log(index)
console.log(times)
times.push({ time: '' })
const handleSelect = (index) => {
activeIndex.value = index
}
const switchTime = (index) => {
times.splice(index, 1)
}
const timechange = (value) => {
const count = getTimeIntervals(times[0][0], times[0][1])
const count1 = getTimeIntervals(times[value][0], times[value][1])
if (count !== count1) {
times[value] = { time: '' }
value = ElMessage.warning('查询时间点错误,请重新舒服')
}
console.log('🚀 ~ timechange ~ count:', count)
}
const isExpand = ref(false)
const handleClick = () => {
isExpand.value = !isExpand.value
console.log(isExpand)
}
const iotModelId = ref('')
watch(
() => statAnalysisSelect.deviceId,
(newVal) => {
if (newVal) {
const row = statAnalysisSelectOptions.deviceId.filter((item) => {
console.log(item.value == newVal)
return item.value == newVal
})
console.log()
iotModelId.value = row[0].iotModelId
console.log('🚀 ~ iotModelId:', iotModelId)
}
},
{
immediate: true,
}
)
const showMeasure = ref(false)
const selectedAttrRow = ref({
attributeCode: '',
attributeName: '',
})
const handleRadioChange = (value) => {
const { attributeCode, attributeName } = { ...value }
selectedAttrRow.attributeCode = attributeCode
selectedAttrRow.attributeName = attributeName
}
const selectstatAnalysisAttributes = () => {
statAnalysisSelect.attributes = selectedAttrRow.attributeName
console.log('🚀 ~ selectstatAnalysisAttributes ~ selectedAttrRow:', selectedAttrRow)
statAnalysisSelect.attributeCode = selectedAttrRow.attributeCode
showMeasure.value = false
}
const chartContainer = ref<HTMLElement | null>(null)
const option = {
// dataZoom: [
// {
// type: 'inside',
// start: 0,
// end: 100,
// },
// {
// start: 0,
// },
// ],
tooltip: {
trigger: 'axis',
// axisPointer: {
// type: 'cross',
// label: {
// backgroundColor: '#6a7985',
// },
// },
},
legend: {
right: 10,
top: 0,
icon: 'rect',
itemGap: 20,
itemWidth: 8,
itemHeight: 8,
data: [],
selected: {},
},
xAxis: {
type: 'category',
data: [],
},
yAxis: {
type: 'value',
},
series: [],
grid: {
left: '3%',
right: '3%',
},
}
const statAnalysisSelectOptions = reactive({
interval: [
{ label: '五分钟', value: '5m' },
{ label: '十五分钟', value: '15m' },
{ label: '一小时', value: '1h' },
{ label: '一天', value: '1d' },
{ label: '原始', value: 'NONE' },
],
deviceId: [],
})
const customName = ref('第一条数据')
const chart = ref(null)
onMounted(() => {
if (chartContainer.value) {
chart.value = echarts.init(chartContainer.value)
chart.value.setOption(option)
}
queryWindTurbines()
})
const queryWindTurbines = () => {
queryWindTurbinesPages().then((res) => {
if (res.code == 200) {
statAnalysisSelectOptions.deviceId = res.data.map((item) => {
return {
value: item.irn,
label: item.name ?? '-',
iotModelId: item.modelId,
}
})
}
})
}
window.onresize = () => {
chart.resize()
}
const handleSelect = () => {}
const selectstatAnalysis = () => {}
const shortcuts = [
{
text: '昨日',
value: () => {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24)
return [start, end]
},
},
{
text: '前三天',
value: () => {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 3)
return [start, end]
},
},
{
text: '前七天',
value: () => {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
return [start, end]
},
},
{
text: '上个月',
value: () => {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
return [start, end]
},
},
]
const getTimeIntervals = (startTimestamp, endTimestamp) => {
const startDate = new Date(startTimestamp)
const endDate = new Date(endTimestamp)
let count = 0
switch (statAnalysisSelect.interval) {
case 'NONE':
count = Math.floor((endDate - startDate) / 1000)
break
case '5m':
count = Math.floor((endDate - startDate) / (5 * 60 * 1000))
break
case '15m':
count = Math.floor((endDate - startDate) / (15 * 60 * 1000))
break
case '1h':
count = Math.floor((endDate - startDate) / (1 * 60 * 60 * 1000))
break
case '1d':
count = Math.floor((endDate - startDate) / (1 * 24 * 60 * 60 * 1000))
break
// default:
// throw new Error('Invalid interval')
}
return count
}
const statAnalysisOperate = () => {
console.log(statAnalysisSelect)
console.log(times)
times.forEach((time) => {
if (time[0] && time[1]) {
const requestData = {
devices: [
{
deviceId: statAnalysisSelect.deviceId,
attributes: [statAnalysisSelect.attributeCode],
},
],
interval: statAnalysisSelect.interval,
startTime: new Date(time[0]).getTime(),
endTime: new Date(time[1]).getTime(),
}
historyDataReq(requestData)
console.log(requestData)
}
})
}
const historyDataReq = (data) => {
// historyReq(data).then((res) => {
// console.log(res)
const res = {
//ID
'129476828342323': {
//
power: {
//
times: [123452435924242, 123452435924342, 123452435924442, 123452435924542],
//
values: [123.23, 35.21, 34.56, 67],
},
},
}
const deviceId = statAnalysisSelect.deviceId
const attributeCode = statAnalysisSelect.attributeCode
const resData = res['129476828342323']['power']
const xData = resData['times']
const yData = resData['values']
option.tooltip = {
trigger: 'axis',
show: true,
formatter: function (params) {
console.log('🚀 ~ //historyReq ~ params:', params)
return params
.map((item) => {
return `${item.seriesName} (${xData[item.dataIndex]}): ${item.data}`
})
.join('<br/>')
},
}
option.xAxis.data = Array.from({ length: xData.length }, (_, index) => index)
option.series = [
{
name: '',
type: 'line',
data: yData,
},
]
console.log('🚀 ~ //historyReq ~ option:', option)
chart.value.setOption(option)
// })
}
const statAnalysisExport = () => {}
const statAnalysiImport = () => {}
</script>
<style scoped lang="scss">
.statAnalysis {
@ -421,93 +31,5 @@ const statAnalysiImport = () => {}
--el-menu-text-color: v-bind('config.getColorVal("menuColor")');
--el-menu-active-color: v-bind('config.getColorVal("menuActiveColor")');
}
.headerPart {
padding: 20px;
display: flex;
justify-content: space-between;
align-items: center;
.topLeft {
display: flex;
.selectPart {
display: flex;
justify-content: space-between;
align-items: center;
height: 40px;
margin-right: 20px;
span {
margin-right: 10px;
}
.statAnalysisSelect {
width: 200px;
:deep(.el-select__wrapper) {
height: 40px;
}
:deep(.el-input__inner) {
height: 38px;
}
}
.max,
.min,
.average {
border-radius: 6px;
height: 40px;
width: 72px;
text-align: center;
line-height: 40px;
}
.max {
background: rgba(254, 55, 49, 0.2);
border: 1px solid #fe3731;
color: #fe3731;
}
.min {
background: rgba(0, 160, 150, 0.2);
border: 1px solid #00a096;
color: #00a096;
}
.average {
background: rgba(0, 100, 170, 0.2);
border: 1px solid #0064aa;
color: #0064aa;
}
}
.dialog-footer button:first-child {
margin-right: 10px;
}
}
.topRight {
// width: 436px;
display: flex;
justify-content: space-between;
.el-button {
width: 100px;
height: 40px;
}
}
}
.timeColumns {
max-height: 120px;
overflow: hidden;
.headerPart {
padding: 10px;
}
&.expand {
max-height: max-content;
height: auto;
overflow: inherit;
}
}
.timeColumns.expand + div.ralIcon {
transform: rotate(-90deg);
}
.ralIcon {
width: 100%;
text-align: center;
transform: rotate(90deg);
}
#myEChart {
width: 100%;
height: 300px;
}
}
</style>

View File

@ -0,0 +1,493 @@
<template>
<div class="contain">
<el-header class="headerPart">
<div class="topLeft">
<div class="selectPart">
<span>{{ t('statAnalysis.deviceId') }}</span>
<el-select
v-model="statAnalysisSelect.deviceId"
@change="selectstatAnalysis('deviceId')"
:placeholder="'请选择' + t('statAnalysis.deviceId')"
class="statAnalysisSelect"
>
<el-option v-for="v in statAnalysisSelectOptions.deviceId" :key="v.value" :label="v.label" :value="v.value"></el-option>
</el-select>
</div>
<div class="selectPart">
<span>{{ t('statAnalysis.attributes') }}</span>
<el-input
class="statAnalysisSelect"
v-model="statAnalysisSelect.attributes"
@click="showMeasure = true"
:placeholder="'请选择' + t('statAnalysis.attributes')"
></el-input>
</div>
<div class="selectPart">
<span>{{ t('statAnalysis.interval') }}</span>
<el-select
v-model="statAnalysisSelect.interval"
@change="selectstatAnalysis('interval')"
:placeholder="'请选择' + t('statAnalysis.interval')"
class="statAnalysisSelect"
>
<el-option v-for="v in statAnalysisSelectOptions.interval" :key="v.value" :label="v.label" :value="v.value"></el-option>
</el-select>
</div>
</div>
<div class="topRight">
<el-button type="primary" @click="statAnalysisOperate()">{{ t('statAnalysis.search') }}</el-button>
<el-button style="color: #0064aa" @click="statAnalysiImport()">{{ t('statAnalysis.import') }}</el-button>
<el-button style="color: #0064aa" @click="statAnalysisExport()">{{ t('statAnalysis.export') }}</el-button>
</div>
</el-header>
<div class="timeColumns" :class="{ expand: isExpand }">
<div class="headerPart" v-for="(time, index) in times" :key="index">
<div class="topLeft">
<div class="selectPart">
<span>{{ index + 1 }}</span>
<span>{{ t('statAnalysis.time') }}</span>
<el-date-picker
class="datetime-picker"
v-model="times[index]"
:type="statAnalysisSelect.interval == '1d' ? 'daterange' : 'datetimerange'"
:value-format="statAnalysisSelect.interval == '1d' ? 'YYYY-MM-DD' : 'YYYY-MM-DD HH:mm:ss'"
:teleported="false"
:shortcuts="shortcuts"
@change="timechange(index)"
/>
</div>
<div class="topLeft">
<div class="icon">
<el-button v-show="index === times.length - 1" type="primary" size="small" :icon="Plus" circle @click="addTime(index)">
</el-button>
</div>
<div class="icon">
<el-button v-show="index !== 0" type="danger" size="small" :icon="Delete" @click="switchTime(index)" circle></el-button>
</div>
<div class="selectPart" v-if="calculate[index] && calculate[index]['max']">
<span>{{ t('statAnalysis.max') }}</span>
<span class="max">{{ calculate[index]['max'] }}</span>
</div>
<div class="selectPart" v-if="calculate[index] && calculate[index]['min']">
<span>{{ t('statAnalysis.min') }}</span>
<span class="min">{{ calculate[index]['min'] }}</span>
</div>
<div class="selectPart" v-if="calculate[index] && calculate[index]['average']">
<span>{{ t('statAnalysis.average') }}</span>
<span class="average">{{ calculate[index]['average'] }}</span>
</div>
</div>
</div>
</div>
</div>
<div v-if="times.length > 2" class="ralIcon" @click="handleClick">
<el-icon :size="20" color="#0064AA"><DArrowRight /></el-icon>
</div>
<div ref="chartContainer" style="width: 100%; height: 400px"></div>
<el-dialog v-model="showMeasure" title="测点名称" :width="800">
<template #header>
<div class="measureSlotHeader">
<span style="font-size: 20px">测点名称</span>
</div>
</template>
<div class="measureSlot">
<MeasurementPage :show="showMeasure" :iotModelId="iotModelId" @handleRadioChange="handleRadioChange"></MeasurementPage>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="showMeasure = false">取消</el-button>
<el-button type="primary" @click="selectstatAnalysisAttributes"> 确认 </el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script setup lang="ts">
import { onUnmounted, reactive, ref, watch, nextTick, onMounted, computed } from 'vue'
import { useI18n } from 'vue-i18n'
import { queryWindTurbinesPages, historyReq } from '/@/api/backend/statAnalysis/request'
import { ElMessage, ElMenu } from 'element-plus'
import { DArrowRight, Plus, Delete } from '@element-plus/icons-vue'
import MeasurementPage from './analysisAttributes.vue'
import * as echarts from 'echarts'
const { t } = useI18n()
const statAnalysisSelect = reactive({
deviceId: '',
attributes: '',
attributeCode: '',
interval: '',
time: '',
})
const times = reactive([{ time: '' }])
const addTime = (index) => {
times.push({ time: '' })
customName.value.push(index + 2)
}
const switchTime = (index) => {
times.splice(index, 1)
customName.value.splice(index, 1)
calculate.splice(index, 1)
}
const timechange = (value) => {
const count = getTimeIntervals(times[0][0], times[0][1])
const count1 = getTimeIntervals(times[value][0], times[value][1])
if (count !== count1) {
times[value] = { time: '' }
value = ElMessage.warning('查询时间点错误,请重新输入')
}
}
const isExpand = ref(false)
const handleClick = () => {
isExpand.value = !isExpand.value
}
const iotModelId = ref('')
watch(
() => statAnalysisSelect.deviceId,
(newVal) => {
if (newVal) {
const row = statAnalysisSelectOptions.deviceId.filter((item) => {
return item.value == newVal
})
iotModelId.value = row[0].iotModelId
}
},
{
immediate: true,
}
)
const showMeasure = ref(false)
const selectedAttrRow = ref({
attributeCode: '',
attributeName: '',
})
const handleRadioChange = (value) => {
const { attributeCode, attributeName } = { ...value }
selectedAttrRow.attributeCode = attributeCode
selectedAttrRow.attributeName = attributeName
}
const selectstatAnalysisAttributes = () => {
statAnalysisSelect.attributes = selectedAttrRow.attributeName
statAnalysisSelect.attributeCode = selectedAttrRow.attributeCode
showMeasure.value = false
}
const chartContainer = ref<HTMLElement | null>(null)
const option = reactive({
dataZoom: [
{
type: 'inside',
start: 0,
end: 100,
},
{
start: 0,
},
],
tooltip: {},
legend: {
icon: 'circle',
itemGap: 20,
itemWidth: 8,
itemHeight: 8,
data: [],
},
xAxis: {
type: 'category',
data: [],
},
yAxis: {
type: 'value',
},
series: [],
grid: {
left: '3%',
right: '3%',
},
})
const statAnalysisSelectOptions = reactive({
interval: [
{ label: '五分钟', value: '5m' },
{ label: '十五分钟', value: '15m' },
{ label: '一小时', value: '1h' },
{ label: '一天', value: '1d' },
{ label: '原始', value: 'NONE' },
],
deviceId: [],
})
const customName = ref(['1'])
const chart = ref(null)
onMounted(() => {
if (chartContainer.value) {
chart.value = echarts.init(chartContainer.value)
chart.value.setOption(option)
}
queryWindTurbines()
})
const queryWindTurbines = () => {
queryWindTurbinesPages().then((res) => {
if (res.code == 200) {
statAnalysisSelectOptions.deviceId = res.data.map((item) => {
return {
value: item.irn,
label: item.name ?? '-',
iotModelId: item.modelId,
}
})
}
})
}
window.onresize = () => {
chart.value.resize()
}
const handleSelect = (index) => {
activeIndex.value = index
}
const selectstatAnalysis = () => {}
const shortcuts = [
{
text: '昨日',
value: () => {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24)
return [start, end]
},
},
{
text: '前三天',
value: () => {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 3)
return [start, end]
},
},
{
text: '前七天',
value: () => {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
return [start, end]
},
},
{
text: '上个月',
value: () => {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
return [start, end]
},
},
]
const getTimeIntervals = (startTimestamp, endTimestamp) => {
const startDate = new Date(startTimestamp)
const endDate = new Date(endTimestamp)
let count = 0
switch (statAnalysisSelect.interval) {
case 'NONE':
count = Math.floor((endDate - startDate) / 1000)
break
case '5m':
count = Math.floor((endDate - startDate) / (5 * 60 * 1000))
break
case '15m':
count = Math.floor((endDate - startDate) / (15 * 60 * 1000))
break
case '1h':
count = Math.floor((endDate - startDate) / (1 * 60 * 60 * 1000))
break
case '1d':
count = c((endDate - startDate) / (1 * 24 * 60 * 60 * 1000))
break
// default:
// throw new Error('Invalid interval')
}
return count
}
const statAnalysisOperate = () => {
option.tooltip = {}
option.xAxis.data = []
option.legend.data = []
option.series = []
times.forEach((time, index) => {
if (time[0] && time[1]) {
const requestData = {
devices: [
{
deviceId: statAnalysisSelect.deviceId,
attributes: [statAnalysisSelect.attributeCode],
},
],
interval: statAnalysisSelect.interval,
startTime: new Date(time[0]).getTime(),
endTime: new Date(time[1]).getTime(),
}
historyDataReq(requestData, index)
}
})
}
const calculate = reactive([{ max: '', min: '', average: '' }])
const historyDataReq = (data, index) => {
historyReq(data).then((res) => {
if (res.code == 200) {
const deviceId = statAnalysisSelect.deviceId
const attributeCode = statAnalysisSelect.attributeCode
const resData = (res.data && deviceId in res.data && res.data[deviceId][attributeCode]) || undefined
if (resData) {
const xData = resData['times']
const yData = resData['values']
calculate[index] = {
max: Math.floor(Math.max(...yData)),
min: Math.floor(Math.min(...yData)),
average: Math.floor(yData.reduce((a, b) => a + b, 0) / yData.length),
}
option.tooltip = {
show: true,
formatter: function (params) {
const x = timestampToTime(xData[params.dataIndex])
return `${params.marker} ${params.seriesName} ${x} : ${params.data}`
},
}
option.xAxis.data = Array.from({ length: xData.length }, (_, index) => index)
const seriesData = {
name: String(index + 1),
type: 'line',
data: yData,
}
option.legend.data.push(String(index + 1))
option.series.push(seriesData)
chart.value.setOption(option)
} else {
ElMessage.warning('查询失败1')
}
} else {
ElMessage.warning('查询失败')
}
})
}
const statAnalysisExport = () => {}
const statAnalysiImport = () => {}
const timestampToTime = (timestamp) => {
timestamp = timestamp ? timestamp : null
let date = new Date(timestamp)
let Y = date.getFullYear() + '-'
let M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-'
let D = (date.getDate() < 10 ? '0' + date.getDate() : date.getDate()) + ' '
let h = (date.getHours() < 10 ? '0' + date.getHours() : date.getHours()) + ':'
let m = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
return Y + M + D + h + m
}
</script>
<style scoped lang="scss">
.statAnalysis {
height: 100%;
.headerPart {
padding: 20px;
display: flex;
justify-content: space-between;
align-items: center;
.topLeft {
display: flex;
.icon {
width: 40px;
height: 40px;
padding: 10px 0;
}
.selectPart {
display: flex;
justify-content: space-between;
align-items: center;
height: 40px;
margin-right: 20px;
span {
margin-right: 10px;
}
.statAnalysisSelect {
width: 200px;
:deep(.el-select__wrapper) {
height: 40px;
}
:deep(.el-input__inner) {
height: 38px;
}
}
.max,
.min,
.average {
border-radius: 6px;
height: 40px;
width: 72px;
text-align: center;
line-height: 40px;
}
.max {
background: rgba(254, 55, 49, 0.2);
border: 1px solid #fe3731;
color: #fe3731;
}
.min {
background: rgba(0, 160, 150, 0.2);
border: 1px solid #00a096;
color: #00a096;
}
.average {
background: rgba(0, 100, 170, 0.2);
border: 1px solid #0064aa;
color: #0064aa;
}
}
.dialog-footer button:first-child {
margin-right: 10px;
}
}
.topRight {
// width: 436px;
display: flex;
justify-content: space-between;
.el-button {
width: 100px;
height: 40px;
}
}
}
.timeColumns {
max-height: 120px;
overflow: hidden;
.headerPart {
padding: 10px 20px;
}
&.expand {
max-height: max-content;
height: auto;
overflow: inherit;
}
}
.timeColumns.expand + div.ralIcon {
transform: rotate(-90deg);
}
.ralIcon {
width: 100%;
text-align: center;
transform: rotate(90deg);
}
#myEChart {
width: 100%;
height: 300px;
}
}
</style>