Files
admin-govern/src/views/govern/device/planData/index.vue
2025-07-15 16:31:06 +08:00

1120 lines
47 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="default-main device-manage" :style="{ height: pageHeight.height }">
<!-- @node-change="nodeClick" -->
<schemeTree @node-change="nodeClick" @node-click="nodeClick" @init="nodeClick" @onAdd="onAdd" @bind="bind"
ref="schemeTreeRef"></schemeTree>
<div class="device-manage-right" v-if="deviceData">
<el-descriptions title="方案信息" :column="2" border>
<!-- <template #extra>
<el-button type="primary" icon="el-icon-Plus" @click="handleOpen(0)">新增方案</el-button>
</template> -->
<el-descriptions-item label="方案名称" width="60">
{{ deviceData.itemName }}
</el-descriptions-item>
<el-descriptions-item label="方案描述" width="60">
{{ deviceData.describe ? deviceData.describe : '/' }}
</el-descriptions-item>
</el-descriptions>
<el-collapse v-model.trim="activeColName" @change="handleChange" accordion>
<el-collapse-item title="测试项信息" name="0">
<div class="monitor_info" v-if="deviceData.records && deviceData.records.length != 0">
<!-- <div class="history_title">
<p>测试项信息</p>
</div> -->
<el-tabs v-model.trim="activeName" type="border-card" @tab-change="handleClickTabs">
<el-tab-pane v-for="(item, index) in deviceData?.records" :label="item.itemName"
:name="item.id" :key="index">
<template #label>
<span class="custom-tabs-label">
<el-icon>
<TrendCharts />
</el-icon>
<span>{{ item.itemName }}</span>
</span>
</template>
<el-descriptions size="small" width="180" :column="4" border>
<!-- <el-descriptions-item label="测试项名称" width="160">
{{ item.itemName }}
</el-descriptions-item> -->
<el-descriptions-item label="测量间隔" width="160">
{{ item.statisticalInterval }}分钟
</el-descriptions-item>
<el-descriptions-item label="电压等级" width="160">
{{
voltageLevelList.find(vv => {
return vv.id == item.voltageLevel
})?.name
}}
</el-descriptions-item>
<el-descriptions-item label="接线方式" width="160">
{{
volConTypeList.find(vv => {
return vv.id == item.volConType
})?.name
}}
</el-descriptions-item>
<el-descriptions-item label="最小短路容量" width="160">
{{ item.capacitySscmin }}MVA
</el-descriptions-item>
<el-descriptions-item label="用户协议容量" width="160">
{{ item.capacitySi }}MVA
</el-descriptions-item>
<el-descriptions-item label="基准短路容量" width="160">
{{ item.capacitySscb }}MVA
</el-descriptions-item>
<el-descriptions-item label="供电设备容量" width="160">
{{ item.capacitySt }}MVA
</el-descriptions-item>
<el-descriptions-item label="PT变比" width="160">
{{ item.pt && item.pt1 ? item.pt + '/' + item.pt1 : '/' }}
</el-descriptions-item>
<el-descriptions-item label="CT变比" width="160">
{{ item.ct && item.ct1 ? item.ct + '/' + item.ct1 : '/' }}
</el-descriptions-item>
<el-descriptions-item label="起始时间" width="160">
<span style="width: 140px; overflow: hidden; display: block">
{{ item.startTime }}
</span>
</el-descriptions-item>
<el-descriptions-item label="结束时间" width="160">
<span style="width: 140px; overflow: hidden; display: block">
{{ item.endTime }}
</span>
</el-descriptions-item>
<el-descriptions-item label="监测位置" width="160">
{{ item.location }}
</el-descriptions-item>
<!-- <el-descriptions-item label="操作" width="160">
<el-button type="primary" icon="el-icon-Tools" @click="handleOpen(3)">
数据绑定
</el-button>
</el-descriptions-item> -->
</el-descriptions>
</el-tab-pane>
</el-tabs>
</div>
<div class="monitor_info" v-else>
<el-empty />
</div>
</el-collapse-item>
</el-collapse>
<div v-if="JSON.stringify(echartsData) != '{}' && deviceData?.records?.length != 0">
<!-- <h3 class="mt10 mb10">历史趋势</h3> -->
<el-tabs v-model.trim="childTab" type="border-card" class="mt10">
<el-tab-pane label="历史趋势" name="0">
<div class="history_trend" v-if="titleList != '(未绑定数据)'">
<div class="history_header" ref="headerRef">
<!-- <el-form :model="searchForm" class="history_select" id="history_select"> -->
<TableHeader :showSearch="false" ref="tableHeaderRef" @selectChange="selectChange">
<template v-slot:select :key="num">
<el-form-item for="-" label="统计指标">
<el-select style="min-width: 200px" collapse-tags collapse-tags-tooltip
v-model.trim="searchForm.index" placeholder="请选择统计指标"
@change="onIndexChange($event)" multiple :multiple-limit="3">
<el-option v-for="item in indexOptions" :key="item.id"
:label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<!-- <el-select style="width: 12px !important" v-model.trim="searchForm.dataLevel">
<el-option value="Primary" label="一次值"></el-option>
<el-option value="Secondary" label="二次值"></el-option>
</el-select> -->
<el-radio-group v-model.trim="searchForm.dataLevel" @change="init(true)">
<el-radio-button label="一次值" value="Primary" />
<el-radio-button label="二次值" value="Secondary" />
</el-radio-group>
</el-form-item>
<el-form-item for="-" label="统计类型" label-width="80px">
<el-select style="width: 120px" v-model.trim="searchForm.type"
placeholder="请选择值类型">
<el-option v-for="item in typeOptions" :key="item.id" :label="item.name"
:value="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<div for="-" v-for="(item, index) in countData" :key="index"
v-show="item.countOptions.length != 0">
<span class="mr12">{{item.name.includes('次数') ? item.name : item.name.includes('幅值') ? item.name.slice(0, -2) + '次数' : item.name + '谐波次数'}}</span>
<el-select v-model.trim="item.count" class="mr20" collapse-tags collapse-tags-tooltip
placeholder="请选择谐波次数" style="width: 120px">
<el-option v-for="vv in item.countOptions" :key="vv" :label="vv"
:value="vv"></el-option>
</el-select>
</div>
</el-form-item>
</template>
<template v-slot:operation>
<!-- <el-button type="primary" icon="el-icon-Download" @click="handleExport">
数据导出
</el-button> -->
<el-button type="primary" icon="el-icon-Search"
@click="init(true)">查询</el-button>
</template>
</TableHeader>
</div>
<!-- <div class="history_title">
<p>{{ chartTitle }}</p>
</div> -->
<div class="history_chart mt5" v-loading="loading" :style="EcharHeight"
:key="EcharHeight.height" ref="chartRef">
<MyEchart ref="historyChart" v-if="echartsData" :isExport="true"
:options="echartsData" />
</div>
</div>
<el-empty :style="EcharHeight" v-else description="未绑定数据" />
</el-tab-pane>
<el-tab-pane label="暂态数据" name="1">
<transient :activeName='activeName' ref="transientRef" :activeColName="activeColName" />
</el-tab-pane>
</el-tabs>
</div>
</div>
<el-empty v-else description="请选择设备" class="device-manage-right" />
<popup ref="dialogRef" @onSubmit="refreshTree" />
</div>
</template>
<script lang="ts" setup>
import popup from './components/popup.vue'
import schemeTree from './components/schemeTree.vue'
import { mainHeight } from '@/utils/layout'
import { queryByCode, queryCsDictTree } from '@/api/system-boot/dictTree'
import { ref, onMounted, watch, nextTick } from 'vue'
import { ElMessage } from 'element-plus'
import MyEchart from '@/components/echarts/MyEchart.vue'
import { getTestRecordInfo, getHistoryTrend } from '@/api/cs-device-boot/planData'
import { useDictData } from '@/stores/dictData'
import { queryStatistical } from '@/api/system-boot/csstatisticalset'
import { TrendCharts, Plus, Platform, } from '@element-plus/icons-vue'
import { yMethod } from '@/utils/echartMethod'
import { color, gradeColor3 } from '@/components/echarts/color'
import TableHeader from '@/components/table/header/index.vue'
import { useConfig } from '@/stores/config'
import { getDeviceList } from '@/api/cs-device-boot/planData'
import transient from './components/transient.vue'
const dictData = useDictData()
defineOptions({
// name: 'govern/device/planData/index'
})
const childTab = ref('0')
const num = ref(0)
const config = useConfig()
const transientRef = ref()
color[0] = config.layout.elementUiPrimary[0]
//电压等级
const voltageLevelList = dictData.getBasicData('Dev_Voltage_Stand')
//接线方式
const volConTypeList = dictData.getBasicData('Dev_Connect')
//值类型
const pageHeight = mainHeight(20)
const EcharHeight = ref(mainHeight(436))
const loading = ref(false)
const searchForm: any = ref({})
const typeOptions = [
{
name: '平均值',
id: 'avg'
},
{
name: '最大值',
id: 'max'
},
{
name: '最小值',
id: 'min'
},
{
name: 'CP95值',
id: 'cp95'
}
]
searchForm.value = {
index: [],
dataLevel: 'Primary',
type: typeOptions[0].id,
count: []
}
//统计指标
const indexOptions: any = ref([])
//谐波次数
const countOptions: any = ref([])
// Harmonic_Type
// portable-harmonic
const legendDictList: any = ref([])
queryByCode('portable-harmonic').then(res => {
queryCsDictTree(res.data.id).then(item => {
indexOptions.value = item.data.sort((a: any, b: any) => {
return a.sort - b.sort
})
searchForm.value.index[0] = indexOptions.value[0].id
// searchForm.value.index = indexOptions.value[0].id
})
queryStatistical(res.data.id).then(vv => {
legendDictList.value = vv.data
indexOptions.value.map((item: any, index: any) => {
if (!countDataCopy.value[index]) {
countDataCopy.value[index] = {
index: item.id,
countOptions: [],
count: [],
name: indexOptions.value.find((vv: any) => {
return vv.id == item.id
})?.name
}
}
legendDictList.value?.selectedList?.map((vv: any, vvs: any) => {
//查找相等的指标
if (item.id == vv.dataType) {
vv.eleEpdPqdVOS.map((kk: any, kks: any) => {
if (kk.harmStart && kk.harmEnd) {
range(0, 0, 0)
if (kk.showName == '间谐波电压含有率') {
countDataCopy.value[index].countOptions = range(kk.harmStart, kk.harmEnd, 1).map(
(item: any) => {
return item - 0.5
}
)
} else {
countDataCopy.value[index].countOptions = range(kk.harmStart, kk.harmEnd, 1)
}
if (!countDataCopy.value[index].count || countDataCopy.value[index].count.length == 0) {
countDataCopy.value[index].count = countDataCopy.value[index].countOptions[0]
}
}
})
}
})
})
})
})
const activeName: any = ref()
const activeColName: any = ref('0')
const deviceData: any = ref([])
const schemeTreeRef = ref()
//历史趋势devId
const historyDevId: any = ref('')
const chartTitle: any = ref('')
//点击测试项切换树节点
const handleClickTabs = () => {
searchForm.value.index = [indexOptions.value[0].id]
historyDevId.value = activeName.value
schemeTreeRef.value.setCheckedNode(activeName.value)
setTimeout(() => {
init(true)
transientRef.value && transientRef.value.init()
}, 100)
}
const nodeClick = async (e: anyObj) => {
if (e == undefined) {
return
}
// onIndexChange([])
deviceData.value = []
historyDevId.value = e?.children && e?.children.length != 0 ? e?.children[0].id : e?.id
let id = e.pid ? e.pid : e.id
//查询测试项信息
if (id) {
await getTestRecordInfo(id)
.then(async res => {
deviceData.value = res.data
if (res.data.records.length == 1) {
activeName.value = res.data.records[0].id
} else {
for (const item of res.data.records) {
if (item.id == e.id) {
activeName.value = item.id;
break; // 找到匹配项后停止遍历
}
}
// 如果没有找到匹配项默认设置为第一个元素的id
if (activeName.value !== e.id) { // 假设e.id是一个用于比较的初始值表示未找到匹配项
activeName.value = res.data.records[0].id;
}
}
// if (searchForm.value.index.length == 0) {
// searchForm.value.index = [indexOptions.value[0].id]
// }
schemeTreeRef.value.getPlanData(deviceData.value)
await setTimeout(() => {
loading.value = true
if (e.pid) {
init(true)
} else {
init(false)
}
transientRef.value && transientRef.value.init()
}, 100)
loading.value = false
})
.catch(e => {
loading.value = false
})
}
}
const onIndexChange = (val: any) => {
num.value += 1
let pp: any = []
indexOptions.value.forEach((item: any) => {
const filteredResult = val.filter(vv => item.id == vv);
if (filteredResult.length > 0) {
pp.push(filteredResult[0]);
}
})
searchForm.value.index = pp
formatCountOptions()
// if (val.length == 0) {
// searchForm.value.index = [indexOptions.value[0].id]
// }
}
const dialogRef = ref()
const dailogForm = ref()
const onAdd = () => {
handleOpen(0)
}
const bind = (data: any) => {
handleOpen(4, data)
}
const handleOpen = (val: any, data?: any) => {
if (!deviceData.value) {
dialogRef.value.open(val, '')
return
}
deviceData.value?.records?.map((item: any) => {
if (item.id == activeName.value) {
dailogForm.value = item
}
})
dialogRef.value.details(dailogForm.value)
// deviceData.value.records[0].id
let ids: any = ''
let name: any = ''
//数据绑定
if (val == 3) {
ids = data?.id
// name = data?.name
dialogRef.value.detailsType('table')
} else if (val == 4) {
ids = data?.id
name = data?.name
dialogRef.value.detailsType('table')
} else {
ids = ''
name = ''
dialogRef.value.detailsType('')
}
dialogRef.value.open(val, ids, name)
}
const echartsData = ref<any>(null)
//加载echarts图表
//历史趋势数据
const historyDataList: any = ref([])
const refreshTree = () => {
schemeTreeRef.value.getTreeList()
}
const range = (start: any, end: any, step: any) => {
return Array.from({ length: (end - start) / step + 1 }, (_, i) => start + i * step)
}
const colors = ['#DAA520', '#2E8B57', '#A52a2a']
const lineStyle = [{ type: 'solid', }, { type: 'dashed', }, { type: 'dotted', }]
const titleList: any = ref('')
const init = (flag: boolean) => {
titleList.value = ''
let list: any = []
//颜色数组
if (historyDevId.value && legendDictList.value && legendDictList.value.selectedList) {
// 选择指标的时候切换legend内容和data数据
legendDictList.value?.selectedList?.map((item: any) => {
searchForm.value.index.map((vv: any) => {
if (item.dataType == vv) {
list.push(item.eleEpdPqdVOS)
}
})
})
//选择的指标使用方法处理
formatCountOptions()
//查询历史趋势
historyDataList.value = []
let middleTitle = ''
if (
deviceData.value.records &&
deviceData.value.records.length != 0 &&
deviceData.value.records.find((item: any) => {
return item.id == activeName.value
})?.itemName
) {
middleTitle = deviceData.value.records.find((item: any) => {
return item.id == activeName.value
})?.itemName
} else {
middleTitle = ''
}
let indexList = searchForm.value.index
chartTitle.value = ''//deviceData.value.itemName + '_' + middleTitle + '_'
indexList.map((item: any, indexs: any) => {
indexOptions.value.map((vv: any) => {
if (vv.id == item) {
chartTitle.value += indexs == indexList.length - 1 ? vv.name : vv.name + '/'
}
})
})
let lists: any = []
let frequencys: any = null
countData.value.map((item: any, index: any) => {
if (item.name.includes('间谐波电压')) {
frequencys = item.count + 0.5
} else {
frequencys = item.count
}
lists[index] = {
statisticalId: item.index,
frequencys: frequencys && frequencys.length != 0 ? [frequencys] : []
}
})
let obj = {
devId: historyDevId.value,
list: lists,
dataLevel: searchForm.value.dataLevel,
valueType: searchForm.value.type
}
if (searchForm.value.index.length == 0 && flag) {
ElMessage.warning('请选择统计指标')
return
}
if (flag) {
getDeviceList({
id: historyDevId.value,
isTrueFlag: 1
}).then(res => {
if (res.data.length == 0) {
titleList.value = '(未绑定数据)'
}
chartTitle.value = chartTitle.value + titleList.value
})
loading.value = true
getHistoryTrend(obj)
.then((res: any) => {
if (res.code === 'A0000') {
historyDataList.value = res.data
let chartsList = JSON.parse(JSON.stringify(res.data))
echartsData.value = {}
//icon图标替换legend图例
// y轴单位数组
let unitList: any = []
let groupedData = chartsList.reduce((acc: any, item: any) => {
let key = ''
if (item.phase == null) {
key = item.unit
} else {
key = item.anotherName
}
if (!acc[key]) {
acc[key] = []
}
acc[key].push(item)
return acc
}, {})
let result = Object.values(groupedData)
if (chartsList.length > 0) {
unitList = result.map((item: any) => {
return item[0].unit
})
}
echartsData.value = {
// title: {
// text: chartTitle.value,
// left: '0',
// textStyle: {
// color: '#000',
// fontSize: '16'
// },
// },
toolbox: {
featureProps: {
myTool1: {
show: true,
title: '下载csv',
icon: 'path://M588.8 551.253333V512H352v39.253333h236.373333z m0 78.933334v-39.253334H352v39.253334h236.373333z m136.533333 78.933333V334.933333l-157.866666-157.866666H273.066667A59.306667 59.306667 0 0 0 213.333333 236.373333v551.253334a59.306667 59.306667 0 0 0 59.306667 59.306666h274.773333v42.666667H853.333333v-180.48zM568.746667 234.666667l100.266666 100.693333h-81.066666a20.053333 20.053333 0 0 1-19.626667-20.053333z m-20.48 573.013333H273.066667a19.2 19.2 0 0 1-17.493334-19.626667V236.373333a19.2 19.2 0 0 1 19.626667-19.626666h256v98.133333a58.88 58.88 0 0 0 58.88 59.306667h96.426667v334.933333h-98.133334v-39.68H352v39.68h196.266667z m100.266666 23.04a37.973333 37.973333 0 0 1-32 15.786667 38.826667 38.826667 0 0 1-32.426666-15.786667 53.76 53.76 0 0 1-10.24-32.853333 42.666667 42.666667 0 0 1 42.666666-47.786667 35.84 35.84 0 0 1 37.546667 29.866667h-12.8a23.893333 23.893333 0 0 0-24.746667-19.2c-17.066667 0-29.013333 14.08-29.013333 35.84s11.52 37.546667 28.586667 37.546666a26.453333 26.453333 0 0 0 26.453333-25.6h12.8a39.253333 39.253333 0 0 1-7.253333 22.186667z m59.733334 15.786667a35.84 35.84 0 0 1-40.106667-34.56H682.666667a23.893333 23.893333 0 0 0 26.88 23.04c12.8 0 22.613333-6.4 22.613333-15.786667s-4.266667-11.52-14.506667-13.653333l-21.333333-5.12c-17.066667-4.266667-24.32-11.52-24.32-23.893334s12.8-26.453333 34.133333-26.453333a31.573333 31.573333 0 0 1 35.413334 30.293333h-13.653334a19.626667 19.626667 0 0 0-22.613333-18.773333c-12.8 0-20.48 5.12-20.48 12.8s5.12 11.093333 17.066667 13.653333l14.933333 2.986667a42.666667 42.666667 0 0 1 20.906667 8.96 23.893333 23.893333 0 0 1 7.68 17.92c-0.426667 17.066667-14.506667 28.16-37.12 28.16z m88.746666 0h-14.506666l-32.426667-92.16h14.08l19.626667 59.733333 6.4 20.053333c0-9.386667 3.413333-12.8 5.546666-20.053333l19.2-59.733333h14.08z',
onclick: e => {
handleExport()
}
}
}
},
legend: {
itemWidth: 20,
itemHeight: 20,
itemStyle: { opacity: 0 },//去圆点
type: 'scroll', // 开启滚动分页
right: 70,
// width: 550,
// height: 50
},
grid: {
top: '80px',
},
tooltip: {
axisPointer: {
type: 'cross',
label: {
color: '#fff',
fontSize: 16
}
},
textStyle: {
color: '#fff',
fontStyle: 'normal',
opacity: 0.35,
fontSize: 14
},
backgroundColor: 'rgba(0,0,0,0.55)',
borderWidth: 0,
formatter(params: any) {
const xname = params[0].value[0]
let str = `${xname}<br>`
params.forEach((el: any, index: any) => {
let marker = ''
if (el.value[3] == 'dashed') {
for (let i = 0; i < 3; i++) {
marker += `<span style="display:inline-block;border: 2px ${el.color} solid;margin-right:5px;width:10px;height:0px;background-color:#ffffff00;"></span>`
}
} else {
marker = `<span style="display:inline-block;border: 2px ${el.color} ${el.value[3]};margin-right:5px;width:40px;height:0px;background-color:#ffffff00;"></span>`
}
str += `${marker}${el.seriesName.split('(')[0]}${el.value[1] ? el.value[1] + ' ' + (el.value[2] || '') : '-'
}<br>`
})
return str
}
},
// color: ['#DAA520', '#2E8B57', '#A52a2a', ...color],
xAxis: {
type: 'time',
axisLabel: {
formatter: {
day: '{MM}-{dd}',
month: '{MM}',
year: '{yyyy}'
}
}
},
yAxis: [{}],
options: {
series: []
}
}
if (chartsList.length > 0) {
let yData: any = []
echartsData.value.yAxis = []
let setList = [...new Set(unitList)];
setList.forEach((item: any, index: any) => {
if (index > 2) {
echartsData.value.grid.right = (index - 1) * 80
}
yData.push([])
let right = {
position: 'right',
offset: (index - 1) * 80
}
echartsData.value.yAxis.push({
name: item,
yAxisIndex: index,
splitNumber: 5,
minInterval: 1,
splitLine: {
show: false
},
...(index > 0 ? right : null)
})
})
// console.log("🚀 ~ result.forEach ~ result:", result)
let ABCName = [...new Set(chartsList.map((item: any) => { return item.anotherName == '电压负序分量' ? '电压不平衡' : item.anotherName == '电压正序分量' ? '电压不平衡' : item.anotherName == '电压零序分量' ? '电压不平衡' : item.anotherName }))];
result.forEach((item: any, index: any) => {
let yMethodList: any = []
let ABCList = Object.values(
item.reduce((acc, item) => {
let key = ''
if (item.phase == null) {
key = item.anotherName
} else {
key = item.phase
}
if (!acc[key]) {
acc[key] = []
}
acc[key].push(item)
return acc
}, {})
)
ABCList.forEach((kk: any) => {
let colorName = kk[0].phase?.charAt(0).toUpperCase()
let lineS = ABCName.findIndex(item => item === (kk[0].anotherName == '电压负序分量' ? '电压不平衡' : kk[0].anotherName == '电压正序分量' ? '电压不平衡' : kk[0].anotherName == '电压零序分量' ? '电压不平衡' : kk[0].anotherName));
let seriesList: any = []
kk.forEach((cc: any) => {
if (cc.statisticalData !== null) {
yData[setList.indexOf(kk[0].unit)].push(cc.statisticalData?.toFixed(2))
}
seriesList.push([cc.time, cc.statisticalData?.toFixed(2), cc.unit, lineStyle[lineS].type])
})
echartsData.value.options.series.push({
name: kk[0].phase
? kk[0].phase + '相' + kk[0].anotherName
: kk[0].anotherName,
type: 'line',
color: colorName == 'A' ? '#DAA520' : colorName == 'B' ? '#2E8B57' : colorName == 'C' ? '#A52a2a' : '',
smooth: true,
symbol: 'none',
lineStyle: lineStyle[lineS],
data: seriesList,
yAxisIndex: setList.indexOf(kk[0].unit)
})
})
// let [min, max] = yMethod(yMethodList)
// echartsData.value.yAxis[index].min = min
// echartsData.value.yAxis[index].max = max
})
yData.forEach((item: any, index: any) => {
let [min, max] = yMethod(item)
echartsData.value.yAxis[index].min = min
echartsData.value.yAxis[index].max = max
})
}
loading.value = false
}
})
.catch(error => {
loading.value = false
})
} else {
loading.value = false
}
}
}
//导出
const historyChart = ref()
const handleExport = async () => {
const planCsv = ref('')
const chartsCsv = ref('')
if (deviceData.value.records && deviceData.value.records.length != 0) {
let csv = '',
obj: any = {}
obj = deviceData.value.records.find((item: any) => {
return item.id == activeName.value
})
if (obj) {
//测试是否与变量名长度有关系
let cell1 = deviceData.value.itemName,
cell2 = deviceData.value.describe,
cell3 = obj?.itemName,
cell4 = obj?.statisticalInterval,
cell5 = voltageLevelList.find(vv => {
return vv.id == obj.voltageLevel
})?.name,
cell6 = volConTypeList.find(vv => {
return vv.id == obj.volConType
})?.name,
cell7 = obj.capacitySscmin,
cell8 = obj.capacitySi,
cell9 = obj.capacitySscb,
cell10 = obj.capacitySt,
cell11 = obj.pt && obj.pt1 ? obj.pt / obj.pt1 + '\b' : '/',
cell12 = obj.ct && obj.ct1 ? obj.ct / obj.ct1 + '\b' : '/',
cell13 = obj.startTime ? obj.startTime : '/',
cell14 = obj.endTime ? obj.endTime : '/',
cell15 = obj.location
csv = `方案测试项信息,
方案名称, ${cell1},
方案描述, ${cell2},
测试项名称, ${cell2},
测量间隔, ${cell4 + '分钟'},
电压等级, ${cell5},
接线方式, ${cell6},
最小短路容量, ${cell7 + 'MVA'},
用户协议容量, ${cell8 + 'MVA'},
基准短路容量, ${cell9 + 'MVA'},
供电设备容量, ${cell10 + 'MVA'},
PT变比, ${cell11},
CT变比, ${cell12},
起始时间, ${cell13},
结束时间, ${cell14},
监测位置, ${cell15}\n,
`
planCsv.value = csv
}
}
if (historyDataList.value.length != 0) {
let xAxis: any = []
let timeList: any = []
historyDataList.value.map((item: any) => {
timeList.push(item.time)
})
xAxis = timeList.sort((a: any, b: any) => {
new Date(a).getTime() - new Date(b).getTime()
})
xAxis = Array.from(new Set(xAxis))
// 使用这个函数转换数据为CSV格式
let csv: any = ''
const list = echartsData.value.options.series
csv = convertToCSV([], [])
chartsCsv.value = csv
// 如果你想提供下载链接
function convertToCSV(data: any, key: any) {
// 添加列头
let title = '统计时间,'
list.map((item: any, index: any) => {
index == list.length - 1 ? (title += `${item.name}\n`) : (title += `${item.name},`)
})
let csv = ''
csv = title
// 遍历数据并添加到CSV字符串中
list[0]?.data.map((vv: any, indexs: any) => {
let strs = '',
count = null
list.map((item: any, index: any) => {
if (index == 0) {
count = index
}
let itemList: any = list[index].data[indexs]
if (itemList && itemList.length != 0) {
itemList[1] = itemList[1] ? itemList[1] : '/'
index == list.length - 1 ? (strs += itemList[1]) : (strs += itemList[1] + ',')
} else {
index == list.length - 1 ? (strs += '/') : (strs += '/,')
}
})
if (count == 0 && xAxis[indexs]) {
csv += `${xAxis[indexs]},` + strs + '\n'
} else {
strs += '/,'
}
})
return csv
}
}
let csvs = ''
if (chartsCsv.value) {
csvs = planCsv.value + '历史趋势数据,\n\n' + chartsCsv.value
} else {
csvs = planCsv.value
}
// 如果你想提供下载链接
const blob = new Blob([csvs], { type: 'text/csv;charset=utf-8;' })
const link = document.createElement('a')
link.href = URL.createObjectURL(blob)
let obj = deviceData.value.records.find((item: any) => {
return item.id == activeName.value
})
const date = window.XEUtils.toDateString(new Date(), 'yyyyMMdd HHmmss').replace(' ', '_')
link.download = `${deviceData.value.itemName}_${obj?.itemName}_${date}.csv`
link.click()
return
}
const countData: any = ref([])
const countDataCopy: any = ref([])
const tableHeaderRef = ref()
//根据选择的指标处理谐波次数
const formatCountOptions = () => {
countData.value = []
// console.log(123, indexOptions.value);
if (searchForm.value.index.length != 0) {
searchForm.value.index.forEach((item: any, index: any) => {
countDataCopy.value.forEach((vv: any, vvs: any) => {
if (vv.index == item) {
countData.value.push(vv)
}
})
})
// indexOptions.value.map((item: any, index: any) => {
// if (!countDataCopy.value[index]) {
// countDataCopy.value[index] = {
// index: item.id,
// countOptions: [],
// count: [],
// name: indexOptions.value.find((vv: any) => {
// return vv.id == item.id
// })?.name
// }
// }
// legendDictList.value?.selectedList?.map((vv: any, vvs: any) => {
// //查找相等的指标
// if (item.id == vv.dataType) {
// vv.eleEpdPqdVOS.map((kk: any, kks: any) => {
// if (kk.harmStart && kk.harmEnd) {
// range(0, 0, 0)
// if (kk.showName == '间谐波电压含有率') {
// countDataCopy.value[index].countOptions = range(kk.harmStart, kk.harmEnd, 1).map(
// (item: any) => {
// return item - 0.5
// }
// )
// } else {
// countDataCopy.value[index].countOptions = range(kk.harmStart, kk.harmEnd, 1)
// }
// if (!countDataCopy.value[index].count || countDataCopy.value[index].count.length == 0) {
// countDataCopy.value[index].count = countDataCopy.value[index].countOptions[0]
// }
// }
// })
// }
// })
// })
// console.log("🚀 ~ vv.eleEpdPqdVOS.map ~ countData.value:", countDataCopy.value)
countData.value.map((item: any, key: any) => {
if (item.name.includes('谐波电流有效值')) {
item.name = '谐波电流次数'
}
if (item.name == '谐波电压含有率') {
item.name = '谐波电压次数'
}
if (item.name == '间谐波电压含有率') {
item.name = '间谐波电压次数'
}
})
} else {
countData.value = []
}
setTimeout(() => {
tableHeaderRef.value && tableHeaderRef.value?.computedSearchRow()
}, 100)
}
const flag = ref(false)
const selectChange = (e: boolean) => {
flag.value = e
// console.log("🚀 ~ handleChange ~ activeColName.value:", activeColName.value, flag.value)
if (activeColName.value == '0') {
if (flag.value) {
EcharHeight.value = mainHeight(480)
} else {
EcharHeight.value = mainHeight(436)
}
} else {
if (flag.value) {
EcharHeight.value = mainHeight(340)
} else {
EcharHeight.value = mainHeight(300)
}
}
}
const handleChange = () => {
if (activeColName.value == '0') {
if (flag.value) {
EcharHeight.value = mainHeight(480)
} else {
EcharHeight.value = mainHeight(436)
}
} else {
if (flag.value) {
EcharHeight.value = mainHeight(340)
} else {
EcharHeight.value = mainHeight(300)
}
}
setTimeout(() => {
transientRef.value && transientRef.value.setHeight()
}, 100);
}
watch(
() => searchForm.value.index,
(val: any, oldval: any) => {
// if (val) {
// let list = val
// setTimeout(() => {
// formatCountOptions(list)
// }, 100)
// countData.value.map((item: any, key: any) => {
// if (
// list.findIndex((vv: any) => {
// return vv == item.index
// }) == -1
// ) {
// countData.value.splice(key, 1)
// }
// })
// init(false)
// }
},
{
deep: true,
immediate: true
}
)
onMounted(() => {
setTimeout(() => {
init(true)
}, 1500)
})
</script>
<style lang="scss" scoped>
::v-deep .el-select {
min-width: 120px;
}
.device-manage {
display: flex;
height: calc(100vh - 100px);
// overflow-y: auto;
&-right {
// overflow: auto;
flex: 1;
padding: 10px 10px 10px 0;
.el-descriptions__header {
height: 36px;
margin-bottom: 7px;
display: flex;
align-items: center;
}
}
.device-manage-right {
overflow: hidden;
flex: 1 !important;
height: calc(100vh - 135px);
// padding: 10px 10px 10px 10px;
// border: 2px solid #eeeeee;
display: flex;
flex-direction: column;
.el-descriptions__header {
height: 36px;
margin-bottom: 7px;
display: flex;
align-items: center;
}
}
}
.history_title {
width: 100%;
padding-left: 10px;
p {
height: 32px;
line-height: 32px;
font-size: 16px;
font-weight: bold;
font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, SimSun, sans-serif;
}
}
::v-deep .monitor_info {
width: 100%;
.el-tabs__content {
padding: 0 !important;
// min-height: 130px !important;
}
}
.history_collapse {
height: calc(100vh - 300px);
width: 100%;
.history_trend {
width: 100%;
height: calc(100vh - 340px);
display: flex;
flex-direction: column;
.history_header {
width: 100%;
}
.history_chart {
margin: 10px 0;
z-index: 1001;
}
}
}
::v-deep .el-select {
width: 120px !important;
}
::v-deep .el-collapse-item__header {
font-size: 16px !important;
font-weight: 800 !important;
}
</style>